Iptables 指南 1.1.19

from: http://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html


Iptables 指南 1.1.19

Oskar Andreasson

     [email protected]
    

本文在符合 GNU Free Documentation 許可版本1.1的條件下,可以拷貝、分發、更改,但必須保留緒言 和所有的章節,如印刷成書,封面要包括“原著:Oskar Andreasson”,且書背不準有文字。本文附錄有 “GNU Free Documentation License”的詳細內容。

文中的所有腳本均置於GNU General Public License版本2下,可以自由地分發、更改。

給出這些腳本是希望它們有所作用,但沒有任何保證,也沒有商業可用性或某些特殊用途的內在保證。 參見GNU General Public License

本文附帶一份GNU General Public License,在章節“GNU Free Documentation License”中,如沒 有,請聯繫the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- 1307 USA



獻辭

首先,我要把本文獻給我那wonderful的女友Ninel(她給我的幫助遠遠勝過我給她的):希望我能 讓你幸福,就象你給我的。( 譯者注:我沒有想到合適的詞能表達作者女友的wonderful,你就自己想 去吧。還有,不知他們現在是否結婚了:) )

其次,我要把這篇文章獻給所有Linux的開發者和維護者,就是他們完成了令人無法相信的艱難工作, 使這麼優秀的操作系統成爲可能。

目錄
譯者序
關於作者
如何閱讀
必備知識
本文約定
1. 序言
1.1. 爲什麼要寫這個指南
1.2. 指南是如何寫的
1.3. 文中出現的術語
2. 準備階段
2.1. 哪裏能取得iptables
2.2. 內核配置
2.3. 編譯與安裝
2.3.1. 編譯
2.3.2. 在Red Hat 7.1上安裝
3. 表和鏈
3.1. 概述
3.2. mangle 表
3.3. nat 表
3.4. Filter 表
4. 狀態機制
4.1. 概述
4.2. conntrack記錄
4.3. 數據包在用戶空間的狀態
4.4. TCP 連接
4.5. UDP 連接
4.6. ICMP 連接
4.7. 缺省的連接操作
4.8. 複雜協議和連接跟蹤
5. 保存和恢復數據管理規則
5.1. 速度
5.2. restore的不足之處
5.3. iptables-save
5.4. iptables-restore
6. 規則是如何練成的
6.1. 基礎
6.2. Tables
6.3. Commands
6.4. Matches
6.4.1. 通用匹配
6.4.2. 隱含匹配
6.4.3. 顯式匹配
6.4.4. 針對非正常包的匹配
6.5. Targets/Jumps
6.5.1. ACCEPT target
6.5.2. DNAT target
6.5.3. DROP target
6.5.4. LOG target
6.5.5. MARK target
6.5.6. MASQUERADE target
6.5.7. MIRROR target
6.5.8. QUEUE target
6.5.9. REDIRECT target
6.5.10. REJECT target
6.5.11. RETURN target
6.5.12. SNAT target
6.5.13. TOS target
6.5.14. TTL target
6.5.15. ULOG target
7. 防火牆配置實例 rc.firewall
7.1. 關於rc.firewall
7.2. rc.firewall詳解
7.2.1. 參數配置
7.2.2. 外部模塊的裝載
7.2.3. proc的設置
7.2.4. 規則位置的優化
7.2.5. 缺省策略的設置
7.2.6. 自定義鏈的設置
7.2.7. INPUT鏈
7.2.8. FORWARD鏈
7.2.9. OUTPUT鏈
7.2.10. PREROUTING鏈
7.2.11. POSTROUTING鏈
8. 例子簡介
8.1. rc.firewall.txt腳本的結構
8.1.1. 腳本結構
8.2. rc.firewall.txt
8.3. rc.DMZ.firewall.txt
8.4. rc.DHCP.firewall.txt
8.5. rc.UTIN.firewall.txt
8.6. rc.test-iptables.txt
8.7. rc.flush-iptables.txt
8.8. Limit-match.txt
8.9. Pid-owner.txt
8.10. Sid-owner.txt
8.11. Ttl-inc.txt
8.12. Iptables-save ruleset
A. 常用命令詳解
A.1. 查看當前規則集的命令
A.2. 修正和清空iptables的命令
B. 常見問題於與解答
B.1. 模塊裝載問題
B.2. 未設置SYN的NEW狀態包
B.3. NEW狀態的SYN/ACK包
B.4. 使用私有IP地址的ISP
B.5. 放行DHCP數據
B.6. 關於mIRC DCC的問題
C. ICMP類型
D. 其他資源和鏈接
E. 鳴謝
F. History
G. GNU Free Documentation License
0. PREAMBLE
1. APPLICABILITY AND DEFINITIONS
2. VERBATIM COPYING
3. COPYING IN QUANTITY
4. MODIFICATIONS
5. COMBINING DOCUMENTS
6. COLLECTIONS OF DOCUMENTS
7. AGGREGATION WITH INDEPENDENT WORKS
8. TRANSLATION
9. TERMINATION
10. FUTURE REVISIONS OF THIS LICENSE
How to use this License for your documents
H. GNU General Public License
0. Preamble
1. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
2. How to Apply These Terms to Your New Programs
I. 示例腳本的代碼
I.1. rc.firewall腳本代碼
I.2. rc.DMZ.firewall腳本代碼
I.3. rc.UTIN.firewall腳本代碼
I.4. rc.DHCP.firewall腳本代碼
I.5. rc.flush-iptables腳本代碼
I.6. rc.test-iptables腳本代碼

譯者序

譯者sllscn是中國Linux公社裏的“Linux 新鮮社員”,一個Linux愛好者,在實際工作中使用iptables構造防火牆時,發現有關iptables的中文資 料太少,故而不得已參考英文版的材料。爲了今後參考的方便,也爲了廣大使用者,不怕自己的英文水平 太差,翻着字典翻譯了本文。翻譯只爲了能看懂,達不到“好看”,勿怪!

第一章序言部分除了第三小節介紹的術語要看看,其他都沒什麼。第二章對想要親自編 譯iptables的兄弟們是有些幫助的。第三、第四兩章可以使我們理解、掌握iptables工作方式和流程。第五 章和第六章是iptables命令使用方法的詳細介紹。第七章與第八章是實例講解,對我們編寫自己的規則很有 指導意義的,強烈建議你看一看。附錄裏有一些資源鏈接是很好的,相信你一定會喜歡。

因爲術語的緣故,目錄部分有一些未翻譯,但正文的內容都翻譯了。附錄F是本文的更 新歷史,附錄G是GNU Free Documentation License,附錄H是GNU General Public License,它們對理解 iptables沒有什麼作用,故未翻譯。

在閱讀本文時,你可能會發現有重複的地方,這不是原作者的水平不高,反而恰恰是他 爲我們考慮的結果。你可以把這篇文章的任何一章抽出來閱讀,而不需要反覆地參照其他章節。在此,再次 向作者表示敬意!

因譯者水平有限,對原文的理解不敢保證完全正確,如有意見或建議,可以聯繫譯者[email protected]

鄭重聲明:翻譯得到了原文作者Oskar Andreasson的許可。對於本文(不是原文),可自由使用、修 改、 傳播、轉載,但對以盈利爲目的使用,保留所有權利。


關於作者

我的局域網裏有很多“年老的”計算機,他們也想連接到Internet上,還要保證安全。做到這一點, iptables是的ipchains的一個很好的升級。使用ipchains你可以通過丟棄所有“目的端口不是特定端口” 的包來建立一個安全的網絡。但這將導致一些服務出現問題,比如被動FTP,還有在IRC中流出的DCC。它 們在服務器上分配端口,並告知客戶端,然後再讓客戶連接。 但是,iptables的代碼中也有一些小毛病, 在某些方面我發現這些代碼並沒有爲作爲完整的產品發佈做好準備,但我仍然建議使用ipchains或更老的 ipfwadm 的人們進行升級,除非他們對正在使用的代碼滿意,或它們足以滿足他們的需要。


如何閱讀

本文介紹了iptables,以便你可以領會iptables的精彩,文中不包含iptables或Netfilter在安全方面的 bug。如果你發現iptables(或其組成部分)任何bug或特殊的行爲,請聯繫Netfilter mailing lists ,他 們會告訴你那是否是bug或如何解決。iptables或Netfilter中幾乎沒有安全方面的bug,當然偶爾也會出些 問題,它們能在Netfilter主頁中找到。

文中用到的腳本不能解決Netfilter內部的bug,給出它們,只是爲了演示如何構造規則,以便我們能解 決遇到的數據流管理問題。但本文沒有包括象“如何關閉HTTP端口,因爲Apache 1.2.12偶爾會被攻擊” 這樣的問題。本指南會告訴你如何通過iptables關閉HTTP端口,但不是因爲Apache偶爾會被攻擊。

本文適合於初學者,但也儘可能完善。因爲有太多的targets或matches,所以沒有完全收錄。如果你需 要這方面的信息,可以訪問Netfilter主頁


必備知識

閱讀本文,要具備一些基礎知識,如Linux/Unix,shell腳本編寫,內核編譯,最好還有一些簡單的內核 知識。

我嘗試着儘可能使讀者不需要這些知識也能完全弄懂這篇文章,但要理解擴展部分是不行的。所以還是 要有點基礎的:)


本文約定

以下的約定會在文中用到:

  • 代碼和命令輸出使用定寬字體,命令用粗體。

    [blueflux@work1 neigh]$ ls
    default  eth0  lo
    [blueflux@work1 neigh]$
         
  • 所有的命令和程序名都用粗體。

  • 所有的系統部件,如硬件、內核部件、loopback使用斜體

  • 計算機文本輸出用 這種字體

  • 文件名和路徑名象這樣 /usr/local/bin/iptables 。


1. 序言

1.1. 爲什麼要寫這個指南

我發現目前所有的HOWTO都缺乏Linux 2.4.x 內核中的Iptables和Netfilter 函數的信息,於是我試圖回 答一些問題,比如狀態匹配。我會用插圖和例子 rc.firewall.txt 加以說明,此處的例子可以在你的/etc/rc.d/使用。最初這篇文章是以HOWTO文 檔的形式書寫的,因爲許多人只接受HOWTO文檔。

還有一個小腳本rc.flush-iptables.txt,我寫它只是爲 使你在配置它的時候能象我一樣有成功的感覺。


1.2. 指南是如何寫的

我請教了Marc Boucher 及netfilter團隊的其他核心成員。對他們的工作以及對我在爲boingworld.com 書寫這個指南時的幫助表示極大的謝意,現在這個指南在我自己的站點frozentux.net上進行維護。這個文 檔將一步一步教你setup過程,讓你對iptables包有更多的瞭解。這大部分的東西都基於例子rc.firewall 文件,因爲我發現這是學習iptables的一個好方法。我決定自頂向下地跟隨rc.firewall 文件來學習 iptables。雖然這樣會困難一些,但更有邏輯。當你碰到不懂的東西時再來查看這個文件。


1.3. 文中出現的術語

文中包含了一些術語,你應該有所瞭解。這裏有一些解釋,並說明了本文中如何使用它們。

DNAT - Destination Network Address Translation 目的網絡地址轉換。 DNAT是一種改變數據包目的 ip地址的技術,經常和SNAT聯用,以使多臺服務器能共享一個ip地址連入Internet,並且繼續服務。通過對 同一個ip地址分配不同的端口,來決定數據的流向。

Stream - 流 是指發送和接收的數據包和通信的雙方都有關係的一種連接(譯者注:本文中,作者把連 接看作是單向的,流表示雙向的連接)。一般的,這個詞用於描述在兩個方向上發送兩個或三個數據包的連 接。對於TCP,流意味着連接,它發送了一個SYN,然後又回覆SYN/ACK。但也可能是指這樣的連接,發送一 個SYN,回覆ICMP主機不可達信息。換句話說,我使用這個詞很隨意。

SNAT - Source Network Address Translation源網絡地址轉換。這是一種改變數據包源ip地址的技術, 經常用來使多臺計算機分享一個Internet地址。這隻在IPv4中使用,因爲IPv4的地址已快用完了,IPv6將解 決這個問題。

State - 狀態 指明數據包處於什麼狀態。狀態在RFC 793 - Transmission Control Protocol中定義,或由用戶在Netfilter/iptables中自定義。需要注 意的是Netfilter設定了一些關於連接和數據包的狀態,但沒有完全使用使用RFC 793的定義。

User space - 用戶空間,指在內核外部或發生在內核外部的任何東西。例如,調用 iptables -h 發生在內核外部,但iptables -A FORWARD -p tcp -j ACCEPT (部分地)發生在內核內部,因爲一條新的規則加入了規則集。

Kernel space - 內核空間 ,與用戶空間相對,指那些發生在內核內部。

Userland - 參見用戶空間

target - 這個詞在後文中有大量的應用,它表示對匹配的數據包所做的操作。


2. 準備階段

這一章是學習iptables的開始,它將幫助你理解Netfilter和iptables在Linux中 扮演的角色。它會告訴你如何配置、安裝防火牆,你的經驗也會隨之增長。當然,要想達到你的目標,是要 花費時間,還要有毅力。( 譯者注:聽起來很嚇人的:) )


2.1. 哪裏能取得iptables

iptables 可以從www.netfilter.org 下載,網站中的FAQs也是很好的教程。iptables 也使用一些內核空間,可 以在用make configure配置內核的過程中配置,下面會介紹必要的步驟。


2.2. 內核配置

爲了運行iptables,需要在內核配置期間,選擇以下一些選項,不管你用make config或其他命令。

CONFIG_PACKET - 允許程序直接訪問網絡設備(譯者注:最常用的就 是網卡了),象tcpdump 和 snort就要使用這個功能。

Note

嚴格地說,iptables並不需要CONFIG_PACKET,但是它有很多用處(譯者注:其他程序需要), 所以就選上了。當然,你不想要,不選就是了。(譯者注:建議還是選的爲好)

CONFIG_NETFILTER - 允許計算機作爲網關或防火牆。 這個是必需的,因爲整篇文章都要用到這個功能。我想你也需要這個,誰叫你學iptables呢:)

當然,你要給網絡設備安裝正確的驅動程序,比如,Ethernet 網卡, PPP 還有 SLIP 。 上面的選項,只是在內核中建立了一個框架, iptables確實已經可以運行,但不能做任何實質性的工作。我們需要更多的選項。以下給出內核2.4.9的選 項和簡單的說明:

CONFIG_IP_NF_CONNTRACK - 連接跟蹤模塊,用於 NAT(網絡地址轉換) 和 Masquerading(ip地址僞 裝),當然,還有其他應用。如果你想把LAN中的一臺機子作爲防 火牆,這個模塊你算選對了。腳本rc.firewall.txt 要想正常工作,就必需有它的存在。

CONFIG_IP_NF_FTP - 這個選項提供針對FTP連接進行連接跟蹤的功 能。一般情況下,對FTP連接進行連接跟蹤是很困難的,要做到這一點,需要一個名爲helper的動態鏈接 庫。此選項就是用來編譯helper的。如果沒有這個功能,就無法穿越防火牆或網關使用FTP。

CONFIG_IP_NF_IPTABLES - 有了它,你才能使用過濾、僞裝、NAT。它 爲內核加入了iptables標識框架。沒有它,iptables毫無作用。

CONFIG_IP_NF_MATCH_LIMIT - 此模塊並不是十分必要,但我在例子rc.firewall.txt中用到了。它提供匹配LIMIT的功能,以便於使用一 個適當的規則來控制每分鐘要匹配的數據包的數量。比如, -m limit --limit 3/minute 的作用是每分鐘最多匹配三個數據包。這個功能也可用來消除某種DoS攻擊。

CONFIG_IP_NF_MATCH_MAC - 選擇這個模塊,可以根據MAC地址匹配數 據包。例如,我們想要阻塞使用了某些MAC地址的數據包,或阻塞某些計算機的通信,用這個很容易。因爲 每個Ethernet網卡都有它自己的MAC地址,且幾乎從不會改變。但我在 rc.firewall.txt中沒有用到這個功能,其他例子也未用到。(譯者注:這又一次說明了學習是爲 將來打基礎:) )

CONFIG_IP_NF_MATCH_MARK - 這個選項用來標記數據包。對數據包做 MARK(標記)操作,我們就可以在後面的表中用這個標記來匹配數據包。後文有詳細的說明。

CONFIG_IP_NF_MATCH_MULTIPORT - 選擇這個模塊我們可以使用端口範 圍來匹配數據包,沒有它,是無法做到這一點的。

CONFIG_IP_NF_MATCH_TOS - 使我們可以設置數據包的TOS(Type Of Service 服務類型)。這個工作也可以用命令ip/tc完成,還可在mangle表中用某種規則設定。

CONFIG_IP_NF_MATCH_TCPMSS - 可以基於MSS匹配TCP數據包。

CONFIG_IP_NF_MATCH_STATE - 相比較ipchains 這是最大的更新,有了它,我們可以對數據包做狀態匹配。比如,在某個TCP連接的兩個方向上已有通 信,則這個連接上的數據包就被看作ESTABLISHED(已建立連接)狀態。在rc.firewall.txt 裏大量使用了此模塊的功能。

CONFIG_IP_NF_MATCH_UNCLEAN - 匹配那些不符合類型標準或無效的 P、TCP、UDP、ICMP數據包(譯者注:之所以此模塊名爲UNCLEAN,可以這樣理解,凡不是正確模式的包都是 髒的。這有些象操作系統內存管理中的“髒頁”,那這裏就可以稱作“髒包”了,自然也就UNCLEAN了)。 我們一般丟棄這樣的包,但不知這樣做是否正確。另外要注意,這種匹配功能還在實驗階段,可能會有些問 題。

CONFIG_IP_NF_MATCH_OWNER - 根據套接字的擁有者匹配數據包。比 如,我們只允許root訪問Internet。在iptables中,這個模塊最初只是用一個例子 來說明它的功能。同樣,這個模塊也處於實驗階段,還無法使用。

CONFIG_IP_NF_FILTER - 這個模塊爲iptables添加基本的過濾表,其 中包含INPUT、FORWARD、OUTPUT鏈。通過過濾表可以做完全的IP過濾。只要想過濾數據包,不管是接收的還 是發送的,也不管做何種過濾,都必需此模塊。

CONFIG_IP_NF_TARGET_REJECT - 這個操作使我們用ICMP錯誤信息來回 應接收到的數據包,而不是簡單地丟棄它。有些情況必須要有迴應的,比如,相對於ICMP和UDP來說,要重 置或拒絕TCP連接總是需要一個TCP RST包。

CONFIG_IP_NF_TARGET_MIRROR - 這個操作使數據包返回到發送它的計 算機。例如,我們在INPUT鏈裏對目的端口爲HTTP的包設置了MIRROR操作,當有人訪問HTTP時,包就被髮送 回原計算機,最後,他訪問的可能是他自己的主頁。(譯者注:應該不難理解爲什麼叫做MIRROR了)

CONFIG_IP_NF_NAT - 顧名思義,本模塊提供NAT功能。這個選項使我 們有權訪問nat表。端口轉發和僞裝是必需此模塊的。當然,如果你的LAN裏的所有計算機都有唯一的有效的 IP地址,那在做防火牆或僞裝時就無須這個選項了。rc.firewall.txt 是需要的:)

CONFIG_IP_NF_TARGET_MASQUERADE - 提供MASQUERADE(僞裝)操作。 如果我們不知道連接Internet的IP,首選的方法就是使用MASQUERADE,而不是DNAT或SNAT。換句話說,就是 如果我們使用PPP或SLIP等連入Internet,由DHCP或其他服務分配IP,使用這個比SNAT好。因爲MASQUERADE 不需要預先知道連接Internet的IP,雖然對於計算機來說MASQUERADE要比NAT的負載稍微高一點。

CONFIG_IP_NF_TARGET_REDIRECT - 這個操作和代理程序一起使用是很 有用的。它不會讓數據包直接通過,而是把包重新映射到本地主機,也就是完成透明代理。

CONFIG_IP_NF_TARGET_LOG - 爲iptables增加 LOG(日誌)操作。通過它,可以使用系統日誌服務記錄某些數據包,這樣我們 就能瞭解在包上發生了什麼。這對於我們做安全審查、調試腳本的幫助是無價的。

CONFIG_IP_NF_TARGET_TCPMSS - 這個選項可以對付一些阻塞ICMP分段 信息的ISP(服務提供商)或服務。沒有ICMP分段信息,一些網頁、大郵件無法通過,雖然小郵件可以,還 有,在握手完成之後,ssh可以但scp不能工作。我們可以用TCPMSS解決這個問題,就是使MSS(Maximum Segment Size)被鉗制於PMTU(Path Maximum Transmit Unit)。這個方法可以處理被Netfilter開發者們 在內核配置幫助中稱作“criminally brain-dead ISPs or servers”的問題。

CONFIG_IP_NF_COMPAT_IPCHAINS - ipchains 的,這只是爲內核從2.2轉換到2.4而使用的,它會在2.6中刪除。

CONFIG_IP_NF_COMPAT_IPFWADM - 同上,這只是 ipfwadm的暫時使用的兼容模式。

上面,我簡要介紹了很多選項,但這只是內核2.4.9中的。要想看看更多的選項,建議你去Netfilter 看看patch-o-matic。在那裏,有其他的一些選項。POM可能會被加到內核裏,當然現在還沒有。這有很多 原因,比如,還不穩定,Linus Torvalds沒打算或沒堅持要把這些補丁放入主流的內核,因爲它們還在實 驗。

把以下選項編譯進內核或編譯成模塊,rc.firewall.txt才能使 用。

  • CONFIG_PACKET

  • CONFIG_NETFILTER

  • CONFIG_IP_NF_CONNTRACK

  • CONFIG_IP_NF_FTP

  • CONFIG_IP_NF_IRC

  • CONFIG_IP_NF_IPTABLES

  • CONFIG_IP_NF_FILTER

  • CONFIG_IP_NF_NAT

  • CONFIG_IP_NF_MATCH_STATE

  • CONFIG_IP_NF_TARGET_LOG

  • CONFIG_IP_NF_MATCH_LIMIT

  • CONFIG_IP_NF_TARGET_MASQUERADE

以上是爲保證 rc.firewall.txt正常工作而需要的最少的選 項。其他腳本需要的選項,在相應的章節裏都有說明。目前,我們只需注意要學習的這個腳本。


2.3. 編譯與安裝

下面,我們來看看如何編譯iptables。iptables很多組件的配置、編譯是與內核 的配置、編譯相關聯的,瞭解這一點是很重要的。某些Linux產品預裝了iptables, 比如Red Hat,但是它的缺省設置是不啓用iptables的。後文我們會介紹如何啓用它,也會介紹一下其他 Linux產品裏的iptables情況。


2.3.1. 編譯

首先要解壓iptables包。這裏,我用iptables 1.2.6a做例子(譯者注:在我翻譯時,最新版本已經是 1.2.9,其中又有了不少改進,修補了一些bug,增添了幾個match和target。)。命令 bzip2 -cd iptables-1.2.6a.tar.bz2 | tar -xvf -(當然也可以用tar -xjvf iptables-1.2.6a.tar.bz2,但這個命令可能對一些老版的tar不適用 ) 將壓 縮包解壓至目錄iptables-1.2.6a,其中的INSTALL文件有很多對編譯、運行有用的信息。

這一步,你將配置、安裝一些額外的模塊,也可以爲內核增加一些選項。我們這裏只是檢查、安裝一些 未被納入內核的標準的補丁。當然,更多的在實驗階段的補丁,僅在進行其他某些操作時纔會用到。

Note

有一些補丁僅僅處在實驗階段,把它們也安裝上不是一個好主意。這一步,你會遇到很多十分有 趣的匹配和對數據包的操作,但它們還正在實驗。

爲了完成這一步,我們要在iptables的目錄內用到如下一些命令:

make pending-patches KERNEL_DIR=/usr/src/linux/

變量KERNEL_DIR指向內核原碼的真實路徑。一般情況下,都是/usr/src/linux/ ,但也會不一樣,這要看你所用的Linux產品了。

Note

總之,只有某些補丁會被詢問是否加入內核,而Netfilter的開發者們有大量的補丁或附件想要加 入內核,但還要再實驗一陣子才能做到。如果你想安裝這些東西,就用下面的命令:

make most-of-pom KERNEL_DIR=/usr/src/linux/

這個命令會安裝部分patch-o-matic(netfilter世界對補丁的稱呼),忽略掉的是非常極端的那一部 分,它們可能會對內核造成嚴重的破壞。你要知道這個命令的作用,要了解它們對內核原碼的影響,好在在 你選用之前,會有所提示。下面的命令可以安裝所有的patch-o-matic(譯者注:一定要小心哦)。

make patch-o-matic KERNEL_DIR=/usr/src/linux/

要仔細的讀讀每一個補丁的幫助文件,因爲有些patch-o-matic會損壞內核,而有些對其他補丁有破壞作 用。

Note

你要是不打算用patch-o-matic修補內核,以上的命令都用不着,它們不是必需的。不過,你可以 用這些命令來看看有什麼有趣的玩意兒,這不會影響任何東西。

安裝好patch-o-matic,現在應該重新編譯內核了,因爲其中增加了一些補丁。但別忘了重新配置內核, 現有的配置文件裏可沒有你增加的補丁的信息。當然,你也可以先編譯iptables , 再來編譯內核。

接下來就該編譯iptables了,用下面這個簡單的命令:

make KERNEL_DIR=/usr/src/linux/

iptables應該編譯好了,如果不行,好好考慮考慮問題在哪兒,要麼訂閱 Netfilter mailing list,那裏可能有人能幫助你。

一切順利的話,我們該安裝iptables了,這幾乎不會有什麼問題的。我們用下面 的命令來完成這一步:

make install KERNEL_DIR=/usr/src/linux/

現在大功告成了。如果你在前面沒有重新編譯、安裝內核,現在就要做了,不然,你還是不能使用更新 後的iptables。好好看看INSTALL吧,那裏面有詳細的安裝信息。


2.3.2. 在Red Hat 7.1上安裝

Red Hat 7.1使用2.4.x的內核,支持Netfilter和iptables。Red Hat包含了所有 基本的程序和需要的配置文件,但缺省使用的是B class=COMMAND>ipchains。“iptables爲什麼不能 用”是最常見的問題,下面就讓我們就來說說如何關閉ipchains而起用iptables 。

Note

Red Hat 7.1預裝的iptables版本有些老了,在使用之前,你可能想裝個新的,再自己編譯一下內 核。

我們先要關閉ipchains,並且不想再讓它運行起來,做到這一點,要更改目錄/etc/rc.d/下的一些文件名。用以下命令完成:

chkconfig --level 0123456 ipchains off

這個命令把所有指向/etc/rc.d/init.d/ipchains的軟連接改名爲 K92ipchains。以S開頭表示,在啓動時會由初始化腳本運行此腳本。改爲K開頭後,就表示終止服務,或以 後在啓動時不再運行。這樣,ipchains以後不會再開機就運行了。

要想終止正在運行的服務,要用service命令。終止ipchains 服務的命令是:

service ipchains stop

現在,我們可以啓動iptables服務了。首先,要確定在哪個運行層運行,一般是 2,3和5,這些層有不同的用處:

  • 2. 不帶NFS的多用戶環境,和層3的區別僅在於不帶網絡支持。

  • 3. 多用戶環境,就是我們一般事用的層。

  • 5. X11,圖形界面。

用下面的命令以使iptables能在這些層運行:

chkconfig --level 235 iptables on

你也可以使用這個命令使iptables能在其他層運行。但沒這個必要,因爲層1是 單用戶模式,一般用在維修上;層4保留不用;層6用來關閉計算機。

啓動iptables用:

service iptables start

在腳本iptables裏還沒有定義規則。在Red Hat 7.1中添加規則的方法有二:第 一個方法是編輯/etc/rc.d/init.d/iptables,要注意在用RPM升級iptables時, 已有的規則可能會被刪除。另一個方法是先裝載規則,然後用命令iptables-save把 規則保存到文件中,再由目錄rc.d下的腳本(/etc/rc.d/init.d/iptables)自 動裝載。

我們先來說明如何利用“剪切粘貼大法”設置/etc/rc.d/init.d/iptables。 爲了能在計算機啓動iptables時裝載規則,可以把規則放在“start)”節或函數start()中。注意:如果把 規則放在“start)”節裏,則不要在“start)”節裏運行start(),還要編輯“stop)”節,以便在關機時或 進入一個不需要iptables的層時,腳本知道如何處理。還應檢查“restart”節和“condrestart”節的設 置。 一定要注意,我們所做的改動在升級iptables時可能會被刪除,而不管是通過Red Hat網絡自動升級還是用 RPM升級。

下面介紹第二種方法:先寫一個規則的腳本,或直接用iptables命令生成規則。規則要適合自己的需 要,別忘了實驗一下是否有問題,確認正常之後,使用命令iptables-save來保存規 則。一般用iptables-save > /etc/sysconfig/iptables生成保存規則的文件 /etc/sysconfig/iptables,也可以用service iptables save,它能把規則自動保存在/etc/sysconfig/iptables中。當計算機啓動 時,rc.d下的腳本將用命令iptables-restore調用這個文件,從而就自動恢復了規 則。

以上兩種方法最好不要混用,以免用不同方法定義的規則互相影響,甚至使防火牆的設置無效。

至此,可以刪除預裝的ipchainsiptables了,這樣可以 避免新舊版本的iptables之間的衝突。其實,只有當你從原碼安裝時,才需要這樣 做。但一般來說,也不會出現互相影響的問題,因爲基於rpm的包不使用原碼的缺省目錄。刪除用以下命 令:

rpm -e iptables

既然不用ipchains爲什麼要保留呢?刪吧!命令如下:

rpm -e ipchains

歷經磨難,勝利終於到來了。你已經能夠從源碼安裝iptables了。那些老版的東西就刪掉吧。


Chapter 3. 表和鏈

這一章我們來討論數據包是以什麼順序、如何穿越不同的鏈和表的。稍後,在你自己寫規則時,就會知 道這個順序是多麼的重要。一些組件是iptables與內核共用的,比如,數據包路由的判斷。瞭解到這一點是 很重要的,尤其在你用iptables改變數據包的路由時。這會幫助你弄明白數據包是如何以及爲什麼被那樣路 由,一個好的例子是DNATSNAT,不要忘了TOS的作用。


3.1. 概述

當數據包到達防火牆時,如果MAC地址符合,就會由內核裏相應的驅動程序接收,然後會經過一系列操 作,從而決定是發送給本地的程序,還是轉發給其他機子,還是其他的什麼。

我們先來看一個以本地爲目的的數據包,它要經過以下步驟才能到達要接收它的程序:

下文中有個詞mangle,我實在沒想到什麼合適的詞來表達這個意思,只因爲我的英語太差!我只能把我 理解的寫出來。這個詞表達的意思是,會對數據包的一些傳輸特性進行修改,在mangle表中允許的操作是 TOS、TTL、MARK。也就是說,今後只要我們見到這個詞能理解它的作用就行了。

Table 3-1. 以本地爲目標(就是我們自己的機子了)的包

Step(步驟) Table(表) Chain(鏈) Comment(註釋)
1     在線路上傳輸(比如,Internet)
2     進入接口 (比如, eth0)
3 mangle PREROUTING 這個鏈用來mangle數據包,比如改變TOS等
4 nat PREROUTING 這個鏈主要用來做DNAT。不要在這個鏈做過慮操作,因爲某 些情況下包會溜過去。
5     路由判斷,比如,包是發往本地的,還是要轉發的。
6 mangle INPUT 在路由之後,被送往本地程序之前,mangle數據包。
7 filter INPUT 所有以本地爲目的的包都要經過這個鏈,不管它們從哪兒 來,對這些包的過濾條件就設在這裏。
8     到達本地程序了(比如,服務程序或客戶程序)

注意,相比以前(譯者注:就是指ipchain)現在數據包是由INPUT鏈過,而不是FORWARD鏈。這樣更符合 邏輯。剛看上去可能不太好理解,但仔細想想就會恍然大悟的。

現在我們來看看源地址是本地器的包要經過哪些步驟:

Table 3-2. 以本地爲源的包

Step Table Chain Comment
1     本地程序(比如,服務程序或客戶程序)
2     路由判斷,要使用源地址,外出接口,還有其他一些信息。
3 mangle OUTPUT 在這兒可以mangle包。建議不要在這兒做過濾,可能有副作 用哦。
4 nat OUTPUT 這個鏈對從防火牆本身發出的包進行DNAT操作。
5 filter OUTPUT 對本地發出的包過濾。
6 mangle POSTROUTING 這條鏈主要在包DNAT之後(譯者注:作者把這一次DNAT稱作 實際的路由,雖然在前面有一次路由。對於本地的包,一旦它被生成,就必須經過路由代碼的處理,但這個 包具體到哪兒去,要由NAT代碼處理之後才能確定。所以把這稱作實際的路由。),離開本地之前,對包 mangle。有兩種包會經過這裏,防火牆所在機子本身產生的包,還有被轉發的包。
7 nat POSTROUTING 在這裏做SNAT。但不要在這裏做過濾,因爲有副作用,而且 有些包是會溜過去的,即使你用了DROP策略。
8     離開接口(比如: eth0)
9     在線路上傳輸(比如,Internet)

在這個例子中,我們假設一個包的目的是另一個網絡中的一臺機子。讓我們來看看這個包的旅程:

Table 3-3. 被轉發的包

Step Table Chain Comment
1     在線路上傳輸(比如,Internet)
2     進入接口(比如, eth0)
3 mangle PREROUTING mangle數據包,,比如改變TOS等。
4 nat PREROUTING 這個鏈主要用來做DNAT。不要在這個鏈做過慮操作,因爲某 些情況下包會溜過去。稍後會做SNAT。
5     路由判斷,比如,包是發往本地的,還是要轉發的。
6 mangle FORWARD 包繼續被髮送至mangle表的FORWARD鏈,這是非常特殊的情 況纔會用到的。在這裏,包被mangle(還記得mangle的意思嗎)。這次mangle發生在最初的路由判斷之後, 在最後一次更改包的目的之前(譯者注:就是下面的FORWARD鏈所做的,因其過濾功能,可能會改變一些包 的目的地,如丟棄包)。
7 filter FORWARD 包繼續被髮送至這條FORWARD鏈。只有需要轉發的包纔會走 到這裏,並且針對這些包的所有過濾也在這裏進行。注意,所有要轉發的包都要經過這裏,不管是外網到內 網的還是內網到外網的。在你自己書寫規則時,要考慮到這一點。
8 mangle POSTROUTING 這個鏈也是針對一些特殊類型的包(譯者注:參考第6步, 我們可以發現,在轉發包時,mangle表的兩個鏈都用在特殊的應用上)。這一步mangle是在所有更改包的目 的地址的操作完成之後做的,但這時包還在本地上。
9 nat POSTROUTING 這個鏈就是用來做SNAT的,當然也包括Masquerade(僞 裝)。但不要在這兒做過濾,因爲某些包即使不滿足條件也會通過。
10     離開接口(比如: eth0)
11     又在線路上傳輸了(比如,LAN)

就如你所見的,包要經歷很多步驟,而且它們可以被阻攔在任何一條鏈上,或者是任何有問題的地方。 我們的主要興趣是iptables的概貌。注意,對不同的接口,是沒有什麼特殊的鏈和表的。所有要經防火牆/ 路由器轉發的包都要經過FORWARD鏈。

Caution

在上面的情況裏,不要在INPUT鏈上做過濾。INPUT是專門用來操作那些以我們的機子爲目的地址 的包的,它們不會被路由到其它地方的。

現在,我們來看看在以上三種情況下,用到了哪些不同的鏈。圖示如下:

要弄清楚上面的圖,可以這樣考慮。在第一個路由判斷處,不是發往本地的包,我們會發送它穿過 FORWARD鏈。若包的目的地是本地監聽的IP地址,我們就會發送這個包穿過INPUT鏈,最後到達本地。

值得注意的是,在做NAT的過程中,發往本機的包的目的地址可能會在PREROUTING鏈裏被改變。這個操作 發生在第一次路由之前,所以在地址被改變之後,才能對包進行路由。注意,所有的包都會經過上圖中的某 一條路徑。如果你把一個包DNAT回它原來的網絡,這個包會繼續走完相應路徑上剩下的鏈,直到它被髮送回 原來的網絡。

Tip

想要更多的信息,可以看看rc.test-iptables.txt ,這個腳本包括了一些規則,它們會向你展示包是怎樣通過各個表和鏈的。


3.2. mangle 表

這個表主要用來mangle包,你可以使用mangle匹配來改變包的TOS等特性。

Caution

強烈建議你不要在這個表裏做任何過濾,不管是DANT,SNAT或者Masquerade。

以下是mangle表中僅有的幾種操作:

  • TOS

  • TTL

  • MARK

TOS操作用來設置或改變數據包的服務類型域。這常用來設置網絡上的數據包如何被路由等策略。 注意這個操作並不完善,有時得不所願。它在Internet上還不能使用,而且很多路由器不會注意到 這個域值。換句話說,不要設置發往Internet的包,除非你打算依靠TOS來路由,比如用iproute2。

TTL操作用來改變數據包的生存時間域,我們可以讓所有數據包只有一個特殊的TTL。它的存在有 一個很好的理由,那就是我們可以欺騙一些ISP。爲什麼要欺騙他們呢?因爲他們不願意讓我們共享 一個連接。那些ISP會查找一臺單獨的計算機是否使用不同的TTL,並且以此作爲判斷連接是否被共享 的標誌。

MARK用來給包設置特殊的標記。iproute2能識別這些標記,並根據不同的標記(或沒有標記) 決定不同的路由。用這些標記我們可以做帶寬限制和基於請求的分類。


3.3. nat 表

此表僅用於NAT,也就是轉換包的源或目標地址。注意,就象我們前面說過的,只有流的第一個 包會被這個鏈匹配,其後的包會自動被做相同的處理。實際的操作分爲以下幾類:

  • DNAT

  • SNAT

  • MASQUERADE

DNAT操作主要用在這樣一種情況,你有一個合法的IP地址,要把對防火牆的訪問 重定向到其他的機子上(比如DMZ)。也就是說,我們改變的是目的地址,以使包能重路由到某臺主機。

SNAT改變包的源地址,這在極大程度上可以隱藏你的本地網絡或者DMZ等。一個 很好的例子是我們知道防火牆的外部地址,但必須用這個地址替換本地網絡地址。有了這個操作,防火牆就 能自動地對包做SNAT和De-SNAT(就是反向的SNAT),以使LAN能連接到Internet。如果使用類似 192.168.0.0/24這樣的地址,是不會從Internet得到任何迴應的。因爲IANA定義這些網絡(還有其他的)爲 私有的,只能用於LAN內部。

MASQUERADE的作用和MASQUERADE完全一樣,只是計算機 的負荷稍微多一點。因爲對每個匹配的包,MASQUERADE都要查找可用的IP地址,而 不象SNAT用的IP地址是配置好的。當然,這也有好處,就是我們可以使用通過PPP、 PPPOE、SLIP等撥號得到的地址,這些地址可是由ISP的DHCP隨機分配的。


3.4. Filter 表

filter 表用來過濾數據包,我們可以在任何時候匹配包並過濾它們。 我們就是在這裏根據包的內容對包做DROP或ACCEPT的。當然,我們也可以預先在其他地方做些過濾,但是這 個表纔是設計用來過濾的。幾乎所有的target都可以在這兒使用。大量具體的介紹在後面,現在你只要知道 過濾工作主要是在這兒完成的就行了。


Chapter 4. 狀態機制

本章將詳細介紹狀態機制。通讀本章,你會對狀態機制是如何工作的有一個全面的瞭解。我們用一些例 子來進行說明狀態機制。實踐出真知嘛。


4.1. 概述

狀態機制是iptables中特殊的一部分,其實它不應該叫狀態機制,因爲它只是一種連接跟蹤機制。但 是,很多人都認可狀態機制這個名字。文中我也或多或或少地用這個名字來表示和連接跟蹤相同的意思。這 不應該引起什麼混亂的。連接跟蹤可以讓Netfilter知道某個特定連接的狀態。運行連接跟蹤的防火牆稱作 帶有狀態機制的防火牆,以下簡稱爲狀態防火牆。狀態防火牆比非狀態防火牆要安全,因爲它允許我們編寫 更嚴密的規則。

在iptables裏,包是和被跟蹤連接的四種不同狀態有關的。它們是NEWESTABLISHEDRELATEDINVALID。 後面我們會深入地討論每一個狀態。使用--state匹配操作,我們能很容易地控制 “誰或什麼能發起新的會話”。

所有在內核中由Netfilter的特定框架做的連接跟蹤稱作conntrack(譯者注:就是connection tracking 的首字母縮寫)。conntrack可以作爲模塊安裝,也可以作爲內核的一部分。大部分情況下,我們想要,也 需要更詳細的連接跟蹤,這是相比於缺省的conntrack而言。也因爲此,conntrack中有許多用來處理TCP, UDP或ICMP協議的部件。這些模塊從數據包中提取詳細的、唯一的信息,因此能保持對每一個數據流的跟 蹤。這些信息也告知conntrack流當前的狀態。例如,UDP流一般由他們的目的地址、源地址、目的端口和源 端口唯一確定。

在以前的內核裏,我們可以打開或關閉重組功能。然而,自從iptables和Netfilter,尤其是連接跟蹤被 引入內核,這個選項就被取消了。因爲沒有包的重組,連接跟蹤就不能正常工作。現在重組已經整合入 conntrack,並且在conntrack啓動時自動啓動。不要關閉重組功能,除非你要關閉連接跟蹤。

除了本地產生的包由OUTPUT鏈處理外,所有連接跟蹤都是在PREROUTING鏈裏進行處理的,意思就是, iptables會在PREROUTING鏈裏從新計算所有的狀態。如果我們發送一個流的初始化包,狀態就會在OUTPUT鏈 裏被設置爲NEW,當我們收到迴應的包時,狀態就會在PREROUTING鏈裏被設置爲ESTABLISHED。如果第一個包不是本地產生的,那就會在PREROUTING鏈裏被設置爲NEW狀 態。綜上,所有狀態的改變和計算都是在nat表中的PREROUTING鏈和OUTPUT鏈裏完成的。


4.2. conntrack記錄

我們先來看看怎樣閱讀/proc/net/ip_conntrack裏的conntrack記錄。這些記 錄表示的是當前被跟蹤的連接。如果安裝了ip_conntrack模塊,cat /proc/net/ip_conntrack 的顯示類似:

tcp      6 117 SYN_SENT src=192.168.1.6 dst=192.168.1.9 sport=32775 \
     dport=22 [UNREPLIED] src=192.168.1.9 dst=192.168.1.6 sport=22 \
     dport=32775 use=2
     

conntrack模塊維護的所有信息都包含在這個例子中了,通過它們就可以知道某個特定的連接處於什麼狀 態。首先顯示的是協議,這裏是tcp,接着是十進制的6(譯者注:tcp的協議類型代碼是6)。之後的117是 這條conntrack記錄的生存時間,它會有規律地被消耗,直到收到這個連接的更多的包。那時,這個值就會 被設爲當時那個狀態的缺省值。接下來的是這個連接在當前時間點的狀態。上面的例子說明這個包處在狀態 SYN_SENT,這個值是iptables顯示的,以便我們好理解,而內部用的值稍有不同。SYN_SENT說明我們正在觀 察的這個連接只在一個方向發送了一TCP SYN包。再下面是源地址、目的地址、源端口和目的端口。其 中有個特殊的詞UNREPLIED,說明這個連接還沒有收到任何迴應。最後,是希望接收的應答包的信息,他們 的地址和端口和前面是相反的。

連接跟蹤記錄的信息依據IP所包含的協議不同而不同,所有相應的值都是在頭文件linux/include/netfilter-ipv4/ip_conntrack*.h中定義的。IP、TCP、UDP、ICMP協 議的缺省值是在linux/include/netfilter-ipv4/ip_conntrack.h裏定義的。具 體的值可以查看相應的協議,但我們這裏用不到它們,因爲它們大都只在conntrack內部使用。隨着狀態的 改變,生存時間也會改變。

Note

最近patch-o-matic裏有一個新的補丁,可以把上面提到的超時時間也作爲系統變量,這樣我們就 能夠在系統空閒時改變它們的值。以後,我們就不必爲了改變這些值而重編譯內核了。

這些可通過/proc/sys/net/ipv4/netfilter下的一些特殊的系統調用 來改變。仔細看看/proc/sys/net/ipv4/netfilter/ip_ct_*裏的變量吧。

當一個連接在兩個方向上都有傳輸時,conntrack記錄就刪除[UNREPLIED]標誌,然後重置。在末尾有 [ASSURED]的記錄說明兩個方向已沒有流量。這樣的記錄是確定的,在連接跟蹤表滿時,是不會被刪除的, 沒有[ASSURED]的記錄就要被刪除。連接跟蹤表能容納多少記錄是被一個變量控制的,它可由內核中的ip- sysctl函數設置。默認值取決於你的內存大小,128MB可以包含8192條目錄,256MB是16376條。你也可以在 /proc/sys/net/ipv4/ip_conntrack_max裏查看、設置。


4.3. 數據包在用戶空間的狀態

就象前面說的,包的狀態依據IP所包含的協議不同而不同,但在內核外部,也就是用戶空間裏,只有4種 狀態:NEWESTABLISHEDRELATED 和INVALID。它們主要是和狀態匹配一起使用。下面就簡要地介紹以下這幾種狀態:

Table 4-1. 數據包在用戶空間的狀態

State(狀態) Explanation(註釋)
NEW NEW說明這個包是我們看到的第一個 包。意思就是,這是conntrack模塊看到的某個連接第一個包,它即將被匹配了。比如,我們看到一個SYN 包,是我們所留意的連接的第一個包,就要匹配它。第一個包也可能不是SYN包,但它仍會被認爲是NEW狀態。這樣做有時會導致一些問題,但對某些情況是有非常大的幫助的。例如,在 我們想恢復某條從其他的防火牆丟失的連接時,或者某個連接已經超時,但實際上並未關閉時。
ESTABLISHED ESTABLISHED已經注意到兩個方向上 的數據傳輸,而且會繼續匹配這個連接的包。處於ESTABLISHED狀態的連接是非常容 易理解的。只要發送並接到應答,連接就是ESTABLISHED的了。一個連接要從NEW變 爲ESTABLISHED,只需要接到應答包即可,不管這個包是發往防火牆的,還是要由防 火牆轉發的。ICMP的錯誤和重定向等信息包也被看作是ESTABLISHED,只要它們是我 們所發出的信息的應答。
RELATED RELATED是個比較麻煩的狀態。當一 個連接和某個已處於ESTABLISHED狀態的連接有關係時,就被認爲是RELATED的了。換句話說,一個連接要想 是RELATED的,首先要有一個ESTABLISHED的連接。這個ESTABLISHED連接再產生一個主連接之外的連接,這 個新的連接就是RELATED的了,當然前提是conntrack模塊要能理解RELATED。ftp是個很好的例子,FTP-data 連接就是和FTP-control有RELATED的。還有其他的例子,比如,通過IRC的DCC連接。有了這個狀態,ICMP應 答、FTP傳輸、DCC等才能穿過防火牆正常工作。注意,大部分還有一些UDP協議都依賴這個機制。這些協議 是很複雜的,它們把連接信息放在數據包裏,並且要求這些信息能被正確理解。
INVALID INVALID說明數據包不能被識別屬於 哪個連接或沒有任何狀態。有幾個原因可以產生這種情況,比如,內存溢出,收到不知屬於哪個連接的ICMP 錯誤信息。一般地,我們DROP這個狀態的任何東西。

這些狀態可以一起使用,以便匹配數據包。這可以使我們的防火牆非常強壯和有效。以前,我們經常打 開1024以上的所有端口來放行應答的數據。現在,有了狀態機制,就不需再這樣了。因爲我們可以只開放那 些有應答數據的端口,其他的都可以關閉。這樣就安全多了。


4.4. TCP 連接

本節和下面的幾節,我們來詳細討論這些狀態,以及在TCP、UDP和ICMP這三種基本的協議裏怎樣操作它 們。當然,也會討論其他協議的情況。我們還是從TCP入手,因爲它本身就是一個帶狀態的協議,並且具有 很多關於iptables狀態機制的詳細信息。

一個TCP連接是經過三次握手協商連接信息才建立起來的。整個會話由一個SYN包開始,然後是一個 SYN/ACK包,最後是一個ACK包,此時,會話才建立成功,能夠發送數據。最大的問題在於連接跟蹤怎樣控制 這個過程。其實非常簡單。

默認情況下,連接跟蹤基本上對所有的連接類型做同樣的操作。看看下面的圖片,我們就能明白在連接 的不同階段,流是處於什麼狀態的。就如你看到的,連接跟蹤的代碼不是從用戶的觀點來看待TCP連接建立 的流程的。連接跟蹤一看到SYN包,就認爲這個連接是NEW狀態,一看到返回的SYN/ACK包,就認爲連接是 ESTABLISHED狀態。如果你仔細想想第二步,應該能理解爲什麼。有了這個特殊處理,NEW和ESTABLISHED包 就可以發送出本地網絡,且只有ESTABLISHED的連接纔能有迴應信息。如果把整個建立連接的過程中傳輸的 數據包都看作NEW,那麼三次握手所用的包都是NEW狀態的,這樣我們就不能阻塞從外部到本地網絡的連接 了。因爲即使連接是從外向內的,但它使用的包也是NEW狀態的,而且爲了其他連接能正常傳輸,我們不得 不允許NEW狀態的包返回並進入防火牆。更復雜的是,針對TCP連接內核使用了很多內部狀態,它們的定義在 RFC 793 - Transmission Control Protocol的21-23頁。但好在我們在用 戶空間用不到。後面我們會詳細地介紹這些內容。

正如你看到的,以用戶的觀點來看,這是很簡單的。但是,從內核的角度看這一塊還有點困難的。我們 來看一個例子。認真考慮一下在/proc/net/ip_conntrack裏,連接的狀態是如何 改變的。

tcp      6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 \
     dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23 \
     dport=1031 use=1
   

從上面的記錄可以看出,SYN_SENT狀態被設置了,這說明連接已經發出一個SYN包,但應答還沒發送過 來,這可從[UNREPLIED]標誌看出。

tcp      6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031 \
     dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 \
     use=1
   

現在我們已經收到了相應的SYN/ACK包,狀態也變爲SYN_RECV,這說明最初發出的SYN包已正確傳輸,並 且SYN/ACK包也到達了防火牆。 這就意味着在連接的兩方都有數據傳輸,因此可以認爲兩個方向都有相應的 迴應。當然,這是假設的。

tcp      6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35 \
     sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 \
     sport=23 dport=1031 use=1
   

現在我們發出了三步握手的最後一個包,即ACK包,連接也就進入ESTABLISHED狀態了。再傳輸幾個數據 包,連接就是[ASSURED]的了。

下面介紹TCP連接在關閉過程中的狀態。

如上圖,在發出最後一個ACK包之前,連接(指兩個方向)是不會關閉的。注意,這只是針對一般的情 況。連接也可以通過發送關閉,這用在拒絕一個連接的時候。在RST包發送之後,要經過預先設定的一段時 間,連接才能斷掉。

連接關閉後,進入TIME_WAIT狀態,缺省時間是2分鐘。之所以留這個時間,是爲了讓數據包能完全通過 各種規則的檢查,也是爲了數據包能通過擁擠的路由器,從而到達目的地。

如果連接是被RST包重置的,就直接變爲CLOSE了。這意味着在關閉之前只有10秒的默認時間。RST包是不 需要確認的,它會直接關閉連接。針對TCP連接,還有其他一些狀態我們沒有談到。下面給出一個完整的狀 態列表和超時值。

Table 4-2. 內部狀態

State Timeout value
NONE 30 minutes
ESTABLISHED 5 days
SYN_SENT 2 minutes
SYN_RECV 60 seconds
FIN_WAIT 2 minutes
TIME_WAIT 2 minutes
CLOSE 10 seconds
CLOSE_WAIT 12 hours
LAST_ACK 30 seconds
LISTEN> 2 minutes

這些值不是絕對的,可以隨着內核的修訂而變化,也可以通過/proc/sys/net/ipv4/netfilter/ip_ct_tcp_*的變量更改。這些默認值都是經過實踐 檢驗的。它們的單位是jiffies(百分之一秒),所以3000就代表30秒。

Note

注意狀態機制在用戶空間裏的部分不會查看TCP包的標誌位(也就是說TCP標誌對它而言是透明 的)。如果我們想讓NEW狀態的包通過防火牆,就要指定NEW狀態,我們理解的NEW狀態的意思就是指SYN包, 可是iptables又不查看這些標誌位。這就是問題所在。有些沒有設置SYN或ACK的包,也會被看作NEW狀態 的。這樣的包可能會被冗餘防火牆用到,但對只有一個防火牆的網絡是很不利的(可能會被攻擊哦)。那我 們怎樣才能不受這樣的包的影響呢?你可以使用未設置SYN的NEW狀態包 裏的命令。還有一個辦法,就是安裝patch-o-matic裏的tcp-window-tracking擴展功能,它可以使防火牆能 根據TCP的一些標誌位來進行狀態跟蹤。


4.5. UDP連接

UDP連接是無狀態的,因爲它沒有任何的連接建立和關閉過程,而且大部分是無序列號的。以某個順序收 到的兩個數據包是無法確定它們的發出順序的。但內核仍然可以對UDP連接設置狀態。我們來看看是如何跟 蹤UDP連接的,以及conntrack的相關記錄。

從上圖可以看出,以用戶的角度考慮,UDP連接的建立幾乎與TCP的一樣。雖然conntrack信息看起來有點 兒不同,但本質上是一樣的。下面我們先來看看第一個UDP包發出後的conntrack記錄。

udp      17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 \
     [UNREPLIED] src=192.168.1.5 dst=192.168.1.2 sport=1025 \
     dport=137 use=1
   

從前兩個值可知,這是一個UDP包。第一個是協議名稱,第二個是協議號,第三個是此狀態的生存時間, 默認是30秒。接下來是包的源、目地址和端口,還有期待之中迴應包的源、目地址和端口。[UNREPLIED]標 記說明還未收到迴應。

udp      17 170 src=192.168.1.2 dst=192.168.1.5 sport=137 \
     dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 \
     dport=137 use=1
   

一旦收到第一個包的迴應,[UNREPLIED]標記就會被刪除,連接就被認爲是ESTABLISHED的,但在記錄裏 並不顯示ESTABLISHED標記。相應地,狀態的超時時間也變爲180秒了。在本例中,只剩170秒了,10秒後, 就會減少爲160秒。有個東西是不可少的,雖然它可能會有些變化,就是前面提過的[ASSURED]。要想變爲 [ASSURED]狀態,連接上必須要再有些流量。

udp      17 175 src=192.168.1.5 dst=195.22.79.2 sport=1025 \
     dport=53 src=195.22.79.2 dst=192.168.1.5 sport=53 \
     dport=1025 [ASSURED] use=1
   

可以看出來,[ASSURED]狀態的記錄和前面的沒有多大差別,除了標記由[UNREPLIED]變成[ASSURED]。如 果這個連接持續不了180秒,那就要被中斷。180秒是短了點兒,但對大部分應用足夠了。只要遇到這個連接 的包穿過防火牆,超時值就會被重置爲默認值,所有的狀態都是這樣的。


4.6. ICMP 連接

ICMP也是一種無狀態協議,它只是用來控制而不是建立連接。ICMP包有很多類型,但只有四種類型有應 答包,它們是回顯請求和應答(Echo request and reply),時間戳請求和應答(Timestamp request and reply),信息請求和應答(Information request and reply),還有地址掩碼請求和應答(Address mask request and reply),這些包有兩種狀態,NEWESTABLISHED 。時間戳請求和信息請求已經廢除不用了,回顯請求還是常用的,比如ping命令就用的到,地址掩碼請 求不太常用,但是可能有時很有用並且值得使用。看看下面的圖,就可以大致瞭解ICMP連接的NEWESTABLISHED狀態了。

如圖所示,主機向目標發送一個回顯請求,防火牆就認爲這個包處於NEW狀態。 目標迴應一個回顯應答,防火牆就認爲包處於ESTABLISHED了。當回顯請求被髮送 時,ip_conntrack裏就有這樣的記錄了:

icmp     1 25 src=192.168.1.6 dst=192.168.1.10 type=8 code=0 \
     id=33029 [UNREPLIED] src=192.168.1.10 dst=192.168.1.6 \
     type=0 code=0 id=33029 use=1
   

可以看到,ICMP的記錄和TCP、UDP的有點區別,協議名稱、超時時間和源、目地址都一樣,不同之處在 於沒有了端口,而新增了三個新的字段:typecodeid。字段type說明ICMP的類型。code說明ICMP的代 碼,這些代碼在附錄ICMP類型裏有說明。id是ICMP包的ID。每個ICMP包被髮送時都被分配一個ID,接受方把同樣的ID 分配給應答包,這樣發送方能認出是哪個請求的應答。

[UNREPLIED]的含義和前面一樣,說明數的傳輸只發生在一個方向上,也就是說未收到應答。再往後,是 應答包的源、目地址,還有相應的三個新字段,要注意的是type和code是隨着應答包的不同而變化的,id和 請求包的一樣。

和前面一樣,應答包被認爲是ESTABLISHED的。然而,在應答包之後,這個ICMP 連接就不再有數據傳輸了。所以,一旦應答包穿過防火牆,ICMP的連接跟蹤記錄就被銷燬了。

以上各種情況,請求被認爲NEW,應答是ESTABLISHED。 換句話說,就是當防火牆看到一個請求包時,就認爲連接處於NEW狀態,當有應答 時,就是ESTABLISHED狀態。

Note

注意,應答包必須符合一定的標準,連接才能被認作established的,每個傳輸類型都是這樣。

ICMP的缺省超時是30秒,可以在/proc/sys/net/ipv4/netfilter/ip_ct_icmp_timeout中修改。這個值是比較合適 的,適合於大多數情況。

ICMP的另一個非常重要的作用是,告訴UDP、TCP連接或正在努力建立的連接發生了什麼,這時ICMP應答 被認爲是RELATED的。主機不可達和網絡不可達就是這樣的例子。當試圖連接某臺機 子不成功時(可能那臺機子被關上了),數據包所到達的最後一臺路由器就會返回以上的ICMP信息,它們就 是RELATED的,如下圖:

我們發送了一個SYN包到某一地址,防火牆認爲它的狀態是NEW。但是,目標網絡 有問題不可達,路由器就會返回網絡不可達的信息,這是RELATED的。連接跟蹤會認 出這個錯誤信息是哪個連接的,連接會中斷,同時相應的記錄刪除會被刪除。

當UDP連接遇到問題時,同樣會有相應的ICMP信息返回,當然它們的狀態也是RELATED ,如下圖:

我們發送一個UDP包,當然它是NEW的。但是,目標網絡被一些防火牆或路由器所 禁止。我們的防火牆就會收到網絡被禁止的信息。防火牆知道它是和哪個已打開的UDP連接相關的,並且把 這個信息(狀態是RELATED)發給它,同時,把相應的記錄刪除。客戶機收到網絡被 禁止的信息,連接將被中斷。


4.7. 缺省的連接操作

有時,conntrack機制並不知道如何處理某個特殊的協議,尤其是在它不瞭解這個協議或不知道協議如何 工作時,比如,NETBLT,MUX還有EGP。這種情況下,conntrack使用缺省的操作。這種操作很象對UDP連接的 操作,就是第一個包被認作NEW,其後的應答包等等數據都是 ESTABLISHED

使用缺省操作的包的超時值都是一樣的,600秒,也就是10分鐘。當然,這個值可以通過/proc/sys/net/ipv4/netfilter/ip_ct_generic_timeout更改,以便適應你的通信 量,尤其是在耗時較多、流量巨大的情況下,比如使用衛星等。


4.8. 複雜協議和連接跟蹤

有些協議比其他協議更復雜,這裏複雜的意思是指連接跟蹤機制很難正確地跟蹤它們,比如,ICQ、IRC 和FTP,它們都在數據包的數據域裏攜帶某些信息,這些信息用於建立其他的連接。因此,需要一些特殊的 helper來完成工作。

下面以FTP作爲例子。FTP協議先建立一個單獨的連接——FTP控制會話。我們通過這個連接發佈命令,其 他的端口就會打開以便傳輸和這個命令相關的數據。這些連接的建立方法有兩種:主動模式和被動模式。先 看看主動模式,FTP客戶端發送端口和IP地址信 息給服務器端,然後,客戶端打開這個端口,服務器端從它自己的20端口(FTP-Data端口號)建立與這個端 口的連接,接着就可以使用這個連接發送數據了。

問題在於防火牆不知道這些額外的連接(相對於控制會話而言),因爲這些連接在建立時的磋商信息都 在協議數據包的數據域內,而不是在可分析的協議頭裏。因此,防火牆就不知道是不是該放這些從服務器到 客戶機的連接過關。

解決的辦法是爲連接跟蹤模塊增加一個特殊的helper,以便能檢測到那些信息。這樣,那些從FTP服務器 到客戶機的連接就可以被跟蹤了,狀態是RELATED,過程如下圖所示:

被動FTP工作方式下,data連接的建立過程和主動FTP的相反。客戶機告訴服務器需要某些數據,服務器 就把地址和端口發回給客戶機,客戶機據此建立連接接受數據。如果FTP服務器在防火牆後面,或你對用戶 限制的比較嚴格,只允許他們訪問HTTP和FTP,而封閉了其他所有端口,爲了讓在Internet是的客戶機能訪 問到FTP,也需要增加上面提到的helper。下面是被動模式下data連接的建立過程:

有些conntrack helper已經包含在內核中,在寫這篇文章時,FTP和IRC已有了相應的conntrack helper。如果在內核裏沒有你想要的helper,可以到iptables用戶空間的patch-o-matic目錄中看看,那裏 有很多的helper,比如針對ntalk或H.323協議的等等。如果沒找到,還有幾個選擇:可以查查iptables的 CVS,或者聯繫Netfilter-devel問問有沒有你要的。還不行的話,只有你 自己寫了,我可以給你介紹一篇好文章,Rusty Russell's Unreliable Netfilter Hacking HOW-TO,連接放在附錄裏其他資源和 鏈接

Conntrack helper即可以被靜態地編譯進內核,也可以作爲模塊,但要用下面的命令裝載:

modprobe ip_conntrack_*
   

注意連接跟蹤並不處理NAT,因此要對連接做NAT就需要增加相應的模塊。比如,你想NAT並跟蹤FTP連 接,除了FTP的相應模塊,還要有NAT的模塊。所有的NAT helper名字都是以ip_nat_開頭的,這是一個命名 習慣:FTP NAT helper叫做ip_nat_ftp,IRC的相應模塊就是ip_nat_irc。conntrack helper 的命名也遵循 一樣的習慣:針對IRC的conntrack helper叫ip_conntrack_irc,FTP的叫作ip_conntrack_ftp。


Chapter 5. 規則的保存與恢復

iptables提供了兩個很有用的工具用來處理大規則集: iptables-saveiptables-restore,它們把規則存入一個與標準腳本代碼只有 細微查別的特殊格式的文件中,或從中恢復規則。


5.1. 速度

使用iptables-saveiptables-restore的一個最重要的 原因是,它們能在相當程度上提高裝載、保存規則的速度。使用腳本更改規則的問題是,改動每個規則都要 調運命令iptables,而每一次調用iptables,它首先要把Netfilter內核空間中的整個規則集都提取出來, 然後再插入或附加,或做其他的改動,最後,再把新的規則集從它的內存空間插入到內核空間中。這會花費 很多時間。

爲了解決這個問題,可以使用命令iptables-saverestore 。 iptables-save用來把規則集保存到一個特殊格式的文本文件裏,而iptables-restore是用來把這個文件重新裝入內核空間的。這兩個命令最好的地方在於 一次調用就可以裝載和保存規則集,而不象腳本中每個規則都要調用一次iptables。 iptables-save運行一次就可以把整個規則集從內核裏提取出來,並保存到文件裏,而iptables-restore每次裝入一個規則表。換句話說,對於一個很大的規則集,如果用腳 本來設置,那這些規則就會反反覆覆地被卸載、安裝很多次,而我們現在可以把整個規則集一次就保存下 來,安裝時則是一次一個表,這可是節省了大量的時間。

如果你的工作對象是一組巨大的規則,這兩個工具是明顯的選擇。當然,它們也有不足之處,下面的章 節會詳細說明。


5.2. restore的不足之處

iptables-restore能替代所有的腳本來設置規則嗎?不,到現在爲止不行,很可能永遠都不 行。iptables-restore的主要不足是不能用來做複雜的規則集。例如,我們想在計算機啓動時獲取連接的動 態分配的IP地址,然後用在腳本里。這一點,用iptables-restore來實現,或多或少是不可能的。

一個可能的解決辦法是寫一個小腳本來獲取那個IP地址,並在iptables-restore調用的配置文件中設置 相應的關鍵字,然後用獲取的IP值替換關鍵字。你可以把更改後的配置文件存到一個臨時文件中,再由 iptables-restore使用它。然而這會帶來很多問題,並且你不能用iptables-save來保存帶關鍵字的配置文 件。此法較笨。

另一個辦法是先裝入iptables-restore文件,再運行一個特定的腳本把動態的規則裝入。其實,這也是 較笨的方法。iptables-restore並不適合於使用動態IP的場合,如果你想在配置文件裏使用選項來實現不同 的要求,iptables-restore也不適用。

iptables-restore和iptables-save還有一個不足,就是功能不夠齊全。因爲使用的人不是太多,所以發 現這個問題的人也不多,還有就是一些match和target被引用時考慮不細緻,這可能會出現我們預期之外的 行爲。 儘管存在這些問題,我還是強烈建議你使用它們,因爲它們對於大部分規則集工作的還是很好的, 只要在規則中別包含那些新的都不知如何使用的match和target。


5.3. iptables-save

iptables-save用來把當前的規則存入一個文件裏以備iptables-restore使用。它的使用很簡單,只有兩 個參數:

iptables-save [-c] [-t table]

參數-c的作用是保存包和字節計數器的值。這可以使我們在重啓防火牆後不丟失 對包和字節的統計。帶-c參數的iptables-save命令使重啓 防火牆而不中斷統計記數程序成爲可能。這個參數默認是不使用的。

參數-t指定要保存的表,默認是保存所有的表。下面給出未裝載任何規則的情況 下iptables-save的輸出。

# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:17 2002
*filter
:INPUT ACCEPT [404:19766]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [530:43376]
COMMIT
# Completed on Wed Apr 24 10:19:17 2002
# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:17 2002
*mangle
:PREROUTING ACCEPT [451:22060]
:INPUT ACCEPT [451:22060]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [594:47151]
:POSTROUTING ACCEPT [594:47151]
COMMIT
# Completed on Wed Apr 24 10:19:17 2002
# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:17 2002
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [3:450]
:OUTPUT ACCEPT [3:450]
COMMIT
# Completed on Wed Apr 24 10:19:17 2002

我們來解釋一下這個輸出格式。#後面的是註釋。表都以*<table-name>開始,例如*mangle。每個表都包含鏈和規則,鏈的詳細說明是:<chain-name> <chain-policy> [<packet-counter>:<byte-counter>]。例如,鏈的名字是 PREROUTING,策略是ACCEPT,然後是包記數器和字節計數器,這兩個計數器和iptables -L -v輸出中用到的計數器一樣。每個表的描述都以關鍵字COMMIT結 束,它說明在這一點,就要把規則裝入內核了。

上面的例子是最基本的,我想用一個簡短的例子說明會更好,其中包含一個非常小的規則集Iptables-save ruleset。iptables-save的輸出如下:

# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
*filter
:INPUT DROP [1:229]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -i eth1 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT 
-A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT 
COMMIT
# Completed on Wed Apr 24 10:19:55 2002
# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
*mangle
:PREROUTING ACCEPT [658:32445]
:INPUT ACCEPT [658:32445]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [891:68234]
:POSTROUTING ACCEPT [891:68234]
COMMIT
# Completed on Wed Apr 24 10:19:55 2002
# Generated by iptables-save v1.2.6a on Wed Apr 24 10:19:55 2002
*nat
:PREROUTING ACCEPT [1:229]
:POSTROUTING ACCEPT [3:450]
:OUTPUT ACCEPT [3:450]
-A POSTROUTING -o eth0 -j SNAT --to-source 195.233.192.1 
COMMIT
# Completed on Wed Apr 24 10:19:55 2002

每個命令前都有包和字節計數器,這說明使用了-c參數。除了有計數器,其他的 都和普通的腳本一樣。現在的問題是怎麼把輸出保存到文件中。非常簡單,既然使用linux,你應該早就知 道了,用重定向啊:

iptables-save -c > /etc/iptables-save

這就會把規則集保存到/etc/iptables-save中,而且還有計數器。


5.4. iptables-restore

iptables-restore用來裝載由iptables-save保存的規則 集。不幸的是,它只能從標準輸入接受輸入,而不能從文件接受。下面是它的事方法:

iptables-restore [-c] [-n]

參數-c要求裝入包和字節計數器。如果你用iptables-save保存了計數器,現在 想重新裝入,就必須用這個參數。它的另一種較長的形式是--counters

參數-n告訴iptables-restore不要覆蓋已有的表或表內的規則。默認情況是清除 所有已存的規則。這個參數的長形式是--noflush

iptables-restore裝載規則有好幾種方法,我們來看看最簡單、最一般的:

這樣規則集應該正確地裝入內核並正常工作了。如果有問題,你就要除措了。


Chapter 6. 規則是如何練成的

本章將詳細地討論如何構件你自己的規則。規則就是指向標,在一條鏈上,對不同的連接和數據包阻塞 或允許它們去向何處。插入鏈的每一行都是一條規則。我們也會討論基本的matche及其用法,還有各種各樣 的target,以及如何建立我們自己的target(比如,一個新的子鏈)。


6.1. 基礎

我們已經解釋了什麼是規則,在內核看來,規則就是決定如何處理一個包的語句。如果一個包符合所有 的條件(就是符合matche語句),我們就運行target或jump指令。書寫規則的語法格式是:

iptables [-t table] command [match] [target/jump]

對於這個句法沒什麼可說的,但注意target指令必須在最後。爲了易讀,我們一般用這種語法。總之, 你將見到的大部分規則都是按這種語法寫的。因此,如果你看到別人寫的規則,你很可能會發現用的也是這 種語法,當然就很容易理解那些規則了。

如果你不想用標準的表,就要在[table]處指定表名。一般情況下沒有必要指定使用的表,因爲iptables 默認使用filter表來執行所有的命令。也沒有必要非得在這裏指定表名,實際上幾乎可在規則的任何地方。 當然,把表名在開始處已經是約定俗成的標準。

儘管命令總是放在開頭,或者是直接放在表名後面,我們也要考慮考慮到底放在哪兒易讀。command告訴 程序該做什麼,比如:插入一個規則,還是在鏈的末尾增加一個規則,還是刪除一個規則,下面會仔細地介 紹。

match細緻地描述了包的某個特點,以使這個包區別於其它所有的包。在這裏,我們可以指定包的來源IP 地址,網絡接口,端口,協議類型,或者其他什麼。下面我們將會看到許多不同的match。

最後是數據包的目標所在。若數據包符合所有的match,內核就用target來處理它,或者說把包發往 target。比如,我們可以讓內核把包發送到當前表中的其他鏈(可能是我們自己建立的),或者只是丟棄這 個包而沒有什麼處理,或者向發送者返回某個特殊的應答。下面有詳細的討論。


6.2. Tables

選項-t用來指定使用哪個表,它可以是下面介紹的表中的任何一個,默認的是 filter表。注意,下面的介紹只是章節表和鏈的摘要。

Table 6-1. Tables

Table (表名) Explanation (註釋)
nat nat表的主要用處是網絡地址轉換,即Network Address Translation,縮寫爲NAT。做過NAT操作的數據包的地址就被改變了,當然這種改變是根據我們的規則進行 的。屬於一個流的包只會經過這個表一次。如果第一個包被允許做NAT或Masqueraded,那麼餘下的包都會自 動地被做相同的操作。也就是說,餘下的包不會再通過這個表,一個一個的被NAT,而是自動地完成。這就 是我們爲什麼不應該在這個表中做任何過濾的主要原因,對這一點,後面會有更加詳細的討論。PREROUTING 鏈的作用是在包剛剛到達防火牆時改變它的目的地址,如果需要的話。OUTPUT鏈改變本地產生的包的目的地 址。POSTROUTING鏈在包就要離開防火牆之前改變其源地址。
mangle 這個表主要用來mangle數據包。我們可以改變不同的包及包 頭的內容,比如 TTLTOSMARK。 注意MARK並沒有真正地改動數據包,它只是在內核空間爲包設了一個標記。防火牆 內的其他的規則或程序(如tc)可以使用這種標記對包進行過濾或高級路由。這個表有五個內建的鏈: PREROUTINGPOSTROUTINGOUTPUTINPUT FORWARDPREROUTING在包進入防火牆之後、路由判斷之前改變 包,POSTROUTING是在所有路由判斷之後。 OUTPUT在確定包的目的之前更改數據包。INPUT在包被路由到本地 之後,但在用戶空間的程序看到它之前改變包。FORWARD在最初的路由判 斷之後、最後一次更改包的目的之前mangle包。注意,mangle表不能做任何NAT,它只是改變數據包的 TTLTOSMARK,而不是其源目地 址。NAT是在nat表中操作的。
filter filter表是專門過濾包 的,內建三個鏈,可以毫無問題地對包進行DROPLOGACCEPTREJECT等操作。FORWARD 鏈過濾所有不是本地產生的並且目的地不是本地(所謂本地就是防火牆了)的包,而 INPUT恰恰針對那些目的地是本地的包。OUTPUT 是用來過濾所有本地生成的包的。

上面介紹了三個不同的表的最基本的內容。你應該知道它們的使用目的完全不同,還要清楚每一條鏈的 使用。如果你不瞭解,就可能會在防火牆上留下漏洞,給人以可乘之機。在章節表和鏈 中,我們已詳細地討論了這些必備的的表和鏈。如果你 沒有完全理解包是怎樣通過這些表、鏈的話,我建議你回過頭去再仔細看看。


6.3. Commands

在這一節裏,我們將要介紹所有的command以及它們的用途。command指定iptables 對我們提交的規則要做什麼樣的操作。這些操作可能是在某個表裏增加或刪除一些東西,或做點兒其他 什麼。以下是iptables可用的command(要注意,如不做說明,默認表的是 filter表。):

Table 6-2. Commands

Command -A--append
Example iptables -A INPUT ...
Explanation 在所選擇的鏈末添加規則。當源地址或目的地址是以名字而 不是ip地址的形式出現時,若這些名字可以被解析爲多個地址,則這條規則會和所有可用的地址結合。
Command -D--delete
Example iptables -D INPUT --dport 80 -j DROPiptables -D INPUT 1
Explanation 從所選鏈中刪除規則。有兩種方法指定要刪除的規則:一是 把規則完完整整地寫出來,再就是指定規則在所選鏈中的序號(每條鏈的規則都各自從1被編號)。
Command -R--replace
Example iptables -R INPUT 1 -s 192.168.0.1 -j DROP
Explanation 在所選中的鏈裏指定的行上(每條鏈的規則都各自從1被編 號)替換規則。它主要的用處是試驗不同的規則。當源地址或目的地址是以名字而不是ip地址的形式出現 時,若這些名字可以被解析爲多個地址,則這條command會失敗。
Command -I--insert
Example iptables -I INPUT 1 --dport 80 -j ACCEPT
Explanation 根據給出的規則序號向所選鏈中插入規則。如果序號爲1, 規則會被插入鏈的頭部,其實默認序號就是1。
Command -L--list
Example iptables -L INPUT
Explanation 顯示所選鏈的所有規則。如果沒有指定鏈,則顯示指定表中 的所有鏈。如果什麼都沒有指定,就顯示默認表所有的鏈。精確輸出受其它參數影響,如-n -v等參數,下面會介紹。
Command -F--flush
Example iptables -F INPUT
Explanation 清空所選的鏈。如果沒有指定鏈,則清空指定表中的所有 鏈。如果什麼都沒有指定,就清空默認表所有的鏈。當然,也可以一條一條地刪,但用這個command會快些。
Command -Z--zero
Example iptables -Z INPUT
Explanation 把指定鏈(如未指定,則認爲是所有鏈)的所有計數器歸 零。
Command -N--new-chain
Example iptables -N allowed
Explanation 根據用戶指定的名字建立新的鏈。上面的例子建立了一個名 爲allowed的鏈。注意,所用的名字不能和已有的鏈、target同名。
Command -X--delete-chain
Example iptables -X allowed
Explanation 刪除指定的用戶自定義鏈。這個鏈必須沒有被引用,如果被 引用,在刪除之前你必須刪除或者替換與之有關的規則。如果沒有給出參數,這條命令將會刪除默認表所有 非內建的鏈。
Command -P--policy
Example iptables -P INPUT DROP
Explanation 爲鏈設置默認的target(可用的是DROP ACCEPT,如果還有其它的可用,請告訴我),這個target稱作策略。所有不 符合規則的包都被強制使用這個策略。只有內建的鏈纔可以使用規則。但內建的鏈和用戶自定義鏈都不能被 作爲策略使用,也就是說不能象這樣使用:iptables -P INPUT allowed(或者是內建的鏈)。
Command -E--rename-chain
Example iptables -E allowed disallowed
Explanation 對自定義的鏈進行重命名,原來的名字在前,新名字在後。 如上,就是把allowed改爲disallowed。這僅僅是改變 鏈的名字,對整個表的結構、工作沒有任何影響。

在使用iptables時,如果必須的參數沒有輸入就按了回車,那麼它就會給出一些 提示信息:告訴你需要哪些參數等等。iptables的選項-v用來顯示iptables的版 本,-h給出語法的簡短說明。。下面將要介紹的就是部分選項,還有它們的作用。

Table 6-3. Options

Option(選項) -v--verbose(詳細的)
可用此選項的命令 --list--append--insert--delete--replace
Explanation(說明) 這個選項使輸出詳細化,常與--list 連用。與--list連用時,輸出中包括網絡接口的地址、規則的選項、TOS掩碼、 字節和包計數器,其中計數器是以K、M、G(這裏用的是10的冪而不是2的冪哦)爲單位的。如果想知道到底 有多少個包、多少字節,還要用到選項-x,下面會介紹。如果-v --append--insert--delete --replace連用,iptables會輸出詳細的信息告訴你規則是如何被解釋的、是 否正確地插入等等。
Option -x--exact(精確的)
Commands used with --list
Explanation 使--list輸出中的計數器顯示準確 的數值,而不用K、M、G等估值。注意此選項只能和--list連用。
Option -n--numeric(數值)
Commands used with --list
Explanation 使輸出中的IP地址和端口以數值的形式顯示,而不是默認的 名字,比如主機名、網絡名、程序名等。注意此選項也只能和--list連用。
Option --line-numbers
Commands used with --list
Explanation 又是一個只能和--list連用的選 項,作用是顯示出每條規則在相應鏈中的序號。這樣你可以知道序號了,這對插入新規則很有用哦。
Option -c--set-counters
Commands used with --insert--append--replace
Explanation 在創建或更改規則時設置計數器,語法如下:--set-counters 20 4000,意思是讓內核把包計數器設爲20,把字節計數器設爲4000。
Option --modprobe
Commands used with All
Explanation 此選項告訴iptables探測並裝載要使用的模塊。這是非常有 用的一個選項,萬一modprobe命令不在搜索路徑中,就要用到了。有了這個選項, 在裝載模塊時,即使有一個需要用到的模塊沒裝載上,iptables也知道要去搜索。

6.4. Matches

這一節,我們會詳細討論一些matche,我把它們歸爲五類。第一類是generic matches(通用的匹配),適用於所有的規則;第二類是TCP matches,顧名思 義,這隻能用於TCP包;第三類是UDP matches, 當然它只能用在UDP包上了;第四類是ICMP matches ,針對ICMP包的;第五類比較特殊,針對的是狀態(state),所有 者(owner)和訪問的頻率限制(limit)等,它們已經被分到更多的小類當中,儘管它們並不是完全不同 的。我希望這是一種大家都容易理解的分類。


6.4.1. 通用匹配

無論我們使用的是何種協議,也不管我們又裝入了匹配的何種擴展,通用匹配都使可用的。也就是說, 它們可以直接使用,而不需要什麼前提條件,在後面你會看到,有很多匹配操作是需要其他的匹配作爲前提 的。

Table 6-4. Generic matches

Match -p--protocol
Example iptables -A INPUT -p tcp
Explanation 匹配指定的協議。指定協議的形式有以下幾種:

1、名字,不分大小寫,但必須是在/etc/protocols中定 義的。

2、可以使用它們相應的整數值。例如,ICMP的值是1,TCP是6,UDP是17。

3、缺省設置,ALL,相應數值是0,但要注意這隻代表匹配TCP、UDP、ICMP,而不是/etc/protocols中定義的所有協議。

4、可以是協議列表,以英文逗號爲分隔符,如:udp,tcp

5、可以在協議前加英文的感嘆號表示取反,注意有空格,如: --protocol ! tcp 表示非tcp協議,也就是UDP和ICMP。可以看出這個取反的範圍只是TCP、UDP和ICMP。

Match -s--src--source
Example iptables -A INPUT -s 192.168.1.1
Explanation 以IP源地址匹配包。地址的形式如下:

1、單個地址,如192.168.1.1,也可寫成 192.168.1.1/255.255.255.255192.168.1.1/32

2、網絡,如192.168.0.0/24,或 192.168.0.0/255.255.255.0

3、在地址前加英文感嘆號表示取反,注意空格,如--source ! 192.168.0.0/24 表示除此地址外的所有地址

4、缺省是所有地址

Match -d--dst--destination
Example iptables -A INPUT -d 192.168.1.1
Explanation 以IP目的地址匹配包。地址的形式和 -- source完全一樣。
Match -i--in-interface
Example iptables -A INPUT -i eth0
Explanation 以包進入本地所使用的網絡接口來匹配包。要注意這個匹配 操作只能用於INPUTFORWARD PREROUTING這三個鏈,用在其他任何地方都會提示錯誤信息。指定接口有一下方 法:

1、指定接口名稱,如:eth0、ppp0等

2、使用通配符,即英文加號,它代表字符數字串。若直接用一個加號,即iptables -A INPUT -i +表示匹配所有的包,而不考慮使用哪個接口。這也是不指定接口的默認行爲。通配符還 可以放在某一類接口的後面,如:eth+表示所有Ethernet接口,也就是說,匹配所有從Ethernet接口進入的 包。

3、在接口前加英文感嘆號表示取反,注意空格,如:-i ! eth0意思是匹配來自 除eth0外的所有包。

Match -o--out-interface
Example iptables -A FORWARD -o eth0
Explanation 以包離開本地所使用的網絡接口來匹配包。使用的範圍和指 定接口的方法與--in-interface完全一樣。
Match -f--fragment
Example iptables -A INPUT -f
Explanation 用來匹配一個被分片的包的第二片或及以後的部分。因爲它 們不包含源或目的地址,或ICMP類型等信息,其他規則無法匹配到它,所以纔有這個匹配操作。要注意碎片 攻擊哦。這個操作也可以加英文感嘆號表示取反,但要注意位置,如:! -f 。取反 時,表示只能匹配到沒有分片的包或者是被分片的包的第一個碎片,其後的片都不行。現在內核有完善的碎 片重組功能,可以防止碎片攻擊,所以不必使用取反的功能來防止碎片通過。如果你使用連接跟蹤,是不會 看到任何碎片的,因爲在它們到達任何鏈之前就被處理過了。

6.4.2. 隱含匹配

這種匹配操作是自動地或隱含地裝載入內核的。例如我們使用--protocol tcp 時,不需再裝入任何東西就可以匹配只有IP包纔有的一些特點。現在有三種隱含的匹配針對三種不同的協 議,即TCP matchesUDP matches ICMP matches。它們分別包括一套只適用於相應協議的判別標準。相對於隱含匹配的是顯式匹配,它們 必須使用-m--match被明確地裝載,而不能是自動地或隱 含地,下一節會介紹到。


6.4.2.1. TCP matches

TCP matches只能匹配TCP包或流的細節,它們必須有--protocol tcp作爲前提條 件。

Table 6-5. TCP matches

Match --sport--source-port
Example iptables -A INPUT -p tcp --sport 22
Explanation 基於TCP包的源端口來匹配包,端口的指定形式如下:

1、不指定此項,則暗示所有端口。

2、使用服務名或端口號,但名字必須是在/etc/services 中定義的,因爲iptables從這個文件裏查找相應的端口號。從這可以看出,使用端口號會使規則裝入快一點 兒,當然,可讀性就差些了。但是如果你想寫一個包含200條或更多規則的規則集,那你還是老老實實地用 端口號吧,時間是主要因素(在一臺稍微慢點兒地機子上,這最多會有10秒地不同,但要是1000條、10000 條呢)。

3、可以使用連續的端口,如:--source-port 22:80這表示從22到80的所有端 口,包括22和80。如果兩個號的順序反了也沒關係,如:--source-port 80:22這和 --source-port 22:80的效果一樣。

4、可以省略第一個號,默認第一個是0,如:--source-port :80表示從0到80的 所有端口。

5、也可以省略第二個號,默認是65535,如:--source-port 22:表示從22到 65535的所有端口

6、在端口號前加英文感嘆號表示取反,注意空格,如:--source-port ! 22表 示除22號之外的所有端口;--source-port ! 22:80表示從22到80(包括22和80)之 外的所有端口。

注意:這個匹配操作不能識別不連續的端口列表,如:--source-port ! 22, 36, 80 這樣的操作是由後面將要介紹的多端口匹配擴展來完成的。

Match --dport--destination-port
Example iptables -A INPUT -p tcp --dport 22
Explanation 基於TCP包的目的端口來匹配包,端口的指定形式和--sport完全一樣。
Match --tcp-flags
Example  
Explanation 匹配指定的TCP標記。有兩個參數,它們都是列表,列表內 部用英文的逗號作分隔符,這兩個列表之間用空格分開。第一個參數指定我們要檢查的標記(作用就象掩 碼),第二個參數指定“在第一個列表中出現過的且必須被設爲1(即狀態是打開的)的”標記(第一個列 表中其他的標記必須置0)。也就是說,第一個參數提供檢查範圍,第二個參數提供被設置的條件(就是哪 些位置1)。這個匹配操作可以識別以下標記:SYN ACKFINRST URGPSH。另外還有兩個詞 也可使用,就是ALL和NONE。顧名思義,ALL是指選定所有的標記,NONE是指未選定任何標記。這個匹配也可 在參數前加英文的感嘆號表示取反。例如:

1、iptables -p tcp --tcp-flags SYN,FIN,ACK SYN表示匹配那些SYN標記被設 置而FIN和ACK標記沒有設置的包,注意各標記之間只有一個逗號而沒有空格。

2、--tcp-flags ALL NONE匹配所有標記都未置1的包。

3、iptables -p tcp --tcp-flags ! SYN,FIN,ACK SYN表示匹配那些FIN和ACK標 記被設置而SYN標記沒有設置的包,注意和例1比較一下。

Match --syn
Example iptables -p tcp --syn
Explanation 這個匹配或多或少算是ipchains時代的遺留物,之所以還保 留它,是爲了向後兼容,也是爲了方便規則在iptables和ipchains間的轉換。它匹配那些SYN標記被設置而 ACK和RST標記沒有設置的包,這和iptables -p tcp --tcp-flags SYN,RST,ACK SYN 的作用毫無二樣。這樣的包主要用在TCP連接初始化時發出請求。如果你阻止了這樣的包,也就阻止了所有 由外向內的連接企圖,這在一定程度上防止了一些攻擊。但外出的連接不受影響,恰恰現在有很多攻擊就利 用這一點。比如有些攻擊黑掉服務器之後安裝會一些軟件,它們能夠利用已存的連接到達你的機子,而不要 再新開一個端口。這個匹配也可用英文感嘆號取反,如:! --syn用來匹配那些 RSTACK被置位的包,換句話說,就是 狀態爲已建立的連接的包。
Match --tcp-option
Example iptables -p tcp --tcp-option 16
Explanation 根據匹配包。TCP選項是TCP頭中的特殊部分,有三個不同的 部分。第一個8位組表示選項的類型,第二個8位組表示選項的長度(這個長度是整個選項的長度,但不包含 填充部分所佔的字節,而且要注意不是每個TCP選項都有這一部分的),第三部分當然就是選項的內容了。 爲了適應標準,我們不必執行所有的選項,但我們可以查看選項的類型,如果不是我們所支持的,那就只是 看看長度然後跳過數據部分。這個操作是根據選項的十進制值來匹配的,它也可以用英文感嘆號取反。所有 的選項都可在Internet Engineering Task Force裏找到。

6.4.2.2. UDP matches

UDP matches是在指定--protocol UDP時自動裝入的。UDP是一種無連接協議,所 以在它打開、關閉連接以及在發送數據時沒有多少標記要設置,它也不需要任何類型的確認。數據丟失了, 就丟失了(不會發送ICMP錯誤信息的)。這就說明UDP matches要比TCP matches少多了。即使UDP和ICMP是 無連接協議,狀態機制也可以很好的工作,就象在TCP上一樣,這在前面討論過。

Table 6-6. UDP matches

Match --sport--source-port
Example iptables -A INPUT -p udp --sport 53
Explanation 基於UDP包的源端口來匹配包,端口的指定形式和TCP matches中的--sport完全一樣。
Match --dport--destination-port
Example iptables -A INPUT -p udp --dport 53
Explanation 基於UDP包的目的端口來匹配包,端口的指定形式和TCP matches中的--sport完全一樣。

6.4.2.3. ICMP matches

ICMP協議也是無連接協議,ICMP包更是短命鬼,比UDP的還短。ICMP協議不是IP協議的下屬協議,而是它 的輔助者,其主要作用是報告錯誤和連接控制。ICMP包的頭和IP的很相似,但又有很多不同。這個協議最主 要的特點是它有很多類型,以應對不同的情況。比如,我們想訪問一個無法訪問的地址,就會收到一個ICMP host unreachable信息,它的意思是主機無法到達。在附錄ICMP類型裏有完整的ICMP類型列表。雖然有這麼多類型,但只有一個 ICMP matche,這就足夠對付它們了。這個matche是在指定--protocol ICMP時自動 裝入的。注意所有的通用匹配都可以使用,這樣我們就可以匹配ICMP包的源、目地址。

Table 6-7. ICMP matches

Match --icmp-type
Example iptables -A INPUT -p icmp --icmp-type 8
Explanation 根據ICMP類型匹配包,類型的指定可以使用十進制數值或相 應的名字,數值在RFC792中有定義,名字可以用iptables --protocol icmp --help 查看,或者在附錄ICMP類型中查找。這個匹配也可用英文感嘆號取 反,如:--icmp-type ! 8就表示匹配除類型8之外的所有ICMP包。要注意有些ICMP 類型已經廢棄不用了,還有一些可能會對無防護的主機帶來“危險”,因爲它們可能把包重定向到錯誤的地 方。

6.4.3. 顯式匹配

顯式匹配必須用-m--match裝載,比如要使用狀態匹配 就必須使用-m state。有些匹配還需要指定協議,有些就不需要,比如連接狀態就 不要。這些狀態是NEW(還未建立好的連接的第一個包),ESTABLISHED(已建立的連接,也就是已經在內核裏註冊過的),RELATED(由 已經存在的、處於已建立狀態的連接生成的新連接),等等。有些匹配還處在開發階段,或者還只是爲了說 明iptables的強大能力。這說明不是所有的匹配一開始就是實用的,但以後你可能會用到它。隨着iptables 新版本的發佈,會有一些新的匹配可用。隱含匹配和顯式匹配最大的區別就是一個是跟隨協議匹配自動裝載 的,一個是顯式裝載的。


6.4.3.1. Limit match

這個匹配操作必須由-m limit明確指定才能使用。有了它的幫助,就可以對指定 的規則的日誌數量加以限制,以免你被信息的洪流淹沒哦。比如,你可以事先設定一個限定值,當符合條件 的包的數量不超過它時,就記錄;超過了,就不記錄了。我們可以控制某條規則在一段時間內的匹配次數 (也就是可以匹配的包的數量),這樣就能夠減少DoS syn flood攻擊的影響。這 是它的主要作用,當然,還有很多其他作用(譯者注:比如,對於某些不常用的服務可以限制連接數量,以 免影響其他服務)。limit match也可以用英文感嘆號取反,如:-m limit ! --limit 5/s表示在數量超過限定值後,所有的包都會被匹配。

(譯者注:爲了更好地理解這個匹配操作,我們通過一個比喻來解釋一下。原文也做了類似地比喻,但 我覺得對於初學者不易理解,故未採用。)limit match的工作方式就像一個單位大門口的保安,當有人要 進入時,需要找他辦理通行證。早上上班時,保安手裏有一定數量的通行證,來一個人,就簽發一個,當通 行證用完後,再來人就進不去了,但他們不會等,而是到別的地方去(在iptables裏,這相當於一個包不符 合某條規則,就會由後面的規則來處理,如果都不符合,就由缺省的策略處理)。但有個規定,每隔一段時 間保安就要簽發一個新的通行證。這樣,後面來的人如果恰巧趕上,也就可以進去了。如果沒有人來,那通 行證就保留下來,以備來的人用。如果一直沒人來,可用的通行證的數量就增加了,但不是無限增大的,最 多也就是剛開始時保安手裏有的那個數量。也就是說,剛開始時,通行證的數量是有限的,但每隔一段時間 就有新的通行證可用。limit match有兩個參數就對應這種情況,--limit-burst指 定剛開始時有多少通行證可用,--limit指定要隔多長時間才能簽發一個新的通行 證。要注意的是,我這裏強調的是“簽發一個新的通行證”,這是以iptables的角度考慮的。在你自己寫規 則時,就要從這個角度考慮。比如,你指定了--limit 3/minute --limit-burst 5 ,意思是開始時有5個通行證,用完之後每20秒增加一個(這就是從iptables的角度看的,要是以用戶 的角度看,說法就是每一分鐘增加三個或者每分鐘只能過三個)。你要是想每20分鐘過一個,只能寫成--limit 3/hour --limit-burst 5,也就是說你要把時間單位湊成整的。

Table 6-8. Limit match options

Match --limit
Example iptables -A INPUT -m limit --limit 3/hour
Explanation limit match設置最大平均匹配速 率,也就是單位時間內limit match可以匹配幾個包。它的形式是一個數值加一個時 間單位,可以是/second /minute /hour /day 。默認值是每小時3次(用戶角度),即3/hour ,也就是每20分鐘一次(iptables角度)。
Match --limit-burst
Example iptables -A INPUT -m limit --limit-burst 5
Explanation 這裏定義的是limit match的峯值, 就是在單位時間(這個時間由上面的--limit指定)內最多可匹配幾個包(由此可 見,--limit-burst的值要比--limit的大)。默認值是5。 爲了觀察它是如何工作的,你可以啓動“只有一條規則的腳本”Limit- match.txt,然後用不同的時間間隔、發送不同數量的ping數據包。這樣,通過返回的 echo replies就可以看出其工作方式了。

6.4.3.2. MAC match

基於包的MAC源地址匹配包。到寫這篇文章時,這個match還有一點限制(就是隻能匹配MAC源地址匹), 但今後定會有所發展,會更有用的。

Note

注意,這個match是由-m mac裝入的,而不是一些人想當然的-m mac-source,後者只是前者的選項而已。

Table 6-9. MAC match options

Match --mac-source
Example iptables -A INPUT -m mac --mac-source 00:00:00:00:00:01
Explanation 基於包的MAC源地址匹配包,地址格式只能是XX:XX:XX:XX:XX:XX,當然它也可以用英文感嘆號取反,如--mac- source ! 00:00:00:00:00:01,意思很簡單了,就是除此之外的地址都可接受嘛。注意,因爲 MAC addresses只用於Ethernet類型的網絡,所以這個match只能用於Ethernet接 口。而且,它還只能在PREROUTINGFORWARD INPUT鏈裏使用。

6.4.3.3. Mark match

以包被設置的mark來匹配包,這個值只能由內核更改。前面曾經提到過,mark比較特殊,它不是包本身 的一部分,而是在包穿越計算機的過程中由內核分配的和它相關聯的一個字段。它可能被用來改變包的傳輸 路徑或過濾。時至今日,在linux裏只有一種方法能設置mark,即iptables的MARK target,以前在ipchains裏是FWMARK target。這就是爲什 麼在高級路由裏我們仍要參照FWMARK的原因。mark字段的值是一個無符號的整數, 在32位系統上最大可以是4294967296(就是2的32次方),這足夠用的了:)

Table 6-10. Mark match options

Match --mark
Example iptables -t mangle -A INPUT -m mark --mark 1
Explanation 以包被設置的mark值來匹配包,這個值是是由下面將要介紹 的 MARK target來設置的,它是一個無符號的整數。所有通過 Netfilter的包都會被分配一個相關聯的mark field 。但要注意mark值可不是在任何情況下都能使用的,它只能在分配給它值的那臺機子裏使用,因爲 它只是由內核在內存裏分配的和包相關的幾個字節,並不屬於包本身,所以我們不能在本機之外的路由器上 使用。mark的格式是--mark value[/mask],如上面的例子是沒有掩碼的,帶掩碼的 例子如--mark 1/1。如果指定了掩碼,就先把mark值和掩碼取邏輯與,然後再和包 的mark值比較。

6.4.3.4. Multiport match

多端口匹配擴展使我們能夠在一條規則裏指定不連續的多個端口,如果沒有這個擴展,我們只能按端口 來寫規則了。其實這只是標準端口匹配的增強版罷了,使我們書寫規則更方便而已。

Note

注意:不能在一條規則裏同時使用標準端口匹配和多端口匹配,如--sport 1024:63353 -m multiport --dport 21,23,80。這條規則並不能想你想象的那樣工作,但也不是 不能工作,iptables會使用第一個合法的條件,那麼這裏多端口匹配就白寫了:)

Table 6-11. Multiport match options

Match --source-port
Example iptables -A INPUT -p tcp -m multiport --source-port 22,53,80,110
Explanation 源端口多端口匹配,最多可以指定15個端口,以英文逗號分 隔,注意沒有空格。使用時必須有-p tcp-p udp爲前提條 件。
Match --destination-port
Example iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80,110
Explanation 目的端口多端口匹配,使用方法和源端口多端口匹配一樣, 唯一的區別是它匹配的是目的端口。
Match --port
Example iptables -A INPUT -p tcp -m multiport --port 22,53,80,110
Explanation 同端口多端口匹配,意思就是它匹配的是那種源端口和目的 端口是同一個端口的包,比如:端口80到端口80的包,110到110的包等。使用方法和源端口多端口匹配一 樣。

6.4.3.5. Owner match

基於包的生成者(也就是所有者,或稱作擁有者,owner)的ID來匹配包,owner可以是啓動進程的用戶 的ID,或用戶所在的組的ID,或進程的ID,或會話的ID。這個擴展原本只是爲了說明iptables可以做什麼, 現在發展到實用階段了。但要注意,此擴展只能用在OUTPUT中,原因顯而 易見:我們幾乎不可能得到發送端例程的ID的任何信息,或者在去往真正目的地的路上哪兒有路由。甚至在 OUTPUT鏈裏,這也不是十分可靠,因爲有些包根本沒有owner,比如 ICMP responses,所以它們從不會被這個match抓到:)

Table 6-12. Owner match options

Match --uid-owner
Example iptables -A OUTPUT -m owner --uid-owner 500
Explanation 按生成包的用戶的ID(UID)來匹配外出的包。使用這個匹 配可以做這樣一些事,比如,阻止除root外的用戶向防火牆外建立新連接,或阻止除用戶http外的任何人使 用HTTP端口發送數據。
Match --gid-owner
Example iptables -A OUTPUT -m owner --gid-owner 0
Explanation 按生成包的用戶所在組的ID(GID)來匹配外出的包。比 如,我們可以只讓屬於network組的用戶上Internet,而其他用戶都不 行;或者只允許http組的成員能從HTTP端口發送數據。
Match --pid-owner
Example iptables -A OUTPUT -m owner --pid-owner 78
Explanation 按生成包的進程的ID(GID)來匹配外出的包。比如,我們 可以只允許PID爲94的進程(http進程當然不能是多線程的)使用http端口。這個匹配使用起來有一點難 度,因爲你要知道進程的ID號。當然,你也可以寫一個小小的腳本,先從ps的輸出 中得到PID,再添加相應的規則,這兒有個例子Pid-owner.txt
Match --sid-owner
Example iptables -A OUTPUT -m owner --sid-owner 100
Explanation 按生成包的會話的ID(SID)來匹配外出的包。一個進程以 及它的子進程或它的多個線程都有同一個SID。比如,所有的HTTPD進程的SID和它的父進程一樣(最初的 HTTPD進程),即使HTTPD是多線程的(現在大部分都是,比如Apache和Roxen)也一樣。這裏有個腳本Sid-owner.txt可以反映出這一點。

6.4.3.6. State match

狀態匹配擴展要有內核裏的連接跟蹤代碼的協助,因爲它是從連接跟蹤機制中得到包的狀態的。這樣我 們就可以瞭解連接所處的狀態。它幾乎適用於所有的協議,包括那些無狀態的協議,如ICMP和UDP。針對每 個連接都有一個缺省的超時值,如果連接的時間超過了這個值,那麼這個連接的記錄就被會從連接跟蹤的記 錄數據庫中刪除,也就是說連接就不再存在了。這個match必須有-m state作爲前提 才能使用。狀態機制的詳細內容在章節狀態機制 中。

Table 6-13. State matches

Match --state
Example iptables -A INPUT -m state --state RELATED,ESTABLISHED
Explanation 指定要匹配包的的狀態,當前有4種狀態可用:INVALIDESTABLISHEDNEWRELATED。 INVALID意味着這個包沒有已知的流或連接與之關 聯,也可能是它包含的數據或包頭有問題。ESTABLISHED意思是包是完全有效的,而 且屬於一個已建立的連接,這個連接的兩端都已經有數據發送。NEW表示包將要或已 經開始建立一個新的連接,或者是這個包和一個還沒有在兩端都有數據發送的連接有關。RELATED說明包正在建立一個新的連接,這個連接是和一個已建立的連接相關的。比 如,FTP data transferICMP error 和一個TCP或UDP連接相關。注意NEW狀態並不在試圖建立新連接的TCP包裏尋找SYN標 記,因此它不應該不加修改地用在只有一個防火牆或在不同的防火牆之間沒有啓用負載平衡的地方。具體如 何使用,你就再看看章節狀態機制吧:)

6.4.3.7. TOS match

根據TOS字段匹配包,必須使用-m tos才能裝 入。TOS是IP頭的一部分,其含義是Type Of Service,由8個二進制位組成,包括一個3 bit的優先權子字段(現在已被忽略),4 bit的TOS子字 段和1 bit未用位(必須置0)。它一般用來把當前流的優先權和需要的服務(比如,最小延時、最大吞吐量 等)通知路由器。但路由器和管理員對這個值的處理相差很大,有的根本就不理會,而有的就會盡量滿足要 求。

Table 6-14. TOS matches

Match --tos
Example iptables -A INPUT -p tcp -m tos --tos 0x16
Explanation 根據TOS字段匹配包。這 個match常被用來mark包,以便後用,除此之外,它還常和iproute2或高級路由功能 一起使用。它的參數可以是16進制數,也可以是十進制數,還可以是相應的名字(用 iptables -m tos -h能查到)。到寫這篇文章時,有以下參數可用:

Minimize-Delay 16 (0x10),要求找一條路徑使延時最小,一些標準服務如telnet、SSH、FTP-control 就需要這個選項。

Maximize-Throughput 8 (0x08),要求找一條路徑能使吞吐量最大,標準服務FTP-data能用到這個。

Maximize-Reliability 4 (0x04),要求找一條路徑能使可靠性最高,使用它的有BOOTP和TFTP。

Minimize-Cost 2 (0x02),要求找一條路徑能使費用最低,一般情況下使用這個選項的是一些視頻音頻 流協議,如RTSP(Real Time Stream Control Protocol)。

Normal-Service 0 (0x00),一般服務,沒有什麼特殊要求。


6.4.3.8. TTL match

根據IP頭裏的TTL (Time To Live,即生存期)字段來匹配包,此必須 由-m ttl裝入。TTL field是一個字節(8個二進 制位),一旦經過一個處理它的路由器,它的值就減去1它的值。當該字段的值減爲0時,報文就被認爲是不 可轉發的,數據報就被丟棄,併發送ICMP報文通知源主機,不可轉發的報文被丟棄。這也有兩種情況,一是 傳輸期間生存時間爲0,使用類型爲11代碼是0的ICMP報文;二是在數據報重組期間生存時間爲0,使用類型 爲11代碼是1的ICMP報文。這個match只是根據TTL匹配包,而對其不做任 何更改,所以在它之後可使用任何類型的match。

Table 6-15. TTL matches

Match --ttl
Example iptables -A OUTPUT -m ttl --ttl 60
Explanation 根據TTL的值來匹配包,參數的形式只有一種,就是十進制 數值。它可以被用來調試你的局域網,比如解決LAN內的主機到Internet上的主機的連接問題,或找出 Trojan(Trojan)可能的入口。這個match的用處相對有限,但它其實是很有用的,這就看你的想象力如何 了。比如可以用它來發現那些TTL具有錯誤缺省值的機子(這可能是實現TCP/IP棧功能的那個程序本身的錯 誤,或者是配置有問題)。

6.4.4. 針對非正常包的匹配

這個匹配沒有任何參數,也不需要顯式地裝載。注意這應該被看作是一個實驗性的匹配,它不總是能正 常工作的,對有些不正常的包(unclean package,就是所謂的髒包)或問題,它是視而不見的。這個match 試圖匹配那些好象畸形或不正常的包,比如包頭錯或校驗和錯,等等。它可能常用來DROP錯誤的連接、檢查 有錯的流,但要知道這樣做也可能會中斷合法的連接。


6.5. Targets/Jumps

target/jump決定符合條件的包到何處去,語法是--jump target-j target。(譯者注:本文中,原作者把target細分爲兩類,即Target和Jump。它們 唯一的區別是jump的目標是一個在同一個表內的鏈,而target的目標是具體的操作。)我們會先接觸到兩個 基本的target,就是ACCEPT和DROP。

前面提到過用戶自定義鏈要用到-N命令。下面我們在filter表中建一個名爲tcp_packets的鏈:

iptables -N tcp_packets

然後再把它作爲jump的目標:

iptables -A INPUT -p tcp -j tcp_packets

這樣我們就會從INPUT鏈跳入tcp_packets鏈,開始在tcp_packets中的旅行。如果到達了tcp_packets鏈的結尾(也 就是未被鏈中的任何規則匹配),則會退到INPUT鏈的下一條規則繼續它的旅行。如 果在子鏈中被ACCEPT了,也就相當於在父鏈中被ACCEPT了,那麼它不會再經過父鏈中的其他規則。但要注意 這個包能被其他表的鏈匹配,過程可查看章節 表和鏈

target指定我們要對包做的操作,比如DROP和ACCEPT,還有很多,我們後面會介紹。不同的target有不 同的結果。一些target會使包停止前景,也就是不再繼續比較當前鏈中的其他規則或父鏈中的其他規則,最 好的例子就是DROP和ACCEPT。而另外一些target在對包做完操作之後,包還會繼續和其他的規則比較,如LOGULOGTOS。它們會對包進行記 錄、mangle,然後讓包通過,以便匹配這條鏈中的其他規則。有了這樣的target,我們就可以對同一個包既 改變它的TTL又改變它的TOS。有些target必須要有準確的參數(如TOS需要確定的數值),有些就不是必須 的,但如果我們想指定也可以(如日誌的前綴,僞裝使用的端口,等等)。本節我們會儘可能全面地介紹每 一個target。現在我們就來看看有哪幾種target。


6.5.1. ACCEPT target

這個target沒有任何選項和參數,使用也很簡單,指定-j ACCEPT即可。一旦包 滿足了指定的匹配條件,就會被ACCEPT,並且不會再去匹配當前鏈中的其他規則或同一個表內的其他規則, 但它還要通過其他表中的鏈,而且在那兒可能會百DROP也說不準哦。


6.5.2. DNAT target

這個target是用來做目的網絡地址轉換的,就是重寫包的目的IP地址。如果一個包被匹配了,那麼和它 屬於同一個流的所有的包都會被自動轉換,然後就可以被路由到正確的主機或網絡。DNAT target是非常有 用的。比如,你的Web服務器在LAN內部,而且沒有可在Internet上使用的真實IP地址,那就可以使用這個 target讓防火牆把所有到它自己HTTP端口的包轉發給LAN內部真正的Web服務器。目的地址也可以是一個範 圍,這樣的話,DNAT會爲每一個流隨機分配一個地址。因此,我們可以用這個target做某種類型地負載平 衡。

注意,DANT target只能用在nat表的PREROUTING和OUTPUT鏈中,或者是被這兩條鏈調用的鏈裏。但還要 注意的是,包含DANT target的鏈不能被除此之外的其他鏈調用,如POSTROUTING。

Table 6-16. DNAT target

Option --to-destination
Example iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10
Explanation 指定要寫入IP頭的地址,這也是包要被轉發到的地方。上面 的例子就是把所有發往地址15.45.23.67的包都轉發到一段LAN使用的私有地址中,即192.168.1.1到 192.168.1.10。如前所述,在這種情況下,每個流都會被隨機分配一個要轉發到的地址,但同一個流總是使 用同一個地址。我們也可以只指定一個IP地址作爲參數,這樣所有的包都被轉發到同一臺機子。我們還可以 在地址後指定一個或一個範圍的端口。比如:--to-destination 192.168.1.1:80或 --to-destination 192.168.1.1:80-100SNAT的語法和這 個target的一樣,只是目的不同罷了。要注意,只有先用--protocol指定了TCP或 UDP協議,才能使用端口。

因爲DNAT要做很多工作,所以我要再羅嗦一點。我們通過一個例子來大致理解一 下它是如何工作的。比如,我想通過Internet連接發佈我們的網站,但是HTTP server在我們的內網裏,而 且我們對外只有一個合法的IP,就是防火牆那個對外的IP——$INET_IP。防火牆還 有一個內網的IP——$LAN_IP,HTTP server的IP是$HTTP_IP (這當然是內網的了)。爲了完成我們的設想,要做的第一件事就是把下面的這個簡單的規則加入到nat表 的PREROUTING鏈中:

iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP

現在,所有從Internet來的、到防火牆的80端口去的包都會被轉發(或稱做被DNAT )到在內網的HTTP服務器上。如果你在Internet上試驗一下,一切正常吧。再從內網裏試驗一下,完全 不能用吧。這其實是路由的問題。下面我們來好好分析這個問題。爲了容易閱讀,我們把在外網上訪問我們 服務器的那臺機子的IP地址記爲$EXT_BOX

  1. 包從地址爲$EXT_BOX的機子出發,去往地址爲$INET_IP 的機子。

  2. 包到達防火牆。

  3. 防火牆DNAT(也就是轉發)這個包,而且包會經過很多其他的鏈檢驗及處理。

  4. 包離開防火牆向$HTTP_IP前進。

  5. 包到達HTTP服務器,服務器就會通過防火牆給以迴應,當然,這要求把防火牆作爲HTTP到達$EXT_BOX的網關。一般情況下,防火牆就是HTTP服務器的缺省網關。

  6. 防火牆再對返回包做Un-DNAT(就是照着DNAT的步驟反過來做一遍),這樣就 好像是防火牆自己回覆了那個來自外網的請求包。

  7. 返回包好象沒經過這麼複雜的處理、沒事一樣回到$EXT_BOX

現在,我們來考慮和HTTP服務器在同一個內網(這裏是指所有機子不需要經過路由器而可以直接互相訪 問的網絡,不是那種把服務器和客戶機又分在不同子網的情況)的客戶訪問它時會發生什麼。我們假設客戶 機的IP爲$LAN_BOX,其他設置同上。

  1. 包離開$LAN_BOX,去往$INET_IP

  2. 包到達防火牆。

  3. 包被DNAT,而且還會經過其他的處理。但是包沒有經過SNAT 的處理,所以包還是使用它自己的源地址,就是$LAN_BOX(譯者注:這就是IP 傳輸包的特點,只根據目的地的不同改變目的地址,但不因傳輸過程中要經過很多路由器而隨着路由器改變 其源地址,除非你單獨進行源地址的改變。其實這一步的處理和對外來包的處理是一樣的,只不過內網包的 問題就在於此,所以這裏交待一下原因)。

  4. 包離開防火牆,到達HTTP服務器。

  5. HTTP服務器試圖回覆這個包。它在路由數據庫中看到包是來自同一個網絡的一臺機子,因此它會把回 復包直接發送到請求包的源地址(現在是回覆包的目的地址),也就是$LAN_BOX

  6. 回覆包到達客戶機,但它會很困惑,因爲這個包不是來自它訪問的那臺機子。這樣,它就會把這個包 扔掉而去等待“真正”的回覆包。

針對這個問題有個簡單的解決辦法,因爲這些包都要進入防火牆,而且它們都去往需要做DNAT才能到達 的那個地址,所以我們只要對這些包做SNAT操作即可。比如,我們來考慮上面的例子,如果對那些進入防火 牆而且是去往地址爲$HTTP_IP、端口爲80的包做SNAT操作,那麼這些包就好象是從$LAN_IP來的了,也就是 說,這些包的源地址被改爲$LAN_IP了。這樣,HTTP服務器就會把回覆包發給防火牆,而防火牆會再對包做 Un-DNAT操作,並把包發送到客戶機。解決問題的規則如下:

iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \ --to-source $LAN_IP

要記住,按運行的順序POSTROUTING鏈是所有鏈中最後一個,因此包到 達這條鏈時,已經被做過DNAT操作了,所以我們在規則裏要基於內網的地址$HTTP_IP(包的目的地)來匹配 包。

Warning

警告:我們剛纔寫的這條規則會對日誌產生很大影響,這種影響應該說是很不好的。因爲來自 Internet包在防火牆內先後經過了DNAT和SNAT處理,才能到達HTTP服務器(上面的例子),所以HTTP服務器 就認爲包是防火牆發來的,而不知道真正的源頭是其他的IP。這樣,當它記錄服務情況時,所有訪問記錄的 源地址都是防火牆的IP而不是真正的訪問源。我們如果想根據這些記錄來了解訪問情況就不可能了。因此上 面提供的“簡單辦法”並不是一個明智的選擇,但它確實可以解決“能夠訪問”的問題,只是沒有考慮到日 志而已。

其他的服務也有類似的問題。比如,你在LAN內建立了SMTP服務器,那你就要設置防火牆以便能轉 發SMTP的數據流。這樣你就創建了一個開放的SMTP中繼服務器,隨之而來的就是日誌的問題了。

一定要注意,這裏所說的問題只是針對沒有建立DMZ或類似結構的網絡,並且內網的用戶訪問的是 服務器的外網地址而言的。(譯者注:因爲如果建立了DMZ,或者服務器和客戶機又被分在不同的子網裏, 那就不需要這麼麻煩了。因爲所有訪問的源頭都不在服務器所在的網裏,所以就沒必要做SNAT去改變包的源 地址了,從而記錄也就不是問題了。如果內網客戶是直接訪問服務器的內網地址那就更沒事了)

較好的解決辦法是爲你的LAN在內網建立一臺單獨的DNS服務器(譯者注:這樣,內網的客戶使用網站名 訪問HTTP服務器時,DNS就可以把它解析成內網地址。客戶機就可以直接去訪問HTTP服務器的內網地址了, 從而避免了通過防火牆的操作,而且包的源地址也可以被HTTP服務器的日誌使用,也就沒有上面說的日誌問 題了。),或者乾脆建立DMZ得了(這是最好的辦法,但你要有錢哦,因爲用的設備多啊)。

對上面的例子應該考慮再全面些,現在還有一個問題沒解決,就是防火牆自己要訪問HTTP服務器時會發 生什麼,能正常訪問嗎?你覺得呢:)很可惜,現在的配置還是不行,仔細想想就明白了。我們這裏討論的基 礎都是假設機子訪問的是HTTP服務器的外網地址,但這個外網地址其實就是防火牆對外的地址,所以當防火 牆訪問這個外網地址時,就是訪問它自己。防火牆上如果有HTTP服務,那客戶機就會看到頁面內容,不過這 不是它想看到的(它想要的在DNAT上了),如果沒有HTTP服務,客戶就只能收到錯 誤信息了。前面給出的規則之所以不起作用是因爲從防火牆發出的請求包不會經過那兩條鏈。還記得防火牆 自己發出的包經過哪些鏈吧:)我們要在nat表的OUTPUT鏈中添加下面的規則:

iptables -t nat -A OUTPUT --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP

有了最後這條規則,一切都正常了。和HTTP服務器不在同一個網的機子能正常訪問服務了,和它在一個 網內的機子也可以正常訪問服務了,防火牆本身也能正常訪問服務了,沒有什麼問題了。這種心情,套用 《大話西遊》裏的一句話,就是“世界又清淨了”。(不要說你不知道什麼是《大話西遊》)

Note

我想大家應該能明白這些規則只說明了數據包是如何恰當地被DNAT和SNAT的。除此之外,在 filter表中還需要其他的規則(在FORWARD鏈裏),以允許特定的包也能經過前面寫的(在POSTROUTING鏈和 OUTPUT鏈裏的)規則。千萬不要忘了,那些包在到達FORWARD鏈之前已經在PREROUTING鏈裏被DNAT過了,也 就是說它們的目的地址已被改寫,在寫規則時要注意這一點。


6.5.3. DROP target

顧名思義,如果包符合條件,這個target就會把它丟掉,也就是說包的生命到此結束,不會再向前走一 步,效果就是包被阻塞了。在某些情況下,這個target會引起意外的結果,因爲它不會向發送者返回任何信 息,也不會向路由器返回信息,這就可能會使連接的另一方的sockets因苦等迴音而亡:) 解決這個問題的較 好的辦法是使用REJECT target,(譯者注:因爲它在丟棄包的同時還會向發送者返 回一個錯誤信息,這樣另一方就能正常結束),尤其是在阻止端口掃描工具獲得更多的信息時,可以隱蔽被 過濾掉的端口等等(譯者注:因爲掃描工具掃描一個端口時,如果沒有返回信息,一般會認爲端口未打開或 被防火牆等設備過濾掉了)。還要注意如果包在子鏈中被DROP了,那麼它在主鏈裏也不會再繼續前進,不管 是在當前的表還是在其他表裏。總之,包死翹翹了。


6.5.4. LOG target

這個target是專門用來記錄包地有關信息的。這些信息可能是非法的,那就可以用來除錯。LOG會返回包 的有關細節,如IP頭的大部分和其他有趣的信息。這個功能是通過內核的日誌工具完成的,一般是syslogd。返回的信息可用dmesg閱讀,或者可以直接查看syslogd的日誌文件,也可以用其他的什麼程序來看。LOG對調試規則有很大的幫助,你 可以看到包去了哪裏、經過了什麼規則的處理,什麼樣的規則處理什麼樣的包,等等。當你在生產服務器上 調試一個不敢保證100%正常的規則集時,用LOG代替DROP是比較好的(有詳細的信息可看,錯誤就容易定 位、解決了),因爲一個小小的語法錯誤就可能引起嚴重的連接問題,用戶可不喜歡這樣哦。如果你想使用 真正地擴展日誌地話,可能會對ULOG target有些興趣,因爲它可以把日誌直接記錄 到MySQL databases或類似的數據庫中。

Note

注意,如果在控制檯得到的信息不是你想要的,那不是iptables或Netfilter的問題,而是 syslogd 配置文件的事,這個文件一般都是/etc/syslog.conf。有關這個問題的更多信息請查通過man syslog.conf查看。

LOG現在有5個選項,你可以用它們指定需要的信息類型或針對不同的信息設定一 些值以便在記錄中使用。選項如下:

Table 6-17. LOG target options

Option --log-level
Example iptables -A FORWARD -p tcp -j LOG --log-level debug
Explanation 告訴iptables syslog使用哪個記錄等級。記錄等級的詳細信息可以查看文件syslog.conf,一般來說有以下幾種,它 們的級別依次是:debug,info,notice,warning,warn,err,error,crit,alert, emerg,panic。其中,error和err、warn和warning、panic和emerg分別是同義詞,也就是說作用完全 一樣的。注意這三種級別是不被贊成使用的,換句話說,就是不要使用它們(因爲信息量太大)。信息級別 說明了被記錄信息所反映的問題的嚴重程度。所有信息都是通過內核的功能被記錄的,也就是說,先在文件syslog.conf裏設置kern.=info /var/log/iptables,然 後再讓所有關於iptables的LOG信息使用級別info,就可以把所有的信息存入文件/var/log/iptables內。注意,其中也可能會有其他的信息,它們是內核中使用info 這個等級的其他部分產生的。有關日誌的詳細信息,我建議你看看syslogsyslog.conf的幫助,還有HOWTO,等等。
Option --log-prefix
Example iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT packets"
Explanation 告訴iptables在記錄的信息之前加 上指定的前綴。這樣和grep或其他工具一起使用時就容易追蹤特定的問題,而且也 方便從不同的規則輸出。前綴最多能有29個英文字符,這已經是包括空白字符和其他特殊符號的總長度了。
Option --log-tcp-sequence
Example iptables -A INPUT -p tcp -j LOG --log-tcp-sequence
Explanation 把包的TCP序列號和其他日誌信息一起記錄下來。TCP序列號 可以唯一標識一個包,在重組時也是用它來確定每個分組在包裏的位置。注意,這個選項可能會帶來危險, 因爲這些記錄被未授權的用戶看到的話,可能會使他們更容易地破壞系統。其實,任何iptables的輸出信息 都增加了這種危險。(譯者注:現在,我深刻理解了什麼是“言多必失”,什麼是“沉默是金”)
Option --log-tcp-options
Example iptables -A FORWARD -p tcp -j LOG --log-tcp-options
Explanation 記錄TCP包頭中的字段大小不變的選項。這對一些除錯是很 有價值的,通過它提供的信息,可以知道哪裏可能出錯,或者哪裏已經出了錯。
Option --log-ip-options
Example iptables -A FORWARD -p tcp -j LOG --log-ip-options
Explanation 記錄IP包頭中的字段大小不變的選項。這對一些除錯是很有 價值的,還可以用來跟蹤特定地址的包。

6.5.5. MARK target

用來設置mark值,這個值只能在本地的mangle表裏使用,不能用在其他任何地方,就更不用說路由器或 另一臺機子了。因爲mark比較特殊,它不是包本身的一部分,而是在包穿越計算機的過程中由內核分配的和 它相關聯的一個字段。它可以和本地的高級路由功能聯用,以使不同的包能使用不同的隊列要求,等等。如 果你想在傳輸過程中也有這種功能,還是用TOS target吧。有關高級路由的更多信息,可以查看Linux Advanced Routing and Traffic Control HOW-TO

Table 6-18. MARK target options

Option --set-mark
Example iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2
Explanation 設置mark值,這個值是一個無符號的整數。比如,我們對一 個流或從某臺機子發出的所有的包設置了mark值,就可以利用高級路由功能來對它們進行流量控制等操作 了。

6.5.6. MASQUERADE target

這個target和SNAT target的作用是一樣的,區別就是它不需要指定--to-source 。MASQUERADE是被專門設計用於那些動態獲取IP地址的連接的,比如,撥號上網、DHCP連接等。如果你 有固定的IP地址,還是用SNAT target吧。

僞裝一個連接意味着,我們自動獲取網絡接口的IP地址,而不使用--to-source 。當接口停用時,MASQUERADE不會記住任何連接,這在我們kill掉接口時是有 很大好處的。如果我們使用SNAT target,連接跟蹤的數據是被保留下來的,而且時 間要好幾天哦,這可是要佔用很多連接跟蹤的內存的。一般情況下,這種處理方式對於撥號上網來說是較好 的(這有利於已有那連接繼續使用)。如果我們被分配給了一個不同於前一次的IP,不管怎樣已有的連接都 要丟失,但或多或少地還是有一些連接記錄被保留了(真是白癡,是吧)。

即使你有靜態的IP,也可以使用MASQUERADE,而不用SNAT 。不過,這不是被贊成的,因爲它會帶來額外的開銷,而且以後還可能引起矛盾,比如它也許會影響你 的腳本,使它們不能用。

注意,MASQUERADESNAT一樣,只能用於nat表的 POSTROUTING鏈,而且它只有一個選項(不是必需的):

Table 6-19. MASQUERADE target

Option --to-ports
Example iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000
Explanation 在指定TCP或UDP的前提下,設置外出包能使用的端口,方式 是單個端口,如--to-ports 1025,或者是端口範圍,如--to- ports 1024-3000。注意,在指定範圍時要使用連字號。這改變了SNAT中缺省的端口選擇,詳情請查看 SNAT target

6.5.7. MIRROR target

這個target是實驗性的,它只是一個演示而已,不建議你使用它,因爲它可能引起循環,除此之外,還 可能引起嚴重的DoS。這個target的作用是顛倒IP頭中的源目地址,然後再轉發包。這會引起很有趣的事, 一個駭客最後攻破的可能就是他自己的機子。看來,使用這個target至少可以使我們的機子更強壯:) 我們 如果對機子A的80端口使用了MIRROR,會發生什麼呢?假設有來自yahoo.com的機子B 想要訪問A的HTTP服務,那他得到的將是yahoo的主頁,因爲請求是來自yahoo的。

注意,MIRROR只能用在INPUT FORWARD、 PREROUTING鏈和被它們調用的自定義鏈中。還要注意,如果外出的包是因 MIRROR target發出的,則它們是不會被filter、nat或mangle表內的鏈處理的,這 可能引起循環或其他問題。比如,一臺機子向另一臺配置了MIRRORTTL值爲255的機子發送一個會被認爲是欺騙的數據 包,同時這臺機子也欺騙自己的數據包,以使它被認爲好像是來自第三個使用了MIRROR 的機子。這樣,那個包就會不間斷地往來很多次,直到TTL爲0。如果兩臺機子之間只有一個路由器,這 個包就會往返240-255次。對駭客來說,這是不壞的情況,因爲他只要發送一個1500字節的數據(也就是一 個包),就可以消耗你的連接的380K字節。對於駭客或者叫做腳本小子(不管我們把他們稱作什麼)來說, 這可是很理想的情況。


6.5.8. QUEUE target

這個target爲用戶空間的程序或應用軟件管理包隊列。它是和iptables之外的程序或工具協同使用的, 包括網絡計數工具,高級的數據包代理或過濾應用,等等。討論程序的編碼已超出了本文的範圍。即使討 論,也要花很多時間,而且在這樣一篇文章之內也無法說清有關Netfilter和iptables的編程。具體的信息 請查看Netfilter Hacking HOW-TO


6.5.9. REDIRECT target

在防火牆所在的機子內部轉發包或流到另一個端口。比如,我們可以把所有去往端口HTTP的包REDIRECT到HTTP proxy(例如squid),當然這都發生在我們自己的主機內部。本地生成的包都會被映射到127.0.0.1。換句 話說,這個target把要轉發的包的目的地址改寫爲我們自己機子的IP。我們在做透明代理(LAN內的機子根 本不需要知道代理的存在就可以正常上網)時,這個target可是起了很大作用的。

注意,它只能用在nat表的PREROUTING、OUTPUT鏈和被它們調用的自定義鏈裏。 REDIRECT只有一個選項:

Table 6-20. REDIRECT target

Option --to-ports
Example iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
Explanation 在指定TCP或UDP協議的前提下,定義目的端口,方式如下:

1、不使用這個選項,目的端口不會被改變。

2、指定一個端口,如--to-ports 8080

3、指定端口範圍,如--to-ports 8080-8090


6.5.10. REJECT target

REJECTDROP基本一樣,區別在於它除了阻塞包之外, 還向發送者返回錯誤信息。現在,此target還只能用在INPUT、FORWARD、OUTPUT和它們的子鏈裏,而且包含 REJECT的鏈也只能被它們調用,否則不能發揮作用。它只有一個選項,是用來控制 返回的錯誤信息的種類的。雖然有很多種類,但如果你有TCP/IP方面的基礎知識,就很容易理解它們。

Table 6-21. REJECT target

Option --reject-with
Example iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset
Explanation 告訴REJECT target應向發送者返回 什麼樣的信息。一旦包滿足了設定的條件,就要發送相應的信息,然後再象DROP一 樣無情地拋棄那些包。可用的信息類型有:1、icmp-net-unreachable 2、icmp-host-unreachable 3、 icmp-port-unreachable 4、icmp-proto-unreachable 5、icmp-net-prohibited 6、icmp-host-prohibited 。其中缺省的是port-unreachable。你可以在附錄ICMP類 型中看到更多的信息。還有一個類型——echo-reply,它只能和匹配 ICMP ping包的規則聯用。最後一個類型是tcp-reset,(顯然,只能用於TCP協議) 它的作用是告訴REJECT返回一個TCP RST包(這個包以文雅的方式關閉TCP連接,有關它的詳細信息在RFC 793 - Transmission Control Protocol裏)給發送者。正如iptables的 man page中說的,tcp-reset主要用來阻塞身份識別探針(即113/tcp,當向被破壞的郵件主機發送郵件時, 探針常被用到,否則它不會接受你的信)。

6.5.11. RETURN target

顧名思義,它使包返回上一層,順序是:子鏈——>父鏈——>缺省的策略。具體地說,就是若包在子鏈 中遇到了RETURN,則返回父鏈的下一條規則繼續進行條件的比較,若是在父鏈(或稱主鏈,比如INPUT)中 遇到了RETURN,就要被缺省的策略(一般是ACCEPT或DROP)操作了。(譯者注:這很象C語言中函數返回值 的情況)

我們來舉個例子說明一下,假設一個包進入了INPUT鏈,匹配了某條target爲--jump EXAMPLE_CHAIN規則,然後進入了子鏈EXAMPLE_CHAIN。在子鏈中又匹配了某條 規則,恰巧target是--jump RETURN,那包就返回INPUT鏈了。如果在INPUT鏈裏又遇 到了--jump RETURN,那這個包就要交由缺省的策略來處理了。


6.5.12. SNAT target

這個target是用來做源網絡地址轉換的,就是重寫包的源IP地址。當我們有幾個機子共享一個Internet 連接時,就能用到它了。先在內核裏打開ip轉發功能,然後再寫一個SNAT規則,就 可以把所有從本地網絡出去的包的源地址改爲Internet連接的地址了。如果我們不這樣做而是直接轉發本地 網的包的話,Internet上的機子就不知道往哪兒發送應答了,因爲在本地網裏我們一般使用的是IANA組織專 門指定的一段地址,它們是不能在Internet上使用的。SNAT target的作用就是讓所 有從本地網出發的包看起來都是從一臺機子發出的,這臺機子一般就是防火牆。

SNAT只能用在nat表的POSTROUTING鏈裏。只要連接的第一個符合條件的包被SNAT了,那麼這個連接的其他所有的包都會自動地被SNAT,而且這個規則還會應用於這 個連接所在流的所有數據包。

Table 6-22. SNAT target

Option --to-source
Example iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000
Explanation 指定源地址和端口,有以下幾種方式:

1、單獨的地址。

2、一段連續的地址,用連字符分隔,如194.236.50.155-194.236.50.160,這樣可以實現負載平衡。每 個流會被隨機分配一個IP,但對於同一個流使用的是同一個IP。

3、在指定-p tcp 或 -p udp的前提下,可以指定源端口的範圍,如194.236.50.155:1024-32000,這樣 包的源端口就被限制在1024-32000了。

注意,如果可能,iptables總是想避免任何的端口變更,換句話說,它總是盡力使用建立連接時所用的 端口。但是如果兩臺機子使用相同的源端口,iptables 將會把他們的其中之一映射到另外的一個端口。如 果沒有指定端口範圍, 所有的在512以內的源端口會被映射到512以內的另一個端口,512和1023之間的將會 被映射到 1024內,其他的將會被映射到大於或對於1024的端口,也就是說是同範圍映射。還要注意,這種 映射和目的端口無關。因此,如果客戶想和防火牆外的HTTP服務器聯繫,它是不會被映射到FTP control所用的端口的。


6.5.13. TOS target

TOS是用來設置IP頭中的Type of Service字段的。這個字段長一個字節,可以控 制包的路由情況。它也是iproute2及其子系統可以直接使用的字段之一。值得注意 的是,如果你有幾個獨立的防火牆和路由器,而且還想在他們之間利用包的頭部來傳遞路由信息,TOS是唯 一的辦法。前面說過,MARK是不能用來傳遞這種信息的。如果你需要爲某個包或流 傳遞路由信息,就要使用TOS字段,它也正是爲這個而被開發的。

Internet上有很多路由器在這一方面並沒有做好工作,因此,在發送包之前改變其TOS沒有什麼大用處。 最好的情況是路由器根本不理它,最壞的情況是路由器會根據TOS處理,但都是錯誤的。然而,如果你是在 一個很大的WAN或LAN裏,而且有很多路由器,TOS還是能有很好的作爲的。總的來說,基於TOS的值給包以不 同的路由和參數還是可能的,即使在網絡裏是受限制的(譯者注:大不了不起作用就是了)。

Caution

TOS只能用來設置具體的或者說是特定的值(這些預定義的值在內核源碼的include文件——Linux/ip.h中),原因是很多的,但不管怎麼說,你不要使用其他的值就是了。當 然,我們也有辦法突破這個限制,就是使用一個名爲FTOS的patch,你可在由Matthew G. Marsh維護的站點 Paksecured Linux Kernel patches得到它,但要小心使用哦。除了非 常特殊、極端的情況,我們是不應該使用預定義以外的值的。

Note

注意,這個target只能在mangle表內使用。

Note

還要注意,在一些老版(1.2.2或更低)的iptables中包含的這個target在設置了TOS之後,不會 調整包的校驗和,這樣包會被認爲是錯誤的並要求重發。而且,這很可能會導致更多的mangle操作,從而使 整個連接無法工作。(譯者注:好在我們現在不會再用這麼老的版本了:) )

TOS target只有一個選項:

Table 6-23. TOS target

Option --set-tos
Example iptables -t mangle -A PREROUTING -p TCP --dport 22 -j TOS --set-tos 0x10
Explanation 設置TOS的值,值的形式可以是名字或者使相應的數值(十 進制或16進制的)。一般情況下,建議你使用名字而不使用數值形式,因爲以後這些數值可能會有所改變, 而名字一般是固定的。TOS字段有8個二進制位,所以可能的值是0-255(十進制)或0x00-0xFF(16進制)。 如前所述,你最好使用預定義的值,它們是:

1、Minimize-Delay 16 (0x10),要求找一條路徑使延時最小,一些標準服務如telnet、SSH、FTP- control 就需要這個選項。

2、Maximize-Throughput 8 (0x08),要求找一條路徑能使吞吐量最大,標準服務FTP-data能用到這個。

3、Maximize-Reliability 4 (0x04),要求找一條路徑能使可靠性最高,使用它的有BOOTP和TFTP。

4、Minimize-Cost 2 (0x02),要求找一條路徑能使費用最低,一般情況下使用這個選項的是一些視頻音 頻 流協議,如RTSP(Real Time Stream Control Protocol)。

5、Normal-Service 0 (0x00),一般服務,沒有什麼特殊要求。這個值也是大部分包的缺省值。

完整的列表可以通過命令iptables -j TOS -h

得到。在1.2.5版時,這個列 表就已經是完整的了,而且會保持很長一段時間。

6.5.14. TTL target

Caution

這個target需要patch-o-matic裏的名爲TTL的patch,可從 http://www.netfilter.org獲得。此站點的FAQ是開始學習iptables和Netfilter的好地方。

TTL可以修改IP頭中Time To Live字段的值。它有很大的作用,我們可以把所有外出包的Time To Live值 都改爲一樣的,比如64,這是Linux的默認值。有些ISP不允許我們共享連接(他們可以通過TTL的值來區分 是不是有多個機子使用同一個連接),如果我們把TTL都改爲一樣的值,他們就不能再根據TTL來判斷了。

關於任何設置Linux的TTL默認值,請參閱附錄其他資源和鏈接 內的ip-sysctl.txt

TTL只能在mangle表內使用,它有3個選項:

Table 6-24. TTL target

Option --ttl-set
Example iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-set 64
Explanation 設置TTL的值。這個值不要太大,也不要太小,大約64就很 好。值太大會影響網絡,而且有點不道德,爲什麼這樣說呢?如果有些路由器的配置不太正確,包的TTL又 非常大,那它們就會在這些路由器之間往返很多次,值越大,佔用的帶寬越多。這個target就可以被用來限 制包能走多遠,一個比較恰當的距離是剛好能到達DNS服務器。
Option --ttl-dec
Example iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-dec 1
Explanation 設定TTL要被減掉的值,比如--ttl-dec 3。假設一個進來的包的TTL是53,那麼當它離開我們這臺機子時,TTL就變爲49了。爲什麼不是50呢? 因爲經過我們這臺機子,TTL本身就要減1,還要被TTL target再減3,當然總共就是減去4了。使用這個 target可以限制“使用我們的服務的用戶”離我們有多遠。比如,用戶總是使用比較近的DNS,那我們就可 以對我們的DNS服務器發出的包進行幾個--ttl-dec。(譯者注:意思是,我們只想 讓距離DNS服務器近一些的用戶訪問我們的服務)當然,用--set-ttl控制更方便 些。
Option --ttl-inc
Example iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-inc 1
Explanation 設定TTL要被增加的值,比如--ttl-inc 4。假設一個進來的包的TTL是53,那麼當它離開我們這臺機子時,TTL應是多少呢?答案是56,原因同--ttl-dec。使用這個選項可以使我們的防火牆更加隱蔽,而不被trace-routes發現, 方法就是設置--ttl-inc 1。原因應該很簡單了,包每經過一個設備,TTL就要自動 減1,但在我們的防火牆裏這個1又被補上了,也就是說,TTL的值沒變,那麼trace-routes就會認爲我們的 防火牆是不存在的。Trace-routes讓人又愛又恨,愛它是因爲在連接出問題時,它可以給我們提供極有用的 信息,告訴我們哪裏有毛病;恨它是由於它也可以被黑客或駭客用來收集目標機器的資料。怎麼使用它呢? 這裏有個很好的例子,請看腳本Ttl-inc.txt

6.5.15. ULOG target

ULOG可以在用戶空間記錄被匹配的包的信息,這些信息和整個包都會通過netlink socket被多播。然 後,一個或多個用戶空間的進程就會接受它們。換句話說,ULOG是至今iptables和Netfilter下最成熟、最 完善的日誌工具,它包含了很多更好的工具用於包的記錄。這個target可以是我們把信息記錄到MySQL或其 他數據庫中。這樣,搜索特定的包或把記錄分組就很方便了。你可以在ULOGD project page裏找到ULOGD用戶空間的軟件。

Table 6-25. ULOG target

Option --ulog-nlgroup
Example iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-nlgroup 2
Explanation 指定向哪個netlink組發送包,比如-- ulog-nlgroup 5。一個有32個netlink組,它們被簡單地編號位1-32。默認值是1。
Option --ulog-prefix
Example iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-prefix "SSH connection attempt: "
Explanation 指定記錄信息的前綴,以便於區分不同的信息。使用方法和 LOG的prefix一樣,只是長度可以達到32個字符。
Option --ulog-cprange
Example iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-cprange 100
Explanation 指定每個包要向“ULOG在用戶空間的代理”發送的字節數, 如--ulog-cprange 100,表示把整個包的前100個字節拷貝到用戶空間記錄下來,其 中包含了這個包頭,還有一些包的引導數據。默認值是0,表示拷貝整個包,不管它有多大。
Option --ulog-qthreshold
Example iptables -A INPUT -p TCP --dport 22 -j ULOG --ulog-qthreshold 10
Explanation 告訴ULOG在向用戶空間發送數據以供記錄之前,要在內核裏 收集的包的數量(譯者注:就像集裝箱),如--ulog-qthreshold 10。這表示先在 內核裏積聚10個包,再把它們發送到用戶空間裏,它們會被看作同一個netlink的信息,只是由好幾部分組 成罷了。默認值是1,這是爲了向後兼容,因爲以前的版本不能處理分段的信息。

Chapter 7. 防火牆配置實例 rc.firewall

在本章裏,我們將要建立一個防火牆,並且詳細地說明了如何去閱讀、理解它。在這個例子中,我們使 用的是最基本的配置,對其工作方式和我們在裏面做了些什麼都有深入的解釋。這個例子應該能在某些方面 給你提供基本的思路,比如,如何解決不同的問題(當然是網絡方面的),再如,在真正把腳本應用於工作 之前應該考慮些什麼,等等。對本例中的變量值做些修改就可能在實際的網絡中使用,但不建議你這樣做, 因爲你的網絡配置和我在例子中使用的情況可能不一樣哦。但只要你有了這個基本的防火牆規則集,很可能 只需要少量的調整就可以把它用於實際了。

Note

可能有效率更高的方法來建立規則集,但這個腳本就是爲易讀而寫的,所以每個人都能理解它, 即使沒有多少BASH腳本編程的知識。


7.1. 關於rc.firewall

好,既然你能從頭看到這兒,就說明你已經做好一切準備來檢查這個腳本了。例子rc.firewall.txt(代碼在附錄示例腳本 的代碼裏)很大,但沒有多少註釋。我建議你先大致看看它的內容,留個印象,再來仔細地閱讀本 章(要有耐心哦)。


7.2. rc.firewall詳解

7.2.1. 參數配置

本小節要對照着rc.firewall腳本代碼來看。

rc.firewall.txt的第一小節是配置選項,包含的都是一些至關 重要的信息,它們是隨着你的網絡的不同而改變的。比如,每個網絡的IP地址都不一樣,所有要把它放在這 兒。$INET_IP的值應該是在Internet上能使用的纔可以,如果你有$INET_IP的話。如果沒有,你就要看看 rc.DHCP.firewall.txt這種配置方法了,裏面有很多有趣的東西。變量 $INET_IFACE應該指向連接Internet的真實設備,比如eth0、eth1、ppp0、tr0等等。

這個腳本里沒有包含任何DHCP或PPPoE的選項,所以這兩節是空白的。其他空白的部分,也是這樣的原 因。之所以保留這些空白,是爲了更容易區分這些結構相同而內容不同的腳本。如果你需要這些部分,可以 從其他腳本拷貝過來,或者你自己寫了:)

Local Area Network小節包含的是LAN必須的信息,如連接到LAN的網 卡的IP、LAN所用的地址段等。

Localhost configuration小節裏的信息在99%的情況下都不要改變,因爲我們總是使用127.0.0.1作爲地 址,也總是把接口命名爲lo。緊隨其後的是IPTables Configuration,裏面只有一個變量,即$IPTABLES。它指定的是iptables程序的準確位置,如果是自己編譯安裝的話,一般都 是/usr/local/sbin/iptables。但更多的發行版都把程序放在另外的地方,如 /usr/sbin/iptables,等等。


7.2.2. 外部模塊的裝載

首先,我們要使用命令/sbin/depmod -a使module dependencies files保持最 新,然後,再裝載腳本需要的模塊。我們應該始終避免裝入不需要的模塊,如果可能,還要盡力避免裝入無 所事事的模塊,除非你確實需要它們。這樣做主要是爲了安全,因爲每增加一個模塊都要花費額外的努力以 增加新的規則(這樣就容易出漏洞哦)。比如,如果你想支持LOG、REJECT和MASQUERADE target,不要把相 應的功能靜態地編譯進內核,我們使用以下模塊來完成:

/sbin/insmod ipt_LOG
/sbin/insmod ipt_REJECT
/sbin/insmod ipt_MASQUERADE
    

Caution

注意,本文使用的腳本都是用類似命令裝入模塊,這可能會引起裝載失敗(有錯誤信息顯示)。 原因是多方面的,但如果較基本的模塊也失敗的話,那最大的可能是哪個模塊或相應的功能已被靜態地編譯 進內核了。進一步的信息可以看看附錄常見問題與解答中的模塊裝載問題

接下來的一行是裝載ipt_owner模塊,它的作用是“只允許特定的用戶 創建特定的連接”。在這個例子中,我沒有使用到它,但你可能會用到。比如,你可能只允許root建立FTP 和HTTP連接訪問redhat.com,而其他用戶都不可以。你也可以只允許你自己使用的用戶名和root才能訪問 Internet,這樣別人會很煩的,但你的安全性在某些方面會有所提高哦,比如,把你當作發起攻擊的跳板的 情況。關於ipt_owner的更多信息,可以看看章節規則是如何練成的裏的Owner match 

在這兒我們也可以爲狀態匹配安裝擴展模塊。狀態匹配和連接跟蹤的所有擴展模塊的名字都是這樣的: ip_conntrack_*和ip_nat_* 。連接跟蹤的helper是一些特殊的模塊,正是它們告訴了內核怎樣恰當地跟蹤 特殊的連接。沒有這些helper,內核在處理特殊連接的時候,就不知道該查看些什麼東西。NAT helper就是 連接跟蹤helper的擴展,它會告訴內核在包裏找什麼、如何轉換它們,這樣連接才能真正工作起來。比如, FTP是一個複雜的協議,它利用包的有效數據部分來發送連接信息。如果一臺需要被NAT的機子(譯者注:也 就是說,機子在一個內網裏)連接Internet上的FTP服務器,它就會把自己的內網IP地址放在包的數據區內 發送出去,以使FTP服務器能連接到那個地址。但私有地址不能在LAN外使用,所以FTP服務器不知道用它做 什麼,連接就會斷掉了。FTP NAT helper能完成這些連接中所有的地址轉換工作,因此FTP服務器就知道該 往哪兒連了。同樣的事情也發生在DCC的文件傳輸(這裏指的是發送)和聊天上,爲了建立連接,IP地址和 端口都需要利用IRC協議的數據區發送,而且還要做一些轉換工作。沒有這些helper的話,FTP和IRC只有一 部分工作是正常的,但另一部分根本就無法工作。例如,你可以通過DCC接收文件,但就是不能發送。這個 問題的原因在於DCC是如何建立連接的。當DCC想發送文件時,會告訴接收者你要發送文件,並讓它知道要連 接到什麼地方。如果沒有helper,這個DCC連接最終會斷開,因爲接收者收到的是內網的地址。這樣,當它 按那個地址連接時,其實就連到和它在同一內網的機子了。那爲什麼可以接收呢?因爲發送者給你的是可在 Internet上使用的IP地址(大部分情況下,IRC服務器都有真實的IP地址)。

Note

如果你在通過防火牆使用mIRC DCC時遇到了問題,但和其他IRC客戶溝通很正常,看看附錄常見問題與解答裏的 關於mIRC DCC的問題 吧。

在這個例子中,我們在這兒裝載支持FTP和IRC協議的模塊。有關連接跟蹤和nat的詳細信息,請查看附錄 常見問題與解答。在patch-o-matic中,還有H.323 conntrack helper等其他象NAT helper的模塊。但爲了使用它們,你需要使用patch-o-matic提供的補丁,還需要編譯 內核。詳細的操作信息可以查看章節準備階段 。

Note

注意,爲了能對FTP和IRC協議做網絡地址轉換,需要裝載ip_nat_ftp和ip_nat_irc。在裝載NAT模 塊之前,你還要載入ip_conntrack_ftp和ip_conntrack_irc模塊。NAT模塊和conntrack模塊以相同的方式被 使用,但NAT模塊使我們能對這兩個協議做NAT。


7.2.3. proc的設置

我們可以使用下面的語句打開IP轉發功能(IP forwarding):

echo "1" > /proc/sys/net/ipv4/ip_forward

Warning

注意,何時何地打開這個功能纔算合適是值得好好考慮的一個問題。在本文所用的腳本中,我都 是在創建IP過濾器(在本文裏就是指iptables的過濾規則)之前打開它的。這可能引起這樣一種情況,就是 在一小段時間內(時間的長短隨腳本的複雜程度和機子的性能高低而變化,可能只有一毫秒,也可能會長達 一分鐘),防火牆可以轉發任何包(譯者注:因爲這時防火牆的過濾規則還沒有被裝入)。這種情況又會導 致安全方面的問題,不懷好意的人可能會趁此通過防火牆破壞我們的網絡。也就是說,我們應該在創建所有 防火牆的規則之後再打開IP轉發功能,我這樣做只是爲了保正所有腳本的兼容性。(譯者注:我們在實際應 用中一定要注意這一點,儘量不要先開IP轉發功能)

萬一你使用的是SLIP、PPP或DHCP,也就是說你是動態獲取IP的,那還要用下面的命令打開ip_dynaddr

echo "1" > /proc/sys/net/ipv4/ip_dynaddr

如果你還要打開其他的proc選項,也是用類似的方法,但有關那些選項的具體介紹以不是本文的內容, 你可以看看其他相關的文章。在附錄其他資源和鏈接裏就有一些 介紹了內核proc系統的短小精幹的文章。如果你在本文中找不到想要的資料,就可以到附錄其他資源和鏈接去看看,你會有所收穫的。

Note

在本文所用的腳本中還包含了一個名爲Non-Required proc configuration(非必需的proc設置) 的小節。當有什麼工作不象你所想象的那麼正常時,可以來這兒看看,它能提供給你最基本的一些信息,但 在你真正弄明白它們的含義之前不要進行改動。


7.2.4. 規則位置的優化

本節簡要地描述了針對腳本rc.firewall.txt,我將如何選擇、使用內建的鏈 鏈和自定義的鏈。我選擇過的一些路徑從這個或那個角度看可能是錯誤的,我會指出這些情況和問題發生在 何時何地。這裏還對章節 表和鏈 做了簡要的回顧,希望能 給你一點兒提醒,以使你能想起在實際應用中包是如何表和鏈的。

爲了儘可能地少佔用CPU,我們已經替換了所有不同的自定義鏈,與此同時,我把主要的精力放在了安全 性和易讀性上。我不讓TCP包去經歷ICMP、UDP和TCP規則的洗禮,而是簡單地匹配所有的TCP包,然後讓它去 一個自定義鏈中旅行。這種方法並不比讓它經歷所有的規則開銷大。下圖可以解釋在Netfilter中,外來的 包是如何被處理的(相對於章節表和鏈的深入討論,這個圖 形太粗糙了)。我希望通過上面的解釋和下面的圖形能讓大家明白寫這個腳本的目的,詳細的註釋在後面幾 節。

利用這個圖形,我們可以弄清楚腳本的目的。整個腳本基於這樣一種假設,我們有一個局域網,一個防 火牆及一個Internet連接,且有一個靜態IP地址(相對的是動態地址,它們使用的連接是DHCP、PPP、 SLIP,等等),還想把防火牆作爲Internet上的一臺服務器來運行某些服務。我們完全信任局域網,因此不 能阻塞任何從局域網發出的數據傳輸。還有一個要優先考慮的事,我們只允許那些被明確說明爲可以接受的 數據通過。爲了做到這一點,我們就要把缺省策略設爲DROP。這樣,那些沒有被明確標識爲允許進入的數據 就都被阻塞了。

在上面的假設裏,我們想讓局域網能夠訪問Internet。因爲局域網是被完全信任的,所以我們應該允許 所有來自局域網的數據通過。但Internet是不被信任的,所以我們想阻塞從Internet向我們的局域網發起的 連接。根據上面的所有假設,我們來考慮考慮需要做什麼、不需要做什麼以及我們想做什麼。

首先,我們解決的是局域網要能連接到Internet的問題。那我們就要對所有數據包做NAT操作,因爲局域 網內的機子都沒有真實的IP地址。NAT是在PREROUTING鏈中完成的,這也是腳本最後創建的那個規則所在的 鏈。這意味着我們必須要在FORWARD鏈中做過濾工作,否則我們就是允許所有外部的機子都能完全訪問局域 網了。因爲我們完全信任局域網,所以允許所有由內向外的數據通過。由於我們假設Internet上的機子都不 可以 訪問局域網內的機子,所以要阻塞所有由外向內的連接,但已經建立的或相關的連接除外,因爲它們只是用 來回應內網對外網的訪問,而不是建立對內網的新連接。

由於資金有限,我們的防火牆只提供了有限的幾個服務:HTTP FTPSSHIDENTD。因此,我們要在INPUT鏈裏允許這些協議通過,還要在 OUTPUT鏈裏允許返回的數據通過。我們除了完全信任局域網,也信任loopback和 它的IP地址,因此我們要有相應的規則來允許所有來自局域網和loopback的數據通過。但是我們不會允許一 些特 殊的包或包頭通過,也不會接受Internet上某一段IP的訪問。比如,網段 10.0.0.0/8是爲局域網而保留的,一般來說,我們不允許來自它們的包進入,因爲這樣的包90%都是 用來進行欺騙的。不過,在實現這條標準之前,還要注意一個問題,就是有一些ISP在他們的網絡裏使用的 恰恰就是這些地址。 在附錄常見問題與解答裏有這個問題的進一 步說明。

因爲我們在防火牆上運行FTP服務,而且想讓包經歷最少的規則,所以要把處理established和related狀 態的規則放到INPUT鏈的頂部。基於同樣的原因,我們把這些規則分到子 鏈中。這樣,包就可以儘量少地穿越規則,從而節省時間,也可以降低網絡的冗餘。

在這個腳本里,我們依據不同的協議(如TCP UDPICMP)把包分到子鏈中。用 來匹配 TCP包的鏈叫做tcp_packets,它可以匹配所有我們允許通過的TCP端口和子協 議(如FTP、HTTP等)。我們還要建立一個名爲allowed的子鏈,以便在真正接受“那些使用有效端口 來訪問防火牆的TCP包”之前,對它們進行附加的檢查。至於ICMP包,自有稱作 icmp_packets的鏈來處理。在決定如何建立這個鏈時,我考慮到如果我們同意接受ICMP包的類型 和代碼,就沒有必要對它們做附加的檢查,所以直接接受它們就行了。最後,UDP包由誰處理呢?當然就是 udp_packets了。如果包是那種允許被接收的類型,就直接放行了。

因爲我們的網絡很小,所以防火牆也要作爲工作站來用。這就要求我們要允許一些特殊的協議能和它通 信,比如speak freelyICQ

現在,我們來考慮考慮OUTPUT鏈。因爲很信任防火牆,所以我們允許幾乎所有離開它的包通過,而沒有阻 塞任何用戶和協議。但我們也不想讓人利用這臺機子進行IP欺騙,因此我們只放行那些從防火牆本身的IP發 出的包。爲了實現這一點,我們很可能在ACCEPT鏈中加入這樣一條規則:如果包是由防火牆的IP發出的,就 放行,否則,它們就會被OUTPUT鏈的缺省策略DROP掉。


7.2.5. 缺省策略的設置

在開始寫其他規則之前,我們先要用下面的語句建立缺省的策略:

iptables [-P {chain} {policy}]

每一條鏈的策略都是用來處理那些在相應的鏈裏沒被規則匹配的包。也就是說,如果有一個包沒有被規 則集中的任何規則匹配,那策略就有用武之地了。

Caution

要謹慎地設置其他表裏的鏈的策略,因爲它們不是用來過濾包的,這就可能引起很怪異的行爲發 生。


7.2.6. 自定義鏈的設置

現在,你對我們的防火牆應該已經有了一個很清晰的印象,心動了吧。心動不如行動,讓我們把它變爲現 實吧。這一節我們就要小心仔細地創建所有自定義鏈和鏈內的規則。

如前所述,我們要建立這幾條自定義鏈:icmp_packetstcp_packetsudp_packets allowed,其中allowed鏈是由tcp_packets鏈調用的。所有進入$INET_IFACE的ICMP包都會被重定向到icmp_packets鏈,TCP包是到 tcp_packets鏈,那UDP包自然就是udp_packets鏈了,詳細的解釋都在 INPUT chain裏。創建自定義鏈的命令還記得嗎?很簡單哦,只要使用選項-N ,再指定鏈的名字即可(不要忘了,新建的鏈都是空的),如下:

iptables [-N chain]

在下面的幾節裏,我們會詳盡地介紹上面創建的每一條鏈,以使你瞭解它們包含哪些規則、有什麼作用。


7.2.6.1. bad_tcp_packets鏈

這條鏈包含的規則檢查進入包(incoming packet)的包頭是否不正常或有沒有其他問題,並進行相應地 處理。但事實上,我們使用它只是爲了過濾掉一些特殊的包:沒有設置SYN位但又是NEW狀態的TCP包,還有那 些設置了SYN/ACK但也被認爲是NEW狀態的TCP包。這條鏈可以用來檢查所有可能的不一致的東西,比如上面的 包或者XMAS port-scans等。我們還可以爲INVALID狀態的包 增加一條規則的。

如果你想完全瞭解無SYN位的NEW狀態(NEW not SYN),可以去附錄常見 問題與解答裏看看未設置SYN的NEW狀態包一節,它介紹了未設 置SYN的NEW狀態包通過其他規則的情況。在某些情況下可以允許這種包通過,但99%的情況是我們不想讓它們 通過。因此,我們會先記錄這種包,然後再扔掉它們。

我們拒絕SYN/ACK包以NEW狀態進入的原因也是非常簡單的,深入的說明在附錄常見問題與解答NEW狀態的SYN/ACK包 裏。基本上,我們這樣做是出於對其他主機的好意,因爲我們爲他們預防了序列號預測攻擊 (sequence number prediction)。


7.2.6.2. allowed鏈

如果包是從$INET_IFACE進入的,而且是TCP包,那它就要經過tcp_packets 鏈的檢驗。如果這個連接就是衝着被允許通過的端口來的,我們還要對它進行一些檢查,以確定是否真 的要接受它。這些“最後的審判”都是在allowed鏈裏進行的。

首先,我們看看這個包是否是SYN包,如果是,它很可能是新連接的第一個包,我們當然接受了。如果不 是,那就看看包是否來自某個ESTABLISHEDRELATED狀態的 連接,是的話,就接受。ESTABLISHED狀態的連接是那種在兩個方向上都有流量存在 的連接。依據狀態機制的觀點,這個連接一定處於是ESTABLISHED狀態的,因爲我們 現在能看到這個包,說明以前肯定收到了相應的SYN包。最後一條規則將DROP所有其 他的包。當包到達最後這條規則,就幾乎意味着所有連接都不會有雙向的交流,也就是說,我們不會迴應 SYN包。當試圖用非SYN包開始新的連接時,包也會走到這條規則。不用SYN包建立新連接 沒有什麼實際的用處,當然,端口掃描要排除在外。就我知道的而言,現在沒有什麼有用的TCP/ IP程序會使用SYN包以外的包來打開一個TCP連接。因此,我們要把這樣的包DROP掉,我 有99%的把握說它們是端口掃描用的。


7.2.6.3. 處理TCP的鏈

tcp_packets鏈指定了哪些端口可從Internet訪問。但我們還要對進入的包做更多的檢查,因此, 每個包都會被髮送到上面提到的allowed鏈。

-A tcp_packets告訴iptables要在哪條鏈裏增加規則,規則被放在指定鏈的末 尾。-p TCP指定要匹配的是TCP包,-s 0/0說明要匹 配的源地址是從網絡掩碼爲0.0.0.0的地址0.0.0.0開始的,換句話說,就是所有的地址。這實際上是默認 值,我寫出來只是儘可能使你更明白。--dport 21指定目的端口,也就是說如果包是 發往端口21的,就會被匹配。如果所有的標準都匹配了,包就要被送往allowed鏈。

TCP的21號端口也是允許訪問的,也就是FTP的控制端口,它可以控制FTP連接,前面提到 過,我還允許所有RELATED狀態的連接通過。這樣,我們也就可以使用PASSIVE(主 動)和ACTIVE(被動)的連接了,當然,要事先裝載ip_conntrack_ftp模塊。如果我們不想再提供 FTP服務,就卸載ip_conntrack_ftp模塊,並把$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed 這一行從文件rc.firewall.txt裏刪掉。

22號端口是SSH使用的。如果你允許外網的如何人都能通過telnet(使用23號端口)訪問你的機 子,那你還是使用SSH吧,它的安全性要好很多。注意,你操作的是防火牆,把任何訪問權分配給除 你自己之外的人都不是什麼好主意。防火牆總是應該儘量少地暴露自己。

80是HTTP端口,也就是說你在防火牆上運行了網頁服務。如果你不提供網頁服務,就刪掉這條規 則吧。

最後我們還提供了IDENTD服務,端口是113。這個服務對某些協議是必須的,如IRC。注意,如果 你NAT一些在內網裏的主機的話,軟件oidentd也值得一用,它會把 IDENTD請求中繼給內網裏正確的機子。

如果沒有匹配上面任何一條規則,包就會被送回tcp_packets鏈的父鏈,也就是把它發到 tcp_packets鏈的那條規則所在的鏈。如果你想打開更多的端口,只要對tcp_packets鏈裏的任何 一行使用“複製、粘貼大法”,再修改一下端口號即可。


7.2.6.4. 處理UDP的鏈

如果我們在INPUT鏈中遇到了UDP包,就把它發送到udp_packets鏈。在那裏,我們 只處理UDP包,所以要用-p UDP來指定相應的協議。我們接受來自任何地址的 包,故有-s 0/0,這其實就是源地址選項的默認值,但爲了更明確,我們還是把它寫 出來了。此外,我們只接受發往特定端口的包,這些端口是我們想對Internet開放的。注意,我們不需要依 據發送端的源端口來決定是否打開某個端口,這個工作是由狀態機制完成的。如果我們想運行某個使用 UDP端口的服務(如DNS),只要開放相應的端口,其他的端口不需要打開。那些處於 ESTABLISHED狀態、正在進入防火牆的包在到達包含--state ESTABLISHED,RELATED的規則(這是 INPUT鏈裏那些“處理來自Internet的包的規則”中的第一條規則)之後就會被接受了。

我們不接受外來的以53號端口爲目的的UDP包,也就是說,我們不想接受外來的DNS查詢。 其實,規則已經寫好了,我只是把它給註釋掉了。如果你想把防火牆作爲一臺允許Internet訪問的DNS 服務器,那就把註釋符號去掉。

就我個人而言,我會打開123號端口,它對應的協議是network time protocol,簡稱NTP 。我們可以利用這個協議與某臺具有精確時間的時間服務器聯繫,以設置本機的時間。你們中的大部分 可能用不到此協議,所以我也把它註釋掉了,雖然我已經寫出了規則。

我打開了2074號端口,它是某些實時的多媒體應用程序使用的。比如speak freely ,你可以用這個程序通過音箱、麥克風或耳麥與其他人進行實時交談。如果你不需要,就把這條規則注 釋掉吧。

端口4000相應的協議是ICQ協議,由ICQ使用,世界上使用最廣泛的聊天程序之一,“地球人都知 道”。Linux上至少有2-3種不同的ICQ克隆。我想不必解釋爲什麼要開放這個端口了吧。(譯者注:國產的聊 天程序,常見的是QQ(端口8000),現在又有了UC(端口3001)等。)

如果你正在經歷日誌滿天飛的苦惱,這裏有兩個額外的規則可以使用,當然,這要看是因爲什麼引起的 了。我們這裏的第一條規則會阻塞目的端口是135到139的廣播包。大部分Microsoft使用者會用到NetBIOS SMB,而它們就使用這些廣播包。這條規則可以阻塞所有位於外網的那些Microsoft Network產 生的廣播包,我們的日誌也就可以簡潔一些了。第二條規則也是解決日誌問題,不過問題的產生者變了,這 回是外網的DHCP查詢。如果你的外網是由非交換的以太網組成的,在那裏客戶機可以通過DHCP 得到IP地址,也就是說,如果外網裏會有很多DHCP查詢廣播包,那就啓用這條規則吧。

Note

注意,我把最後這兩條規則也註釋掉了,因爲有些人可能想看看相關的記錄。如果你正經歷“合法 日誌過多”的痛苦,就試試丟棄那些包吧。其實,在INPUT鏈中,就在這兩條有關日誌的規則之前, 還有更多這種類型的規則。


7.2.6.5. 處理ICMP的鏈

現在,我們該決定可以接受哪些ICMP類型了。在INPUT鏈中,如果ICMP包是從eth0 (即本例的Internet接口)進入的,我們就要把它重定向到icmp_packets 鏈(前面提到過),以檢查是否是可以接受的類型。目前,我只接受三種ICMP包:ICMP Echo requestsTTL equals 0 during transitTTL equals 0 during reassembly。默認不 接受其他任何ICMP類型的原因是,幾乎所有其他類型的ICMP包都是RELATED狀態的,也就是說它們都會被處理 RELATED狀態的規則放行。

Note

如果一個ICMP包是用來回應“已經存在的包或流”的,那它就是與那些流相關的,也就是說,它的 狀態是RELATED。更多的信息在章節狀態機制裏。

現在來解釋一下我爲什麼只接受上面提到的三種ICMP包。Echo Request用來請求echo reply,這個操作主 要被用來ping其他的機子,以確定那些機子是否可用。如果沒有這一條規則,其他機子將不能通過ping來確 定我們是否可用。注意,有些人傾向於刪掉此規則,只是因爲他們不想被Internet看到。刪掉這個規則將會 使任何來自Internet的、對我們防火牆的ping都無效,因爲防火牆對他們完全沒有迴應。

允許超時(Time Exceeded,如TTL equals 0 during transit傳輸期間生存時間爲0和TTL equals 0 during reassembly在數據報組裝期間生存時間爲0)信息進入,我們就可以追蹤從本地到某臺 主機的路徑,或者在包的TTL爲0時,我們能得到迴應信息。比如,在我們追蹤到某臺主機的路徑時,會以 TTL = 1的包開始。當它得到第一個路由時,TTL減爲0,我們也會得到第一個路由返回的超時信息。然後 是TTL = 2的包,我們就會得到第二個路由器返回的超時信息。如此,直到得到我們的目的主機返回 的信息。這樣,我們就可以從路徑上的每一臺主機得到一個迴應,從而我們可以看到路徑上的每一臺主機, 也就可以知道路徑是斷在哪臺機子了。

完整的ICMP類型列表在附錄ICMP類型裏。關於ICMP類型的更 多信息與用法,我建議你看看下面的文章:

Note

注意,我阻塞了所有我不想接受的ICMP包,這對你的網絡來說可能會有問題,但在我這 裏,一切工作正常。


7.2.7. INPUT鏈

我寫的INPUT鏈大部分是使用其他鏈來完成這個艱難的工作的。這樣做,我們就不需要從iptables 裝載太多的規則(譯者注:這是針對裝載INPUT鏈的規則說的,因爲這時其他規則已經裝載好了),而且它在 較慢的機子上也可以工作得很好,但另一方面,這樣的機子在高負載時還是會丟棄很多包(譯者注:機子 慢,就是不行)。之所以能做到這一點,是因爲對於大量不同的包,我們通過檢查特定的細節來確定它們的 類別,再把這些包發送到相應的自定義鏈去處理。這樣,我們可以分割規則集使之包含很少的規則,每個包 要經歷的規則也就少了。從而,在過濾包時,防火牆的開銷也就小多了。

首先,我們要檢查進入的tcp包的形態是否是不正常的或我們不想要的。這個工作是這樣完成的,我們把 所有的tcp包送到bad_tcp_packets鏈,由其中的規則進行檢查,具體的描述在小節bad_tcp_packets鏈裏。

然後,我們開始處理被信任的網絡的數據傳輸。這包括所有來自“連接內網的網卡”的流量,所有來自和 發往loopback的流量(要注意,和loopback相對應的IP地址包括了所有分配給防火牆的地 址,其中也包括連接Internet的地址)。我們把處理LAN的流量的規則放在防火牆的上部,因爲我們 的局域網產生的流量要遠遠多於Internet連接。這樣,規則會更有效率,防火牆就能以較小的開銷去匹配 包,從而網絡阻塞的可能性也就減小了,而且也便於我們查看經過防火牆的包主要是什麼類型。

下面的一些規則會處理來自Internet的信息,在接觸這些規則之前,有一個相關的規則,我們可用它來減 少一些開銷。這是一個處理狀態的規則,它允許所有處於狀態ESTABLISHEDRELATED且發往 Internet接口的包進入。在allowed鏈中有一個與此類似的規則(譯者注:實在是多餘,建議大家把它拿掉 吧)。順序上,當然是INPUT鏈裏的規則先處理包了。然而,在allowed鏈裏保留--state ESTABLISHED,RELATED規則還是有一些原因的,比如,方便某些人想剪切此功 能,粘貼到其他地方。

INPUT鏈裏,我們會把從$INET_IFACE進入的所有TCP包發往tcp_packets鏈,類似地,把UDP包發往udp_packets鏈,把 ICMP包發往icmp_packets鏈。一般說來,防火牆遇到的最多的包是TCP包,其次是 UDP包,最後是ICMP包。但要注意,這只是一般情況,對你可能不適用。一樣的規則因爲順序不 同,或者說邏輯不同,效率會有很大的差別。如果規則集寫得不好,即使只有100條規則,而且有100mbit的 網卡,就算是Pentium III的機子也會吃不消的。所以你自己寫規則集時一定要注意這一點。

這裏有一條被註釋掉了規則,萬一在我們的防火牆外部有一些Microsoft網絡,我們可以啓用它來解除日 志過多的煩惱。Microsoft的客戶機有個壞習慣,就是向地址224.0.0.0/8發送大量的多播包。因此我們要有 這條規則來阻塞那些包,以免我們的日誌被它們填滿。還記得嗎?udp_packets鏈裏也有兩條類似的 規則。忘了的話,就到處理UDP的鏈看看吧。

在其他的包被INPUT鏈的策略處理之前,我們會把它們記錄下來,以便查找可能的問題或bug:它 可能就是我們不想允許它進入的那種包,也可能是對我們做了什麼壞事的用戶,還可能是防火牆的問題,如 我們阻塞了應該被放行的包。我們要了解所有的情況,這樣問題才能得以解決。我們每分鐘最多記錄3個包, 因爲我們可不想讓日誌裏記載的都是廢話。爲了容易辨別包的來源,我們還對所有的記錄設置了前綴。

所有沒被上面的規則處理的包都會被策略DROP掉。策略的設置在本章的小節缺省策略的設置裏,距離我們已經很遠嘍。


7.2.8. FORWARD鏈

在本例中,FORWARD鏈包含的規則很少。首先,我們會把所有的包發往bad_tcp_packets 鏈。此鏈我們前面提到過多次,它可以被多條鏈調用,其實它也就是爲這個目的而設計的。

之後就是FORWARD鏈的主要規則了。第一個允許所有來自$LAN_IFACE的數 據通過,沒有任何限制,也就是說,我們的LAN可自由地訪問Internet。第二個允許ESTABLISHEDRELATED狀態的包能通過防火牆。換句話說,就是 所有對我們的內網發出的連接的迴應都可以返回局域網。爲了使我們的內網能訪問Internet,這些規則是必 須的,因爲我們在前面已經把FORWARD鏈的策略設爲DROP了。這樣設置規則也 是很聰明的,因爲它在保證局域網可以訪問Internet的同時阻止了Internet對局域網的訪問。

最後我們也有一個處理日誌的規則,用來記錄沒被上面任何規則匹配的包。這樣的包很可能是形態不正常 的或者是其他問題,比如可能是黑客攻擊。這個規則與INPUT鏈中的那個類似,只是前綴不同,這裏 用的是:"IPT FORWARD packet died: "。前綴主要用來分離日誌的記錄,便於我們 查找包的來源和包頭的一些信息。


7.2.9. OUTPUT鏈

除了我幾乎沒有人把防火牆還當作工作站來使用,但正因爲這樣,我允許幾乎所有從防火牆的IP(包括 LOCALHOST_IP$LAN_IP$STATIC_IP )出發的數據,而阻塞其他情況。因爲其他任何情況都可能被人以某種方式欺騙。最後的規則還是用來 記錄那些要被策略DROP掉的包。這樣,我們就可以瞭解它們,繼而可以對產生的問題(可能是具有威脅性的 錯誤,或者是用來進行欺騙的包)採取行動。


7.2.10. PREROUTING鏈

顧名思義,PREROUTING鏈(nat表的)是在路由之前做網絡地址轉換工作的。然後,包再經過路 由,就會被送到filter表的INPUTFORWARD鏈。我們在這裏討論這個鏈的唯一原因是,我們 覺得有責任再次指出你不應該在此鏈中做任何過濾。PREROUTING鏈只會匹配流的第一個包,也就是 說,這個流的所有其他的包都不會被此鏈檢查。事實上,在這個腳本中,我們根本沒有用到PREROUTING 鏈。如果你想對一些包做DNAT操作,例如,你把web server放在了局域網內,這裏就是 你放置規則的地方。有關PREROUTING鏈的詳細信息在章節表和 鏈中。

Caution

千萬注意,PREROUTING鏈只能做網絡地址轉換,不能被用來做任何過濾,因爲每個流只有 第一個包纔會經過此鏈。


7.2.11. POSTROUTING鏈

我們最後的任務應該是構造網絡地址轉換,對吧?至少對我來說是的。我們在nat表的 POSTROUTING裏只加入了一條規則,它會對所有從Internet接口(對我來說,這是eth0)發出的 包進行NAT操作。在所有的例子腳本里,都有一些變量,它們要給以正確的配置。選項-t指定要在那個表裏插入規則,這裏是nat表。命令-A說明我們要把規則添加到 POSTROUTING鏈末尾。-o $INET_IFACE指定要匹配所有從接口INET_IFACE出去的包,這裏我們使用的是eth0。最後,我們把target設置爲SNAT。這樣,所有匹配此規則的包都會由SNAT target處理,之後,它們的源地 址就是Internet接口的地址了。不要忘了SNAT可是一定要有IP地址的,用--to-source 來設置哦。

在這個腳本中,我們選擇SNAT而不用MASQUERADE是有原因 的。主要的原因是我們的防火牆有靜態IP地址,使用SNAT會更快更有效。還有一個原因是我們要在這 個例子中展示它的作用以及怎樣使用它。如果你沒有靜態的IP地址,要想實現SNAT,還是使用MASQUERADE爲好,因爲它簡單易用,而且它可以自動獲得IP地址。當然,計算機的消耗 會多一點,但如果你使用DHCP,這樣做是很值得的。如果你想了解MASQUERADE target的表現,應該看看腳本rc.DHCP.firewall.txt


Chapter 8. 例子簡介

本章的目的是對指南提到的每個腳本都給以簡單明瞭的說明,以及提供一個關於這些腳本的框架,描述它 們提供的服務。這些腳本不是任何情況都能用的,它們可能並不符合你的意圖。也就是說,爲了能滿足你的 需要,還是要取決於你自己。在這方面,下面的內容可能會給你很大的幫助。第一小節介紹了這些腳本的結 構,你會發現我們在這些腳本里使用的處理方式還是比較容易的。


8.1. rc.firewall.txt腳本的結構

本指南所有的腳本都是依據一個特定的結構來寫的。理由嘛,就是這樣可以使它們彼此相似,便於我們查 找不同之處。本章將要對這個結構做一個很好的說明,而且還會簡單地闡述這些腳本爲什麼會按照現在這種 樣子來寫,以及我爲什麼選擇一直使用這種結構。

Note

注意,即使我選擇了這種結構,你也不一定非要用它,對你來說,它可能並不是最好的。我選擇它 只是因爲它易讀,而且能很好地符合我的邏輯。


8.1.1. 腳本結構

這就是本指南所有腳本遵循的腳本結構。如果有不同於此的地方,可能就是我出錯了,除非我特意說明爲 什麼要打破這種結構。

  1. Configuration —— 首先是一個配置選項區,裏面的變量在腳本中會用到。 幾乎任何腳本(shell-script)的第一部分都是配置選項區。

    1. Internet —— 有關Internet連接的配置。如果我們沒有任何Internet連 接,這一部分就可以跳過去。注意,相比我們列出來的,這一部分可能會包含更多小節,雖然我們這裏只有 了了幾個,但足夠應對我們已有的各種Internet連接了。

      1. DHCP —— 如果腳本用到了DHCP,我們就要在此添加相應的配置。

      2. PPPoE —— 如果想把腳本用於PPPoE連接,就要在此添加相應的配置。

    2. LAN —— 如果防火牆後有局域網,就要使用這裏的配置了。大部分情況下 都會用到這兒,因爲局域網幾乎總是存在的。

    3. DMZ —— 對非軍事區(DMZ zone)的配置。大部分腳本不會用到這個設 置,因爲這些腳本針對的主要是一些普通的家庭網絡,或小企業的網絡。

    4. Localhost —— 本地(local-host)的有關設置。雖然我把它們寫成變量 的形式,但一般不會被改變,也不應該有什麼理由要改變它們。

    5. iptables —— 有關iptables的設置。大部分情況下,這裏只設置一個變 量,用來指向iptables程序的位置。

    6. Other —— 如果還有什麼信息,首先應該把它們放在相應的小節裏,實在 沒有相應的小節,就放這兒吧。

  2. Module loading —— 腳本應該維護一個模塊列表。它分爲兩部分,第一部分 包含必需的模塊,同時第二部分要包含不必要的模塊的列表。

    Note

    注意,這些模塊可能會提高安全性,或爲管理者、客戶添加某些服務,還有一些模塊不是必需 的,但它們可能也被加入了列表。不過,在本例中,我已經注意了這個問題。

    1. Required modules —— 這裏裝載的是必要的模塊,它們可能會提高安全性 或爲管理者、客戶增加某些服務。

    2. Non-required modules —— 這裏列出的是不必要的模塊,所以它們都被注 釋掉了。如果你用到了它們提供的功能,就可以啓用它們。

  3. proc configuration —— 這兒關心的是有關proc系統的設置。如果一些選項 是必須的,我們就啓用它,如果不是,就把它註釋掉。大部分有用的proc配置都列在這兒了,但遠遠不是全 部的。

    1. Required proc configuration —— 包含了使腳本能正常工作的所有必需 的proc配置,它也可以包含一些能提高安全性或爲管理者、客戶增加特定服務的選項。

    2. Non-required proc configuration —— 這裏提到的選項不是必需的,雖 然它們可能很有用。因此,我把它們都註釋掉了。當然,這裏並沒有包括所有這樣的選項。

  4. rules set up —— 現在,應該添加規則了。我把所有的規則都明確地分配到 了與表、鏈相應的小節裏。所有自定義的規則都寫在系統內建的鏈之前(譯者注:當然要寫在前面了,因爲 後面要調用它們哦)。另外,我是按照命令iptables -L輸出的順序來安排此腳本里 表與鏈的出現順序的(譯者注:這樣,便於我們查看哦)。

    1. Filter table —— 首先是filter表,而且我們先要設置策略。

      1. Set policies —— 爲所有系統內建的鏈設置策略。通常,我會設置 DROP,對於允許使用的服務或流會在後面明確地給以ACCEPT。這樣,我們就可以方便地排除所有我們不想讓 人們使用的端口。

      2. Create user specified chains —— 在這裏創建所有以後會用到的自定 義鏈。如果沒有事先建立好,後面是不能使用它們的,所以我們要儘早地建立這些鏈。

      3. Create content in user specified chains —— 建立自定義鏈裏使用 的規則。其實你也可以在後面的某個地方寫這些規則,之所以寫在這兒,唯一的原因是這樣做規則和鏈會離 得近些,便於我們查看。

      4. INPUT chain —— 創建INPUT鏈的規則。

        Note

        從這裏開始,我就是遵循iptables -L的輸出格式來創建規則的,這 樣做的唯一原因就是爲了便於閱讀,避免混淆。

      5. FORWARD chain —— 爲FORWARD鏈創建規則。

      6. OUTPUT chain —— 爲OUTPUT鏈創建規則。其實,在這裏要建的規則很 少。

    2. nat table —— 在處理完filter表之後,該設置nat表了。我們這樣做是有 一定原因的。首先,我們不想太早地打開轉發機制(譯者注:注意,filter表設定的是過濾機制,而不是轉 發)和NAT功能,因爲它們可能導致數據會在錯誤的時間(也就是這樣的時刻:我們打開了NAT,但過濾規則 還沒有運行)通過防火牆。還有,我把nat表看作是圍繞filter表的一個層。也就是說,filter表是核心, nat表是它外部的一個層,mangle表是第二層。從某些觀點來看,這可能有點不對,但也八九不離十了。

      1. Set policies —— 與filter一樣,我們先來設置策略。一般說來,缺省 的策略,即ACCEPT,就很好。這個表不應該被用來做任何過濾,而且我們也不應該在這兒丟棄任何包,因爲 對我們假設的網絡情況來說,可能會發生一些難以應付的事情。我把策略設爲ACCEPT,因爲沒有什麼原因不 這樣做。

      2. Create user specified chains —— 在這兒創建nat表會用到的自定義 鏈。一般情況下,我沒有任何規則要在這兒建立,但我還是保留了這個小節,以防萬一罷了。注意,在被系 統內建鏈調用之前一定要建好相應的自定義鏈。

      3. Create content in user specified chains —— 建立自定義鏈的規 則。

      4. PREROUTING chain —— 要對包做DNAT操作的話,就要用到此鏈了。大部 分腳本不會用到這條鏈,或者是把裏面的規則註釋掉了,因爲我們不想在不瞭解它的情況下就在防火牆上撕 開一個大口子,這會對我們的局域網造成威脅。當然,也有一些腳本默認使用了這條鏈,因爲那些腳本的目 的就是提供這樣的服務。

      5. POSTROUTING chain —— 如果使用SNAT操作,就要在此建立規則。你可 能有一個或多個局域網需要防火牆的保護,而我就是依據這樣的情況來寫此腳本的,所以這個腳本中使用的 POSTROUTING鏈是相當實用的。大部分情況下,我們會使用SNAT target,但有些情況,如PPPoE,我們不得不 使用MASQUERADE target。

      6. OUTPUT chain —— 不管什麼腳本都幾乎不會用到這個鏈。迄今爲止,我 還沒有任何好的理由使用它,如果你有什麼理由用它了的話,麻煩你把相應的規則也給我一份,我會把它加 到本指南里的。

    3. mangle table —— 最後要做的就是處理mangle表了。通常,我不會使用這 個表,因爲一般情況下,它不會被任何人要到,除非他們有什麼特殊的需要,比如爲了隱藏一條連接後的多 臺機子,我們要統一設置TTL或TOS等。在這個腳本里,此表是空白的。但在此指南中還是有個小小的例子說 明瞭mangle表的用處。

      1. Set policies —— 設置策略。這裏的情形和nat表幾乎完全相同。這裏 不應該做過濾,也不應該丟棄任何包。在任何腳本里我都不會把mangle表的策略設爲其他的值,也不鼓勵你 這樣做。

      2. Create user specified chains —— 建立自定義鏈。我幾乎不會用到這 個鏈,所以沒有建立任何規則。保留此小節,只是已備後用。

      3. Create content in user specified chains —— 建立自定義鏈的規 則。

      4. PREROUTING —— 本指南的所有腳本都未在此鏈建立規則。

      5. INPUT chain —— 本指南的所有腳本都未在此鏈建立規則。

      6. FORWARD chain —— 本指南的所有腳本都未在此鏈建立規則。

      7. OUTPUT chain —— 本指南的所有腳本都未在此鏈建立規則。

      8. POSTROUTING chain —— 本指南的所有腳本都未在此鏈建立規則。

這應該可以較詳細地解釋每個腳本的結構是怎樣的以及它們爲什麼要使用這個結構了。

Caution

注意,上面的描述其實還是非常簡單的,應該被看作一個摘要,它簡要地解釋了腳本爲什麼要按照 這種鬆散的結構來寫。千萬注意,我可沒有說過這種結構是唯一的、最好的。


8.2. rc.firewall.txt

腳本rc.firewall.txt是核心,第七章防火牆配置實例 rc.firewall對它已經做了很詳細的解釋,其他的腳 本都是以它爲基礎得到的。這個腳本主要是針對具有兩個連接的家庭網絡而設計的,如一個局域網連接,一 個Internet連接。我們假設的情況是你有一個靜態IP地址,不需要DHCPPPP SLIP或其他什麼協議爲你動態分配IP。如果你想要的恰恰是使用這些協議的腳本,就到rc.DHCP.firewall.txt看看吧。

腳本rc.firewall.txt要完全發揮作用,系統必需要有下面列出的功能,你可 以把它們編譯進內核,也可以編譯成模塊。如果你改變了腳本,就要加入相應的功能模塊或把它們編進內 核。

  • CONFIG_NETFILTER

  • CONFIG_IP_NF_CONNTRACK

  • CONFIG_IP_NF_IPTABLES

  • CONFIG_IP_NF_MATCH_LIMIT

  • CONFIG_IP_NF_MATCH_STATE

  • CONFIG_IP_NF_FILTER

  • CONFIG_IP_NF_NAT

  • CONFIG_IP_NF_TARGET_LOG


8.3. rc.DMZ.firewall.txt

腳本rc.DMZ.firewall.txt所針對的情況 是這樣的:有一個可信任的內網,一個DMZ,還有一個Internet連接。這裏的DMZ是通過設置一對一的NAT 操作得到的,它需要IP別名(就是在一塊網卡上設置多個IP地址)的支持。我們還有其他的方法來實現 DMZ:如果你有一個整個的網段,可劃分子網,然後把某個子網分給DMZ,再爲防火牆配置相應的內網與外網 IP地址(譯者注:第一種方法是針對有多個網段的情況,即內網一個網段,DMZ一個網段,第二種方法是把一 個網段劃分成幾個子網,這樣就和第一種情況一樣了)。注意,這種方法會多消耗兩個IP,一個是網絡地 址,一個是廣播地址(譯者注:具體細節請上網搜索子網劃分的相關信息,這個指南並不包含此類信息)。 以上兩種方法用哪一個就要你自己決定了。本指南會給你實現防火牆與NAT的手段或叫做技術,但具體如何去 做,沒有完全的說明,因爲這已經超出本文的範圍了。

這個腳本需要以下模塊,也可能它們已被編譯進內核了。

  • CONFIG_NETFILTER

  • CONFIG_IP_NF_CONNTRACK

  • CONFIG_IP_NF_IPTABLES

  • CONFIG_IP_NF_MATCH_LIMIT

  • CONFIG_IP_NF_MATCH_STATE

  • CONFIG_IP_NF_FILTER

  • CONFIG_IP_NF_NAT

  • CONFIG_IP_NF_TARGET_LOG

從圖中可以看出,此腳本假設你有兩個內網,一個是可信任的內網,使用地址192.168.0.0/24,另一個是 DMZ(我們正是對它做一對一的NAT),使用地址192.168.1.0/24。如果有人從Internet向我們的DNS_IP發送一個包,我們就要對它使用DNAT,之後,此包的目的地址就指向DMZ 裏的DNS服務器了,它也就可以到達真正的DNS服務器。否則,DNS服務器不會看到這個包,也就沒有應答之說 了。下面是實現上述DNAT功能的語句:

$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d 
$DNS_IP \
--dport 53 -j DNAT --to-destination $DMZ_DNS_IP
    

我們可以看出,這個規則要放在nat表的PREROUTING鏈中,包要滿足的條件是:使用 TCP協議且使用53號端口,從接口$INET_IFACE進入,而且要以$DNS_IP爲目的。被匹配的包要交給DNAT target來處理,它會把包的目的地址 改爲由--to-destination指定的地址$DMZ_DNS_IP。這就是 DNAT的工作流程。當相應的應答包被髮送到防火牆時,會自動地被un-DNAT。

現在,你應該完全可以讀懂這個腳本了。如果有什麼你不明白的東西在腳本的其他部分沒有被用到,那可 能就是我的錯誤了,要告訴我哦。


8.4. rc.DHCP.firewall.txt

腳本rc.DHCP.firewall.txt適用於那些 使用DHCPPPPSLIP連接Internet的情況,它和原始的腳本rc.firewall.txt幾乎一樣,主要的區別在於這裏不再使用變量STATIC_IP。原因很簡單了,就是它不能和動態的IP一起使用。此腳本相對於原始腳本的 改變是很少的,但還是有一些人發信問我做了什麼改變。經過大家的考驗,這個腳本應該是一個很好的解決 方案了。

它需要如下功能模塊。

  • CONFIG_NETFILTER

  • CONFIG_IP_NF_CONNTRACK

  • CONFIG_IP_NF_IPTABLES

  • CONFIG_IP_NF_MATCH_LIMIT

  • CONFIG_IP_NF_MATCH_STATE

  • CONFIG_IP_NF_FILTER

  • CONFIG_IP_NF_NAT

  • CONFIG_IP_NF_TARGET_MASQUERADE

  • CONFIG_IP_NF_TARGET_LOG

我做的改變主要是刪除了變量STATIC_IP以及和它相關的所有東西。以前,主要 的過濾工作是基於變量STATIC_IP的,現在是INET_IFACE 了。也就是說,在這個腳本里,我們不再把-d $STATIC_IP作爲過濾的條件,而是用 -i $INET_IFACE。這幾乎是唯一的改變,也是必需的改變。

可還是有一些問題要考慮。現在,我們不能再在INPUT鏈依據某些條件,比如--in-interface $LAN_IFACE --dst $INET_IP來進行過濾(譯者注:因爲這時已無固定 的INET_IP)。這強迫我們只能基於Internet接口進行包的過濾,在這種情況下,內網必須訪問那個可變的 Internet的IP。這會出現一些問題,有個例子可以說明這一點,就是我們在防火牆上運行HTTP服務。如果我 們訪問這個網站(其中,主頁包含了一個指向HTTP服務器的靜態連接,這可能是某個動態的DNS解決方案), 問題就暴露了。經過NAT操作的機子會向DNS查詢HTTP服務器的IP,然後再試着訪問這 個IP。萬一我們是基於接口和IP做的過濾,這臺機子就不能訪問到HTTP了,因爲INPUT鏈會 DROP掉這個包(譯者注:還是因爲Internet接口的IP不固定)。在某種情況下,這也會發生在你有靜態IP的 時候,但在那種情況下,我們可以增加一條規則,以檢查LAN接口的包是否是發往INET_IP的,若是,則ACCEPT

如果你看過以前的內容,得到或寫一個可以獲取動態IP的腳本可能會是個解決問題的好辦法。比如,我們 可以寫一個腳本,它緊隨着Internet連接的啓動而運行,而且它能從命令ifconfig的 輸出中提取IP,再把這個IP賦給某個變量。較好的辦法是使用一些程序自帶的腳本,如 pppd帶的腳本ip-up。也有一些網站,如linuxguruz.org,提供了很多有用的 腳本,你可以在附錄其他資源和鏈接找到它的鏈接。

Note

這個腳本比rc.firewall.txt的安全性要差一點。我明確地建議你儘可 能使用後者,因爲前者的開放性大了點,所以外部攻擊的威脅就大了。

還有一種方法可獲得IP,就是在腳本里加上類似這樣的語句:

INET_IP=`ifconfig $INET_IFACE | grep inet | cut -d : -f 2 | 
\
cut -d ' ' -f 1`
    

上面這句話的作用是從ifconfig的輸出裏提取接口$INET_IFACE的IP,再賦給$INET_IP。更好的辦法是使用腳本 retreiveip.txt。但要注意,這個方法可能會引起一些不正常的情況,比如使防火牆和內網之間已有的 連接停止。下面就說明一下最常見的問題。

  1. 如果這個腳本的代碼是在另一個腳本內運行的,而那個腳本又是由PPP daemon啓動的,就會因 爲NEW not SYN rules(具體信息查看未設置SYN的NEW狀態包)的原因而 掛起所以當前活動的連接。如果你刪掉那個規則,可能會沒有事,但還是不保險。

  2. 如果你不想改動已有的規則,而又要添加或刪除規則,還要不損害已有的規則,這就沒法做了。比如, 你又想阻塞所有局域網裏的機子訪問防火牆,又想讓它們能控制防火牆上的PPP daemon,如果不刪除 那個用來阻塞的規則,怎麼能完成這樣的事?

  3. 事情可能也不必這麼複雜,就像上面說的,這會導致一些安全問題。但如果這個腳本能保持簡單,維 持規則的順序與發現問題都是很容易的。


8.5. rc.UTIN.firewall.txt

腳本rc.UTIN.firewall.txt適用於這樣 的情況:我們不信任任何與防火牆連接的網絡,包括內網。我們只允許內網使用POP3HTTP 和FTP。至於從Internet來的連接,權限和其他腳本一樣。

此腳本需要以下功能模塊。

  • CONFIG_NETFILTER

  • CONFIG_IP_NF_CONNTRACK

  • CONFIG_IP_NF_IPTABLES

  • CONFIG_IP_NF_MATCH_LIMIT

  • CONFIG_IP_NF_MATCH_STATE

  • CONFIG_IP_NF_FILTER

  • CONFIG_IP_NF_NAT

  • CONFIG_IP_NF_TARGET_LOG

這個腳本遵循的原則是不要相信任何人,包括我們自己的員工。這是個令人悲痛的現實,大部分破壞和攻 擊確實是來自我們內部的。這個腳本只是在加強防火牆方面給了你一個例子。它和rc.firewall.txt並沒有太多的不同,只是少了一些允許通行的規則。


8.6. rc.test-iptables.txt

這個腳本用來測試iptables裏所有的鏈。當然,這要根據你的配置情況做些操作,如打開ip_forwarding或是設置masquerading,等等。只要你的安裝了基本的 iptables,就可以使用它。其實這個腳本只使用了LOG,以便能記錄所有的ping請求 與應答。通過這種方式,我們就可以瞭解哪些鏈被穿越了以及被穿越的順序。使用方法如下,先運行這個腳 本,再發佈一個ping命令,如:

ping -c 1 host.on.the.internet

    

然後用命令tail -n 0 -f /var/log/messages就可看到用了哪些鏈以及是什麼順 序,除非記錄因某些原因被替換了。

Note

此腳本僅僅是爲測試而寫的。也就是說,不要使用類似這樣的規則,它記錄某一類包的所有信息, 這會很快地佔滿你的日誌分區,而且它會成爲一個有效的DoS攻擊。它還可能導致在最初的DoS攻擊之後,無 法記錄真正的攻擊信息。


8.7. rc.flush-iptables.txt

rc.flush-iptables.txt不應該被稱作 腳本,它只是重置並清空所有的表、鏈。它先把filter表的INPUTOUTPUT FORWARD鏈的策略設爲缺省的ACCEPT,然後是nat表的PREROUTINGPOSTROUTINGOUTPUT鏈。我們這樣做就不必爲被關閉的連接和沒有通過的包而操心。 這個腳本就是爲防火牆設置和除錯用的,因此我們只關心打開所有的東西並恢復它們的缺省值就行了。

之後,我們清空filter表裏所有的鏈,緊接着是NAT表的。這樣,就不會有什麼不應該存 在的規則了。這個做完後就該刪除filter表和NAT表裏的自定義鏈了。這時,腳本的工作就應 該完成了。當然,如果你用到了mangle表,可以在這個腳本里添加相應的清空規則。(譯者注:其實 作者已經這樣做了)

Note

最後再說明一下,有些人寫信建議我把這個腳本放到rc.firewall腳本里面,而且是用Red Hat Linux腳本的語法,這樣當rc.firewall啓動時,這個腳本也可以啓動。但我不會這樣做的,因爲這是一個指 南,主要是用來學習iptables的使用方法的,不應該有過多的shell腳本特有的語法。加入shell腳本特有的 語法會使閱讀的難度大大增加,這就遠離了我的初衷。這個指南是按照易讀的標準來寫的,以後我會繼續這 樣做。


8.8. Limit-match.txt

這個腳本是用來測試limit match的,也會讓你明白limit match是如何工作的。裝入這個腳本,再用不同 的時間間隔發送ping數據包,可以看出哪個包可以通過,這些包又是以什麼頻率通過的。你應該可以看出, 在limit的burst值再次到達之前,所有的echo replies都會被阻塞。


8.9. Pid-owner.txt

這個腳本說明了如何使用PID owner match。它其實什麼都沒做,但你可以運行一下,命令iptables -L -v的輸出會說明它確實匹配了些東西。


8.10. Sid-owner.txt

說明SID owner match如何使用的一個例子。同樣,它也是什麼都沒做,但你可以運行一下,命令iptables -L -v的輸出會說明它確實匹配了些東西。


8.11. Ttl-inc.txt

一個小小的例子,說明了如何隱藏我們的防火牆或路由器,以使跟蹤路由程序看不到,這樣就可以對可能 的攻擊者隱藏很多信息。


8.12. Iptables-save ruleset

這只是一個輸出的例子,它在規則的保存與恢復裏被用來說明 iptables-save命令是如何使用的。所以,它沒有任何用處,只是一個參考而已。


附錄 A. 常用命令詳解

A.1. 查看當前規則集的命令

查看當前正在使用的規則集是一個十分常用的操作,使用iptables的什麼命令還 記得嗎?我們可是在規則是如何練成的這一章裏介紹過啊,雖然 到時說得簡單了點。再複習一下吧,命令語法如下:

iptables -L

這個命令會儘可能地以易讀的形式顯示當前正在使用的規則集。比如,它會盡量用文件/etc/services裏相應的名字表示端口號,用相應的DNS記錄表示IP地址。但後者可能 會導致一些問題,例如,它想盡力把LAN的IP地址(如192.168.1.1)解析 成相應的名字。但192.168.0.0/16這個網段是私有的,也就是說,它只能 用在局域網裏,而不能在Internet裏使用,所以它不會被Internet上的DNS服務器解析。因此,當解析這個地 址時,命令就好像停在那兒了。爲了避免這種情況的發生,我們就要使用選項:

iptables -L -n

如果你想看看每個策略或每條規則、每條鏈的簡單流量統計,可以在上面的命令後再加一個verbose標 志,如下:

iptables -L -n -v

不要忘了,iptables -L命令還可以查看nat表和mangle表的內容哦(更不要忘 了,默認的表是filter),只需要使用-t選項,比如我們只想看nat表的規則,就用下面的命令:

iptables -L -t nat

/proc裏,可能還有一些文件你會感興趣。比如,你可以在連接跟蹤記錄表 裏看到當前有哪些連接。這個表包含了當前的所有連接,你還可以通過它瞭解到每個連接處於什麼狀態。要 注意,這個表是不能編輯的,即使可以,也不應該更改它。可以用下面的命令查看這個表:

cat /proc/net/ip_conntrack | less

此命令會顯示當前所有被跟蹤的連接,但要讀懂那些記錄可是有些難度哦。


A.2. 修正和清空iptables的命令

即使你把iptables弄的一塌糊塗,我們也有非常有效的命令來處理,而不必重新啓動計算機。我接到過很 多關於這個問題的詢問,所以我想最好在這兒回答一下。如果你增加的規則有問題,要想刪掉它,只要把命 令中的-A改爲-D即可。這樣,iptables就會找到那個錯誤的 規則並刪掉它,但如果在你的規則裏有好幾條同樣的規則,它只能刪掉找到的第一條。如果你不想這樣的事 情發生,那就試試用序號來刪除。如,你想刪除INPUT鏈的第10條規則,可以使用 iptables -D INPUT 10

還有一種情況,就是要清空整個鏈,這就要使用選項-F。比如,我們要清空整個 INPUT鏈,使用的命令就是iptables -F INPUT。但是要注意,選項-F並不改變鏈的缺省策 略。所以,如果被我們清空的那條INPUT鏈的策略是DROP,它還是會阻塞所有的包。那怎麼才能重置策略呢? 還記得策略DROP是如何設置的吧,還是用那個方法啊。比如,我們把INPUT鏈的策略改爲ACCEPT,就用iptables -P INPUT ACCEPT

我已經寫了一個用來清空並重置iptables的腳本,叫做rc.flush- iptables.txt(附錄裏有它的代碼),在你寫自己的防火 牆腳本時,很可能會用到。但如果你在mangle表裏亂試亂改而導致問題的話,這個腳本就幫不上忙了。因爲 在腳本rc.firewall.txt裏,我沒有用到mangle表,所以在 rc.flush-iptables.txt裏也就沒有添加相應的恢復功能。


附錄 B. 常見問題與解答

B.1. 模塊裝載問題

裝載模塊時,你可能會遇到幾個問題,比如,有錯誤提示說明沒有你指定名字的那種模塊:

insmod: iptable_filter: no module by 
that name found

這個提示是無關緊要的,因爲那些模塊很有可能已經被靜態地編譯進內核了。當你遇到這個信息時,這是 你應該首先想到的。至於是否真的如我們所想,最簡單的測試方就是敲一個用到那個模塊功能的命令試試。 對於上面的情況,可能是filter表沒有裝入,從而就沒有相應的功能,當然不能使用filter表了。爲了檢查 filter表是否裝入,可以用下面的命令來試試:

iptables -t filter -L
   

這個命令會輸出filter表裏所有的鏈,或者是運行失敗,給出錯誤提示信息。如果一切正常,輸出結果類 似下面的情況,當然,這還要看你是否已經在filter表裏加入了規則(譯者注:在這個例子裏,表是空 的)。

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
    

如果你確實沒有裝載filter表,得到的就是如下信息:

iptables 
v1.2.5: can't initialize iptables table `filter': Table \
     does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
    

這個問題就有些嚴重了,從此提示中我們能得到兩個信息:第一,我們確實沒有把相應的功能編譯進內核 裏;第二,在模塊一般應在的目錄中沒有找到這個模塊。這意味着問題是,你或者忘記了裝載想用的模塊, 或者沒有用depmod -a命令更新模塊數據庫,或者沒有把相應的功能編譯進內核(不 論是靜態的還是作爲模塊)。當然還可能是其他原因,但這些是主要的,不管怎樣,大部分原因是很容易解 決的。比如,第一個問題可以簡單地通過在內核源碼目錄裏運行make modules_install 命令來解決,這當然是有前提的,就是源碼已經編譯(compile)而且模塊已經構建(build)。第二個 問題的解決辦法也很簡單,只要運行一下depmod -a命令,之後再看看能否正常工作即可。第三個問題有點超出我們的範圍了,而 且這個問題或多或少會讓你感到發暈。更多的信息可以在Linux文檔計劃裏找 到。

在運行iptables時,你還可能得到另外一個錯誤信息:

iptables: No chain/target/match by that name
   

這說明你要用的鏈或target、或match不存在,原因有很多,但最普遍的是你拼錯了名字。當你想使用一 個不可用的模塊時也會產生這種錯誤。模塊之所以不可用,可能是因爲你沒有裝載正確的模塊,或者內核裏 不包含那個模塊,或者是iptables自動裝載模塊時失敗了。通常,你不止應該考慮上面提到的所有解決辦 法,還要考慮規則中target的拼寫錯誤,或者其他的原因。


B.2. 未設置SYN的NEW狀態包

iptables有個“特點”沒有被很好地給以說明,所以很多人(當然,也包括我)都忽視了它。這個“特 點”就是:如果你使用狀態NEW,那麼未設置SYN的包也會通過防火牆。之所以有這個特點,是因爲在某些情況下, 我們想把那樣的包看作某個(比如是和另一個防火牆有關的)已處於ESTABLISHED狀 態的連接的一部分。這個特點使擁有兩個或更多的防火牆協同工作成爲可能,而且可使數據在服務器間無丟 失的傳輸,如輔助防火牆可以接受子網的防火牆的操作。但它也會導致這樣的事情:狀態 NEW會允許幾乎所有的TCP連接進入,而不管是否有3次握手。爲了處理這個問題,我們需要在防火牆的 INPUT鏈、OUTPUT鏈和FORWARD鏈加入如下規則(譯者注:此規則作者稱爲“NEW not SYN rules”,下一小節 還會提到):

$IPTABLES -A 
INPUT -p tcp ! --syn -m state --state NEW -j LOG \
     --log-prefix "New not syn:"
$IPTABLES -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
    

Caution

警告,在Netfilter/iptables項目中,這個特點所 擁有的行爲缺少文檔說明,更明確的說,在你的防火牆上,它是一個很不安全的因素。

注意,這個規則用於microsoft的TCP/IP(微軟實現的TCP/IP就是不行,至少現在不行)產生的包時還是 有些問題。如果包是由microsoft的產品生成的,且被標爲狀態NEW,那麼就會被此規 則記錄然後丟棄。看起來規則工作很正常啊,是吧。但問題就出在這兒了,因爲連接無法中斷了。這個問題 出現在關閉連接時,在最後一個包即FIN/ACK包發出後,Netfilter的狀態機制就會關 閉連接、刪除連接跟蹤表裏的相應記錄。但就在這時,Microsoft那不完善的程序會發送另外一個包,這個包 就是那種未設置SYN且被認爲是NEW狀態的包,因此它就會被上面的規則匹配。換句話說,就是對這個規則不 需要過於關注,如果你很在意它,就在規則里加入選項--log-headers吧。這樣,你 就可以把包頭記錄下來,從而可以更好地瞭解相應的包。

對於這個規則,還有一些已知的問題。比如,某個連接(比如是從LAN發出的)已經連接到防火牆,而且 有個腳本要在啓動PPP時激活。當你啓動PPP連接時,剛纔提到的那個連接可能就會被幹掉(be killed)。當 然,這只會在特定的情況下才能發生,就是你把conntrack和nat作爲模塊運行,並且每次運行那個腳本時這 兩個模塊都要被裝入和卸載。如果你在防火牆之外的機子上運行telnet,而且又通過這個telnet連接運行腳 本rc.firewall.txt,也會導致上面的問題。爲了能簡單地表達這個問題,你先準 備一個telnet連接,或其他的流連接,再運行連接跟蹤模塊,然後裝入上面的規則,最後,試着用telnet clientdaemon發送一些數據。效果應該出來了,連接 跟蹤代碼會認爲這個連接是非法的,因爲在此之前,它沒有看到任何方向有包發出,更爲嚴重的是現在連接 上有了未設置SYN的包,因爲剛纔由telnet client或daemon發出的包肯定不是這個連接的第一個包。因此, 上面的規則就起作用了,也就是說,這個包會被記錄下來,然後被無情地扔掉,從而連接就會中斷。


B.3. NEW狀態的SYN/ACK包

某些,TCP欺騙攻擊所用的技術叫做序列號預測(Sequence Number Prediction)。在這類攻擊中,攻擊 者利用另一臺機子的IP訪問攻擊對象(譯者注:這就是爲什麼叫欺騙的原因了,攻擊者是想假冒另一臺被攻 擊對象信任的機子,以達到欺騙攻擊對象的目的),然後再試着預測攻擊對象使用什麼序列號。

我們來看看典型的使用序列號預測技術的欺騙是如何實現的,參與者:攻擊者[A](attacker)試圖假裝 另一臺機子[O](other host)向受害者[V](victim)發送數據。

  1. [A]以[O]的IP爲源地址向[V]發SYN。

  2. [V]向[O]迴應SYN/ACK。

  3. 現在,若[O]以RST迴應這個未知的SYN/ACK,攻擊就失敗了,但如果[O]已經沒有這個能力了呢?比如它 早已被另外的攻擊(如SYN flood)降服,或者被關閉,或者它的RST包被防火牆拒絕。

  4. 如果[O]沒能破壞這條連接,而且[A]猜對了序列號,那它就能以[O]的身份和[V]交談了。

只要我們沒能在第三步以RST迴應那個未知的SYN/ACK包,[V]就會被攻擊,而且我們還會被連累(譯者 注:因爲我們本身也被攻擊了,而且還可能會成爲攻擊者的替罪羊被起訴,嗚嗚,好慘)。所以,爲安全起 見,我們應該以正確的方式向[V]發送一個RST包。如果我們使用類似“NEW not SYN rules”(譯者注:在上 一小節中)的規則,SYN/ACK包就可以被丟棄了。因此,我們在bad_tcp_packets鏈中加入瞭如下規則:

iptables -A 
bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset
   

這樣,你想成爲上面那個[O]的機會就很少了(譯者注:作者好幽默啊,我們可不想成爲被別人利用的對 象),而且這條規則在絕大部分情況下是安全的,不會有什麼副作用,但多個防火牆要協同工作的情況要除 外。那種情況下,防火牆之間會經常傳遞、接受包或流,有了這條規則,有些連接可能會被阻塞,即使是合 法的連接。這條規則的存在還產生了另外一問題,就是有幾個portscan(端口掃描器)會看到我們的防火 牆,但好在僅此而已。


B.4. 使用私有IP地址的ISP

我的一位朋友告訴我說有些事我完全忘記了,從那時起,我就把這一節加上了。你剛上網時連接的網絡是 ISP提供的,但某些愚蠢的ISP在那個網絡裏使用的是私有地址,而那是IANA專門分 配給局域網使用的。Swedish Internet Service Provider和電話壟斷企業Telia就是這樣做的,例如在DNS服 務器上,他們使用的IP地址段就是10.x.x.x。我們最容易遇到的問題是,在這個腳本里,爲了防止被欺騙, 不允許從10.x.x.x發出的連接來訪問我們。不幸的是,對於上面的例子,爲了DNS能正常地被訪問,我們不得 不把規則的放寬鬆一些。也就是說,我們或者在剛纔提到的那條防止欺騙的規則上面增加一條規則(如 下),或者是把那條規則註釋掉:

/usr/local/sbin/iptables -t nat -I PREROUTING -i 
eth1 -s \
     10.0.0.1/32 -j ACCEPT
   

我願意對這些ISP再多費些脣舌。這些IP地址不是爲了讓你象這樣愚蠢的使用而分配給你的,至少我知道 不是這樣的。對於一個大集團的站點或者是我們自己的家庭網絡來說,這樣用是很合適的,但你不能只因爲 你們的一些原因就強迫我們把自己公示於天下。


B.5. 放行DHCP數據

一旦你瞭解DHCP是如何工作的,就會知道這其實是一個很簡單的任務。但你必須小心處理到底讓誰進入、 不讓誰進入。首先,我們要明白DHCP是工作在UDP協議之上的,所以,UDP協議是我們期望的第一個條件。其 次,我們應該檢查是從那個接口接收和發送請求的。例如,如果我們設置了DHCP使用接口eth0,那就要阻塞 eth1上的DHCP請求。爲了讓規則再詳細些,我們只需打開(allow)DHCP實際使用的UDP端口,一般都是67和 68。這兩個端口是標準定義,我們就用它們來匹配被允許的包。現在,規則應該是這個樣子的:

$IPTABLES  -I INPUT -i $LAN_IFACE -p udp --dport 67:68 --sport \
     67:68 -j ACCEPT
   

注意,現在我們能夠接受所有來自和發往UDP端口67、68的數據,好像不太安全,但這並不是多大的問 題,因爲這條規則只允許從67或68端口連接的主機才能訪問。當然,此規則還可以更嚴謹一些,但也應該足 夠接受所有的DHCP請求和更新,而不至於需要在防火牆上開一個大洞。如果你很在意現在的規則是否很寬 鬆,你當然可以寫一個限制條件更緊的。


B.6. 關於mIRC DCC的問題

mIRC使用一個特殊的設定,它可以使mIRC連接穿過防火牆,也可以使DCC連接能在防火牆不瞭解它的情況 下正常工作。如果此選項和iptables還有ip_conntrack_irc模塊與ip_nat_irc模塊一起使用,那mIRC就不能 工作了。問題在於mIRC會自動對包進行NAT操作,這樣當包到達防火牆後,防火牆就完全不知道該對包做什麼 了,也不知道該怎麼做。如果是防火牆來處理,它只是簡單地用自己的IP去詢問IRC服務器,然後用那個地址 發送DCC請求。mIRC不希望防火牆自作聰明地以這種方式代替自己來處理這個包。

打開“I am behind a firewall”(我在防火牆後)這個配置選項並且使用ip_conntrack_irc和 ip_nat_irc模塊,會導致Netfilter建立包含“Forged DCC send packet”的記錄。

最簡單的解決辦法是不要選中mIRC的那個選項而讓iptables來做這些工作。意思就是要明確地告訴mIRC, 它不是在防火牆後面的。


附錄 C. ICMP類型

這是一個完整的ICMP類型的列表:

Table C-1. ICMP類型

TYPE CODE Description Query Error
0 0 Echo Reply——回顯應答(Ping應答) x  
3 0 Network Unreachable——網絡不可達   x
3 1 Host Unreachable——主機不可達   x
3 2 Protocol Unreachable——協議不可達   x
3 3 Port Unreachable——端口不可達   x
3 4 Fragmentation needed but no frag. bit set——需要進行分片但設置不分片比特   x
3 5 Source routing failed——源站選路失敗   x
3 6 Destination network unknown——目的網絡未知   x
3 7 Destination host unknown——目的主機未知   x
3 8 Source host isolated (obsolete)——源主機被隔離(作廢 不用)   x
3 9 Destination network administratively prohibited——目的網絡被強制禁止   x
3 10 Destination host administratively prohibited——目的主機被強制禁止   x
3 11 Network unreachable for TOS——由於服務類型TOS,網絡 不可達   x
3 12 Host unreachable for TOS——由於服務類型TOS,主機不可 達   x
3 13 Communication administratively prohibited by filtering——由於過濾,通信被強制禁止   x
3 14 Host precedence violation——主機越權   x
3 15 Precedence cutoff in effect——優先中止生效   x
4 0 Source quench——源端被關閉(基本流控制)    
5 0 Redirect for network——對網絡重定向    
5 1 Redirect for host——對主機重定向    
5 2 Redirect for TOS and network——對服務類型和網絡重定 向    
5 3 Redirect for TOS and host——對服務類型和主機重定向    
8 0 Echo request——回顯請求(Ping請求) x  
9 0 Router advertisement——路由器通告    
10 0 Route solicitation——路由器請求    
11 0 TTL equals 0 during transit——傳輸期間生存時間爲0   x
11 1 TTL equals 0 during reassembly——在數據報組裝期間生 存時間爲0   x
12 0 IP header bad (catchall error)——壞的IP首部(包括各 種差錯)   x
12 1 Required options missing——缺少必需的選項   x
13 0 Timestamp request (obsolete)——時間戳請求(作廢不 用) x  
14   Timestamp reply (obsolete)——時間戳應答(作廢不用) x  
15 0 Information request (obsolete)——信息請求(作廢不 用) x  
16 0 Information reply (obsolete)——信息應答(作廢不用) x  
17 0 Address mask request——地址掩碼請求 x  
18 0 Address mask reply——地址掩碼應答 x  

附錄 D. 其他資源和鏈接

這裏有一些資源的鏈接,我從這些地方獲得了不少信息,相信對你應該也很有幫助:

  • ip-sysctl.txt ——來自內核2.4.14,一篇關於IP網絡控制參數的短小精幹的參考文 章。

  • The Internet Control Message Protocol ——一篇很好的詳細介紹ICMP協議的文章, 作者是Ralph Walden。

  • RFC 792 - Internet Control Message Protocol ——ICMP的權威文件,如果你想找關 於ICMP協議的信息,這是你應該首先想到的地方。作者:J. Postel。

  • RFC 793 - Transmission Control Protocol ——TCP的權威文件,從1981年開始,它就 成爲TCP的規範了。只要你想學習TCP,就一定要讀讀這篇技術性很強的文章。作者:J. Postel

  • ip_dynaddr.txt ——來自內核2.4.14,關於通過sysctl和proc文件系統設置ip_dynaddr 的參考文章。

  • iptables.8 ——iptables 1.2.4的幫助,這是HTML版本的。在你讀寫iptables規則時, 這是一個很好的參考,你應該把它帶在身邊。

  • Firewall rules table ——由Stuart Clark給出的一個小小的PDF文件,裏面是防火牆 配置的參考樣式,對你書寫自己的防火牆規則很有幫助。

  • http://www.netfilter.org/ ——Netfilteriptables的官方網站,是每一個打算在linux裏配置iptables和 Netfilter的人必到之處。

  • http://www.netfilter.org/documentation/index.html#FAQ ——官方的Netfilter Frequently Asked Questions,是開始瞭解iptablesNetfilter的好去處。

  • http://www.netfilter.org/unreliable-guides/packet-filtering-HOWTO/index.html ——非常好的包過濾基礎指南,介紹瞭如何使用iptables進行包過濾。作者是iptables Netfilter的核心開發者之一Rusty Russell。

  • http://www.netfilter.org/unreliable-guides/NAT-HOWTO/index.html ——介紹網絡 地址轉換的很好的指南。作者是iptablesNetfilter的核心 開發者之一Rusty Russell。

  • http://www.netfilter.org/unreliable-guides/netfilter-hacking-HOWTO/index.html ——只有很少的文章介紹如何在Netfilteriptables 的用戶空間、內核空間裏編寫代碼,這是其中一篇。作者還是Rusty Russell。

  • http://www.linuxguruz.org/iptables/ ——很好的資源鏈接網頁,裏包含了Internet 上大部分關於iptables的鏈接,尤其是它還包含了很多爲不同用處而寫的iptables腳本的鏈接。

  • http://www.islandsoft.net/veerapen.html ——這篇文章討論了iptables自動增強堅 固性的可能,以及如何通過很少的改動使你的計算機能自動地把敵對站點加入iptables的一個特殊的“禁止 列表”。

  • /etc/protocols ——此文件是從Slackware發行版中抽取 的。你可以利用此文件找到協議所對應的協議號,如IP、ICMP或TCP對應的號碼。

  • /etc/services ——此文件也是從Slackware發行版中抽取 的。它非常值得一讀,你可以大致瞭解什麼協議使用什麼端口。

  • Internet Engineering Task Force ——IETF是制定和維護互聯網標準的最大的組織之一,很多大企業集團和個人都是它的成員, 他們共同工作是爲了確保Internet的互操作性。

  • Linux Advanced Routing and Traffic Control HOW-TO ——此站點主要討論Linux高級路由和流量控制,這個HOW-TO是關於Linux高 級路由的最大的也是最好的一篇文章。作者是Bert Hubert。

  • Paksecured Linux Kernel patches ——此站點包含了Matthew G. Marsh寫的所有內核補丁,FTOS patch就在這兒。

  • ULOGD project page ——ULOGD的站點。

  • The Linux Documentation Project ——有關Linux的文檔的極好(可以說是最好)的站點。有關Linux的很多較大的文檔這兒都 有,如果TLDP裏沒有,你就要好好地在網絡上搜索一下了。如果你想了解多一些,就去看看吧。

  • http://kalamazoolinux.org/presentations/20010417/conntrack.html ——這篇文章 裏有一個極其精彩的例子,它是用來展示conntrack模塊以及它在Netfilter裏的工作的。如果你想多看一些 有關conntrack的文章,這一篇應該是必讀的。

  • http://www.docum.org/ ——此站點包含了全部 有關CBQ(Class Based Queue)、tcip命令的資料,這是 很少的幾個這樣的站點中的一個。此站點由Stef Coene維護。

  • http://lists.samba.org/mailman/listinfo/netfilter ——Netfilter的官方郵件列 表,非常有用哦。萬一你遇到了一些問題,而這篇文章或這裏提到的一些鏈接解決不了,它就是你的救世主 了。

當然,資源不止我上面提到的這些,還有iptables的源碼和文檔,及很多可以幫 助你的朋友。


附錄 E. 鳴謝

很多朋友在我寫這篇文章時給了我熱心的幫助,我要感謝他們:

  • Fabrice Marie,對我糟糕的語法和拼寫做了大量的訂正,還用make文件等工具 把這篇指南轉換成了DocBook。

  • Marc Boucher,在狀態匹配代碼的使用方面給了我很多幫助。

  • Frode E. Nyboe,大幅度改善了rc.firewall的規則,當我要重寫這個規則集、 把多個表的遍歷(the multiple table traversing)引入同一份文件時,給了我很多靈感。

  • Chapman BradAlexander W. Janssen,開始時,我對包如何穿越nat和filter 表的理解是錯誤的,是他們使我瞭解到這一點的,而且他們還給了我正確的順序。

  • Michiel BrandenburgMyles Uyema,幫我解決了一些狀態匹配代碼,並讓它正常問 題。

  • Kent `Artech' Stahre,幫我繪製圖形,還幫我查錯。

  • Anders 'DeZENT' Johansson,提示我有些古怪的ISP在Internet上使用保留的 網址,至少對他來說遇到了這樣的情況。

  • Jeremy `Spliffy' Smith,提示我有些內容容易使大家糊塗,還幫我進行了測試 和查錯。

還有很多人,我和他們進行過討論,也請教過他們,這裏不能一一提及了。


Appendix F. History

Version 1.1.19 (21 May 2003)
.
By:  Oskar Andreasson
Contributors: Peter van Kampen,  Xavier Bartol, Jon Anderson, Thorsten Bremer 
and Spanish Translation Team.

Version 1.1.18 (24  Apr 2003)
.
By: Oskar Andreasson
Contributors:  Stuart Clark, Robert P. J. Day,  Mark Orenstein and Edmond Shwayri.

Version 1.1.17  (6  Apr 2003)
.
By: Oskar Andreasson
Contributors:  Geraldo Amaral Filho, Ondrej Suchy, Dino Conti,  Robert P. J. Day, 
Velev Dimo, Spencer Rouser,  Daveonos, Amanda Hickman, Olle Jonsson and 
Bengt Aspvall.

Version 1.1.16 (16 Dec 2002)
.
By:  Oskar Andreasson
Contributors: Clemens Schwaighower,  Uwe Dippel and Dave Wreski.

Version 1.1.15 (13  Nov 2002)
.
By: Oskar Andreasson
Contributors:  Mark Sonarte, A. Lester Buck, Robert P. J. Day,  Togan Muftuoglu,
Antony Stone, Matthew F.  Barnes and Otto Matejka. 

Version 1.1.14 (14  Oct 2002)
.
By: Oskar Andreasson
Contributors:  Carol Anne, Manuel Minzoni, Yves Soun, Miernik,  Uwe Dippel, 
Dave Klipec and Eddy L O Jansson. 

Version 1.1.13 (22 Aug 2002)
http://iptables- tutorial.haringstad.com
By: Oskar Andreasson
Contributors:  Tons of people reporting bad HTML version.

Version 1.1.12 (19 Aug 2002)
http://www.netfilter.org/tutorial/
By:  Oskar Andreasson
Contributors: Peter Schubnell, Stephen J.  Lawrence, Uwe Dippel, Bradley 
Dilger, Vegard Engen,  Clifford Kite, Alessandro Oliveira, Tony Earnshaw, 
Harald Welte, Nick Andrew and Stepan Kasal.

Version 1.1.11 (27 May 2002)
http://www.netfilter.org/tutorial/
By:  Oskar Andreasson
Contributors: Steve Hnizdur,  Lonni Friedman,  Jelle Kalf, Harald Welte, 
Valentina Barrios and Tony Earnshaw.

Version 1.1.10 (12  April 2002)
http://www.boingworld.com/workshops/linux/iptables-tutorial/
By:  Oskar Andreasson
Contributors: Jelle Kalf,  Theodore Alexandrov, Paul Corbett, Rodrigo 
Rubira Branco, Alistair Tonner, Matthew G. Marsh,  Uwe Dippel, Evan 
Nemerson and Marcel J.E. Mol.  

Version 1.1.9 (21 March 2002)
http://www.boingworld.com/workshops/linux/iptables-tutorial/
By: Oskar Andreasson 
Contributors: Vince Herried, Togan Muftuoglu, Galen Johnson,  Kelly Ashe, Janne
Johansson, Thomas Smets, Peter Horst,  Mitch Landers, Neil Jolly, Jelle Kalf,
Jason Lam and Evan Nemerson.

Version 1.1.8 (5  March 2002)
http://www.boingworld.com/workshops/linux/iptables-tutorial/
By:  Oskar Andreasson

Version 1.1.7 (4 February 2002)
http://www.boingworld.com/workshops/linux/iptables-tutorial/
By: Oskar Andreasson 
Contributors: Parimi Ravi, Phil Schultz, Steven McClintoc,  Bill Dossett,
Dave Wreski, Erik Sj鰈und,  Adam Mansbridge, Vasoo Veerapen, Aladdin and
Rusty Russell.

Version 1.1.6 (7 December 2001)
http://people.unix-fu.org/andreasson/
By: Oskar Andreasson
Contributors:  Jim Ramsey, Phil Schultz, G鰎an B錱e, Doug Monroe,  Jasper
Aikema, Kurt Lieber, Chris Tallon, Chris Martin,  Jonas Pasche, Jan
Labanowski, Rodrigo R. Branco,  Jacco van Koll and Dave Wreski.

Version 1.1.5  (14 November 2001)
http://people.unix-fu.org/andreasson/
By:  Oskar Andreasson
Contributors: Fabrice Marie,  Merijn Schering and Kurt Lieber.

Version 1.1.4 (6  November 2001)
http://people.unix-fu.org/andreasson
By:  Oskar Andreasson
Contributors: Stig W. Jensen,  Steve Hnizdur, Chris Pluta and Kurt Lieber.

Version 1.1.3 (9 October 2001)
http://people.unix-fu.org/andreasson
By: Oskar Andreasson
Contributors: Joni Chu, N.Emile Akabi- Davis and Jelle Kalf.

Version 1.1.2 (29  September 2001)
http://people.unix-fu.org/andreasson
By:  Oskar Andreasson

Version 1.1.1 (26 September 2001)
http://people.unix-fu.org/andreasson
By: Oskar Andreasson
Contributors:  Dave Richardson.

Version 1.1.0 (15 September 2001)
http://people.unix-fu.org/andreasson
By: Oskar Andreasson

Version 1.0.9 (9 September 2001)
http://people.unix-fu.org/andreasson 
By: Oskar Andreasson

Version 1.0.8 (7 September 2001) 
http://people.unix-fu.org/andreasson
By: Oskar Andreasson

Version 1.0.7 (23 August 2001)
http://people.unix-fu.org/andreasson
By: Oskar Andreasson
Contributors: Fabrice Marie.

Version 1.0.6
http://people.unix-fu.org/andreasson
By: Oskar Andreasson 

Version 1.0.5
http://people.unix-fu.org/andreasson
By:  Oskar Andreasson
Contributors: Fabrice Marie.
   


Appendix G. GNU Free Documentation License

Version 1.1, March 2000

Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.


0. PREAMBLE

The purpose of this License is to make a manual, textbook, or other written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.


1. APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you".

A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License.

The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License.

A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not "Transparent" is called "Opaque".

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only.

The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.


2. VERBATIM COPYING

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.


3. COPYING IN QUANTITY

If you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.


4. MODIFICATIONS

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

  1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.

  2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has less than five).

  3. State on the Title page the name of the publisher of the Modified Version, as the publisher.

  4. Preserve all the copyright notices of the Document.

  5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.

  6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.

  7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.

  8. Include an unaltered copy of this License.

  9. Preserve the section entitled "History", and its title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.

  10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.

  11. In any section entitled "Acknowledgements" or "Dedications", preserve the section's title, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.

  12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.

  13. Delete any section entitled "Endorsements". Such a section may not be included in the Modified Version.

  14. Do not retitle any existing section as "Endorsements" or to conflict in title with any Invariant Section.

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.

You may add a section entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.


5. COMBINING DOCUMENTS

You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections entitled "History" in the various original documents, forming one section entitled "History"; likewise combine any sections entitled "Acknowledgements", and any sections entitled "Dedications". You must delete all sections entitled "Endorsements."


6. COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.


7. AGGREGATION WITH INDEPENDENT WORKS

A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an "aggregate", and this License does not apply to the other self-contained works thus compiled with the Document, on account of their being thus compiled, if they are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.


8. TRANSLATION

Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License. In case of a disagreement between the translation and the original English version of this License, the original English version will prevail.


9. TERMINATION

You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.


10. FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.


How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled "GNU Free Documentation License".

If you have no Invariant Sections, write "with no Invariant Sections" instead of saying which ones are invariant. If you have no Front-Cover Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being LIST"; likewise for Back-Cover Texts.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.


Appendix H. GNU General Public License

Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.


0. Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.

Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.


1. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  1. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".

    Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.

  2. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.

    You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

  3. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

    1. You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.

    2. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.

    3. If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)

    These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

    Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.

    In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

  4. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:

    1. Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

    2. Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,

    3. Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)

    The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

    If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.

  5. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

  6. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.

  7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.

  8. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.

    If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.

    It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

    This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

    If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

    Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.

  10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

  11. NO WARRANTY

    BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS


2. How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.

<one line to give the program's name and a bri e f idea of what it does.>
Copyright (C) <year>   <name of author>
    

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when it starts in an interactive mode:

Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:

Yoyodyne, Inc.,  hereby disclaims all copyright interest in the progra m 
`Gnomovision' (which makes passes at compilers)  written by James Hacker.
  

<signature of Ty Coon>, 1 April 1989 
Ty Coon, President of Vice
  

This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.


附錄 I. 示例腳本的代碼

I.1. rc.firewall腳本代碼

#!/bin/sh
#
# rc.firewall - Initial SIMPLE IP Firewall script for Linux 2.4.x and iptables
#
# Copyright (C) 2001  Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA  02111-1307   USA
#

###########################################################################
#
# 1. Configuration options.
#

#
# 1.1 Internet Configuration.
#

INET_IP="194.236.50.155"
INET_IFACE="eth0"
INET_BROADCAST="194.236.50.255"

#
# 1.1.1 DHCP
#

#
# 1.1.2 PPPoE
#

#
# 1.2 Local Area Network configuration.
#
# your LAN's IP range and localhost IP. /24 means to only use the first 24
# bits of the 32 bit IP address. the same as netmask 255.255.255.0
#

LAN_IP="192.168.0.2"
LAN_IP_RANGE="192.168.0.0/16"
LAN_IFACE="eth1"

#
# 1.3 DMZ Configuration.
#

#
# 1.4 Localhost Configuration.
#

LO_IFACE="lo"
LO_IP="127.0.0.1"

#
# 1.5 IPTables Configuration.
#

IPTABLES="/usr/sbin/iptables"

#
# 1.6 Other Configuration.
#

###########################################################################
#
# 2. Module loading.
#

#
# Needed to initially load modules
#

/sbin/depmod -a

#
# 2.1 Required modules
#

/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state

#
# 2.2 Non-Required modules
#

#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc

###########################################################################
#
# 3. /proc set up.
#

#
# 3.1 Required proc configuration
#

echo "1" > /proc/sys/net/ipv4/ip_forward

#
# 3.2 Non-Required proc configuration
#

#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr

###########################################################################
#
# 4. rules set up.
#

######
# 4.1 Filter table
#

#
# 4.1.1 Set policies
#

$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP

#
# 4.1.2 Create userspecified chains
#

#
# Create chain for bad tcp packets
#

$IPTABLES -N bad_tcp_packets

#
# Create separate chains for ICMP, TCP and UDP to traverse
#

$IPTABLES -N allowed
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets

#
# 4.1.3 Create content in userspecified chains
#

#
# bad_tcp_packets chain
#

$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset 
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP

#
# allowed chain
#

$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP

#
# TCP rules
#

$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j allowed

#
# UDP ports
#

#$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 53 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 123 -j ACCEPT
$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 2074 -j ACCEPT
$IPTABLES -A udp_packets -p UDP -s 0/0 --destination-port 4000 -j ACCEPT

#
# In Microsoft Networks you will be swamped by broadcasts. These lines 
# will prevent them from showing up in the logs.
#

#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d $INET_BROADCAST \
#--destination-port 135:139 -j DROP

#
# If we get DHCP requests from the Outside of our network, our logs will 
# be swamped as well. This rule will block them from getting logged.
#

#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--destination-port 67:68 -j DROP

#
# ICMP rules
#

$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT

#
# 4.1.4 INPUT chain
#

#
# Bad TCP packets we don't want.
#

$IPTABLES -A INPUT -p tcp -j bad_tcp_packets

#
# Rules for special networks not part of the Internet
#

$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT

#
# Special rule for DHCP requests from LAN, which are not caught properly
# otherwise.
#

$IPTABLES -A INPUT -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j ACCEPT

#
# Rules for incoming packets from the internet.
#

$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \
-j ACCEPT
$IPTABLES -A INPUT -p TCP -i $INET_IFACE -j tcp_packets
$IPTABLES -A INPUT -p UDP -i $INET_IFACE -j udp_packets
$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets

#
# If you have a Microsoft Network on the outside of your firewall, you may 
# also get flooded by Multicasts. We drop them so we do not get flooded by 
# logs
#

#$IPTABLES -A INPUT -i $INET_IFACE -d 224.0.0.0/8 -j DROP

#
# Log weird packets that don't match the above.
#

$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT packet died: "

#
# 4.1.5 FORWARD chain
#

#
# Bad TCP packets we don't want
#

$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets

#
# Accept the packets we actually want to forward
#

$IPTABLES -A FORWARD -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

#
# Log weird packets that don't match the above.
#

$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD packet died: "

#
# 4.1.6 OUTPUT chain
#

#
# Bad TCP packets we don't want.
#

$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets

#
# Special OUTPUT rules to decide which IP's to allow.
#

$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT

#
# Log weird packets that don't match the above.
#

$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "

######
# 4.2 nat table
#

#
# 4.2.1 Set policies
#

#
# 4.2.2 Create user specified chains
#

#
# 4.2.3 Create content in user specified chains
#

#
# 4.2.4 PREROUTING chain
#

#
# 4.2.5 POSTROUTING chain
#

#
# Enable simple IP Forwarding and Network Address Translation
#

$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP

#
# 4.2.6 OUTPUT chain
#

######
# 4.3 mangle table
#

#
# 4.3.1 Set policies
#

#
# 4.3.2 Create user specified chains
#

#
# 4.3.3 Create content in user specified chains
#

#
# 4.3.4 PREROUTING chain
#

#
# 4.3.5 INPUT chain
#

#
# 4.3.6 FORWARD chain
#

#
# 4.3.7 OUTPUT chain
#

#
# 4.3.8 POSTROUTING chain
#

    


I.2. rc.DMZ.firewall腳本代碼

#!/bin/sh
#
# rc.DMZ.firewall - DMZ IP Firewall script for Linux 2.4.x and iptables
#
# Copyright (C) 2001  Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA  02111-1307   USA
#

###########################################################################
#
# 1. Configuration options.
#

#
# 1.1 Internet Configuration.
#

INET_IP="194.236.50.152"
HTTP_IP="194.236.50.153"
DNS_IP="194.236.50.154"
INET_IFACE="eth0"

#
# 1.1.1 DHCP
#

#
# 1.1.2 PPPoE
#

#
# 1.2 Local Area Network configuration.
#
# your LAN's IP range and localhost IP. /24 means to only use the first 24
# bits of the 32 bit IP address. the same as netmask 255.255.255.0
#

LAN_IP="192.168.0.1"
LAN_IFACE="eth1"

#
# 1.3 DMZ Configuration.
#

DMZ_HTTP_IP="192.168.1.2"
DMZ_DNS_IP="192.168.1.3"
DMZ_IP="192.168.1.1"
DMZ_IFACE="eth2"

#
# 1.4 Localhost Configuration.
#

LO_IFACE="lo"
LO_IP="127.0.0.1"

#
# 1.5 IPTables Configuration.
#

IPTABLES="/usr/sbin/iptables"

#
# 1.6 Other Configuration.
#

###########################################################################
#
# 2. Module loading.
#

#
# Needed to initially load modules
#
/sbin/depmod -a



#
# 2.1 Required modules
#

/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state

#
# 2.2 Non-Required modules
#

#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc

###########################################################################
#
# 3. /proc set up.
#

#
# 3.1 Required proc configuration
#

echo "1" > /proc/sys/net/ipv4/ip_forward

#
# 3.2 Non-Required proc configuration
#

#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr

###########################################################################
#
# 4. rules set up.
#

######
# 4.1 Filter table
#

#
# 4.1.1 Set policies
#

$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP

#
# 4.1.2 Create userspecified chains
#

#
# Create chain for bad tcp packets
#

$IPTABLES -N bad_tcp_packets

#
# Create separate chains for ICMP, TCP and UDP to traverse
#

$IPTABLES -N allowed
$IPTABLES -N icmp_packets

#
# 4.1.3 Create content in userspecified chains
#

#
# bad_tcp_packets chain
#

$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP

#
# allowed chain
#

$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP

#
# ICMP rules
#

# Changed rules totally
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT

#
# 4.1.4 INPUT chain
#

#
# Bad TCP packets we don't want
#

$IPTABLES -A INPUT -p tcp -j bad_tcp_packets

#
# Packets from the Internet to this box
#

$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets

#
# Packets from LAN, DMZ or LOCALHOST
#

#
# From DMZ Interface to DMZ firewall IP
#

$IPTABLES -A INPUT -p ALL -i $DMZ_IFACE -d $DMZ_IP -j ACCEPT

#
# From LAN Interface to LAN firewall IP
#

$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -d $LAN_IP -j ACCEPT

#
# From Localhost interface to Localhost IP's
#

$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT

#
# Special rule for DHCP requests from LAN, which are not caught properly
# otherwise.
#

$IPTABLES -A INPUT -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j ACCEPT

#
# All established and related packets incoming from the internet to the
# firewall
#

$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \
-j ACCEPT

#
# In Microsoft Networks you will be swamped by broadcasts. These lines
# will prevent them from showing up in the logs.
#

#$IPTABLES -A INPUT -p UDP -i $INET_IFACE -d $INET_BROADCAST \
#--destination-port 135:139 -j DROP

#
# If we get DHCP requests from the Outside of our network, our logs will
# be swamped as well. This rule will block them from getting logged.
#

#$IPTABLES -A INPUT -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--destination-port 67:68 -j DROP

#
# If you have a Microsoft Network on the outside of your firewall, you may
# also get flooded by Multicasts. We drop them so we do not get flooded by
# logs
#

#$IPTABLES -A INPUT -i $INET_IFACE -d 224.0.0.0/8 -j DROP

#
# Log weird packets that don't match the above.
#

$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT packet died: "

#
# 4.1.5 FORWARD chain
#

#
# Bad TCP packets we don't want
#

$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets


#
# DMZ section
#
# General rules
#

$IPTABLES -A FORWARD -i $DMZ_IFACE -o $INET_IFACE -j ACCEPT
$IPTABLES -A FORWARD -i $INET_IFACE -o $DMZ_IFACE -m state \
--state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -o $DMZ_IFACE -j ACCEPT
$IPTABLES -A FORWARD -i $DMZ_IFACE -o $LAN_IFACE -m state \
--state ESTABLISHED,RELATED -j ACCEPT

#
# HTTP server
#

$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_HTTP_IP \
--dport 80 -j allowed
$IPTABLES -A FORWARD -p ICMP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_HTTP_IP \
-j icmp_packets

#
# DNS server
#

$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_DNS_IP \
--dport 53 -j allowed
$IPTABLES -A FORWARD -p UDP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_DNS_IP \
--dport 53 -j ACCEPT
$IPTABLES -A FORWARD -p ICMP -i $INET_IFACE -o $DMZ_IFACE -d $DMZ_DNS_IP \
-j icmp_packets

#
# LAN section
#

$IPTABLES -A FORWARD -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

#
# Log weird packets that don't match the above.
#

$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD packet died: "

#
# 4.1.6 OUTPUT chain
#

#
# Bad TCP packets we don't want.
#

$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets

#
# Special OUTPUT rules to decide which IP's to allow.
#

$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT

#
# Log weird packets that don't match the above.
#

$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "

######
# 4.2 nat table
#

#
# 4.2.1 Set policies
#

#
# 4.2.2 Create user specified chains
#

#
# 4.2.3 Create content in user specified chains
#

#
# 4.2.4 PREROUTING chain
#

$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $HTTP_IP --dport 80 \
-j DNAT --to-destination $DMZ_HTTP_IP
$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $DNS_IP --dport 53 \
-j DNAT --to-destination $DMZ_DNS_IP
$IPTABLES -t nat -A PREROUTING -p UDP -i $INET_IFACE -d $DNS_IP --dport 53 \
-j DNAT --to-destination $DMZ_DNS_IP

#
# 4.2.5 POSTROUTING chain
#

#
# Enable simple IP Forwarding and Network Address Translation
#

$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP

#
# 4.2.6 OUTPUT chain
#

######
# 4.3 mangle table
#

#
# 4.3.1 Set policies
#

#
# 4.3.2 Create user specified chains
#

#
# 4.3.3 Create content in user specified chains
#

#
# 4.3.4 PREROUTING chain
#

#
# 4.3.5 INPUT chain
#

#
# 4.3.6 FORWARD chain
#

#
# 4.3.7 OUTPUT chain
#

#
# 4.3.8 POSTROUTING chain
#

    


I.3. rc.UTIN.firewall腳本代碼

#!/bin/sh
#
# rc.firewall - UTIN Firewall script for Linux 2.4.x and iptables
#
# Copyright (C) 2001  Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA  02111-1307   USA
#

###########################################################################
#
# 1. Configuration options.
#

#
# 1.1 Internet Configuration.
#

INET_IP="194.236.50.155"
INET_IFACE="eth0"
INET_BROADCAST="194.236.50.255"

#
# 1.1.1 DHCP
#

#
# 1.1.2 PPPoE
#

#
# 1.2 Local Area Network configuration.
#
# your LAN's IP range and localhost IP. /24 means to only use the first 24
# bits of the 32 bit IP address. the same as netmask 255.255.255.0
#

LAN_IP="192.168.0.2"
LAN_IP_RANGE="192.168.0.0/16"
LAN_IFACE="eth1"

#
# 1.3 DMZ Configuration.
#

#
# 1.4 Localhost Configuration.
#

LO_IFACE="lo"
LO_IP="127.0.0.1"

#
# 1.5 IPTables Configuration.
#

IPTABLES="/usr/sbin/iptables"

#
# 1.6 Other Configuration.
#

###########################################################################
#
# 2. Module loading.
#

#
# Needed to initially load modules
#

/sbin/depmod -a

#
# 2.1 Required modules
#

/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_state

#
# 2.2 Non-Required modules
#

#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc

###########################################################################
#
# 3. /proc set up.
#

#
# 3.1 Required proc configuration
#

echo "1" > /proc/sys/net/ipv4/ip_forward

#
# 3.2 Non-Required proc configuration
#

#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr

###########################################################################
#
# 4. rules set up.
#

######
# 4.1 Filter table
#

#
# 4.1.1 Set policies
#

$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP

#
# 4.1.2 Create userspecified chains
#

#
# Create chain for bad tcp packets
#

$IPTABLES -N bad_tcp_packets

#
# Create separate chains for ICMP, TCP and UDP to traverse
#

$IPTABLES -N allowed
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets

#
# 4.1.3 Create content in userspecified chains
#

#
# bad_tcp_packets chain
#

$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP

#
# allowed chain
#

$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP

#
# TCP rules
#

$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j allowed

#
# UDP ports
#

#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 53 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 123 -j ACCEPT
$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 2074 -j ACCEPT
$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 4000 -j ACCEPT

#
# In Microsoft Networks you will be swamped by broadcasts. These lines
# will prevent them from showing up in the logs.
#

#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d $INET_BROADCAST \
#--destination-port 135:139 -j DROP

#
# If we get DHCP requests from the Outside of our network, our logs will
# be swamped as well. This rule will block them from getting logged.
#

#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--destination-port 67:68 -j DROP

#
# ICMP rules
#

$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT

#
# 4.1.4 INPUT chain
#

#
# Bad TCP packets we don't want.
#

$IPTABLES -A INPUT -p tcp -j bad_tcp_packets

#
# Rules for special networks not part of the Internet
#

$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT

#
# Rules for incoming packets from anywhere.
#

$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \
-j ACCEPT
$IPTABLES -A INPUT -p TCP -j tcp_packets
$IPTABLES -A INPUT -p UDP -j udp_packets
$IPTABLES -A INPUT -p ICMP -j icmp_packets

#
# If you have a Microsoft Network on the outside of your firewall, you may
# also get flooded by Multicasts. We drop them so we do not get flooded by
# logs
#

#$IPTABLES -A INPUT -i $INET_IFACE -d 224.0.0.0/8 -j DROP

#
# Log weird packets that don't match the above.
#

$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT packet died: "

#
# 4.1.5 FORWARD chain
#

#
# Bad TCP packets we don't want
#

$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets

#
# Accept the packets we actually want to forward
#

$IPTABLES -A FORWARD -p tcp --dport 21 -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 80 -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 110 -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

#
# Log weird packets that don't match the above.
#

$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD packet died: "

#
# 4.1.6 OUTPUT chain
#

#
# Bad TCP packets we don't want.
#

$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets

#
# Special OUTPUT rules to decide which IP's to allow.
#

$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT

#
# Log weird packets that don't match the above.
#

$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "

######
# 4.2 nat table
#

#
# 4.2.1 Set policies
#

#
# 4.2.2 Create user specified chains
#

#
# 4.2.3 Create content in user specified chains
#

#
# 4.2.4 PREROUTING chain
#

#
# 4.2.5 POSTROUTING chain
#

#
# Enable simple IP Forwarding and Network Address Translation
#

$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP

#
# 4.2.6 OUTPUT chain
#

######
# 4.3 mangle table
#

#
# 4.3.1 Set policies
#

#
# 4.3.2 Create user specified chains
#

#
# 4.3.3 Create content in user specified chains
#

#
# 4.3.4 PREROUTING chain
#

#
# 4.3.5 INPUT chain
#

#
# 4.3.6 FORWARD chain
#

#
# 4.3.7 OUTPUT chain
#

#
# 4.3.8 POSTROUTING chain
#

    


I.4. rc.DHCP.firewall腳本代碼

#!/bin/sh
#
# rc.firewall - DHCP IP Firewall script for Linux 2.4.x and iptables
#
# Copyright (C) 2001  Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA  02111-1307   USA
#

###########################################################################
#
# 1. Configuration options.
#

#
# 1.1 Internet Configuration.
#

INET_IFACE="eth0"

#
# 1.1.1 DHCP
#

#
# Information pertaining to DHCP over the Internet, if needed.
#
# Set DHCP variable to no if you don't get IP from DHCP. If you get DHCP
# over the Internet set this variable to yes, and set up the proper IP
# address for the DHCP server in the DHCP_SERVER variable.
#

DHCP="no"
DHCP_SERVER="195.22.90.65"

#
# 1.1.2 PPPoE
#

# Configuration options pertaining to PPPoE.
#
# If you have problem with your PPPoE connection, such as large mails not
# getting through while small mail get through properly etc, you may set
# this option to "yes" which may fix the problem. This option will set a
# rule in the PREROUTING chain of the mangle table which will clamp
# (resize) all routed packets to PMTU (Path Maximum Transmit Unit).
#
# Note that it is better to set this up in the PPPoE package itself, since
# the PPPoE configuration option will give less overhead.
#

PPPOE_PMTU="no"

#
# 1.2 Local Area Network configuration.
#
# your LAN's IP range and localhost IP. /24 means to only use the first 24
# bits of the 32 bit IP address. the same as netmask 255.255.255.0
#

LAN_IP="192.168.0.2"
LAN_IP_RANGE="192.168.0.0/16"
LAN_IFACE="eth1"

#
# 1.3 DMZ Configuration.
#

#
# 1.4 Localhost Configuration.
#

LO_IFACE="lo"
LO_IP="127.0.0.1"

#
# 1.5 IPTables Configuration.
#

IPTABLES="/usr/sbin/iptables"

#
# 1.6 Other Configuration.
#

###########################################################################
#
# 2. Module loading.
#

#
# Needed to initially load modules
#

/sbin/depmod -a

#
# 2.1 Required modules
#

/sbin/modprobe ip_conntrack
/sbin/modprobe ip_tables
/sbin/modprobe iptable_filter
/sbin/modprobe iptable_mangle
/sbin/modprobe iptable_nat
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_limit
/sbin/modprobe ipt_MASQUERADE

#
# 2.2 Non-Required modules
#

#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc

###########################################################################
#
# 3. /proc set up.
#

#
# 3.1 Required proc configuration
#

echo "1" > /proc/sys/net/ipv4/ip_forward

#
# 3.2 Non-Required proc configuration
#

#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
#echo "1" > /proc/sys/net/ipv4/ip_dynaddr

###########################################################################
#
# 4. rules set up.
#

######
# 4.1 Filter table
#

#
# 4.1.1 Set policies
#

$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP

#
# 4.1.2 Create userspecified chains
#

#
# Create chain for bad tcp packets
#

$IPTABLES -N bad_tcp_packets

#
# Create separate chains for ICMP, TCP and UDP to traverse
#

$IPTABLES -N allowed
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets

#
# 4.1.3 Create content in userspecified chains
#

#
# bad_tcp_packets chain
#

$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP

#
# allowed chain
#

$IPTABLES -A allowed -p TCP --syn -j ACCEPT
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed -p TCP -j DROP

#
# TCP rules
#

$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 21 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 22 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 80 -j allowed
$IPTABLES -A tcp_packets -p TCP -s 0/0 --dport 113 -j allowed

#
# UDP ports
#

$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 53 -j ACCEPT
if [ $DHCP == "yes" ] ; then
 $IPTABLES -A udp_packets -p UDP -s $DHCP_SERVER --sport 67 \
 --dport 68 -j ACCEPT
fi

#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 53 -j ACCEPT
#$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 123 -j ACCEPT
$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 2074 -j ACCEPT
$IPTABLES -A udp_packets -p UDP -s 0/0 --source-port 4000 -j ACCEPT

#
# In Microsoft Networks you will be swamped by broadcasts. These lines
# will prevent them from showing up in the logs.
#

#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE \
#--destination-port 135:139 -j DROP

#
# If we get DHCP requests from the Outside of our network, our logs will
# be swamped as well. This rule will block them from getting logged.
#

#$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
#--destination-port 67:68 -j DROP

#
# ICMP rules
#

$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT

#
# 4.1.4 INPUT chain
#

#
# Bad TCP packets we don't want.
#

$IPTABLES -A INPUT -p tcp -j bad_tcp_packets

#
# Rules for special networks not part of the Internet
#

$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -j ACCEPT

#
# Special rule for DHCP requests from LAN, which are not caught properly 
# otherwise.
#

$IPTABLES -A INPUT -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j ACCEPT

#
# Rules for incoming packets from the internet.
#

$IPTABLES -A INPUT -p ALL -i $INET_IFACE -m state --state ESTABLISHED,RELATED \
-j ACCEPT
$IPTABLES -A INPUT -p TCP -i $INET_IFACE -j tcp_packets
$IPTABLES -A INPUT -p UDP -i $INET_IFACE -j udp_packets
$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets

#
# If you have a Microsoft Network on the outside of your firewall, you may
# also get flooded by Multicasts. We drop them so we do not get flooded by
# logs
#

#$IPTABLES -A INPUT -i $INET_IFACE -d 224.0.0.0/8 -j DROP

#
# Log weird packets that don't match the above.
#

$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT packet died: "

#
# 4.1.5 FORWARD chain
#

#
# Bad TCP packets we don't want
#

$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets

#
# Accept the packets we actually want to forward
#

$IPTABLES -A FORWARD -i $LAN_IFACE -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

#
# Log weird packets that don't match the above.
#

$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD packet died: "

#
# 4.1.6 OUTPUT chain
#

#
# Bad TCP packets we don't want.
#

$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets

#
# Special OUTPUT rules to decide which IP's to allow.
#

$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -o $INET_IFACE -j ACCEPT

#
# Log weird packets that don't match the above.
#

$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "

######
# 4.2 nat table
#

#
# 4.2.1 Set policies
#

#
# 4.2.2 Create user specified chains
#

#
# 4.2.3 Create content in user specified chains
#

#
# 4.2.4 PREROUTING chain
#

#
# 4.2.5 POSTROUTING chain
#

if [ $PPPOE_PMTU == "yes" ] ; then
 $IPTABLES -t nat -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN \
 -j TCPMSS --clamp-mss-to-pmtu
fi
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j MASQUERADE

#
# 4.2.6 OUTPUT chain
#

######
# 4.3 mangle table
#

#
# 4.3.1 Set policies
#

#
# 4.3.2 Create user specified chains
#

#
# 4.3.3 Create content in user specified chains
#

#
# 4.3.4 PREROUTING chain
#

#
# 4.3.5 INPUT chain
#

#
# 4.3.6 FORWARD chain
#

#
# 4.3.7 OUTPUT chain
#

#
# 4.3.8 POSTROUTING chain
#

    


I.5. rc.flush-iptables腳本代碼

#!/bin/sh
# 
# rc.flush-iptables - Resets iptables to default values. 
# 
# Copyright (C) 2001  Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA  02111-1307   USA

#
# Configurations
#
IPTABLES="/usr/sbin/iptables"

#
# reset the default policies in the filter table.
#
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT

#
# reset the default policies in the nat table.
#
$IPTABLES -t nat -P PREROUTING ACCEPT
$IPTABLES -t nat -P POSTROUTING ACCEPT
$IPTABLES -t nat -P OUTPUT ACCEPT

#
# reset the default policies in the mangle table.
#
$IPTABLES -t mangle -P PREROUTING ACCEPT
$IPTABLES -t mangle -P OUTPUT ACCEPT

#
# flush all the rules in the filter and nat tables.
#
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
#
# erase all chains that's not default in filter and nat table.
#
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X



    


I.6. rc.test-iptables腳本代碼

#!/bin/bash
#
# rc.test-iptables - test script for iptables chains and tables.
#
# Copyright (C) 2001  Oskar Andreasson <bluefluxATkoffeinDOTnet>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program or from the site that you downloaded it
# from; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA  02111-1307   USA
#

#
# Filter table, all chains
#
iptables -t filter -A INPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="filter INPUT:"
iptables -t filter -A INPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="filter INPUT:"
iptables -t filter -A OUTPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="filter OUTPUT:"
iptables -t filter -A OUTPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="filter OUTPUT:"
iptables -t filter -A FORWARD -p icmp --icmp-type echo-request \
-j LOG --log-prefix="filter FORWARD:"
iptables -t filter -A FORWARD -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="filter FORWARD:"

#
# NAT table, all chains except OUTPUT which don't work.
#
iptables -t nat -A PREROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="nat PREROUTING:"
iptables -t nat -A PREROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="nat PREROUTING:"
iptables -t nat -A POSTROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="nat POSTROUTING:"
iptables -t nat -A POSTROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="nat POSTROUTING:"
iptables -t nat -A OUTPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="nat OUTPUT:"
iptables -t nat -A OUTPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="nat OUTPUT:"

#
# Mangle table, all chains
#
iptables -t mangle -A PREROUTING -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle PREROUTING:"
iptables -t mangle -A PREROUTING -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle PREROUTING:"
iptables -t mangle -I FORWARD 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle FORWARD:"
iptables -t mangle -I FORWARD 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle FORWARD:"
iptables -t mangle -I INPUT 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle INPUT:"
iptables -t mangle -I INPUT 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle INPUT:"
iptables -t mangle -A OUTPUT -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle OUTPUT:"
iptables -t mangle -A OUTPUT -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle OUTPUT:"
iptables -t mangle -I POSTROUTING 1 -p icmp --icmp-type echo-request \
-j LOG --log-prefix="mangle POSTROUTING:"
iptables -t mangle -I POSTROUTING 1 -p icmp --icmp-type echo-reply \
-j LOG --log-prefix="mangle POSTROUTING:"


發佈了37 篇原創文章 · 獲贊 19 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章