rc.DHCP.firewall.txt は、ほぼ rc.firewall.txtの原型そのままだ。ただし、こちらのスクリプトでは変数 $INET_IP
は使っておらず、そこが元の rc.firewall.txt との大きな違いだ。動的IP での接続 (dynamic IP connection) との組み合わせだと、それでは機能してくれないからだ。とはいえ、原型からの変更点は最小限に留めている。こうしたケースでの問題をメールで質問されたことが何度かあるので、このスクリプトはきっと良い解決策になるだろう。このスクリプトでは、インターネット接続に DHCP、PPP、SLIP を使うことが
できるのだ。
rc.DHCP.firewall.txt スクリプトを満足に働かせるには、最低限でも以下のオプションが、スタティックに、あるいはモジュールとして、カーネルにコンパイルされている必要がある。
CONFIG_NETFILTER
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_FILTER
CONFIG_IP_NF_NAT
CONFIG_IP_NF_TARGET_MASQUERADE
CONFIG_IP_NF_TARGET_LOG
原型からの変更点の主なものは、先にも述べた $INET_IP
変数の除去と、それを参照する記述の削除だ。この変数を使用する代わりに、このスクリプトでは主要なフィルタリングを変数 $INET_IFACE
に基づいて行っている。言い換えれば、-d $INET_IP が -i $INET_IFACE へ変わったわけだ。これがほぼ唯一の変更と言っても過言ではなく、実際、どうしても必要だったのはこれだけなのだ。
ただし、考察しておくべき点がまだ少しばかり残っている。我々はもう、INPUT チェーンでのフィルタリングを --in-interface $LAN_IFACE --dst $INET_IP のような評価基準で行うことはできない。その結果、内側のマシンがインターネット上で有効な種類の IP にアクセスしなければならなくなった際には、インターフェースに基づいてフィルタリングするしかなくなってしまう。その典型となるのが、我々がファイヤーウォール内で HTTP を運営している場合だ。内側のマシンでメインページ (例えば http://192.168.0.1/) を開き、そこに、同じホストへ戻る絶対指定のリンク (例えば http://foobar.dyndns.net/fuubar.html。これはダイナミックDNSに対応するためのひとつの方策) があったとすると、ちょっとした問題が起こる。この NAT されたマシンは HTTP サーバの IP を DNS に問い合わせ、その IP にアクセスしようとする。インターフェースと IP に基づくフィルタリングを行っている場合、INPUT チェーンはそのパケットを床に叩きつけて DROP してしまうので、NAT されたマシンは HTTP に辿り着けない。これは或る意味、固定IP を使っている際にも当てはまるのだが、その場合には、LANインターフェース で $INET_IP
宛のパケットかどうか調べて合致すれば ACCEPT する、というルールを加えることで切り抜けられるのだ。
前のほうから読み進んできた人なら見当がついたと思うが、動的IP をもうちょっとマシに処理できるスクリプトをどこかから入手するか、自分で書き上げるというのは名案だ。例えば、インターネット接続が立ち上がったと同時に ifconfig の出力から IP を取り出して変数にセットするようなスクリプトを書けばいいのだ。一案としては、例えば pppd などのプログラムと一緒に提供されている ip-up スクリプトを利用する手がある。役に立つサイトを探すなら、linuxguruz.org の iptables サイトを見てみるといいだろう。そこでは、膨大な数のスクリプトがダウンロードできるようになっている。linuxguruz.org へのリンクは付録 その他の資料とリンク にある。
このスクリプトは rc.firewall.txt スクリプトに比べるとセキュリティにやや不安がある。外からのアタックに対して防御が甘くなっているので、上記のようなスクリプトが利用可能ならば、迷うことなくそれを使うことを強くお勧めする。 |
または、ファイヤーウォールスクリプト自体の中に、こうしたものを追加するという手もある:
INET_IP=`ifconfig $INET_IFACE | grep inet | cut -d : -f 2 | \ cut -d ' ' -f 1`
上記は、変数 $INET_IFACE
を自動的に調べ、 IPアドレスを含む目的の行を grep し、そのまま使える IPアドレスへと cut で切り詰めている。もっときちんとやりたい人は retreiveip.txt の中からコードを切り出して使うといいだろう。そのスクリプトを走らせれば、インターネットIPアドレスを自動的に検出してくれるはずだ。ただし、これは若干の妙な挙動を引き起こしかねないという点を心していただきたい。ファイヤーウォールの内側で、ファイヤーウォールへの往来が息付きを起こすなどといった現象だ。以下に、妙な挙動のうち、ありがちなものをリストアップしておく。
例えば PPP デーモンなどが何らかのスクリプトを実行し、その中でこのスクリプトが実行された場合、"NEW でありながら SYN でない" ルールの働きによって、現在活動中のコネクションがハングする (NEWステートでありながらSYNビットの立っていないパケット セクションを参照のこと)。ひとつの手段として、"NEW でありながら SYN でない" ルールを取り除けばこの問題から逃げられなくもないが、はなはだ疑問の残るやり方だ。
既に定常化したルールがいくつかあり、それらを常に稼働させておきたい場合、既存のルールを破壊することなくルールを足したり消したりするのはなかなか厄介だ。例えば、LAN のマシンをファイヤーウォールに接続させないようにしていて、且つ PPP デーモンから何らかのスクリプトを実行したい場合、いかにして、LAN をブロックするルールを生かしたままルールを更新するか。
スクリプトが必要以上に複雑になり、既に述べたようなセキュリティの妥協を招く。スクリプトがシンプルであるほど、問題点も発見しやすく、コードに矛盾や混乱が生じにくい。