iptables
- テーブル、チェインなどの基礎知識
- 応用例
- 連載記事 「習うより慣れろ! iptablesテンプレート集」
- junoのへたれサーバ管理日記: iptablesのログをとる
- デフォルトでは「kern.=warning」で振り分けが出来る
Jul 4 01:54:03 ubuntu-napt kernel: [118136.424992] [UFW BLOCK FORWARD]: IN=eth0 OUT=eth2 SRC=192.168.100.197 DST=130.xyz.68.26 LEN=58 TOS=0x00 PREC=0x00 TTL=63 ID=3740 DF PROTO=UDP SPT=40966 DPT=53 LEN=38
- iptable側では「--log-level err」などとしてpriorityを変更できる
- kern.=warningには他にも様々なログが来るので、なるべく混ざらないようにしたければ「kern.=notice」「kern.=err」あたりが妥当か。
- /etc/syslog.conf
kern.=warn -/var/log/kern.warn.log kern.=err -/var/log/kern.err.log
- (少なくともUbuntuでは)errに設定するとコンソールにも出力されるので注意
- /etc/syslog.conf
- デフォルトでは「kern.=warning」で振り分けが出来る
設定ファイル
- Ubuntu => ufw
- CentOS
- /etc/sysconfig/iptables
# Firewall configuration written by system-config-securitylevel # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :RH-Firewall-1-INPUT - [0:0] -A INPUT -j RH-Firewall-1-INPUT -A FORWARD -j RH-Firewall-1-INPUT -A RH-Firewall-1-INPUT -i lo -j ACCEPT -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT -A RH-Firewall-1-INPUT -p 50 -j ACCEPT -A RH-Firewall-1-INPUT -p 51 -j ACCEPT -A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT -A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited COMMIT
- sshのみListen可
- /etc/sysconfig/iptables
table
raw
raw テーブルはiptablesで最初に評価される PREROUTING と OUTPUT で使用出来る
rawテーブルはNOTRACKを使用する事でconntrack、NATを適用せずに通過させる その分、高速になる、TRACE でトレース出来る また conntrackやstateモジュールは使用出来ない
iptablesで最初に評価されるので、QUEUEやIMQなどにパケットを転送する前に おかしなパケットを廃棄出来る
- PREROUTINGが使えることにより、INPUT/FORWARD双方に回る予定のパケットを前もって制御できる
- POSTROUTINGもあれば良いのだが…
巨大 icmp packet の拒否
- デフォルト
- ping 202.12.27.33 -c 1
PING 202.12.27.33 (202.12.27.33) 56(84) bytes of data. 64 bytes from 202.12.27.33: icmp_seq=1 ttl=241 time=5.95 ms
- ping 202.12.27.33 -c 1 -s 10240
PING 202.12.27.33 (202.12.27.33) 10240(10268) bytes of data. 10248 bytes from 202.12.27.33: icmp_seq=1 ttl=241 time=13.3 ms
- ping 202.12.27.33 -c 1
- 自ホストから外へのlarge packetの拒否
- sudo iptables -t raw -A OUTPUT -p icmp --icmp-type echo-request -m length --length 85: -j DROP
- ping 202.12.27.33 -c 1
PING 202.12.27.33 (202.12.27.33) 56(84) bytes of data. 64 bytes from 202.12.27.33: icmp_seq=1 ttl=241 time=10.5 ms
- ping 202.12.27.33 -c 1 -s 57
PING 202.12.27.33 (202.12.27.33) 57(85) bytes of data. ping: sendmsg: Operation not permitted
- 着信拒否
- sudo iptables -t raw -A PREROUTING -p icmp --icmp-type echo-request -m length --length 85: -j DROP
- via http://www.designandcommunication.co.jp/Security/iptables/modules/Modules0.html#raw
- ログを取る場合
sudo iptables -t raw -A PREROUTING -p icmp --icmp-type echo-request -m length --length 85: -j LOG --log-prefix "[IPTABLES BAD-ICMP]: " --log-level err -m limit --limit 3/min --limit-burst 10 sudo iptables -t raw -A PREROUTING -p icmp --icmp-type echo-request -m length --length 85: -j DROP
- 「-m limit」について => パケットサイズが異常なicmp requestが一分間に10回を超えた場合は、一分間に3回のみログを取るように制限する
- 無いと膨大なログになる可能性がある
- 「-m limit」について => パケットサイズが異常なicmp requestが一分間に10回を超えた場合は、一分間に3回のみログを取るように制限する
mangle
- どのようなときに使うべきなのかよく分からない。調査中。
- INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING の全てのchainが使える
misc
- interfacesのpost-upコマンドでスクリプトを呼び出してiptablesを設定するという手法も考えられる(この場合、ipコマンド等を使ってIP/Netmask等を取得できるので、スクリプト中にWANやLANのアドレスを埋め込まなくて良いという利点が考えられる)が、その場合NICが活性化してからiptablesの設定がされることになり、瞬間的にではあるがLinkUPしたにも関わらずFWが未設定という状態になるのでよろしくないと思われる。
- eth0がLAN側で192.168.100.254/24、eth1~ethNがWAN(マルチホーム等)の時、条件の逆転「!」を使うことで、iptablesのルール数を減らすべく、以下のようにIP Spoofing防御設定まとめられる思えるが、実際には問題がある。
sudo iptables -t raw -N LOG_SPOOF sudo iptables -t raw -A LOG_SPOOF -j LOG --log-prefix "[IP-SPOOFING]: " sudo iptables -t raw -A LOG_SPOOF -j DROP sudo iptables -t raw -A PREROUTING -i ! lo -s 127.0.0.0/8 -j LOG_SPOOF sudo iptables -t raw -A PREROUTING -i ! eth0 -s 10.0.0.0/8 -j LOG_SPOOF sudo iptables -t raw -A PREROUTING -i ! eth0 -s 172.16.0.0/12 -j LOG_SPOOF sudo iptables -t raw -A PREROUTING -i ! eth0 -s 192.168.0.0/16 -j LOG_SPOOF
- ローカルへのpingが通らない(192.168.100.254(=eth0)が通らない)
Jul 4 07:07:28 ubuntu-napt kernel: [136737.367943] [IP-SPOOFING]: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.100.254 DST=192.168.100.254 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=40230 SEQ=1 Jul 4 07:07:29 ubuntu-napt kernel: [136738.366434] [IP-SPOOFING]: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=192.168.100.254 DST=192.168.100.254 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=40230 SEQ=2
- 「IN=lo」となっていることから考えると、192.168.100.254=eth0だが実際にはloopbackに送られているためおかしくなる。
- WANの数だけルールを列挙するしかなさそう?
- ローカルへのpingが通らない(192.168.100.254(=eth0)が通らない)
- ルールを削除する際は、追加するときの-Aをそのまま-Dに変えればよい
- ルール追加 => sudo iptables -t nat -A PREROUTING -i eth0 -s ! 192.168.100.254 -d 133.xy.zz.39 -j DNAT --to-destination 192.168.100.254
- 上記ルールを削除するときは↓
- ルール削除 => sudo iptables -t nat -D PREROUTING -i eth0 -s ! 192.168.100.254 -d 133.xy.zz.39 -j DNAT --to-destination 192.168.100.254
- ルール追加 => sudo iptables -t nat -A PREROUTING -i eth0 -s ! 192.168.100.254 -d 133.xy.zz.39 -j DNAT --to-destination 192.168.100.254
sample script
- 注意
- /etc/init.d/ufw (see ufw) でiptablesのfilterテーブルはflushされるため、他のスクリプトでfilterテーブルを追加していても削除されてしまう。
- => ufwスクリプトを先に起動する必要がある
- #setfilter raw,mangle,natテーブルをflushするため、ufwスクリプトと同様の注意が必要
- /etc/init.d/ufw (see ufw) でiptablesのfilterテーブルはflushされるため、他のスクリプトでfilterテーブルを追加していても削除されてしまう。
setnapt.sh
- replaced to #setmasq.sh
- for Ubuntu
- nat table(のPOSTROUTINGチェイン)を添削するため、#setfilterの[13/lab]以降と排他利用
- WANデバイス毎にIP MASQUERADEを設定
- /etc/network/interfaces にて、LANデバイスの活性化時に自動呼び出しされるようにして使用
auto eth0 iface eth0 inet static address 192.168.100.254 netmask 255.255.255.0 post-up /root/setnapt.sh eth1 eth2 post-down /root/setnapt.sh
- 上の例ではWANはeth1,2ということになる
setfilter
- for Ubuntu
- raw, mangle nar tableを使って不要・異常なパケットを落とすポリシーを起動時自動登録
- natテーブルをresetするため、#setnapt.shと排他利用
- /etc/init.d/setfilter start/stop
- source:/lab.git/TipAndDoc/iptables/ufw と併せて使用
- sudo update-rc.d setfilter start 39 S .
- /etc/rcS.d/S39setfilter -> ../init.d/setfilter
setmasq.sh
- for Ubuntu
- WAN deviceに対してIP MASQUERADEを設定
- /etc/init.d/networking restart 等で試すと正常に動作するが、OS起動時のrcS.dからの呼び出し時は正常に動作しないことがあるため、#setfilterを使って/etc/ufw/nat.rules等で静的に設定する方が良い
- ex) /etc/network/interfaces
auto eth1 iface eth1 inet dhcp post-up /root/setroute.sh post-up /root/setlan2wan.sh eth0 post-up /root/setmasq.sh pre-down /root/setlan2wan.sh eth0 post-down /root/setroute.sh post-down /root/setmasq.sh
setlan2wan.sh
- #4への対処をするスクリプト
- 設定例は#setmasq.shを参照
ufw/
- for Ubuntu
- /etc/ufw/*.rules に配置
[12/lab]
- LANがeth0, WANがeth1という想定
- LAN => 192.168.100.0/24
- IP MASQUERADEについては#setnapt.shで設定
- LAN -> GW ->WAN の通信は通過
- WAN -> GW は拒否
- after.rules, before.rules については既存のルールに追加
- ログは「「--log-level err」にしているが、Ubuntuではコンソールにも出力されるようになるので注意 (コンソールで作業する際に表示が邪魔になる)
- noticeあたりにすればコンソール出力は無くなる
[13/lab]
- 22/tcp, 443/tcpをWANからもListen可能に。
- REDIRECTを用いて、
- 8443/tcpへ届いたパケットは443/tcpへ転送(全NIC)
- WAN(eth1)側のみ、8000/tcp -> 443/tcp と転送
- LAN(eth0)側のみ、8000/tcp -> 22/tcp と転送
- 同じポートだがNICごとに違うサービスに接続できる
- WAN:$ telnet 133.xyz.xxx.39 8000
Trying 133.xyz.xxx.39... Connected to 133.xyz.xxx.39. Escape character is '^]'. GET / <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> Reason: You're speaking plain HTTP to an SSL-enabled server port.<br /> Instead use the HTTPS scheme to access this URL, please.<br /> <blockquote>Hint: <a href="https://test.mitty.jp/"><b>https://test.mitty.jp/</b></a></blockquote></p> <hr> <address>Apache/2.2.8 (Ubuntu) DAV/2 SVN/1.5.1 mod_ssl/2.2.8 OpenSSL/0.9.8g Server at test Port 443</address> </body></html> Connection closed by foreign host.
- LAN:% telnet 192.168.100.254 8000
Trying 192.168.100.254... Connected to 192.168.100.254. Escape character is '^]'. SSH-2.0-OpenSSH_4.7p1 Debian-8ubuntu1.2 Protocol mismatch. Connection closed by foreign host.
- WAN:$ telnet 133.xyz.xxx.39 8000
- REDIRECTする場合は、転送先ポートでのINPUTがACCEPTされている必要がある
- REDIRECTのみ設定し、INPUT chain側は設定しない(つまり22/tcp,443/tcpはDROPしたまま、8443/tcp, 8000/tcpのみListenしたい)のは不可
- DNATを用いて、loopback等必ずACCEPTされるデバイスに転送する方法が使えるかも(未検証) see also @IT:natテーブルを利用したLinuxルータの作成(4/6)
[17/lab]
- #setmasq.shを使うようになったので、nat.rulesからIP MASQUERADEを削除
Last modified 11 years ago
Last modified on Nov 27, 2013 9:53:22 PM