2007年10月2日火曜日

iptablesの勉強

iptablesについて、けっこう頑張って勉強したのでまとめてアップします。
iptablesは多機能でいろんなことができるようですが、この記事では単体サーバーで、外部からのアクセスを全部遮断し、サービスを行うポートのみ特定(または不特定)のユーザーに対して開放するという点のみを書きます。ルーター機能とかについては触れません。
まずiptablesコマンドの使い方ですが、説明は割愛します。この記事の最後に参考サイトをリンクしたのでそちらをごらんください。
さっそくですが、具体例を示します。
以下は入ってくるパケットを全部拒否(DROP)し、80番ポート(http)は全開、22番ポート(ssh)は192.168.1.0/24のみ許可という設定です。

 1. iptables -P OUTPUT ACCEPT
 2. iptables -P FORWARD DROP
 3. iptables -P INPUT DROP
 4. iptables -A INPUT -i lo -j ACCEPT
 5. iptables -A INPUT -p icmp -j ACCEPT
 6. iptables -A INPUT -m state --state ESTABLISHE,RELATED -j ACCEPT
 7. iptables -A INPUT -p tcp --dport 80 -j ACCEPT
 8. iptables -A INPUT -p tcp --sport 80 -j ACCEPT
 9. iptables -A INPUT -p tcp -s 192.168.1.0/24 --sport 22 -j ACCEPT
10. iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT

行ごとに説明します。
まず1~3行目。「-P」オプションは基本ルールの設定です。後述する「-A」のルールに当てはまらないパケットにはすべて「-P」の処理が行われます。

1. 内部から外部へのパケット(OUTPUT)を許可(ACCEPT)
2. サーバーを経由して転送されるパケット(FORWARD)をすべて破棄(DROP)
3. 外部から内部へのパケット(INPUT)をすべて破棄(DROP)

4~6行目はそれぞれ以下の意味を持っています。

4. ループバックアドレスからのパケット(自分自身からのパケット)を許可
5. icmp(ping)のパケットを許可
6. ESTABLISHED(確立済みのコネクション)とRELATED(新しいコネクションだがFTPデータ転送やICMPエラーのように既存の接続に関係する)のパケットを許可

7~10行目は特定ポートでのサービスへのパケットの処理です。

7. 80番ポートへのパケットを許可(dportは宛先ポートの指定)
8. 80番ポートへのパケットを許可(dportは送信元ポートの指定)
9. 22番ポートへのパケットを192.168.1.0/24に対してのみ許可(dportは宛先ポートの指定)
10. 22番ポートへのパケットを192.168.1.0/24に対してのみ許可(dportは送信元ポートの指定)

以上でこのサーバーは80と22以外は外部からのアクセスはすべて破棄されるようになりました。
さて、ここでいくつか注意点を。
まず上記のコマンドは、コンソールから実行しないといけません。リモートから実行した場合、3行目を実行した時点で「外部から内部へのパケット(INPUT)をすべて破棄(DROP)」されてしまうので、切断されてしまいます。
というわけなので、リモートからの作業の場合には「iptables -P INPUT DROP」は一番最後に実行してください。
あと6行目の「iptables -A INPUT -m state --state ESTABLISHE,RELATED -j ACCEPT」。
この設定をしておけばたとえ途中で設定を間違えてしまっても、その時点で接続が切れることはなくなります。たとえばsshのルールを間違えて設定したとしても突然接続が切れたりしないので安心です。
だいたいこんなところです。
あと実際に本番機でルールを設定する時は、iptablesコマンドを使うより/etc/sysconfig/iptablesのスクリプトを編集したほうがいいと思います。上の例をスクリプトにすると、

:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 80 -j ACCEPT
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --sport 22 -j ACCEPT
-A INPUT -s 192.168.1.0/255.255.255.0 -p tcp -m tcp --dport 22 -j ACCEPT

となります。ルールを有効にするには「/etc/init.d/iptables restart」。
コマンドは実行した瞬間にルールが適用されるのでミスが起こりやすいので、その点スクリプトだと安全です。
最後に、iptablesはテスト環境を用意して実際にコマンドを試しながら勉強するのがいいと思います。自分もそうしましたが、習うより慣れろなところがあるので、そうすることをおすすめします。(ぶっつけ本番で失敗したら大変なことになっちゃいますしね)
以下、勉強の参考にさせていただいたサイトです。
http://linux.shoukun.com/security/iptables.htm
http://www.fmmc.or.jp/fm/nwts/rh_linux/ch6/6_2_1_4.html
http://kurosuke.net/linux/iptables.shtml
http://www.linux.or.jp/JF/JFdocs/packet-filtering-HOWTO-7.html
http://cyberam.dip.jp/linux_security/iptables.html
http://www.asahi-net.or.jp/~bk3k-andu/linux/tips/iptables4.html
http://www.d3.dion.ne.jp/~koetaka/router.html
※追記
/etc/sysconfig/iptablesはデフォルトでは存在しません。
# /etc/rc.d/init.d/iptables save
を実行すると保存されます。

0 件のコメント:

コメントを投稿