原文:Packet Filtering HOWTO
3 What is a packet filter?
packet filter是一套軟體,會根據packet的header決定這個packet的命運,可能是ACCEPT(bypass)或是DROP,或是其他複雜的操作(NAT/QUEUE/LOG)。
3.2 How Do I Packet Filter Under Linux?
在Linux 1.1就有packet filtering功能,在1994年由Alan Cox根據BSD的ipfw移植過來,經過Jos Vos和其他人的努力,在1999年的Linux 2.4研發出第四代tool"iptables"使用至今。
iptables可以隨時的新增或刪除在kernel中的packet filtering table的rule,每當重新開機後,這些rule就會消失,您可以使用iptables-save/iptables-restore將這些rule存到檔案,或由檔案回存到kernel中。
6. How Packets Traverse The Filters
"filter"這個table有三個chain,分別是"INPUT"、"OUTPUT"和"FORWARD"。如下圖:
當packet傳入(incoming),會先經過Routing Decision,決定封包的去向(Local In/Forwarding/Drop),當封包經過filter的這三個chain的任何一個,都會進行rule的比對並且決定封包的去留,如果是Drop,就會立刻丟棄封包,如果是ACCEPT就會往下一個rule進行比對( `if the packet header looks like this, then here's what to do with the packet')。每一個chain都有所謂的default policy,當所有的rule在這個chain都不match,就會執行這個policy(DROP/ACCEPT)。
7. Using iptables
filter table內建的三個chain INPUT、OUTPUT和FORWARD是不能被刪除的,這裡有幾個對China進行操作的選項
- 新增一個chain / Create a new chain (-N).
- 刪除空白的chain / Delete an empty chain (-X).
- 改變內建的chain的policy / Change the policy for a built-in chain. (-P).
- 列出chain的rule / List the rules in a chain (-L).
- 清除所有在chain中的rule / Flush the rules out of a chain (-F).
- 清除chain中rule的counter / Zero the packet and byte counters on all rules in a chain (-Z).
以下是對rule進行操作的選項:
- 新增rule到chain的後面 / Append a new rule to a chain (-A).
- 插入rule到chain的某個位置 / Insert a new rule at some position in a chain (-I).
- 取代chain中某個rule / Replace a rule at some position in a chain (-R).
- 移除chain中某個rule / Delete a rule at some position in a chain, or the first that matches (-D).
7.2 Operations on a Single Rule
最常用到的就是append(-A)和delete(-D) rule到chain中,當然還有insert(-I)和replace(-R)。每一條rule基本上就是設定一些條件和target,當packet滿足這些條件,就會執行該target,可能是ACCEPT也可能是DROP。比如,我們要將source ip是127.0.0.1的ICMP做DROP:
# ping -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms --- 127.0.0.1 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.2/0.2/0.2 ms # iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP # ping -c 1 127.0.0.1 PING 127.0.0.1 (127.0.0.1): 56 data bytes --- 127.0.0.1 ping statistics --- 1 packets transmitted, 0 packets received, 100% packet loss #
[!] -s, --source address[/mask][,...] source address,除了可以使用IP以外,也可以是hostname,不過只有在設定的當下會做一次resolved。
[!] -p, --protocol protocol 可以是tcp、udp、udplite、icmp、esp、ah、sctp或是all,也可以是 /etc/protocols裡面的名稱,或是任何數值。
-j, --jump target This specifies the target of the rule; i.e., what to do if the packet matches it. Target也可以是 user-defined chain。
每個選項前面都可以加上!表示反向的意思。
要刪除之前設定的rule可以使用
iptables -D INPUT 1
或是
iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
第一種是刪除第一條rule,第二種是刪除符合-s 127.0.0.1 -p icmp -j DROP這個condition的rule。
常用的option還有:
[!] -i, --in-interface name packet由哪個interface收到,只能套用在INPUT、FORWARD和PREROUTING這些chain,interface name以+為結尾就表示pattern比對。如-i ppp+就會比對所有ppp開頭的interface。
[!] -o, --out-interface name packet會由哪個interface送出,只能套用在FORWARD、OUTPUT和POSTROUTING這些chain,同樣可以使用+。