ファイアウォールの設定・動作チェック方法

第6回 ファイアウォールの設定・動作チェック方法

ファイアウォールを構築したらサーバにアクセスできなくなった。あるいは、一見正しく動作しているようでもルールに抜け穴があれば意味がない。ファイアウォールの動作が本当に適切かどうか、各種のツールを利用してチェックしよう。

 第3回から3回に分けて、ファイアウォールの構築方法を紹介してきました。今回は、構築したファイアウォールの動作の確認方法などについて説明します。

tcpdumpによるファイアウォールの導通確認

 導通確認とは、目的のサーバに対してルールどおりにアクセスできることを確認することです。もちろん、実際にアクセスすれば確認できるでしょう。「導通確認」という観点から考えるとこれだけでも目的は達成できるのですが、今回は接続できないというトラブルも想定してツールを使ってみましょう。

 ファイアウォールを介すると目的のホストに接続できないときは、NATやFORWARDの問題など、さまざまな原因が考えられます。これを回避するには、まず原因の切り分けが必要です。原因の切り分けができないと、どこをどう修正すればいいのか分かりにくいものです。そこで、tcpdump(ftp://ftp.ee.lbl.gov/)というツールを使います()。

注:tcpdumpの使い方を間違えてはいけません。tcpdumpはネットワーク障害時の原因切り分けには有効なツールです。しかし、その機能故にパケットを盗聴することもできてしまうのです。telnetやFTPは、パケットが平文で流れるのでパスワードも簡単に知られてしまう可能性があります。sshを使って通信を暗号化することで、この問題を回避可能です。さらに、sshではパスワード認証を許可せずにRSAのみの認証にすることを推奨します。

tcpdumpの動作を制御するオプション

 tcpdumpは、ネットワーク上のパケットをモニタリングするツールです。単純に流れているすべてのパケットをモニタリングするだけでなく、オプションや条件式を指定してそれに一致するパケットのヘッダを表示します。

 代表的なオプションには、以下のようなものがあります。これ以外についてはmanページを参照してください。

-a ネットワークとブロードキャストアドレスをDNS名に変換する
-F file フィルタ条件式の入力にfileを用いる。このオプションの後ろにコマンドラインによる条件式があっても無視する
-i interface name 引数として指定したインターフェイスを監視する
-l 標準出力をバッファリングする。データを蓄積しながら監視する場合に使用する
-n ホストアドレスやポート番号を名前に変換しない
-N ホストのドメイン名を表示しない
-w filename ダンプしたパケットを表示せずにそのままファイルに書き出す
-r filename -wオプションで作成したファイルからパケットを読み込む
-t ダンプ行に時間情報を表示しない
-tt ダンプ行に表示する時間情報を整形しない
-v 詳細に出力する。IPパケットにおける生存時間(TTL)やサービスの種類などが表示される
-vv -vオプションよりも詳細に出力する
-vvv さらに詳細に出力する
-x すべてのパケットを16進数で表示する
-X 16進数表示するとともに、ASCII文字も表示する
tcpdumpのオプション

tcpdumpの対象を指定する条件式

 条件式を与えると、自分の欲しい情報だけを出力させることができます。何も条件を指定せずにtcpdumpを実行すると、ネットワーク上のすべてのパケットをダンプしてしまうので、それを解析するだけでも大変です。条件式を活用して、ダンプする情報を必要なものだけに絞り込むようにしましょう。

 条件式には次の3つの修飾子があります。

 上記の修飾子で構成された条件を演算子「and」「or」「not」でつなぐことで、複雑な条件を指定することが可能です。

tcpdumpの具体的な使い方

 tcpdumpのオプション/条件式が分かったところで、具体例を見ていきましょう。まずは、次のような条件の情報を取得するとします。

80/TCP(HTTP)のアクセスを監視

 tcpdumpの条件式でプロトコル、ポート番号を指定することが可能です。つまり、プロトコルが「tcp」、ポート番号が「80」という条件を与えればいいのです。

 さらに、ホストアドレスやポート番号を名前に変換しないように-nオプションを指定します。これをまとめると次のようになります()。

# tcpdump tcp port 80 -n

注:一般ユーザーでtcpdumpを実行することも可能ですが、その場合はrootにSUIDする必要があります。

 ここまでは、特に難しくないと思います。しかし、これだけではネットワークを流れるすべての80/TCPのパケットをダンプしてしまいます。これを特定のホストに対するアクセスのパケットに限定してみましょう。

 複数の条件を与えたい場合は、and演算子を使います。そこで、ソース、ディスティネーションに関係なく、IPアドレス192.168.0.100に関する80/TCPのパケットを監視したい場合は、次のように条件を指定します。

# tcpdump tcp port 80 and host 192.168.0.100 -n

 さらに、ソースアドレス(src)やディスティネーションアドレス(dst)を分けることも可能です。これは、type修飾子のhostの後ろにdstやsrcを付けるだけです。

# tcpdump tcp port 80 and host dst 192.168.0.100 -n

 前述したように、演算子にはand以外にorやnotがあります。例えば、80/TCP「以外」のパケットを監視する(80/TCPだけ監視しない)ならnot演算子を使います。

# tcpdump not tcp port 80 -n

 sshなどを利用してリモートから操作しているときに、そのホストに対するすべてのパケットを監視しようとすると、22/TCPに関するパケットが大量に出力されてしまいます。このような場合はnot演算子を付けて22/TCPを監視対象から外すといいでしょう。つまり、特定の条件を無視したいときに非常に有効な演算子なのです。

tcpdumpを使った導通確認

 では、実際に導通確認を行ってみましょう。Webサーバ(192.168.0.10)に対して、80/TCPのアクセスができないというトラブルを想定して話を進めます。Webサーバ上では、80/TCPがLISTEN状態にあることを前提とします。

 目的のホストやポートに接続できない原因としては、次のことが考えられるでしょう。

 まずは、どこまでパケットが流れているのかを考えてみましょう。

 下記2つのコマンドを同時に実行し、2つのコンソールで同時にパケットの流れを見ます。

# tcpdump -i eth0 -n tcp and port 80
User level filter, protocol ALL, datagram packet socket
tcpdump: listening on eth0
19:48:32.782168 < 172.16.1.150.2751 > 192.168.0.10.80: S 753558824:753558824(0
win 64240 <mss 1460,nop,nop,sackOK> (DF)
19:48:35.699014 < 172.16.1.150.2751 > 192.168.0.10.80: S 753558824:753558824(0
win 64240 <mss 1460,nop,nop,sackOK> (DF)
19:48:41.707790 < 172.16.1.150.2751 > 192.168.0.10.80: S 753558824:753558824(0
win 64240 <mss 1460,nop,nop,sackOK> (DF)
19:48:53.725317 < 172.16.1.150.2751 > 192.168.0.10.80: S 753558824:753558824(0
win 64240 <mss 1460,nop,nop,sackOK> (DF)
インターフェイス:eth0を流れるパケットで80/TCPをモニタリングする

# tcpdump -i eth1 -n tcp and port 80
User level filter, protocol ALL, datagram packet socket
tcpdump: listening on eth1
インターフェイス:eth1を流れるパケットで80/TCPをモニタリングする

 上記の結果から、目的のホストへのNATは適切に行われていることが分かります。しかし、SYNフラグをセットしたパケットを送信していますがSYN/ACKフラグがセットされたパケットが戻ってきていないことから、接続できていないようです。

 eth1には何も出力されていないので、パケットが流れていないことが分かります。つまり、経路が適切に設定されていないなどの原因が考えられます。FORWARDチェインのルールを再度確認してみてください。リプライパケットの経路を設定することも忘れずに行ってください。

 このように、ファイアウォールを通過して目的のサーバに接続できているか否か、要求に対する応答を送る経路は存在しているのか、サーバ自身のルーティング情報に間違いはないのかなど、どこまでパケットが流れているのかをインターフェイスごとにモニタリングし、順に判断していくことでどこに問題があるのか分かってきます。1つ1つ原因を切り分けて設定を再確認してください。

ツールを使ったアクセス制御の確認

 目的のサーバに接続できるようになった後に考えなければならないのが、ルール上許可していないホストやポートに接続を許可していないかどうかです。つまり、「余計な穴」が開いていないかを確認します。これには、Nmapとhping2を使うといいでしょう。

Nmapによるポートスキャン

 Nmap(http://www.insecure.org/nmap/)はポートスキャナツールです。機能は多彩で、TCPのSYNスキャンやNullスキャン、OSの推測が可能です。このNmapを用いて、余計なポートが開いているように見えないかを確認します()。

注:当然のことですが、Nmapは自サイトのセキュリティを向上する目的にのみ用いるべきものです。

 まずはNmapのオプションを知る必要があります。Nmapには多くのオプションがあるので、ここではその一部を紹介します。

-sT TCPポートのスキャンを行う
-sU UDPポートのスキャンを行う
-sS TCP SYNスキャンを行う。SYNパケットを送った後、SYN/ACKパケットを受信するとRSTパケットを送り、コネクションを中断する。このスキャンは、ログに残りにくいという特徴がある
-sP 指定されたネットワーク上にICMP echo-requestを送り、稼働しているマシンを探す
-P0 ファイアウォールなどでICMP echo-requestが許可されていないホストに対してスキャンするときに使用する
-O TCP/IPのフィンガープリントにより、対象ホストのOSを調べる
-o filename スキャンした結果を指定したファイルに出力する
-i filename スキャン対象ホストをファイルから読み込む
-p port range スキャンするポートを指定する。「-p 1-65535」のように指定することで、ポートをレンジ指定できる
Nmapのオプション

 では、実際にNmapを使ってみましょう。Webサーバ(192.168.0.10)に対して、TCPのフルポートスキャンを実行します。ファイアウォールでICMP requestは特定のホストからしか許可していないので、-P0オプションを付けておきます。

# nmap -P0 -p 1-65535 -sT 192.168.0.10

Starting nmap V. 2.54BETA30 ( www.insecure.org/nmap/ )
Interesting ports on (192.168.0.10):
(The 97 ports scanned but not shown below are in state: filtered)

Port       State       Service
80/tcp     open        http

 Nmapの結果から、80/TCP(HTTP)が開いていることが分かります。ここで注目してもらいたいのが、「filtered」というステータスです。これにより、フィルタリングが行われているであろうということが分かるのです。許可していないポートが開いているように見えないか注意してください。

 すべてのサーバに対してスキャンすることを忘れないでください。また、特定のIPアドレス(メンテナンス用ホストなど)からしかアクセスを許可していないサービスなどがある場合は、必ずそのIPアドレスからスキャンします。もちろん、ファイアウォールに対するスキャンも行いましょう。

hping2によるリプライパケットのチェック

 hping2(http://www.hping.org/)は、ファイアウォールの動作確認に非常に有効なツールです()。カスタマイズしたTCPパケットを生成して目的のポートに送信することで、リプライパケットの状態を見ることができます。そこから、許可されているのか、ドロップされているのか、拒否されているのかが判断できます。IPアドレスが偽造されたパケットについてテストすることも可能です。TCPだけでなく、ICMPやUDPについてもカスタムパケットを送信可能です。

注:hping2をファイアウォールの動作確認に使いましたが、ホストのセキュリティの確認もできます。ソースアドレスを指定して、偽造IPアドレスで動作確認することも可能です。また、IPスプーフィング対策が行われていないホストに対して実行する場合は注意が必要です。偽造IPアドレスが実在すると、ターゲットとなったホストは実在するホストに対してリプライパケットを送ってしまいます。

 hping2もtcpdumpやNmapと同様にコマンドラインからオプションを指定して実行します。まずは、知っておいた方がいいオプションを紹介します。

-c count レスポンスパケットをいくつ送信するかを指定する
-I interface name パケットを送信するために使うインターフェイスを指定する
-V Verboseモード。より詳細な出力結果を得ることができる
-1 ICMPパケットを送信するときに指定する。デフォルトでは、ICMP echo-requestを送信しする。--icmptype、--icmpoptionオプションを指定することも可能
-2 UDPパケットを送信するときに指定する。デフォルトでは0/UDPに送信する。--baseport、--destport、--keepオプションを指定することが可能
-a hostname ソースアドレスを偽造したパケットを送信する。ホスト名ではなくIPアドレスで指定することも可能
-C --icmptype type 指定したtypeのICMPパケットを送信することが可能
-s 送信元ポートを指定することが可能。送信元ポート番号は1つずつ増加していく。--keepオプションを指定することで、この増加を無効にすることが可能
-p 送信先のポートを指定することが可能
-F FINフラグをセットしたパケットを送信することが可能
-S SYNフラグをセットしたパケットを送信することが可能
-R RSTフラグをセットしたパケットを送信することが可能
-P PUSHフラグをセットしたパケットを送信することが可能
-A ACKフラグをセットしたパケットを送信することが可能
-U URGフラグをセットしたパケットを送信することが可能
-X Xmasフラグをセットしたパケットを送信することが可能
-Y Ymasフラグをセットしたパケットを送信することが可能
-d data size パケットのデータサイズを指定することが可能
hping2のオプション

 では、早速hping2を使ってみましょう。ソースアドレスを偽って、80/TCPにSYNフラグがセットされたパケットを送るには、次のようにオプションを指定します。

# hping2 192.168.0.100 -c 4 -p 80 -S -a 192.168.0.200

 ターゲットが「192.168.0.100」で、偽ったIPアドレスが「192.168.0.200」です。これで、80/TCPに4つのSYNフラグがセットされたパケットを送ったことになります。この指定で、ターゲットとなったホストにIPスプーフィング対策が行われているかどうかの確認ができます。

 次にWebサーバ(192.168.0.10)の80番ポートにSYNフラグをセットしたパケットを送ってみます。

# hping2 192.168.0.10 -c 4 -p 80 -S -n
HPING 1192.168.0.10 (eth0 192.168.0.10): S set, 40 headers + 0 data bytes
len=46 ip=192.168.0.10 flags=SA DF seq=0 ttl=63 id=0 win=5840 rtt=22.3 ms
len=46 ip=192.168.0.10 flags=SA DF seq=1 ttl=63 id=0 win=5840 rtt=2.6 ms
len=46 ip=192.168.0.10 flags=SA DF seq=2 ttl=63 id=0 win=5840 rtt=2.6 ms
len=46 ip=192.168.0.10 flags=SA DF seq=3 ttl=63 id=0 win=5840 rtt=3.7 ms

--- 192.168.0.10 hping statistic ---
4 packets tramitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 2.6/7.8/22.3 ms
hping2実行結果1

 「flags=SA」となっていることから、SYN/ACKパケットが返ってきていることが分かります。また、サーバから応答があったことから、接続が許可されていることも分かります。

 ほかのポートについても調べてみます。Webサーバ上では22/TCP(ssh)をLISTEN状態にしてあります。このポートへの接続は特定のホストからしか許可していないので、許可されていないホストから試してみます。

# hping2 192.168.0.10 -c 4 -p 22 -S -n
HPING 192.168.0.10 (eth0 192.168.0.10): S set, 40 headers + 0 data bytes

--- 192.168.0.10 hping statistic ---
4 packets tramitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
hping2実行結果2

 Webサーバの22番ポートは開いているにもかかわらず何ら応答がないことから、許可していないホストからであればパケットがドロップされていると判断できます。

 では、ファイアウォールのルールが適切に設定されていない場合を考えてみましょう。Webサーバ上では、25/TCP(smtp)はLISTEN状態になっていないはずです。このままの状態でファイアウォールのルールを変更し、Webサーバの25/TCPへ接続できる設定を追加してみます。この状態で検査してみます。

# hping2 192.168.0.10 -c 4 -p 25 -S -n
HPING 192.168.0.10 (eth0 192.168.0.10): S set, 40 headers + 0 data bytes
len=46 ip=192.168.0.10 flags=RA DF seq=0 ttl=254 id=0 win=0 rtt=3.1 ms
len=46 ip=192.168.0.10 flags=RA DF seq=1 ttl=254 id=0 win=0 rtt=2.5 ms
len=46 ip=192.168.0.10 flags=RA DF seq=2 ttl=254 id=0 win=0 rtt=6.3 ms
len=46 ip=192.168.0.10 flags=RA DF seq=3 ttl=254 id=0 win=0 rtt=2.4 ms

--- 192.168.0.10 hping statistic ---
4 packets tramitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 2.4/3.6/6.3 ms
hping2実行結果3

 「flags=RA」となっており、SYN/ACKパケットが返ってきていないので実際に接続できているわけではありませんが、ファイアウォールを通過してWebサーバが応答しています。Webサーバで25/TCPポートはLISTEN状態になっていませんが、経路は存在するのではないかと判断できます。

 Nmapでポートスキャンするだけでも、ポートが開いているかいないかの判断はできます。しかし、hping2などを使ってポートがどういう状態にあるのかも確認するようにしてください。ルールが複雑になると、必要のないルールを作成してしまうかもしれないので注意が必要です。

 ツールを使った動作確認の方法を解説しましたが、これらは一度行えばよいというものではありません。定期的に確認作業を行うことを推奨します。また、ルールについても定期的に見直しをかけるようにしてください。以前は必要でも現在は必要のないルールが存在すると、それがセキュリティホールとなる可能性があります。