netfilter: отбрасывать пакеты с параметрами IP

netfilter: отбрасывать пакеты с параметрами IP

Я хотел бы добавить правило, отбрасывающее IPv4пакет с любым IP optionследующим за заголовком. Я понимаю, что IHLполе (длина заголовка Интернета) в заголовке содержит количество 32-битных слов в заголовке IPv4, включая опции. Таким образом, я понимаю, что правило должно получить длину пакета+опции из IHLполя и сравнить с 20 (длина заголовка IPv4 без опций), и если она больше 20, отбросить пакет.

Существует ли специальный iptablesмодуль, позволяющий проверять IPзаголовок и оценивать его (выполнять арифметические операции)?

решение1

iptablesвключает в себя u32метод match, который позволяет выполнять некоторые побитовые (но не произвольные арифметические) операции, сравнения диапазонов и некоторые указательные косвенные обращения к полезной нагрузке пакета для соответствия условиям:

u32

U32 проверяет, имеют ли величины до 4 байтов, извлеченные из пакета, указанные значения. Спецификация того, что извлекать, достаточно общая, чтобы найти данные с заданными смещениями из заголовков или полезных нагрузок TCP.

Он имеет свою собственную грамматику подъязыка, поэтому следует изучить грамматику и примеры в руководстве.

МГП— размер заголовка IP (в 32-битных фрагментах, а не в байтах) и является частью первых 32 бит в заголовке (4 бита для версии со значением 0x04 для IPv4, за которыми следуют 4 бита для IHL) и , поэтому, если нет опции, этот размер должен быть минимальным: 20 (байт) / 4 (байт на 32-битные слова), поэтому IHL = 5 (32-битные слова). Я не буду обрабатывать недопустимые случаи, когда IHL < 5, стек IPv4 уже должен был позаботиться об этом.

Это означает:

  • взять первые 32 бита значения
  • замаскировать его для части МГП
  • сдвиньте его на 24 бита
  • сравнить равенство с 5 (инвертировать результат с !соответствующим совпадением)

Итак, чтобы отбросить такой входящий пакет с помощьюiptables:

iptables -A INPUT -m u32 ! --u32 '0 & 0x0F000000 >> 24 = 5' -j DROP

без инверсии (вместо этого соответствует 6 или больше):

iptables -A INPUT -m u32 --u32 '0 & 0x0F000000 >> 24 = 6:0xF' -j DROP

В руководстве есть похожий пример, где данные сдвигаются на 24 бита, а затем умножаются на 4 (то есть сдвигаются только на 22 бита), чтобы получить байты, а не 32-битные слова (потому что указатели, u32используемые позже, используют 8-битные адреса), чтобы извлечь начало полезной нагрузки уровня 4 и продолжить дальнейшие операции:

... 0 >> 22 & 0x3C @ 0 >> 24 = 0"

Первый 0 означает чтение байтов 0-3, >>22 означает сдвиг на 22 бита вправо. Сдвиг на 24 бита даст первый байт, поэтому только 22 бита — это в четыре раза больше плюс еще несколько бит. Затем &3C удаляет два дополнительных бита справа и первые четыре бита первого байта. Например, если IHL=5, то заголовок IP имеет длину 20 (4 x 5) байт.
[...]

даю показания в пользу ОП:

iptables -A INPUT -m u32 ! --u32 '0 >> 22 & 0x3C = 20' -j DROP

без инверсии (и не заботясь о том факте, что первое следующее возможное значение не 21, а 24, и не заботясь о точном максимальном значении, пока заданное значение больше):

iptables -A INPUT -m u32 --u32 '0 >> 22 & 0x3C = 21:0xFF' -j DROP

Первый метод можно упростить следующим образом:

  • взять первые 32 бита значения
  • замаскировать его для части МГП
  • сравнить равенство с (5<<24), т.е. сравнить с 0x05000000 (то же самое)

давая:

iptables -A INPUT -m u32 ! --u32 '0 & 0x0F000000 = 0x05000000' -j DROP

или:

iptables -A INPUT -m u32 --u32 '0 & 0x0F000000 = 0x06000000:0x0F000000' -j DROP

или даже:

  • взять первые 32 бита значения
  • сравните значение с диапазоном от 0x45000000 до 0x45FFFFFF для ОК (IPv4всегданачинается с 4, и любое значение после части IHL следует игнорировать) или между 0x46000000 и 0x4FFFFFFF, если не ОК.

давая:

iptables -A INPUT -m u32 ! --u32 '0 = 0x45000000:0x45FFFFFF' -j DROP

или:

iptables -A INPUT -m u32 --u32 '0 = 0x46000000:0x4FFFFFFF' -j DROP

Сделайте свой выбор.

Связанный контент