UDP の場合, TCP と異なり ACK フラグなどはありませんから, 内向きパケットが, 外部から内部のサーバーへのアクセスなのか, あるいは内部から外部のサーバーへの問い合わせに対する返答なのかを 区別することはできません。
返答パケットの場合, あて先ポートが問い合わせに利用した送信元ポートと同じになります (図 22 参照)。 したがって, UDP クライアントを利用する場合, そのクライアントが送信元ポートを固定できるか否かが重要です。
図 22 外向き UDP 問い合わせ |
問い合わせ時の送信元ポートへ返答パケットが届く。 |
固定できるならば, 返答パケットのあて先ポートも常に同じ番号になりますから, あて先ポートに基づくフィルタリングを行って, そのポートあての UDP 内向きパケットを許可すれば済みます。 ただし, このクライアントは, 他のプログラムにそのポートを横取りされないようにするため, 常にそのポートを開いている必要があります。 つまりこのクライアント・プログラムはデーモンでなければなりません。
ポートが固定できない UDP クライアントが動いている場合は少々やっかいです。 そのクライアントを動かすことが絶対必要ならば, そのクライアントが送信元ポートとして利用する可能性がある すべてのポートについて, それらのポートあての内向きパケットを許可してしまう*16 か, あるいはクライアントに追随して内向きパケットを許可するポートを変更できる ファイアウオールが必要になってしまいます。
まずはそのようなクライアントが動いていないか確認しましょう。 図 23 のように ipchains コマンドを実行してください。
# ipchains -I output -j ACCEPT -p udp -l -s 210.145.125.160/28 1024:65535 -d ! 210.145.125.160/28 0:1023 |
図 23 UDP クライアントが動いているかどうかを確認する |
「210.145.125.160/28」は, 内部 LAN の IP アドレスの範囲で置き換えてください。 内部 LAN 上のホストのポート 1024 〜 65535 番から, 外部のサーバーのポート 0 〜 1023 番へ UDP パケットが送信されると, syslog に記録されます(「-l」オプション)。 送信元ポートが固定されていないクライアントが動いていれば, そのクライアントから送信されたパケットが記録されるはずです。
例えば図 24 のようなものです。 これを見ると, 内部 LAN 上のマシン「210.145.125.162」のポート 1587 番から ネーム・サーバー「192.5.5.241」に対して UDP による問い合わせが行われています。 幸い, ネーム・サーバーの場合は 問い合わせ時の送信ポートを 53 番に固定することができます。 ネーム・サーバー以外のサーバーへの問い合わせがある場合は, その問い合わせが本当に必要か, あるいはネーム・サーバーへの問い合わせのように送信元ポートが固定できないか, 考えてみてください。
Sep 10 22:53:46 asao kernel: Packet log: output ACCEPT eth0 PROTO=17 210.145.125.162:1587 192.5.5.241:53 L=63 S=0x00 I=5114 F=0x0000 T=64 (#1) |
図 24 syslog の記録 |
ネーム・サーバーへ問い合わせを行うクライアントが通常利用する送信元ポートは 1024 番以上のポートから適当に選ばれます。 ただし 1 つだけ例外があり, ネーム・サーバーが他のネーム・サーバーへ問い合わせを行うときは, あらかじめ決められたポートを送信元ポートとして利用します。 bind-8.2.2-P5 の場合, 設定ファイルの options において, 図 25 などのように書くことにより, 問い合わせ時の送信元アドレス(210.145.125.162)と 送信元ポート(53 番)を指定できます*17。
query-source address 210.145.125.162 port 53; |
図 25 問い合わせ時の送信元アドレス(210.145.125.162)と送信元ポート(53 番)を設定ファイルの options で指定する |
したがって, 上記のように設定したネーム・サーバーを内部 LAN 上に設置し, ネーム・サーバーへの問い合わせはすべて このネーム・サーバーを経由して行うようにすれば, 外部のネーム・サーバーへの問い合わせパケットの送信元ポートを あらかじめ決められたポート(53 番)に固定することができます。
内部 LAN 上で動く UDP クライアントの送信元ポートが固定できれば, 返答パケットのあて先ポートも固定できて, 内向きパケットのあて先ポートに基づくフィルタリングが可能になります。 例えば, 図 26 のように実行すると良いでしょう。
# ipchains -A input -j DENY -p udp -l # ipchains -I input -j ACCEPT -s 210.145.125.160/28 # ipchains -I input -j ACCEPT -p udp --destination-port domain # ipchains -I input -j ACCEPT -p udp --destination-port ntp |
図 26 内部 LAN 上で動く UDP クライアントの送信元ポートを固定することによりフィルタリングが可能になる |
図 26 の 4 つのコマンドを順に実行すると, 入力用チェーンは図 27 のようになります。 あて先ポートが「domain」か「ntp」であれば, それぞれ 1 番目(--destination-port domain), 2 番目のルール(--destination-port ntp)が適用されて ACCEPT, 送信元アドレスが内部のものであれば 3 番目のルール(-s 210.145.125.160/28)が適用されて ACCEPT, いずれの条件も成立しなければ最後のルールが適用されて DENY になります。
# ipchains -L input Chain input (policy ACCEPT): target prot opt source destination ports ACCEPT tcp !y---- anywhere anywhere any -> any ACCEPT all ------ 210.145.125.160/28 anywhere n/a DENY tcp ----l- anywhere anywhere any -> any |
図 27 図 26 の入力用チェーン |
(ライターから)
本稿は日経Linux 2000 年 11 月号に掲載された、 実践で学ぶ、一歩進んだサーバ構築・運用術, 第 8 回「ファイアウォール (後編)」を日経BP 社の許可を得て転載したものです。
Copyright(C)2000 by 仙石浩明 <sengoku@gcd.org>
無断転載を禁じます