netfilter: IP オプションを持つパケットをドロップする

netfilter: IP オプションを持つパケットをドロップする

ヘッダーの後にIPv4any が続くパケットをドロップするルールを追加したいと思います。ヘッダーの (インターネット ヘッダー長) フィールドには、オプションを含む IPv4 ヘッダーの 32 ビット ワードの数が含まれていると理解しています。したがって、ルールはフィールドからパケット + オプションの長さを取得し、20 (オプションなしの IPv4 ヘッダー長) と比較し、20 より大きい場合はパケットをドロップするはずです。IP optionIHLIHL

ヘッダーを検査して評価(算術演算)iptablesできる特定のモジュールはありますか?IP

答え1

iptablesu32条件に一致するようにパケット ペイロード上でビット単位 (任意の算術演算ではない) の演算、範囲の比較、およびポインタのような間接参照を実行できる match メソッドが含まれています。

u32

U32 は、パケットから抽出された最大 4 バイトの量が指定された値であるかどうかをテストします。抽出する内容の指定は、TCP ヘッダーまたはペイロードから指定されたオフセットにあるデータを見つけるのに十分な汎用性があります。

独自のサブ言語文法があり、マニュアルの文法と例を調べる必要があります。

国際人権法は IP ヘッダー サイズ (バイトではなく 32 ビットのチャンク) であり、ヘッダーの最初の 32 ビット (IPv4 の場合は値 0x04 のバージョンの 4 ビット、その後に IHL の 4 ビット) の一部です。したがって、オプションがない場合は、このサイズが最小サイズになります: 20 (バイト) / 4 (32 ビット ワードあたりのバイト数)、つまり IHL = 5 (32 ビット ワード)。IHL < 5 の無効なケースは処理しません。IPv4 スタックがすでにこれを処理しているはずです。

これは次のように翻訳されます:

  • 最初の32ビットの値を取得する
  • IHL部分をマスクする
  • 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 ビットだけはその 4 倍にさらに数ビットを加えたものになります。次に &3C は右側の余分な 2 ビットと最初のバイトの最初の 4 ビットを削除します。たとえば、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ビットの値を取得する
  • IHL部分をマスクする
  • 等しいかどうかを(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 の間であれば OK ではありません。

与える:

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

または:

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

お選びください。

関連情報