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

選擇你的選擇。

相關內容