10.2. 暗黙的なマッチ

このセクションでは、暗黙的にロードされるマッチを取り扱う。暗黙的なマッチ (implicit match) は、暗示された、存在が前提的自動的に認められたマッチだ。例えば、 --protocol tcp によるマッチをその他の評価基準なしで行う場合などが当てはまる。現在のところ、 iptables は 3つのプロトコルに対応する 3種類の暗黙的マッチを備えている。 TCPマッチUDPマッチICMPマッチ だ。 TCP ベースのマッチには、 TCP パケットでのみ有効な特有の評価基準がある。 UDP ベースのマッチでは、 UDP パケットにのみ利用可能な、また別の評価基準がある。 ICMP パケットにもまた同じことが言える。これに対して、明示的にロードしなくてはならない、明示的なマッチがあってもおかしくない。明示的なマッチ (explicit match) は、暗黙的でない、自動的でないマッチで、使用したければ明確に指定する必要がある。その際に使うのが -m または --match オプションだが、それについては次のセクションで詳述することにしよう。

10.2.1. TCPマッチ

これらのマッチはプロトコル固有で、 TCP パケットおよび TCP ストリームを取り扱う場合にのみ有効だ。このマッチを使用するには、コマンドライン上の、これらを使用する前で --protocol tcp を指定しなければならない。念を押しておこう。 --protocol tcp は必ず、特定のプロトコルマッチよりも左側に置く必要がある。これらのマッチは、 UDPマッチICMPマッチ がそうであるように、ある意味、暗黙的にロードされる。 UDP および ICMPマッチについては、 TCPマッチ の後に続くセクションで目を通す。

Table 10-2. TCPマッチ

マッチ--sport, --source-port
カーネル2.3, 2.4, 2.5, 2.6
iptables -A INPUT -p tcp --sport 22
説明--source-port マッチは、その送信元ポートに基づいてパケットを一致させるのに使われる。このマッチを指定しない時には、すべての送信元ポートを暗に合致させていることになる。後ろにはサービス名かポートナンバーを採る。サービス名を指定した場合、そのサービス名は /etc/services ファイルに載っていなければならない。 iptables はこのファイルを検索するからだ。ポートをポートナンバーで指定したほうが、 iptables はサービス名をチェックする必要がなくなるため、ルールのロードはわずかながら速い。しかし、サービス名を使用するのに比べてルールセットはやや読みにくくなる。 200個以上のルールから成るルールセットを書くなら、速度の違いは顕著になるので、迷うことなくポートナンバーのほうを使うべきだ。 (遅いサーバで 1,000 以上のルールを含むような巨大なルールセットを組んだ場合、 10秒単位の差が出ることも珍しくない)。 --source-port 22:80 といった具合に、 --source-port マッチにポートの範囲を使うことも可能だ。この例は 22 から 80 までのポートにマッチする。最初のポートを省略すると、(暗黙的に) ポート 0 として解釈される。 --source-port :80 はポート 0 から 80 にマッチする。また、最後のポートが省略されると、ポート 65535 として解釈される。ポート範囲をひっくり返した場合には、 iptables が自動的に再逆転して元に戻す。もし --source-port 80:22 と書けば、単純に --source-port 22:80 として解釈される。また、 ! 記号を加えることによってマッチを反転させることもできる。例えば --source-port ! 22 は、ポート 22 以外のすべてのポートに一致する。反転はポート範囲との併用も可能で、即ち --source-port ! 22:80 のような記述となり、この例は 22 から 80 までを除く全ポートにマッチさせたいということを表している。注意としては、このマッチは離ればなれのポートとポートや、複数の範囲を扱うことができない。そうした利用について知りたいなら、マルチポート(multiport) マッチ拡張を見てみてほしい。
マッチ--dport, --destination-port
カーネル2.3, 2.4, 2.5, 2.6
iptables -A INPUT -p tcp --dport 22
説明このマッチは TCP パケットを宛先ポートによってマッチさせる。文法は --source-port マッチとまったく同じだ。ポートやポート範囲の指定はもちろん、反転も通用する。また同様に、ポート範囲指定における高低の入れ替えも働く。早い話が --source-port の文法と瓜二つだ。注意としては、このマッチは離ればなれのポートとポートや、複数の範囲を扱うことができない。そうした利用について知りたいなら、マルチポート(multiport) マッチ拡張を参照してほしい。
マッチ--tcp-flags
カーネ2.3, 2.4, 2.5, 2.6
iptables -p tcp --tcp-flags SYN,FIN,ACK SYN
説明このマッチは、TCP のフラグでパケットをマッチさせるのに利用する。これはふたつの引数を取り、まず最初の引数では検討するフラグのリスト (マスク)、そして 2番目で、"1" にセットされているべき (ON になっている) フラグのリストを指定する。ふたつのリストはともにカンマ区切りだ。このマッチに理解できるのは SYN, ACK, FIN, RST, URG, PSH のフラグであり、加えて ALLNONE という語彙も理解する。 ALLNONE は読んで字の如しだが、 ALL はこのオプションに対してすべてのフラグを指定し、 NONE はどのフラグも指定しないことに通じる。つまり、 --tcp-flags ALL NONE は、 TCP フラグすべてを確認して、そのどれひとつとしてセットされていなければマッチするということだ。このオプションは ! 記号で反転することも可能で、例えば ! SYN,FIN,ACK SYN と指定すれば、ACK ビットと FIN ビットは立っているが SYN ビットの立っていないパケットに合致するマッチを作ることができる。カンマ区切りのリストの中にホワイトスペースを入れてはいけないことに注意しよう。正しい文法は上記の用例で分かるだろう。
マッチ--syn
カーネル2.3, 2.4, 2.5, 2.6
iptables -p tcp --syn
説明--syn マッチは ipchains 時代からの遺物の類で、下位互換性と、 ipchains から、あるいは ipchains への移行を容易にするために未だ残されている。もし SYN ビットが立ち ACK ビットと RST ビットが立っていなければ、そのパケットにマッチする。つまり、 --tcp-flags SYN,RST,ACK SYN というマッチと同義だ。このようなパケットは、主として、新しい TCP コネクションをサーバに要求する時に使われる。これらのパケットをブロックすれば、外から接続して来ようとする企てを見事にブロックする効果が得られる。とはいうものの、あなたはまだ外へ出ていくコネクションはブロックしていないだろう。昨今、数々の不正侵入によく使われるのが外へのコネクションなのだ (例えば、正規のサービスをハッキングして何らかのプログラムに類するものをインストールしてから、新たなポートを開けるのではなく既存のコネクションを利用して、あなたのホストへの接続を導き入れるなど)。このマッチは ! --syn のように ! 記号による反転も可能で、これは RSTACK ビットの立ったパケット、つまり、確立済み (established) のコネクションにマッチする。
マッチ--tcp-option
カーネル2.3, 2.4, 2.5, 2.6
iptables -p tcp --tcp-option 16
説明このマッチはパケットの TCPオプション によるマッチに利用される。 TCPオプションとは、ヘッダの中の特別な部分だ。このヘッダ部位は、意味合いの異なる 3つのフィールドで構成されている。最初のフィールドは 8ビット長で、そのストリームでどんなオプションを使用しているかを告げる。 2番目のフィールドは、やはり 8ビット長だが、オプションフィールドの長さを知らせている。長さを示すフィールドがなぜ必要なのかといえば、 TCPオプションはそもそも存在自体が任意だからだ。すべてのオプションをサポートしていなくても、規格違反というわけではない。だから、パケットに使用されているのがどのオプションかを調べて、それがこちらのサポート外だったら、そのデータを読み飛ばしても構わないのだ。このマッチは、オプションを数字で表した値を使って、様々な TCPオプションをマッチさせる。 ! 記号で反転することも可能で、その場合のマッチは、指定した以外の TCPオプションに合致する。オプションの完全なリストを見たければ Internet Engineering Task Force を参照のこと。 IETF はインターネットで使用される数字規格を管理している団体だ。

10.2.2. UDPマッチ

このセクションでは、UDP パケットとの組み合わせでのみ機能するマッチについて述べる。これらのマッチは --protocol UDP を指定することによって暗黙的にロードされ、利用が可能となる。忘れてはならないのは、 UDP パケットがコネクション指向のプロトコルではないという点だ。よって UDP パケットは、コネクションを開きたいのか閉じたいのか、あるいは単にデータを送ろうとしているのかといったデータグラムの目的に応じて、パケットに立てるフラグを区別したりはしない。そればかりか、 UDP パケットはいかなる種類の了解 (acknowledgement) も行わない。パケットが消失したら、ただ消失されっぱなしだ (ICMPエラーメッセージなどは考慮に入れないとしての話)。以上のことから、 UDP パケットで機能するマッチは TCP パケットに比べてはるかに少なくなる。ただし、ステート機構は、 UDPICMP といった非コネクション指向のプロトコルであっても、すべての種類のパケットに対して機能する。ステート機構は UDP パケットに対しても TCP パケットとまったく同様に機能するのだ。

Table 10-3. UDPマッチ

マッチ--sport, --source-port
カーネル2.3, 2.4, 2.5, 2.6
iptables -A INPUT -p udp --sport 53
説明このマッチは TCP版 とまったく同様に働く。送信元 UDP ポートに基づいてパケットのマッチを行うのに使用する。ポートの範囲、単一のポート、意味の反転も、同様の書式でサポートされている。 UDP ポートの範囲を指定するには、22:80 とすればよく、これは UDP22 から 80 番ポートにマッチする。初めの値を省略すると、ポート 0 と解釈、後ろの値を省略すれば 65535 と解釈される。数字の大きいポートが若いポートより前に指定されていた場合には、前後のポートは自動的に入れ替わる。単一UDP ポートによるマッチは上記の例に見る通りだ。ポートマッチを逆転するには ! 記号を使い、 --source-port ! 53 のように書く。これはポート 53 以外のすべてのポートにマッチする。このマッチは /etc/services に記載があるものに限っては、サービス名も理解する。なお、このマッチは離ればなれのポートとポートや、複数の範囲を扱うことができない。そうした利用について知りたいなら、マルチポート(multiport) マッチ拡張を見てほしい。
マッチ--dport, --destination-port
カーネル2.3, 2.4, 2.5, 2.6
iptables -A INPUT -p udp --dport 53
説明前記の --source-port と同じことがこのマッチにも当てはまる。 UDP パケットに用いられるということ以外では、 TCP における同一機能のマッチと完全に同じだ。このマッチは UDP の宛先に基づいてパケットマッチを行う。ポートの範囲、単一ポート、意味反転を扱うことができる。単一のポートに使うには --destination-port 53 のように用い、反転するには --destination-port ! 53 などとすればよい。ひとつ目のマッチはポート 53 に宛てられたすべてのパケットにマッチし、2番目の例はポート 53 へ向かおうとするもの以外のパケットにマッチする。ポートの範囲を指定するには --destination-port 9:19 のように用いる。この例は UDP9 から 19 までを宛先とするすべてのパケットに合致する。初めのポートが省略されれば、ポート 0 と了解され、2番目が省略されればポート 65535 と解釈される。数字の大きいポートが若いポートより前に指定されていた場合には、自動的に入れ替えられ、若いほうのポートが数字の大きいポートの前に繰り込まれる。なお、このマッチは離ればなれのポートとポートや、複数の範囲を扱うことができない。そうした利用について知りたいなら、マルチポート(multiport) マッチ拡張を見ていただきたい。

10.2.3. ICMPマッチ

ICMP にもいくつかのマッチがある。 ICMP パケットは、コネクションレスであるという面で UDP にも増して生存時間が短い、つまり短命だ。 ICMP プロトコルは主に、エラー通知やコネクションコントロールに類する事柄に使われる。 ICMP は、 IPプロトコルの構成要素というよりも、どちらかといえば IP プロトコルを補強する プロトコルとしての性格が強く、エラー担当という役目で IPプロトコルを補佐している。 ICMP パケットのヘッダは IPヘッダ と非常に似通っているものの、いくつかの点において違いがある。その最も特徴的なものが、タイプヘッダだ。これはパケットの目的を表す。ひとつの例を挙げると、アクセス不能の IPアドレスにアクセスしようとした場合、我々は通常、入れ違いに ICMP host unreachable を受け取る。 ICMP タイプの完全なリストが知りたければ、付録 ICMPタイプ を見ていただきたい。 ICMP パケットで利用可能な特有のマッチは 1種類しかないが、たいていはそれだけで事足りる。このマッチは --protocol ICMP を使用した際に暗黙的にロードされ、自動的に利用可能となる。ただし、汎用的なマッチICMP にも使用でき、それによって送信元アドレスや宛先アドレスなどによるマッチも行うことができる。

Table 10-4. ICMPマッチ

マッチ--icmp-type
カーネル2.3, 2.4, 2.5, 2.6
iptables -A INPUT -p icmp --icmp-type 8
説明

このマッチは、合致すべき ICMPタイプ を指定して利用する。 ICMPタイプ は数値でも名称でも指定可能だ。数値は RFC 792 に規定されている。名称での ICMP 値の完全なリストを得るには、 iptables --protocol icmp --help するか、付録 ICMPタイプ を参照のこと。マッチは --icmp-type ! 8 という具合に ! 記号で反転することも可能だ。いくつかの ICMPタイプ は時代遅れで使われなくなっており、他の幾つかのタイプはまた、パケットをお門違いの場所へリダイレクトするなどといった作用も起こしかねないので、きちんと防御していないホストにとって "脅威" とも成り得るという点に注意が必要だ。なお、タイプとコードは、タイプ名称、タイプ番号で書く以外に、 type/code の形で指定することもできる。例えば --icmp-type network-redirect や, --icmp-type 8 や, --icmp-type 8/0 といった具合だ。指定できる名称の全リストは iptables -p icmp --help で得られる。

Note

すべての ICMP タイプをマッチさせる時、netfilterICMP タイプ 255 を使用しているということに気を付けたほうがいい。タイプ 255 の ICMP を捕まえようとしても、 ICMP のタイプのどれもこれもがマッチしてしまうことになるので注意が必要だ。

10.2.4. SCTPマッチ

SCTP つまり Stream Control Transmission Protocol は、 TCPUDP プロトコルに比べると登場して日の浅いネットワークプロトコルだ。SCTP については SCTPの特徴 のチャプターでもっと詳しく述べる。暗黙的な SCTP マッチは iptables コマンドラインに -p sctp を加えた時にロードされる。

SCTP は大手の通信系及びスイッチ/ネットワーク機器メーカー数社によって開発されたプロトコルで、高スループットと信頼性を確保しながら相当数の同時並行トランザクションを成り立たせなければならないような環境に向いている。

Table 10-5. SCTPマッチ

マッチ--source-port, --sport
カーネル2.6
iptables -A INPUT -p sctp --source-port 80
説明

--source-port マッチは SCTP パケットヘッダの送信元ポートに基づいて SCTP パケットをマッチさせるのに使う。ポートには、例に示したように単一のポートを指定することも、 --source-port 20:100 のように範囲で指定したり、 ! マークによって意味を反転させることもできる。最後の形式は例えば --source-port ! 25 といった具合になる。送信元ポートに指定できるのは符号なしの 16ビット数値、つまり最大値は 65535、最小値は 0 ということになる。

マッチ--destination-port, --dport
カーネル2.6
iptables -A INPUT -p sctp --destination-port 80
説明

このマッチは SCTP パケットの宛先に対してマッチを行う。 SCTP パケットはもれなく、そのヘッダに、送信元ポートと並んで宛先のポート情報も持っている。ポートは、例のように指定したり、ポート範囲で --destination-port 6660:6670 のように指定することができる。また、--destination-port ! 80 のように ! マークで反転することもで、この例ならポート 80 以外にマッチすることになる。ポートの値に関しては送信元の場合と同様で、最大値 65535、最小値は 0

マッチ--chunk-types
カーネル2.6
iptables -A INPUT -p sctp --chunk-types any INIT,INIT_ACK
説明

SCTP パケットのチャンク (chunk) タイプによるマッチを行う。現在のところ、チャンクタイプにはかなりの種類がある。詳しくは下記を参照いただきたい。マッチは --chunk-types キーワードで始まり、続いて、どうマッチさせるかを表す all, any または none のフラグ。その後ろに マッチさせたい SCTPチャンクタイプ を指定する。チャンクタイプの種類は下記の表に別記した。

フラグには、追加パラメータとして チャンクフラグ を付加することもできる。例えば --chunk-types any DATA:Be という指定になる。フラグは SCTPチャンクタイプ 毎に異なり、当該のチャンクに対して有効なものでなければならない (別表に示す)。

フラグを大文字で書いた場合には、それがセットされたパケットに対してマッチは真となり、小文字の場合はセットされていない時に真となる。--chunk-types キーワードの手前に ! 記号を置くとマッチ全体の意味を反転させることができる。例えば --chunk-types ! any DATA:Be は、そのパターンを除いた全てのものにマッチする。

下記に示したのが --chunk-types マッチの認識する全ての チャンクタイプ のリストだ。見ての通り膨大な数だが、通常用いられるのは概ね DATA パケットと SACK パケット程度である。その他のものは主にアソシエーションの制御に用いられる。

--chunk-typesで使用できるSCTPチャンクタイプ

前述した、--chunk-types マッチで使用できるフラグの種類が下記。 RFC 2960 - Stream Control Transmission Protocol の規定によると、これ以外のフラグは予約済みか使用されていないかのどちらかとなっており、必ず 0 でなければならない。ありがたいことに、今のところ iptables はそれを強要する何らの仕組みも持っていない。かつて IP プロトコルに ECN が実装された時の二の舞となりかねないからだ。

--chunk-typesで使用できるチャンクフラグ