特定の内容の通信だけを遮断したくなり、きっとiptablesに何かあるだろうと調べたらstringモジュールがあった。iptables 1.4.6のmanpageから引用する。
string
This modules matches a given string by using some pattern matching
strategy. It requires a linux kernel >= 2.6.14.
--algo {bm|kmp}
Select the pattern matching strategy. (bm = Boyer-Moore, kmp =
Knuth-Pratt-Morris)
--from offset
Set the offset from which it starts looking for any matching. If
not passed, default is 0.
--to offset
Set the offset from which it starts looking for any matching. If
not passed, default is the packet size.
[!] --string pattern
Matches the given pattern.
[!] --hex-string pattern
Matches the given pattern in hex notation.
遮断の条件に指定したい内容が非ASCIIのバイト列だったので–hex-stringを指定した。–hex-string ‘e7a781e381aee5908de5898de381af…’のように。ところがうまくいかず、ありそうな書式をいくつか試しても変わりがない。ふと、試しに、文字列をそのまま(16進数表記にせずに)指定したところ、当初の意図の通りにマッチした。
どうやら何かの書式があるらしいと、iptablesのコードにあたったところ、以下のルールに従ってバイト列に変換されることがわかった。
- 「|」にはさまれた部分はバイト列の16進数表記として処理される
- それ以外の部分にある文字はその文字自身を表す
- ただし「\」により続く文字の特別な意味をキャンセルできる(「\|」や「\\」)
先の例については–hex-string ‘|e7a781e381aee5908de5898de381af…|’とするのが正しいやり方となる。また、–hex-string ‘a|62|c’は「abc」にマッチし、–string abcや–hex-string abcを指定したのと同じ結果となる。指定できるバイト列の長さ(変換後の長さ)は128バイトまでのようだ。
–fromや–toの指定を加えると、マッチ対象とする範囲を指定できる。–from 20ならTCPヘッダ(など)以降(〜65535バイト目まで)が対象となり、特に指定しなければIPパケットの先頭から65535バイト目までが対象範囲となる。