2009年4月14日 星期二

Linux 超強防火牆 iptables

作者: Baron. Wan

在上文中, PJ. 介紹了用Linux 實做出一個 ip sharing, 文中內容我們後來採用了 forward 來做一個基本的阻擋, 但如果只使用 forward 來做阻擋條件, 先決條件 input 以及 output 都必須 accept 才行; PJ. 其實以前在設定 iptables 時, 時常設定到後來, input, output 都混亂了, 搞到自己都不知道自己在設甚麼 = =", 以至於後來對 iptables 總是敬而遠之.

但是這樣是不會成長的! 也是最近又興起了用 Linux 來實做 ip sharing 的念頭 (自己沒錢買設備, 而且自己學習Linux 已有一段時日, 如果不實做出來, 實在愧於天地啊!! ~~ 哈, 好像嚴重了點...). 就在自己的強力意念下, 這次真的是一步一腳印, 由寬到緊, 慢慢的了解了它的設定方式.

這篇文章著重於觀念導正, 也是學習 iptables 最重要的心法. PJ. 先來介紹 iptables 三種 chain: (mangle) --> (nat) --> (filter) , 這是優先順序, 也就是 mangle 大於 nat, nat 大於 filter; 這是甚麼呢?! 我們先來看看各 chain 的架構:
1. [mangle] ---------[PREROUTING]
+---[INPUT]
+---[OUTPUT]
+---[FORWARD]
+---[POSTROUTING]

2. [nat] ------------[PREROUTING]
+---[OUTPUT]
+---[POSTROUTING]

3. [filter] ---------[INPUT]
+---[FORWARD]
+---[OUTPUT]


舉例來說, 如果在 nat 的 output 設A ip 便阻擋, filter 的 output 設A ip 允許進入, 依順序, 當A的ip來源封包到了 nat 便被阻擋, 因此無法到達 filter; 所以在設定時要多多注意.

一個封包進入後的流程:


PREROUTING -- 在進入路由之前, 對封包所作的判斷. (pre 有預先之意)
INPUT -- 進入主機之前, 對封包所作的判斷.
OUTPUT -- 經由主機送出封包時, 所作的判斷.
FORWARD -- 轉送, 經由路由判斷出, 目的地為其他主機的封包, 所以不進入本機local, 而轉送到另一個網路介面.
POSTROUTING -- 接收來自OUTPUT與FORWARD來的封包, 進行最後一次的判斷確認.

最後, PJ. 認為學習 iptables 最重要的觀念, 因為 PJ. 以前常設定到頭昏腦脹, 結果就在畫了這張 IN OUT 的關係圖之後, 一切都豁然開朗了, 哈~



接下來就是我自己實做的內容, 與大家分享. PJ. 認為, 自己實際上測試獲益最大^&^.
環境說明:
eth1: 192.168.0.0/24
eth0: 172.22.20.0/24

#
# INPUT:: intranet --> FW <-- internet
# iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A INPUT -i ! lo -s 127.0.0.1/8 -j DROP
iptables -t filter -A INPUT -p icmp --icmp-type 8 -i eth0 -d 172.22.20.0/24 -m state --state NEW -j ACCEPT
iptables -t filter -A INPUT -p icmp --icmp-type 8 -i eth1 -s 192.168.0.0/24 -m state --state NEW -j ACCEPT
iptables -t filter -A INPUT -p udp -s 192.168.0.0/24 -i eth1 --dport 445 -j ACCEPT
iptables -t filter -A INPUT -p udp -s 192.168.0.0/24 -i eth1 --dport 137:139 -j ACCEPT
iptables -t filter -A INPUT -p tcp -i eth1 -s 192.168.0.0/24 --dport 110 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A INPUT -p tcp -i eth1 -s 192.168.0.0/24 --dport 22 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# 在 forward 處再加以限制, 不過也可以只在 input & output 做判斷的, PJ. 認為個人喜好.
# iptables -t filter -A FORWARD -p icmp --icmp-type 8 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth1 -s 192.168.0.0/24 -o eth0 --dport 22 -j ACCEPT
iptables -t filter -A FORWARD -p udp -i eth1 -s 192.168.0.0/24 -o eth0 --dport 53 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth1 -s 192.168.0.0/24 -o eth0 --dport 25 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth1 -s 192.168.0.0/24 -o eth0 --dport 110 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth1 -s 192.168.0.0/24 -o eth0 --dport 80 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth1 -s 192.168.0.0/24 -o eth0 --dport 443 -j ACCEPT
iptables -t filter -A FORWARD -p udp -i eth1 -o eth0 -s 192.168.0.0/24 -d 172.22.20.0/24 --dport 137:139 -j ACCEPT
iptables -t filter -A FORWARD -p udp -i eth1 -o eth0 -s 192.168.0.0/24 -d 172.22.20.0/24 --dport 445 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.0.0/24 --sport 22 --dport 1024:65535 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.0.0/24 --sport 25 --dport 1024:65535 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.0.0/24 --sport 110 --dport 1024:65535 -j ACCEPT
iptables -t filter -A FORWARD -p udp -i eth0 -o eth1 -d 192.168.0.0/24 --sport 53 --dport 1024:65535 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.0.0/24 --sport 80 --dport 1024:65535 -j ACCEPT
iptables -t filter -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.0.0/24 --sport 443 --dport 1024:65535 -j ACCEPT
iptables -t filter -A FORWARD -p udp -i eth0 -o eth1 -s 172.22.20.0/24 -d 192.168.0.0/24 --sport 137:139 -j ACCEPT
iptables -t filter -A FORWARD -p udp -i eth0 -o eth1 -s 172.22.20.0/24 -d 192.168.0.0/24 --sport 445 -j ACCEPT
#
# OUTPUT:: FW --> internet
#
iptables -t filter -A OUTPUT -o lo -j ACCEPT
iptables -t filter -A OUTPUT -o ! lo -d 127.0.0.1/8 -j BADPKT

iptables -t filter -A OUTPUT -p icmp --icmp-type 8 -o eth0 -s 172.22.20.0/24 -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth0 -s 172.22.20.0/24 --dport 80 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth0 -s 172.22.20.0/24 --dport 443 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p udp -o eth0 -s 172.22.20.0/24 --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth0 -s 172.22.20.0/24 --dport 25 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth0 -s 172.22.20.0/24 --dport 110 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth0 -s 172.22.20.0/24 --dport 22 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth0 -s 172.22.20.0/24 --dport 123 --syn -m state --state NEW -j ACCEPT
#
# OUTPUT:: FW --> intranet
#
iptables -t filter -A OUTPUT -p udp -s 172.22.20.0/24 -d 192.168.0.0/24 -o eth1 --sport 445 -j ACCEPT
iptables -t filter -A OUTPUT -p udp -s 172.22.20.0/24 -d 192.168.0.0/24 -o eth1 --sport 137:139 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth1 -s 172.22.20.0/24 -d 192.168.0.0/24 --dport 22 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth1 -d 192.168.0.0/24 --sport 110 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth1 -d 192.168.0.0/24 --sport 25 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p udp -o eth1 -d 192.168.0.0/24 --sport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth1 -d 192.168.0.0/24 --sport 80 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p tcp -o eth1 -d 192.168.0.0/24 --sport 443 --syn -m state --state NEW -j ACCEPT
iptables -t filter -A OUTPUT -p icmp --icmp-type 8 -o eth1 -d 192.168.0.0/24 -m state --state NEW -j ACCEPT

iptables -t filter -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

modprobe ip_tables
modprobe ip_nat_ftp
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_conntrack_irc

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j MASQUERADE

上面是片段內容, 主要參照本文來設計, PJ. 發現, 如對防火牆設定不甚了解的人, 在經由 iptables 的洗禮後, 都會馬上變防火牆設定高手, 哈哈~~

本文還有一個重點, Debug, 是阿, 如果架好的 firewall 不知道如何 debug, PJ. 覺得這樣會跟瞎子摸象一樣, 所以工欲善其事,必先利其器^^. 來吧, 最重要的 debug 也要加入喔; 在 /etc/syslog.conf 中加入:
kern.warning /var/log/iptables.log

存檔後記得restart syslog service 喔.

然後在 firewall 的 script 當中加入:
iptables -A INPUT -j LOG --log-level 4 (level 4 = warning)
or
iptables -A INPUT -j LOG --log-prefix "*** INPUT FIREWALL ***" 也可.

-A 後面的 chain 自己代, 以上.

[註] 參考文獻: Linux iptables 技術實務 -- 施威銘研究室

沒有留言: