7.1. はじめに

ステート機構は iptables の中でも特別な部分であり、本当はステート機構などという名前でさえない。本当はコネクション追跡 (connection tracking) メカニズムのひとつだ。しかし、一般には前者の名で知られている。このチャプターを通して、僕はこれらふたつの名前を同義語のように使っていくが、おそらくひどい混乱を引き起こすことはないだろう。コネクション追跡は、特定の接続における状態 (state) を Netfilter のフレームワークに伝えるためのものだ。こうした機能を備えたファイヤーウォールは、ステートフル (stateful) ファイヤーウォールと呼ばれる。概して、ステートフルファイヤーウォールでは、よりタイトなルールセットが書けるので、ステートフルでないファイヤーウォールよりも高いセキュリティが得られる。

iptables 内部では、パケットは、追跡済みの接続 (tracked connections) との関連性に応じて 4 つの"ステート "なるものに類別される。 NEW, ESTABLISHED, RELATED, INVALID の 4 つだ。各ステートについては追って詳しく述べるが、新たなセッションの開始を誰に、あるいは何に対して許可するかが、 --state マッチを使えばいとも簡単に制御できる。

コネクション追跡は、カーネル内部の conntrack と呼ばれる特別なフレームワークによって行われる。この conntrack はモジュールとしてロードすることもできるし、カーネル自体に組み込んでおくこともできる。たいていは、デフォルトの conntrack エンジン単独でできるよりも、もっと特殊なコネクション追跡を必要とすることのほうが多い。そのために、 TCPUDPICMP プロトコルに対して作用するものなど、より特殊なコンポーネントも用意されている。これらのモジュールは、パケットから特有の情報を読み取り、データストリームを追跡の目から逃さないようにする。 conntrack が収集した情報は、ストリームが現在どのステートにあるのかを conntrack が判断するために用いられる。例えば UDP ストリームであれば、あくまでも一般論だが、宛先IPアドレス, 送信元IPアドレス, 宛先ポート, 送信元ポートによってストリームを特定することができる。

先代のカーネルでは、デフラグメンテーション のオン/オフを切り替えることも可能だった。しかし、 iptablesNetfilter、殊にコネクション追跡が提供されるようになってからは、このオプションは無用となった。コネクション追跡はパケットのデフラグメンテーションなしには正常に機能しないため、デフラグメンテーションは conntrack に組み込まれて自動的に行われるようになったからだ。もはや、デフラグメンテーションをオフにするには、コネクション追跡を切るしかない。コネクション追跡を有効にすれば、デフラグメンテーションも常に行われる。

パケットがローカルで発生したものである場合を除き (この場合は OUTPUT チェーンで行われる)、コネクション追跡はすべて PREROUTING チェーンで行われる。つまり、ステートの再検出などすべての処理は PREROUTING チェーン内で行われるのだ。ローカルからストリームの開始となるパケットを送出した場合、 OUTPUT チェーンにおいて、このストリームは NEW ステートだと判定が下される。このパケットに対して返答が返ってくれば、 PREROUTING チェーンでステートが ESTABLISHED に変わる、といった具合だ。最初のパケットがローカルを始祖とするものでなかった場合には、PREROUTING チェーンで下される判断は、無論 NEW ステートとなる。