Linuxで作るファイアウォール[パケットフィルタリング設定編]:ゼロから始めるLinuxセキュリティ(5)(2/2 ページ)
いよいよパケットフィルタリングの設定を始める。しっかりと不要なパケットをブロックできれば、ファイアウォールの内側の安全度はより向上する。パケットの性質やiptablesの動作をここでマスターしてほしい。
INPUT/OUTPUTチェイン
外部のホストからファイアウォール自身に、メンテナンスなどのために接続することがあるかもしれません。それを許可するルールを追加するのがINPUTおよびOUTPUTチェインになります。INPUTおよびOUTPUTチェインの設定を行っていないと、ファイアウォールそのもののサービスが無防備になるか、逆にまったくアクセスできないということになってしまいます。
INPUT/OUTPUTチェインの設定
メンテナンスを行うためのホストを限定し、22/TCP(ssh)での接続を許可するような場合を考えてみましょう。
メンテナンス用ホスト(172.16.1.150)から、ファイアウォールの外側のインターフェイスeth0(172.16.0.100)に対する22/TCP(ssh)による接続を許可する。
INPUTチェインには外部からホストへ入ってくるためのルールを、OUTPUTチェインにはホストから外部へ出ていくためのルールを追加します。FORWARDチェインと同じで、入ってくるパケットに対する応答が外部に出ていくことを許可するルールを作成しなければなりません。
# /sbin/iptables -A INPUT -p tcp -s 172.16.1.150 --dport 22 -d 172.16.0.100 -i eth0 -j ACCEPT # /sbin/iptables -A OUTPUT -p tcp ! --syn -m state --state ESTABLISHED --sport 22 -s 172.16.0.150 -d 172.16.1.100
指定されているオプションはこれまでに説明したものばかりなので、特に説明は必要ないでしょう。ここで注意すべき点は、OUTPUTチェインです。FORWARDチェインを作成したときと同じく、flagとstatusにオプションを指定して外部へ接続できないようにすることです。
ICMPの処理
ホストの生存確認を行うために、pingコマンドを使うことは多いのではないでしょうか。ファイアウォール自身についてはEcho Replyを返す必要はありません。しかしながら、DMZ上のホストに関しては生存確認を行いたいと思うことがあるかもしれません。iptablesでアクセス制御を行っているホストは、ICMPについても意図的に通るようにする必要があります。
生存確認に必要なICMP-TYPEは?
番号 | メッセージタイプ |
---|---|
0 | Echo Reply |
3 | Destination Unreachable |
4 | Source Quench |
5 | Redirect |
8 | Echo Request |
11 | Time Exceeded |
12 | Parameter Problem |
13 | Timestamp Request |
14 | Timestamp Reply |
15 | Information Request |
16 | Information Reply |
17 | Address Mask Request |
18 | Address Mask Reply |
表 Typeフィールド |
iptablesでは、ICMPのTYPEを指定することができます。pingコマンド使うのであれば、Echo Requestを受け付け、Echo Replyを返すことができればいいのです。このICMP-TYPEについて簡単に説明しておきましょう。
ICMPヘッダの中身は、Typeフィールドから始まります。このTypeフィールドの指定番号によって、ICMPメッセージの種類などが決定されます。ICMPには次のようなTypeメッセージが規定されています。
iptablesでは、この番号を指定することができます。ホストの生存確認はpingコマンドを用いることが多いかと思います。pingコマンドは、Echo Requestを目的のホストに向かって送信し、その応答としてEcho Replyが返ってくるのを確認します。そこで、ここでは生存確認を目的とし、Echo RequestとEcho Replyを双方向に許可するためのルールを追加することにしましょう。iptalbesのオプションとしては「--icmp-type」を指定し、引数としてICMP Type番号を指定します。
生存確認のためメンテナンス用のホスト(172.16.1.150)から、Webサーバ(192.168.0.10)に対するEcho Requestと、その応答のためのEcho Replyを許可する。
# /sbin/iptables -A FORWARD -p icmp -s 172.16.1.150 --icmp-type 8 -d 192.168.0.10 -i eth0 -j ACCEPT # /sbin/iptables -A FORWARD -p icmp --icmp-type 0 -s 192.168.0.10 -d 172.16.1.150 -o eth0 -j ACCEPT
この設定もまた、これまでに説明したオプションの指定方法とそれほど違いはありません。プロトコルがICMPになったことに注意すればいいでしょう。
ブロードキャストあてICMPの拒否
ファイアウォールの外側のインターフェイスに対する生存確認のためのEcho Requestを許可すべきではないでしょう。ましてやブロードキャストあてのicmp-echoには応答する必要もありません。ブロードキャストあてのICMPは、カーネルパラメータを調整することでまったく受け付けなくすることができます。
ブロードキャストあてICMPを拒否する場合は、/etc/sysctl.confファイルに設定を記述します。OS起動時にsysctlコマンドが実行されることで、この設定が反映されます。ブロードキャストあてのicmp-echoを無視するには、設定ファイルに次の1行を追加します。
net.ipv4.icmp_echo_ignore_broadcasts = 1
カーネルパラメータを調整することで、ソースアドレスを偽造していないかチェックするような設定もできますが、これには注意が必要です。あまりやり過ぎると、本来の動作をしなくなってしまう危険があります。
総仕上げ:ルールのスクリプト化
パケットフィルタリングの設定方法について一通り解説してきました。これまでのことが理解できればファイアウォールを構築できるでしょう。では、実際にファイアウォール用のルールを作成していきましょう。
ルールを1つ1つ入力してもよいのですが、OSをリブートするたびに同じ作業を繰り返すことになります。効率的ではないしミスも発生するでしょう。以前に紹介したipchainsと同様に、スクリプトを作成することをお勧めします。以下のようなスクリプトを適当なファイル名で作成します。
#!/bin/sh # # Define IP Address FW_OUT='172.16.0.100' “ファイアウォールの外側のインターフェイス” FW_IN='192.168.1.1' “ファイアウォールの内側のインターフェイス” V_WEB='172.16.0.10' “Webサーバの仮想IPアドレス” V_MAIL='172.16.0.20' “メールサーバの仮想IPアドレス” V_DNS='172.16.0.30' “DNSサーバの仮想IPアドレス” R_WEB='192.168.1.10' “Webサーバの実IPアドレス” R_MAIL='192.168.1.20' “メールサーバの実IPアドレス” R_DNS='192.168.1.30' “DNSサーバの実IPアドレス” MAINT='172.16.1.150' “メンテナンス用ホスト” ANY='0.0.0.0' “すべてのIPアドレスを表現” # # Flush chains /sbin/iptables -F # # すべてのパケットを拒否 /sbin/iptables -P INPUT DROP /sbin/iptables -P FORWARD DROP /sbin/iptables -P OUTPUT DROP # # ループバックアドレスに関してはすべて許可 /sbin/iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT /sbin/iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT # # メンテナンス用のホストからのみpingを許可 /sbin/iptables -A OUTPUT -p icmp -s $FW_OUT --icmp-type 0 -d $MAINT -j ACCEPT /sbin/iptables -A INPUT -p icmp -s $MAINT --icmp-type 8 -d $FW_OUT -j ACCEPT # # 各サーバからファイアウォールの内側のホストへのpingを許可 /sbin/iptables -A OUTPUT -p icmp -s $V_WEB --icmp-type 0 -d $MAINT -j ACCEPT /sbin/iptables -A INPUT -p icmp -s $MAINT --icmp-type 8 -d $V_WEB -j ACCEPT /sbin/iptables -A OUTPUT -p icmp -s $V_MAIL --icmp-type 0 -d $MAINT -j ACCEPT /sbin/iptables -A INPUT -p icmp -s $MAINT --icmp-type 8 -d $V_MAIL -j ACCEPT /sbin/iptables -A OUTPUT -p icmp -s $V_DNS --icmp-type 0 -d $MAINT -j ACCEPT /sbin/iptables -A INPUT -p icmp -s $MAINT --icmp-type 8 -d $V_DNS -j ACCEPT # # メンテナンス用ホストから各サーバに対してpingを許可 /sbin/iptables -A INPUT -p icmp -s $MAINT --icmp-type 0 -d $V_WEB -j ACCEPT /sbin/iptables -A OUTPUT -p icmp -s $V_WEB --icmp-type 8 -d $MAINT -j ACCEPT /sbin/iptables -A INPUT -p icmp -s $MAINT --icmp-type 0 -d $V_MAIL -j ACCEPT /sbin/iptables -A OUTPUT -p icmp -s $V_MAIL --icmp-type 8 -d $MAINT -j ACCEPT /sbin/iptables -A INPUT -p icmp -s $MAINT --icmp-type 0 -d $V_DNS -j ACCEPT /sbin/iptables -A OUTPUT -p icmp -s $V_DNS --icmp-type 8 -d $MAINT -j ACCEPT # # メンテナンス用ホストからファイアウォールに対して22/TCP(ssh)を許可 /sbin/iptables -A INPUT -p TCP -s $MAINT --dport 22 -d $FW_OUT -i eth0 -j ACCEPT/sbin/iptables -A OUTPUT -p TCP ! --syn --sport 22 -s $FW_OUT -d $MAINT -o eth0 -j ACCEPT # # Webサーバに対して80/TCP(http)でのアクセスを許可 /sbin/iptables -A FORWARD -p TCP -s $ANY --dport 80 -d $R_WEB -j ACCEPT /sbin/iptables -A FORWARD -p TCP ! --syn -m state --state ESTABLISHED --sport 80 -s $R_WEB -d $ANY -j ACCEPT # # メールサーバに対して25/TCP(smtp)でのアクセスを許可 /sbin/iptables -A FORWARD -p TCP -s $ANY --dport 25 -d $R_MAIL -j ACCEPT /sbin/iptables -A FORWARD -p TCP ! --sny -m state --state ESTABLISHED --sport 25 -s $R_MAIL -d $ANY -j ACCEPT # # メールサーバから外部への25/TCP(smtp)を許可 /sbin/iptables -A FORWARD -p TCP -s $R_MAIL --dport 25 -d $ANY -j ACCEPT /sbin/iptables -A FORWARD -p TCP ! --syn -m state --state ESTABLISHED --sport 25 -s $ANY -d $R_MAIL -j ACCEPT # DNSサーバに対して53/UDP(dns)でのアクセスを許可 /sbin/iptables -A FORWARD -p UDP -s $ANY --dport 53 -d $R_DNS -j ACCEPT /sbin/iptables -A FORWARD -p UDP --sport 53 -s $R_DNS -d $ANY -j ACCEPT # # DNSサーバから外部への53/UDP(dns)を許可 /sbin/iptables -A FORWARD -p UDP -s $R_DNS --dport 53 -d $ANY -j ACCEPT /sbin/iptables -A FORWARD -p UDP --sport 53 -s $ANY -d $R_DNS -j ACCEPT # # Accept ssh connection from MAINT to All Servers /sbin/iptables -A FORWARD -p TCP -s $MAINT --dport 22 -d $R_WEB -j ACCEPT /sbin/iptables -A FORWARD -p TCP ! --syn --sport 22 -s $R_WEB -d $MAINT -j ACCEPT /sbin/iptables -A FORWARD -p TCP -s $MAINT --dport 22 -d $R_MAIL -j ACCEPT /sbin/iptables -A FORWARD -p TCP ! --syn --sport 22 -s $R_MAIL -d $MAINT -j ACCEPT /sbin/iptables -A FORWARD -p TCP -s $MAINT --dport 22 -d $R_DNS -j ACCEPT /sbin/iptables -A FORWARD -p TCP ! --syn --sport 22 -s $R_DNS -d $MAINT -j ACCEPT # # Flush Nat Rules # /sbin/iptables -t nat -F # # Nat Rules # # 外部のホストがDMZセグメントへ入るためのNATの定義 /sbin/iptables -t nat -A PREROUTING -d $V_WEB -i eth0 -j DNAT --to $R_WEB /sbin/iptables -t nat -A PREROUTING -d $V_MAIL -i eth0 -j DNAT --to $R_MAIL /sbin/iptables -t nat -A PREROUTING -d $V_DNS -i eth0 -j DNAT --to $R_DNS # # DMZ上のホストが外部へ出ていくときのためのNATの定義 /sbin/iptables -t nat -A POSTROUTING -s $R_MAIL -o eth0 -p TCP -j SNAT --to $V_MAIL /sbin/iptables -t nat -A POSTROUTING -s $R_DNS -o eth0 -p UDP -j SNAT --to $V_DNS # # End Of Rules
スクリプトの作成が終わったら、実行権限を与えて実行すればルールが反映されます。
# chmod 744 filename # ./filename
しかし、このままではOSの起動時にこの設定は反映されません。そこで、次のコマンドを実行します。
# /sbin/iptables-save > /etc/sysconfig/iptables
これでファイアウォールの構築作業は取りあえず完了です。次回は、構築したファイアウォールの動作確認方法などについて説明したいと思います。
Copyright © ITmedia, Inc. All Rights Reserved.