iptablesでfirewall

iptable とは

Linuxカーネル2.4以降では、netfilterというパケット処理のためのフレームワークを持っており、これを制御するためのツールが iptable。
パケットフィルタリングやNAT管理ができる。パケットに対し許可や、拒否ができるのでファイヤーウォールとしても使われる。

仕組みとか

iptable には ルール、チェイン、ターゲット、テーブルの概念がある。
テーブルはチェインの集まり。
チェインはルールが連なったもの。
パケットは、その種類に応じたチェインで評価される。
チェインのルールを最初から調べていき、ルールにマッチした場合、指定されているターゲットが実行される。
.... テーブル ⊃ チェイン ⊃ ルール ( マッチの条件と、ターゲットを指定 ) かな。。

テーブル

用途別にチェインをまとめたもの。

filter パケットの出入りを制御
nat パケットの中身書き換え。IPマスカレードなどに
mangle TOSフィールドの書き換え、特別なパケット変換用らしい

他にもrawテーブルがある。しかしカーネル2.6であったとしても、パッチ当てないと使えない。
今回使うのは filter テーブルのみ。

チェイン

ルールをグループ化したもの。ルールを連ねてチェインにすることで、実行する順番を指定できる。

INPUT マシン自体に入ってくるパケットに対するチェイン
OUTPUT ローカルマシンで生成されたパケットに対するチェイン
FORWARD マシンを経由するパケットに対するチェイン

などなど、他にもいろいろ。
自分で作ることもできる。

ルール

パケットの内容に応じて、そのパケットをどのように処理するか定義したもの。
マッチ条件と、マッチした際に実行するターゲット、またはチェインを指定する。
ルールは定義した順番に適用され、途中でターゲットにジャンプすると処理は終了する。
そのため、頻度が高いものほど、最初に定義するとよい。

ターゲット

パケットに対するアクション

ACCEPT パケットを通す
DROP パケットを捨てる
QUEUE パケットをユーザ空間に渡す
RETURN チェインを辿るのをやめて、上位のチェインに戻り、次のルールに処理を渡す
REJECT DROPと同じくパケットを捨てるが、廃棄時にICMPを使って廃棄したことを通知する点が異なる
REDIRECT パケットを指定したポートにリダイレクトする

他にも
http://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/targets.html



設定

現在の設定をバックアップ

$ sudo /sbin/iptables-save > iptables.txt

*1

設定されているルールをクリア

$ sudo /sbin/iptables -F INPUT
$ sudo /sbin/iptables -F OUTPUT
$ sudo /sbin/iptables -F FORWARD
$ sudo /sbin/iptables -F RH-Firewall-1-INPUT

CentOSを使ってるので、RH-Firewall-INPUTはredhatのデフォルトの設定っぽい。


INPUTチェインを使用頻度が高いルールから順に設定していく。
まず、ローカルマシンからの入力と、icmp(ping)を許可

$ sudo /sbin/iptables -A INPUT -i lo -j ACCEPT
$ sudo /sbin/iptables -A INPUT -p icmp -j ACCEPT

Web、sshを許可

$ sudo /sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
$ sudo /sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT

接続が確率したパケットの応答( 内部から行ったアクセスに対する外部からの返答アクセス )は許可

$ sudo /sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 


1秒間に4回を超えるping(icmp)はログを残して破棄

$ sudo /sbin/iptables -N RAPID_PING
$ sudo /sbin/iptables -A RAPID_PING -m limit --limit 1/s --limit-burst 4 -j ACCEPT
$ sudo /sbin/iptables -A RAPID_PING -j LOG --log-prefix '[IPTABLES RAPID_PING] : '
$ sudo /sbin/iptables -A RAPID_PING -j DROP
$ sudo /sbin/iptables -A INPUT -p icmp --icmp-type echo-request -j RAPID_PING 
# ↑ターゲットの代わりにRAPID_PINGチェインを指定


ブロードキャストアドレス、マルチキャストアドレス宛のパケットを破棄

$ sudo /sbin/iptables -A INPUT -d 255.255.255.255 -j DROP
$ sudo /sbin/iptables -A INPUT -d 224.0.0.1 -j DROP

113番ポートへのパケットを無視すると、Sendmail などが何度もリトライするので、拒否応答をする。

$ sudo /sbin/iptables -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset

http://unixluser.org/techmemo/ident/



ポリシー設定
設定してあるルールにマッチしなかった場合の、デフォルトの動作。

$ sudo /sbin/iptables -P INPUT DROP
$ sudo /sbin/iptables -P OUTPUT ACCEPT
$ sudo /sbin/iptables -P FORWARD DROP

ルールにないINPUTはすべてDROP
OUTPUTはマシンから出ていくパケットなので全部許可。
ルータとして使わないので、FORWARDはDROP
※ これを一番最初にやると、 SSHなどで接続している場合、何も受け付けなくなってしまう。


設定をセーブ

$ sudo /etc/init.d/iptables save

実験したいとき

iptablesを色々試したい場合には、セーブせずに、再起動すると起動時の状態に戻るので試せる。

service iptables restart

国単位で設定したいとき

http://nami.jp/ipv4bycc/
ここから、各国に割り当てられているIPの一覧(1日1回更新らしい)を取得することができるので、これを使えば、国ごとで許可や、拒否もできる。

設定前と設定後

設定前
CentOS 5.3(server)のデフォルト

$ sudo /sbin/iptables -n -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
RH-Firewall-1-INPUT  all  --  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain RH-Firewall-1-INPUT (2 references)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 255 
ACCEPT     esp  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     ah   --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     udp  --  0.0.0.0/0            224.0.0.251         udp dpt:5353 
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           udp dpt:631 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:631 
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited 

RHってRedHatの略だろうけど、これがMicroSoftだったら絶対略してないだろうな、って思った。

設定後

$ sudo /sbin/iptables -L -n
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0             # 何かと思ったけど lo っぽい
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22 
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
RAPID_PING  icmp --  0.0.0.0/0            0.0.0.0/0           icmp type 8 
DROP       all  --  0.0.0.0/0            255.255.255.255     
DROP       all  --  0.0.0.0/0            224.0.0.1           
REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:113 reject-with tcp-reset 

Chain FORWARD (policy DROP)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain RAPID_PING (1 references)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           limit: avg 1/sec burst 4 
LOG        all  --  0.0.0.0/0            0.0.0.0/0           LOG flags 0 level 4 prefix `[IPTABLES RAPID_PING] : ' 
DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Chain RH-Firewall-1-INPUT (0 references)
target     prot opt source               destination  


参考にさせて頂きました。
http://www.linux.or.jp/JM/html/iptables/man8/iptables.8.html
http://www.geocities.co.jp/SiliconValley-Bay/9678/iptables.html
http://centossrv.com/iptables.shtml
http://tech.feedforce.jp/iptables.html
http://penguin.nakayosi.jp/linux/iptables.html
http://wiki.bit-hive.com/tomizoo/pg/iptables%A4%CB%A4%E8%A4%EB%A5%D5%A5%A3%A5%EB%A5%BF%C0%DF%C4%EA
http://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/index.html


....やってみたくて設定したが、実はルータで80と22しかポートマッピングしてない。


まとめ

 sudo /sbin/iptables -F INPUT
 sudo /sbin/iptables -F OUTPUT
 sudo /sbin/iptables -F FORWARD
 sudo /sbin/iptables -F RH-Firewall-1-INPUT
 sudo /sbin/iptables -A INPUT -i lo -j ACCEPT
 sudo /sbin/iptables -A INPUT -p icmp -j ACCEPT
 sudo /sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
 sudo /sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT
 sudo /sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 
 sudo /sbin/iptables -N RAPID_PING
 sudo /sbin/iptables -A RAPID_PING -m limit --limit 1/s --limit-burst 4 -j ACCEPT
 sudo /sbin/iptables -A RAPID_PING -j LOG --log-prefix '[IPTABLES RAPID_PING] : '
 sudo /sbin/iptables -A RAPID_PING -j DROP
 sudo /sbin/iptables -A INPUT -p icmp --icmp-type echo-request -j RAPID_PING 
 sudo /sbin/iptables -A INPUT -d 255.255.255.255 -j DROP
 sudo /sbin/iptables -A INPUT -d 224.0.0.1 -j DROP
 sudo /sbin/iptables -A INPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset
 sudo /sbin/iptables -P INPUT DROP
 sudo /sbin/iptables -P OUTPUT ACCEPT
 sudo /sbin/iptables -P FORWARD DROP
 sudo /etc/init.d/iptables save

*1:$ cp /etc/sysconfig/iptables ~/iptables.txt でもOK