iptablesは多機能で複雑でわかりにくい。ここでは主にiptablesを入ってくるパケットに対するファイヤーウォール機能として考える。
まずiptablesはパケットに対して操作を行う。特にパケットのヘッダに対して行う。パケットのデータに対しては処理を行わない。
iptablesには3ビルトインテーブルfilter、nat、mangleがある、firewallとして使うにはfilterを用いる。filterはiptablesコマンドのデフォルトのテーブルであり、-tオプションを指定しなかった場合は、-t filterと同じ意味になる。
tableはchainの集まりとして定義される。chainはruleとtargetを組にしたものの集まりで定義される。ruleはフィルタそのもののことで、targetはそのフィルターにかかったパケットをどう処理するかを指定する。
filter tableにおけるビルドインchainとしてINPUT、FORWARD、OUTPUTが存在する。INPUTは入ってきたパケットで宛先が自分のものに適用される。FORWARDは宛先が自分でないもの、これはマシンをルーターとして動かしているときのもの、そしてOUTPUTは自分から出て行くパケットに適用される。
ユーザ定義のカスタムchainを定義することができ、これらのchainはビルドインchainのtargetととして利用できる。ビルドインchainはあらかじめどんなパケットに適用されているかが決まっているがカスタムchainはビルドインchainから呼び出される形で動くことになる。
targetにはACCEPT、DROP、REJECTなどのビルドインtargetがある。言葉のとおり、ACCEPTはパケットを受け入れ、DROPはパケットを捨て、REJECTはエラーパケットを返す。
実際に動かしてみる。ここではFedora8を使った。
現在のiptablesの状態を確認するには-Lオプションをもちいる。しかしこのオプションだけだと詳細が分からないので-vオプションも一緒に使う。-Lオプションはchain名を引数にとる。ここでは上記のように入ってくるパケットに対して考えているのでINPUT chainを見る。
# iptables -v -L INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
18 1727 RH-Firewall-1-INPUT all -- any any anywhere anywhere
まず、policy ACCEPTとあるが、policyとはすべてのruleにかからなかったパケットをどうするかを定義してもので、デフォルトではACCEPTになっている。つまりruleが一つも定義されてなければすべてのパケットを受け入れると言うことである。
コラムを順に見ると protはプロトコルでinは入ってきたパケットのインターフェース(ネットワークカード)でoutは出て行くパケットのインターフェース。しかしINPUT chainにおいてはoutは関係ないと思われる。sourceはパケットのソースIP、destinationはデストIP、しかし同様にここではINPUT chainなので、デストIPは自分自身のはずである。
エントリーをみると targetがRH-Firewall-1-INPUTになっていて、protなどがanyとなっている。つまりINPUT chainに入ってくるパケットはすべてRH-Firewall-1-INPUT chainに送られるようになっている。そこでこのchainを見てみる。
# iptables -v -L RH-Firewall-1-INPUT
Chain RH-Firewall-1-INPUT (1 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo any anywhere anywhere
0 0 ACCEPT icmp -- any any anywhere anywhere icmp any
0 0 ACCEPT esp -- any any anywhere anywhere
0 0 ACCEPT ah -- any any anywhere anywhere
0 0 ACCEPT udp -- any any anywhere 224.0.0.251 udp dpt:mdns
0 0 ACCEPT udp -- any any anywhere anywhere udp dpt:ipp
0 0 ACCEPT tcp -- any any anywhere anywhere tcp dpt:ipp
179 27376 ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- any any anywhere anywhere state NEW tcp dpt:ssh
4 926 REJECT all -- any any anywhere anywhere reject-with icmp-host-prohibited
一番最初のエントリーでinがloのものはすべてACCEPTしている。これによりブラウザなどでhttp://localhost/でアクセスしたときのパケットを許可している。
つぎにicmpでpingを許可し、esp、ahでIPSec関係のパケットを許可している。
重要なエントリーはstate RELATED,ESTABLISHEDのある行で、実際ほとんどのパケットはここで許可される。stateとは対象パケットが通信全体から見た場合どういう状態でのパケットなのかを表したもので、ESTABLISHEDはすでに通信が確立しているもの、例えばブラウザでどこかのサイトにアクセスし、その結果として戻ってきたパケットはstateがESTABLIEDになる。これを許可しないとほとんどの通信ができなくなってしまう。RELATEDは多分FTPのデータ経路などをACTIVEで開いたときに入ってきたパケットを許可するものだと思う。
つぎのエントリーでsshの接続を許可している、state NEWとあるので、通信開始時のパケットを許可していることになる。一度開始されればそれ以降のパケットは上記のESTABLISHEDで許可されることになるので、state NEWとしているのだと思われる。
一番最後のエントリーでそれ以外のすべてのパケットがREJECTされている。最初に書いたようにREJECTだとエラーパケットを返す。