kernel 已更新至 2.4.x 就有很多人知了,但隨著 kernel 改變而要更新的軟件就有很多不為人知,這個 iptables 即為其中一個。kernel 2.4 已經推出這麼久,但仍然有人問︰為甚麼我的 ipchains 不能使用?皆因 Rusty Russell 等人(ipchains,即 kernel 2.2.x 所用的防火牆工具﹐也是他的傑作!)覺得 ipchains 仍未完善,於是決定在 kernel 2.3.15 時開始重寫,希望在 kernel 2.4 推出時有一個功能更強的 firewall 出現。他們的心血就是今期要介紹的 iptables 了。
這個 iptables 的前身稱為 netfilter,作者仍未搞清楚為何突然會改名,但新名稱約是在 kernel 2.3.99 時出現的。在本章末後的 URL 也可看到點端倪。
話又說回來,憑甚麼說它的功能強大呢?這要由 stateless firewall 這名詞說起了。
所謂 stateless firewall,乃是存在於普遍的 router 中,會對每個 packet 分別加以檢查,再決定是否讓它通過、回傳錯誤還是完全忽略。要點是 "分別" 兩個字。這裡拿 TCP 作個例子。所有 TCP connection 都是以三個 packet 開始︰一是由 client 送出一個 set 了 SYN bit 的 packet 到 server(不明白的,可當是一個特別的標籤表示 connection 開始),第二個是由 server 送出一個 set 了 SYN 和 ACK bit 的 packet 回答 client,而最後是由 client 傳回一個 set 了 ACK bit 的 packet 給 server。
問題來了。如果有人無故 send 一個有 ACK bit 的 packet,那怎分辦是故意的呢,還是一個正常的 connection 呢?stateless firewall 不能分辦這一點,於是就讓它通過了。這種技巧經常被用來 scan 網絡,因這方法可騙過很多的 firewall。
stateful firewall 和 stateless firewall 的分別就在於此了。statefull firwall 會記著每個 connection,若有任何 packet,會先看看這個 packet 是否已知的 connection 的一部份,若找過記憶中的 connection 還沒有任何資料,就可肯定這 packet 是假的,把它丟進垃圾桶裡去!當然,這是簡化了的例子,不過可向大家解釋個大概了。
它還有甚麼好處呢?以往的 ipchains 只用一個 binary,要加入其它功能十分艱難,需要直接修改源程式碼所有有關的地方並再編譯一次 ipchains 才行;但現在 iptables 使用 modules 的架構,所有外加的功能只要寫一個 module 就行,可發展的功能不限於只修改主要的 source code 才可實現,連發展速度也順帶加快了。
沒了?等等,筆者還未說完呢;iptables 能限制 connection 的速率 ── 這個對於防止長期轟炸造成的系統資源完全用盡的情況很有效。最後一點和剛才筆者提及的甚麼 SYN、ACK bit 等有關,統稱 TCP flag。ipchains 只能檢查數種可能的 flag 的其中一種,於是其它不正常的 packet 甚至某些正常的 packet 都可肆無忌憚地通過。現在 iptables 可檢查任何這類的 packet,使得許多的 scanning 無所遁形。
唔……好像在說教似的,到現在還是在講理論。不過,筆者會假設讀者對 IP、TCP、connection 等等有點概念,否則整本書也放不下呢!而且暫時只會簡簡單單地講解一些非常"小兒科"的設定,希望將來會有機會讓各位真正觸摸到 iptables 的威力!
安裝指示
文末 iptables 主網頁的 URL 裡有下載 iptables 的 link,很易看見。下載最新版本前(筆者所能找到的最新版本是 1.2.1a),先得弄清楚︰你的 kernel 是甚麼版本?如果不是 2.4.x,不好意思!還是用 ipchains 罷!
另外,也要清楚你的 kernel 是否預先支援了 iptables。從以下兩點可以判斷︰
1. /proc/net/ip_tables_names 是否存在?
2. /lib/modules/2.x.x/kernel/net/ipv4/netfilter/ip_tables.o 是否存在?
只要其中一個答案是肯定的,就表示可跳過以下兩段 recompile kernel 的步驟了。否則繼續看看怎樣 recompile kernel……
下載 kernel 後(截稿前最新還是 2.4.2,但做清兵的有特權下載 2.4.3-pre4),在 "Networking option" 中選上 "Network packet filtering (replaces ipchains)",之後就會多了一個 "IP: Netfilter Configuration --->" 的選項在 "TCP/IP Networking" menu 下,在那裡按 enter 即可開始選擇你想支援的防火牆功能了。個人提議裡面所有選項都是 "M" (即 module),因為這樣可不用浪費記憶體在沒有用的地方,也可減少 boot 機時間,同時也不怕某些功能會因沒有 compile 而用不到。
這時開始 compile kernel 並 reboot 及使用新的 kernel 吧。若在 compile 時或 compile 後的 depmod 步驟出問題,而且肯定出錯在有關 netfilter(iptables)的地方,隨時可以把剛才有關的 module 選回 "Y"(即內建在 kernel 裡)並重新 compile,沒問題的!(筆者試過了)
接下來就是 compile iptables 了。把 iptables-1.x.x.tar.gz 解壓後,先開啟文字編輯器看看有沒有問題或要修改的地方(例如想將所有 binary 放在 /usr/sbin 裡,便設定 BINDIR 為 /usr/sbin,如此類推)。修改完畢後,鍵入
# make all experimental
就會開始 compile……哎唷,出了 error?是不是像以下那樣?
libipulog/libipulog.c: In function `ipulog_create_handle':
libipulog/libipulog.c:142: `NETLINK_NFLOG' undeclared (first use in this function)
libipulog/libipulog.c:142: (Each undeclared identifier is reported only once
libipulog/libipulog.c:142: for each function it appears in.)
make: *** [libipulog/libipulog.o] Error 1
不緊要,再 edit 一次 Makefile,將 COPT_FLAGS 的一行由
COPT_FLAGS:=-O2 -DNDEBUG
變成
COPT_FLAGS:=-O2 -DNDEBUG -DNETLINK_NFLOG=4
再 compile 一次就行了!最後,輸入
# make install install-experimental
它就會把 iptables、iptables-save 及 iptables-restore 抄到 /usr/local/sbin 中。如果要用,就要把 /usr/local/sbin 加進你的 PATH 裡,這裡不詳細說明了。
若急不及待要試一試,好,鍵入以下一句︰
# iptables -L -v -n
是否 warn 你說甚麼不支援 iptables?這樣似乎是不知何故不能載入 kernel module,需要先用人手加入 module︰
# modprobe iptables
再 run 一次 iptables,就該看到像以下的輸出︰
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
是嗎?那就成功了!且看看下一章,教你怎樣建立簡單的 firwall!
設定 firewall
處理 firewall rule 的選項
且不忙著設計甚麼的,先來熱熱身︰
# iptables -A INPUT -j ACCEPT
大小楷絕不可以亂!輸入這條 rule 後,用 "iptables -L -v -n" 該看到類似以下結果︰
Chain INPUT (policy ACCEPT 2939 packets, 1124863 bytes)
pkts bytes target prot opt in out source destination
1 241 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
它表示甚麼呢?-A 是 append,它會在 INPUT、FORWARD、OUTPUT 其中一條 "chain" 裡加一條 "rule" 而這條 rule 在隨後的參數將會見到。而 -j 呢,則是定義究竟那些 packet 該怎樣處理。現在是 ACCEPT,即讓它通過。如果不想讓任何 packet 通過呢?十分簡單︰
# iptables -R INPUT 1 -j DROP
今次由 ACCEPT 變 DROP,就不會有任何 packet 可以過關了。但…… -R 又是甚麼?那是 replace 的意思,隨後的 "INPUT 1" 即 replace 了第一條 chain,即剛才 ACCEPT 那一條呀!
當然,firewall 的功用不可能是禁止任何 traffic 吧!因此讓我們先清除它︰
# iptables -D INPUT 1
-D 表示 delete,用法和上面的 -R 一樣。除了 -A、-R、-D 外還有 -I 表示 insert;-A 是逐條逐條 rule 加上去,-I 則是在整串的 rule 中間加插某一條 rule,除此之外沒有其它分別了。
最後還有 -F 表示 flush,顧名思義它會把你辛辛苦苦 set 好的 rule 都沖進馬桶裡!
有關 IP address 的選項
再多點熱身才好辦事,試試吧︰
# iptables -A INPUT -s 199.95.206.201 -j DROP
為甚麼用這個 IP 作示範?總之是個討人厭的地方吧!不要問了!一句說完,就是 block 了這一個 IP 不准它有任何 traffic 進入自己的地盤。不單是一個 IP,一個 range 的 IP 也可以︰
# iptables -A INPUT -s 10.0.0.0/8 -j DROP
如果你的 LAN 是使用 192.168.0.x 的,那當然不希望有 10.x.x.x 地址出現!因此 DROP 了這種 IP 是很正常的。
上面兩個例子是用 -s(即 source IP)的,且看看它的反面,即 -d(destination)的例子︰
# iptables -A INPUT -d 192.168.0.1 -j DROP
假設你的 IP 是 192.168.0.2 吧,那麼這條 rule 對你完全沒有影響;相反,若你的 IP 是 192.168.0.1,那任何到你的機器的 packet 都會被 DROP 了。
-s 和 -d 可以放在一起用,而且它們和 IP address 之間可以放一個嘆號(!)表示 "not" 的意思。例如︰
# iptables -P INPUT DROP
# iptables -A INPUT -s ! 192.168.0.3 -d 192.168.0.0/24 -j ACCEPT
筆者漏了 -P 未介紹,那是 default policy 的意思,即預先定義如果甚麼 rule 也不能決定 packet 的去向的時候,會預設讓它通過呢,還是預設拒諸門外,還是做其它動作。這裡預設是 DROP。好了,下一句才是筆者想講的,意思是︰如果 source 不是 192.168.0.3,而 destination 是 192.168.0.x 任何一個 IP,都會讓它通過。那即是封殺了 192.168.0.3!
在看下一節前,先清一清舊的垃圾 rules 罷︰
# iptables -F
指定 network interface 的選項
屬於這類的選項很少,和上面的一樣,只有兩個︰-i 和 -o。-i 是指明 input 的 interface,只會在 INPUT chain 時有用;相反,-o 是 output interface,只會在 output 時有用。先看看實例︰
# iptables -A INPUT -i eth1 -s 192.168.0.0/24 -d 192.168.0.0/24 -j ACCEPT
很簡單,接受所有 LAN 的 traffic 罷了。不過還加上 "-i eth1",防止 LAN 外有人刻意送入一些假的 packet,扮成是內部的 traffic。但這個其實已不需要了,因 kernel 本身已有機制可防止這種情況,輸入以下一句就行,解釋就免了。^_^
# echo '1' > /proc/sys/net/ipv4/conf/all/rp_filter
還有 -o……用一個簡單的例子吧。
# iptables -A OUTPUT -o ppp0 -d 205.138.3.22 -j REJECT
其實並不簡單。首先,-j REJECT 和 -j DROP 的相同之處都是拒絕,但 DROP 是當沒事發生,REJECT 則是送出回應說這個 packet 被 REJECT 了。另外,緊記︰-o 是和 OUTPUT chain 一起用的!至於那個 IP 嘛……總之這條 rule 可防止你的資料在不知情的情況下被送出到某間專收集全世界所有人的上網習慣等資料的公司吧!
這恐怕暫時已經夠一部份讀者們學一段時間了。至於其它早已懂得這方面知識的朋友,筆者謹此致歉!將來希望會有機會和大家探討一些較深入的設定呢!
iptables 主網址︰
http://netfilter.kernelnotes.org
http://netfilter.filewatcher.org
http://netfilter.samba.org
ipchains 網址︰
http://netfilter.kernelnotes.org/ipchains/
http://netfilter.filewatcher.org/ipchains/
http://netfilter.samba.org/ipchains/