実践で学ぶ、一歩進んだサーバ構築・運用術

第 8 回 ファイアウォール (後編)


UDP パケットのフィルタリング

UDP の場合, TCP と異なり ACK フラグなどはありませんから, 内向きパケットが, 外部から内部のサーバーへのアクセスなのか, あるいは内部から外部のサーバーへの問い合わせに対する返答なのかを 区別することはできません。

返答パケットの場合, あて先ポートが問い合わせに利用した送信元ポートと同じになります (図 22 参照)。 したがって, UDP クライアントを利用する場合, そのクライアントが送信元ポートを固定できるか否かが重要です。

外向き 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 の入力用チェーン
*16
アクセスしたい外部の UDP サーバーが限定できるならば, 内向きパケットの送信元アドレスがそれらのサーバーであるときに限り 許可するようにすれば, 少しマシになります。
*17
query-source を指定しない場合, 送信元ポートは 1024 番以上のポートからランダムに選ばれます。

(ライターから)


本稿は日経Linux 2000 年 11 月号に掲載された、 実践で学ぶ、一歩進んだサーバ構築・運用術, 第 8 回「ファイアウォール (後編)」を日経BP 社の許可を得て転載したものです。

Copyright(C)2000 by 仙石浩明 <sengoku@gcd.org>
無断転載を禁じます

| home | up |

sengoku@gcd.org