netfilter:丢弃具有 IP 选项的数据包

netfilter:丢弃具有 IP 选项的数据包

我想添加一条规则,丢弃IPv4带有任何IP option跟随标头的数据包。据我了解,IHL标头中的(Internet 标头长度)字段包含 IPv4 标头中 32 位字的数量,包括选项。所以,我的理解是,规则应该从IHL字段中获取数据包+选项长度并与20(不带选项的IPv4标头长度)进行比较,如果大于20,则丢弃数据包。

是否有一个特定的iptables模块允许检查IP标头并评估(进行算术运算)?

答案1

iptables包括u32match 方法,该方法允许对数据包负载执行一些按位(但不是任意算术)操作、范围比较和一些类似指针的间接寻址以匹配条件:

u32

U32测试从数据包中提取的最多4个字节的数量是否具有指定值。提取内容的规范足够通用,可以从 tcp 标头或有效负载中查找给定偏移量处的数据。

它有自己的子语言语法,应该检查手册中的语法和示例。

国际人道法是 IP 标头大小(以 32 位块而不是字节为单位),并且是标头中前 32 位的一部分(对于 IPv4 值为 0x04 的版本,为 4 位,后跟 IHL 的 4 位),因此,如果没有选项,此大小应为最小大小: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) 字节。
[...]

给予OP的案例:

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 之间的范围进行比较以确定 OK(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

选择你的选择。

相关内容