使用 iptables 建置 Linux 防火牆

作者:李忠憲 shane@mail.spps.tp.edu.tw

2002/11/28

2003/09/26第二次修訂

2004/04/21第三次修訂

2004/12/13增補磁片與USB防火牆單元

壹、什麼是防火牆

防火牆是一套能夠在兩個或兩個以上的網路之間,明顯區隔出實體線路連線的軟硬體設備組合。被區隔開來的網路,可以透過封包轉送技術來相互通訊,透過防火牆的安全管理機制,可以決定哪些資料可以流通,哪些資料無法流通,藉此達到網路安全保護的目的。

防火牆產品可以概略歸類為硬體式防火牆和軟體式防火牆,但實際上無論是硬體式或軟體式防火牆,它們都需要使用硬體來作為連線介接,也需要使用軟體來設定安全政策,嚴格說兩者間的差別並不太大。我們只能從使用的硬體與作業系統來加以區分,硬體式防火牆是使用專有的硬體,而軟體式防火牆則使用一般的電腦硬體,硬體式防火牆使用專有的作業系統,而軟體式防火牆則使用一般的作業系統。

防火牆依照其運作方式來分類,可以區分為封包過濾式防火牆 (Packet Filter) 、應用層閘道式防火牆 (Application-Level Gateway,也有人把它稱為 Proxy 防火牆)、電路層閘道式防火牆 (Circuit-Level Gateway)。其中被廣為採用的是封包過濾式防火牆,本文要介紹的 iptables 防火牆就是屬於這一種。

封包過濾是最早被實作出來的防火牆技術,它是在 TCP/IP 四層架構下的 IP 層中運作。封包過濾器的功能主要是檢查通過的每一個 IP 資料封包,如果其標頭中所含的資料內容符合過濾條件的設定就進行進一步的處理,主要的處理方式包含:放行(accept)、丟棄(drop)或拒絕(reject)。要進行封包過濾,防火牆必須要能分析通過封包的來源 IP 與目的地 IP,還必須能檢查封包類型、來源埠號與目的埠號、封包流向、封包進入防火牆的網卡介面、TCP的連線狀態等資料。

防火牆由於種種理由價格一直居高不下,對於貧窮的中小學來講要採購一台防火牆,簡直是不可能的任務,而由於 Linux 的風行,使用 Linux 來充作軟體式防火牆,似乎是不錯的解決之道,本文擬介紹以 Linux 上最新最強大的 iptables 防火牆軟體,建置出適合學校使用的過濾規則,讓缺錢的學校能有一套好用的防火牆來看守校園網路的大門。

貳、Linux 防火牆演變簡史

Linux 最早出現的防火牆軟體稱為 ipfwipfw 能透過 IP 封包標頭的分析,分辨出封包的來源 IP 與目的地 IP、封包類型、來源埠號與目的埠號、封包流向、封包進入防火牆的網卡介面......等,並藉此分析結果來比對規則進行封包過濾,同時也支援 IP 偽裝的功能,利用這個功能可以解決 IP 不足的問題,可惜這支程式缺乏彈性設計,無法自行建立規則組合(ruleset)作更精簡的設定,同時也缺乏網址轉譯功能,無法應付越來越複雜的網路環境,而逐漸被淘汰。

取而代之的 ipchains,不但指令語法更容易理解,功能也較 ipfw 優越;ipchains 允許自訂規則組合(ruleset),稱之為 user-define chains,透過這種設計,我們可以將彼此相關的規則組合在一起,在需要的時候跳到該組規則進行過濾,有效將規則的數量大幅縮減,以往 ipfw 僅能進行循序過濾,導致規則又臭又長的毛病,就不藥而癒了。除了這個明顯的好處以外,ipchains 並能結合本身的埠對應功能和 redir 程式的封包轉送機制,模擬出網址轉譯的能力,而滿足 NAT 的完整需求,堪稱為一套成熟的防火牆作品。

防火牆軟體的出現,確實曾經讓駭客們晚上睡不著覺,因為防火牆的阻隔能夠有效讓內部網路不設防的單機不致於暴露在外,也能有效降低伺服器的能見度,減少被攻擊的機會,駭客過去所用的網路探測技術因此受到嚴格的挑戰,越來越多的攻擊對象躲藏在防火牆後方,讓駭客難以接近,因此必須針對新的情勢,研究出新的探測技術,藉以規避防火牆的檢查,達到發現目標並進而攻擊入侵的目的,新的技術非常多,本文並不擬進一步討論,請自行參考 CERT 組織的技術文件,網址是 www.cert.org ,想看中文請連到 www.cert.org.tw

iptables 作為 ipchains 的新一代繼承人,當然也針對駭客不斷推陳出新的探測技術擬出一些因應之道,那就是對封包的連線狀態,作出更詳細的分析,例如:是否為新連線或回應封包、是否為轉向連線、連線是否失去回應,連線時間是否過長......等等,透過這樣的分析能對一些可能被駭客利用的弱點加以阻隔(請詳見後文的說明),另外也開發出真正的封包改寫能力,不需要透過其他程式的協助來模擬網址轉譯,除此之外,iptables 也獲得系統核心的直接支援,不需要像 ipchains 那樣需要自行重新編譯核心。

iptables 優越的性能使它取代了 ipchains,成為網路防火牆的主流,而 ipchains 並未被淘汰,目前 ipchains 已經轉型成單機防火牆,在安裝新版 Linux 時,會自動被安裝啟用,以保護單機上未被使用的通訊埠。

參、iptables 防火牆概論

iptables 防火牆的指令非常類似於 ipchains,使用過 ipchains 的人應該很容易上手,但是 iptables 的機制與 ipchains 有很大的不同,使用 ipchains 的概念來設定規則,將會使防火牆無法正常運作。ipchains iptables 最大的不同在於對 INPUTFORWARD OUTPUT 三個網路函式的定義不同,這三個網路函式是 TCP/IP 驅動程式的一部分,結構如下圖所示,是介於網卡驅動程式和應用程式的中間,Linux 核心預設會啟用 INPUTOUTPUT LOOPBACK,而 FORWARD 函式則必須自行啟用,可以使用下面指令,或直接修改 /etc/sysconfig/network 組態檔:

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

左圖為 ipchains 概念下的運作圖

從上圖可以知道 ipchains 如何處理封包的流動,分述如下:

iptables 除了上述三支函式以外,還使用兩個新的函式:PreroutingPostrouting。現在來比較一下 iptables 的運作模式(loopback 介面與上圖相同,所以省略不畫):

從上圖可以知道 iptables 如何處理封包的流動,分述如下:

iptables ipchains 都可以自行定義規則群組(rule-set),規則群組被稱為規則鍊(chains), 前面所描述的函式,也都有相對應的規則鍊(INPUTFORWARDOUTPUTPreroutingPostrouting),為了有別於自行定義的規則鍊,這些規則鍊我們就稱為內建規則鍊,其運作流程模擬如下圖 :

從上面兩張假想圖,學員們不難了解 ipchains 為什麼要叫做 chains,因為它是將所有規則串接成一個序列逐一檢查過濾,就像一條鐵鍊一樣一個環接一個環,在過濾過程中只要符合其中一條規則就會立即進行處理,如果處理動作是跳到某個規則群組,則繼續檢查群組內之規則設定,但如果處理動作是 ACCEPTREJECTDROPREDIRECT MASQUERADE,則會中斷過濾程序,而不再繼續檢查後面的規則設定,在這樣的結構之下,有時候規則順序的對調會產生完全相反的結果,這一點在設定防火牆時不能不謹慎

iptables 是採用規則堆疊的方式來進行過濾,當一個封包進入網卡,會先檢查 Prerouting,然後檢查目的 IP 判斷是否需要轉送出去,接著就會跳到 INPUT Forward 進行過濾,如果封包需轉送處理則檢查 Postrouting,如果是來自本機封包,則檢查 OUTPUT 以及 Postrouting過程中如果符合某條規則將會進行處理,處理動作除了 ACCEPTREJECTDROPREDIRECT MASQUERADE 以外,還多出 LOGULOGDNATSNATMIRRORQUEUERETURNTOSTTLMARK 等,其中某些處理動作不會中斷過濾程序,某些處理動作則會中斷同一規則鍊的過濾,並依照前述流程繼續進行下一個規則鍊的過濾(注意:這一點與 ipchains 不同),一直到堆疊中的規則檢查完畢為止透過這種機制所帶來的好處是,我們可以進行複雜、多重的封包過濾,簡單的說,iptables 可以進行縱橫交錯式的過濾(tables)而非鍊狀過濾(chains

雖然 iptables 為了擴充防火牆功能,而必須採用比較複雜的過濾流程,但在實際應用時,同一規則鍊下的規則設定還是有先後順序的關係,因此在設定規則時還是必須注意其中的邏輯

訂定校園網路安全政策

在實際設定防火牆之前,我們必須根據校園網路的安全需求,先擬定一份安全政策,擬定安全政策前必須蒐集以下資料:

  1. 找出需要過濾保護的伺服器
  2. 條列出被保護的伺服器將提供何種網路服務
  3. 一般工作站,需要何種等級的保護
  4. 了解網路架構與伺服器擺放位置

根據這些資料,我們可以決定安全政策,以石牌國小為例:

  1. 校內使用 NAT 虛擬網路,IP 數量需要兩組 C,所有 IP 均需作 IP 偽裝
  2. 校園內安全需求不高,伺服器與工作站擺在同一網段,不需採用 DMZ 設計
  3. 由於伺服器功能經常擴充,所有伺服器均採用一對一對應,不使用 port 轉送功能
  4. 所有工作站均能自由使用網路資源,不限制只能看網頁
  5. 伺服器提供之服務包含:dnswebmailftpwamwebminsshrdppcaw,不提供 proxy 及其它網路服務
  6. 為增進校園網路之安全性,採用正面表列方式進行封包過濾(定義想放行之封包,其餘封包一律阻擋)

還有一些網路安全須注意的事項,則是每所學校都應防範的,沒有等差之別,例如:連線被綁架、阻斷式攻擊、連接埠掃描......

、iptables 指令

語法:

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

-t 參數用來指定規則表,內建的規則表有三個,分別是:natmangle filter,當未指定規則表時,則一律視為是 filter。各個規則表的功能如下:

nat 此規則表擁有 Prerouting postrouting 兩個規則鍊,主要功能為進行一對一、一對多、多對多、埠轉送等網址轉譯工作(SNATDNAT、PNAT),由於轉譯工作的特性,需進行目的地網址轉譯的封包,就不需要進行來源網址轉譯,反之亦然,因此為了提升改寫封包的效率,在防火牆運作時,每個封包只會經過這個規則表一次。如果我們把封包過濾的規則定義在這個資料表裡,將會造成無法對同一封包進行多次比對,因此這個規則表除了作網址轉譯外,請不要做其他用途。
mangle 此規則表擁有 PreroutingFORWARD postrouting 三個規則鍊。
除了進行網址轉譯工作會改寫封包外,在某些特殊應用可能也必須去改寫封包(TTLTOS)或者是設定 MARK(將封包作記號,以便進行後續的過濾),這時就必須將這些工作定義在 mangle 規則表中,由於使用率不高,我們不打算在這裡討論 mangle 的用法。
filter 這個規則表是預設規則表,擁有 INPUTFORWARD OUTPUT 三個規則鍊,這個規則表顧名思義是用來進行封包過濾的處理動作(例如:DROP、 LOG、 ACCEPT 或 REJECT),我們會將基本規則都建立在此規則表中。

常用命令列表:

命令 -A, --append
範例 iptables -A INPUT ...
說明 新增規則到某個規則鍊中,該規則將會成為規則鍊中的最後一條規則。
命令 -D, --delete
範例 iptables -D INPUT --dport 80 -j DROP
iptables -D INPUT 1
說明 從某個規則鍊中刪除一條規則,可以輸入完整規則,或直接指定規則編號加以刪除。
命令 -R, --replace
範例 iptables -R INPUT 1 -s 192.168.0.1 -j DROP
說明 取代現行規則,規則被取代後並不會改變順序。
命令 -I, --insert
範例 iptables -I INPUT 1 --dport 80 -j ACCEPT
說明 插入一條規則,原本該位置上的規則將會往後移動一個順位。
命令 -L, --list
範例 iptables -L INPUT
說明 列出某規則鍊中的所有規則。
命令 -F, --flush
範例 iptables -F INPUT
說明 刪除某規則鍊中的所有規則。
命令 -Z, --zero
範例 iptables -Z INPUT
說明 將封包計數器歸零。封包計數器是用來計算同一封包出現次數,是過濾阻斷式攻擊不可或缺的工具。
命令 -N, --new-chain
範例 iptables -N tcp_allowed
說明 定義新的規則鍊。
命令 -X, --delete-chain
範例 iptables -X tcp_allowed
說明 刪除某個規則鍊。
命令 -P, --policy
範例 iptables -P INPUT DROP
說明 定義過濾政策。 也就是未符合過濾條件之封包,預設的處理方式。
命令 -E, --rename-chain
範例 iptables -E tcp_allowed disallowed
說明 修改某自訂規則鍊的名稱。

常用封包比對參數:

參數 -p, --protocol
範例 iptables -A INPUT -p tcp
說明 比對通訊協定類型是否相符,可以使用 ! 運算子進行反向比對,例如:-p ! tcp ,意思是指除 tcp 以外的其它類型,包含 udpicmp ...等。如果要比對所有類型,則可以使用 all 關鍵字,例如:-p all
參數 -s, --src, --source
範例 iptables -A INPUT -s 192.168.1.1
說明 用來比對封包的來源 IP,可以比對單機或網路,比對網路時請用數字來表示遮罩,例如:-s 192.168.0.0/24,比對 IP 時也可以使用 ! 運算子進行反向比對,例如:-s ! 192.168.0.0/24
參數 -d, --dst, --destination
範例 iptables -A INPUT -d 192.168.1.1
說明 用來比對封包的目的地 IP,設定方式同上。
參數 -i, --in-interface
範例 iptables -A INPUT -i eth0
說明 用來比對封包是從哪片網卡進入,可以使用通配字元 + 來做大範圍比對,例如:-i eth+ 表示所有的 ethernet 網卡,也可以使用 ! 運算子進行反向比對,例如:-i ! eth0
參數 -o, --out-interface
範例 iptables -A FORWARD -o eth0
說明 用來比對封包要從哪片網卡送出,設定方式同上。
參數 --sport, --source-port
範例 iptables -A INPUT -p tcp --sport 22
說明 用來比對封包的來源埠號,可以比對單一埠,或是一個範圍,例如:--sport 22:80,表示從 22 80 埠之間都算是符合條件,如果要比對不連續的多個埠,則必須使用 --multiport 參數,詳見後文。比對埠號時,可以使用 ! 運算子進行反向比對。
參數 --dport, --destination-port
範例 iptables -A INPUT -p tcp --dport 22
說明 用來比對封包的目的地埠號,設定方式同上。
參數 --tcp-flags
範例 iptables -p tcp --tcp-flags SYN,FIN,ACK SYN
說明 比對 TCP 封包的狀態旗號,參數分為兩個部分,第一個部分列舉出想比對的旗號,第二部分則列舉前述旗號中哪些有被設定,未被列舉的旗號必須是空的。TCP 狀態旗號包括:SYN(同步)、ACK(應答)、FIN(結束)、RST(重設)、URG(緊急)、PSH(強迫推送) 等均可使用於參數中,除此之外還可以使用關鍵字 ALL 和 NONE 進行比對。比對旗號時,可以使用 ! 運算子進行反向比對。
參數 --syn
範例 iptables -p tcp --syn
說明 用來比對是否為要求連線之 TCP 封包,與 iptables -p tcp --tcp-flags SYN,FIN,ACK SYN 的作用完全相同,如果使用 ! 運算子,可用來比對非要求連線封包。
參數 -m multiport --source-port
範例 iptables -A INPUT -p tcp -m multiport --source-port 22,53,80,110
說明 用來比對不連續的多個來源埠號,一次最多可以比對 15 個埠,可以使用 ! 運算子進行反向比對。
參數 -m multiport --destination-port
範例 iptables -A INPUT -p tcp -m multiport --destination-port 22,53,80,110
說明 用來比對不連續的多個目的地埠號,設定方式同上。
參數 -m multiport --port
範例 iptables -A INPUT -p tcp -m multiport --port 22,53,80,110
說明 這個參數比較特殊,用來比對來源埠號和目的埠號相同的封包,設定方式同上。注意:在本範例中,如果來源埠號為 80 但目的地埠號為 110,這種封包並不算符合條件。
參數 --icmp-type
範例 iptables -A INPUT -p icmp --icmp-type 8
說明 用來比對 ICMP 的類型編號,可以使用代碼或數字編號來進行比對。請打 iptables -p icmp --help 來查看有哪些代碼可以用。
參數 -m limit --limit
範例 iptables -A INPUT -m limit --limit 3/hour
說明 用來比對某段時間內封包的平均量(單位時間為秒),上面的例子是用來比對:每小時平均流量是否超過一次 3 封包。 除了小時平均一次外,也可以每秒鐘、每分鐘或每天平均一次預設值為每小時平均一次,參數如後: /second、 /minute、/day。除了進行封包數量的比對外,設定這個參數也會在條件達成時,暫停封包的比對動作 ,一直到平均量降低到門檻值,以避免因駭客使用洪水攻擊法,導致服務被阻斷。
參數 --limit-burst
範例 iptables -A INPUT -m limit --limit-burst 5
說明 用來比對瞬間大量封包的數量,上面的例子是用來比對一次同時湧入的封包是否超過 5 (這是預設值),超過此上限的封包將被直接丟棄 ,其餘封包放入緩衝區等待處理

舉實例來說明:假設現在同時湧入 10 個封包,前 5 個封包進入緩衝區(--limit-burst 5),其餘封包丟棄,這 5 個封包由於 iptables 每秒只處理 1 個(--limit 1/s),所以共需要 5 秒鐘,在這 5 秒鐘內將不再接受任何封包。

參數 -m mac --mac-source
範例 iptables -A INPUT -m mac --mac-source 00:00:00:00:00:01
說明 用來比對封包來源網路介面的硬體位址,這個參數不能用在 OUTPUT Postrouting 規則鍊上,這是因為封包要送出到網卡後,才能由網卡驅動程式透過 ARP 通訊協定查出目的地的 MAC 位址,所以 iptables 在進行封包比對時,並不知道封包會送到哪個網路介面去。
參數 --mark
範例 iptables -t mangle -A INPUT -m mark --mark 1
說明 用來比對封包是否被表示某個號碼,當封包被比對成功時,我們可以透過 MARK 處理動作,將該封包標示一個號碼,號碼最大不可以超過 4294967296。
參數 -m owner --uid-owner
範例 iptables -A OUTPUT -m owner --uid-owner 500
說明 用來比對來自本機的封包,是否為某特定使用者所產生的,這樣可以避免伺服器使用 root 或其它身分將敏感資料傳送出去,可以降低系統被駭的損失。可惜這個功能無法比對出來自其它主機的封包。
參數 -m owner --gid-owner
範例 iptables -A OUTPUT -m owner --gid-owner 0
說明 用來比對來自本機的封包,是否為某特定使用者群組所產生的,使用時機同上。
參數 -m owner --pid-owner
範例 iptables -A OUTPUT -m owner --pid-owner 78
說明 用來比對來自本機的封包,是否為某特定行程所產生的,使用時機同上。
參數 -m owner --sid-owner
範例 iptables -A OUTPUT -m owner --sid-owner 100
說明 用來比對來自本機的封包,是否為某特定連線(Session ID)的回應封包,使用時機同上。
參數 -m state --state
範例 iptables -A INPUT -m state --state RELATED,ESTABLISHED
說明 用來比對連線狀態,連線狀態共有四種:INVALID、ESTABLISHED、NEW 和 RELATED。
INVALID 表示該封包的連線編號(Session ID)無法辨識或編號不正確。
ESTABLISHED 表示該封包屬於某個已經建立的連線。
NEW 表示該封包想要起始一個連線(重設連線或將連線重導向)。
RELATED 表示該封包是屬於某個已經建立的連線,所建立的新連線。例如:FTP-DATA 連線必定是源自某個 FTP 連線。

常用的處理動作:

-j 參數用來指定要進行的處理動作,常用的處理動作包括:ACCEPTREJECTDROPREDIRECTMASQUERADELOGDNATSNATMIRRORQUEUERETURNMARK,分別說明如下:

ACCEPT 將封包放行,進行完此處理動作後,將不再比對其它規則,直接跳往下一個規則鍊(nat:postrouting)。
REJECT 攔阻該封包,並傳送封包通知對方,可以傳送的封包有幾個選擇:ICMP port-unreachable、ICMP echo-reply 或是 tcp-reset(這個封包會要求對方關閉連線),進行完此處理動作後,將不再比對其它規則,直接 中斷過濾程序。 範例如下:
iptables -A FORWARD -p TCP --dport 22 -j REJECT --reject-with tcp-reset
DROP 丟棄封包不予處理,進行完此處理動作後,將不再比對其它規則,直接中斷過濾程序。
REDIRECT 將封包重新導向到另一個埠PNAT,進行完此處理動作後,將 會繼續比對其它規則。 這個功能可以用來實作通透式 porxy 或用來保護 web 伺服器。例如:iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
MASQUERADE 改寫封包來源 IP 為防火牆 NIC IP,可以指定 port 對應的範圍,進行完此處理動作後,直接跳往下一個規則鍊(mangle:postrouting)。這個功能與 SNAT 略有不同,當進行 IP 偽裝時,不需指定要偽裝成哪個 IPIP 會從網卡直接讀取,當使用撥接連線時,IP 通常是由 ISP 公司的 DHCP 伺服器指派的,這個時候 MASQUERADE 特別有用。範例如下:
iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 1024-31000
LOG 將封包相關訊息紀錄在 /var/log 中,詳細位置請查閱 /etc/syslog.conf 組態檔,進行完此處理動作後,將會繼續比對其它規則。例如:
iptables -A INPUT -p tcp -j LOG --log-prefix "INPUT packets"
SNAT 改寫封包來源 IP 為某特定 IP IP 範圍,可以指定 port 對應的範圍,進行完此處理動作後,將直接跳往下一個規則鍊(mangle:postrouting)。範例如下:
iptables -t nat -A POSTROUTING -p tcp-o eth0 -j SNAT --to-source 194.236.50.155-194.236.50.160:1024-32000
DNAT 改寫封包目的地 IP 為某特定 IP IP 範圍,可以指定 port 對應的範圍,進行完此處理動作後,將會直接跳往下一個規則鍊(filter:input filter:forward)。範例如下:
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:80-100
MIRROR 鏡射封包,也就是將來源 IP 與目的地 IP 對調後,將封包送回,進行完此處理動作後,將會中斷過濾程序。
QUEUE 中斷過濾程序,將封包放入佇列,交給其他程式處理。透過自行開發的處理程式,可以進行其它應用,例如:計算連線費用.......等。
RETURN 結束在目前規則鍊中的過濾程序,返回主規則鍊繼續過濾,如果把自訂規則鍊看成是一個副程式,那麼這個動作,就相當於提早結束副程式並返回到主程式中。
MARK 將封包標上某個代號,以便提供作為後續過濾的條件判斷依據,進行完此處理動作後,將會繼續比對其它規則。範例如下:
iptables -t mangle -A PREROUTING -p tcp --dport 22 -j MARK --set-mark 2

、硬碟版防火牆應用實例

請點這裡下載石牌國小指令稿

這個指令稿是 UNIX 格式文字檔,修改時不可以使用記事本或其它系統內建的文書編輯器,建議您使用 editplus 來修改,該編輯器在存檔時會自動辨識檔案格式。下載 editplus

#!/bin/sh
#
# 石牌國小防火牆設定
# 2004/4/21
# 設定者:李忠憲(修改自 iptables tutorial 1.1.11 by Oskar Andreasson )
# 原文件是依 DMZ 需求設計,已根據校園 NAT 網路之需求修改,其餘改動部份包括:
# 新增通訊協定定義區塊
# 新增執行時,自動清除已設定之規則
# 支援 FTP
# 修改所有規則,改採 multiport 方式以簡化規則
# 原文件僅支援 IP 偽裝(多對一對應),已擴充為支援一對一對應及多對多對應
# 原文件僅支援 DNS WEB,新增 ftpmailwamPCAnywheressh......等多種伺服器
# 修改若干原文件規則設定上的小錯誤
# 新增各類 port scan 偵測防護規則
# 新增 IP 防假冒功能
# 修改規則架構,可同時支援:無 DMZ (伺服器放在內部網路),DMZ 以及混合模式(伺服器有的放在內部網路,有的放在DMZ)
# 修改程式碼支援機器群組設定,例如:新增一台 web server 172.16.1.10
# 1. 請在 server-nat 中定義此電腦 172.16.1.10:163.21.xxx.10
# 2. 請將 172.16.1.10 新增到 server-web 檔案中
# 3. 重新執行 iptables.sh
# 不需要再修改 iptables.sh 內的程式碼
#
#
# 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.0 Protocols Configuration.
# 定義會用到的通訊協定
FTP_DATA="20"
FTP="21"
TFTP="69"
DHCP_SERVER="67"
DHCP_CLIENT="68"
SMTP="25"
POP3="110"
IMAP="143"
SSH="22"
DNS="53"
HTTP="80"
HTTPS="443"
WINS="41"
RPC1="135"
RPC2="445"
NETBIOS1="137"
NETBIOS2="138"
NETBIOS3="139"
PCAW_TCP="5631"
PCAW_UDP="5632"
REAL="6970:7170"
WEBMIN="10000"
WAM="12000"

# 這是為了維護校務行政資料庫而設的
######## ADD for SQL Server JSDB database #############
SQL="1433"
REMOTE_SQL_IP="163.21.178.0/255.255.255.128"
#########################################
#
# 1.1 Internet Configuration.
# 定義 NIC IP 及 WAN 介面
INET_IP="163.21.166.254"
IP_POOL="163.21.166.240-163.21.166.250"
INET_IFACE="eth1"

#
# 1.2 Local Area Network configuration.
# 定義 NAT IP 及 LAN 介面
LAN_IP="172.16.1.253"
LAN_IP_RANGE="172.16.0.0/16"
LAN_BROADCAST_ADDRESS="172.16.255.255"
LAN_IFACE="eth0"

#
# 1.3 DMZ Network configuration.
# 定義 DMZ IP 及 DMZ 介面
#DMZ_IP="192.168.1.254"
#DMZ_IP_RANGE="192.168.1.0/24"
#DMZ_BROADCAST_ADDRESS="192.168.1.255"
#DMZ_IFACE="eth2"
 

#
# 1.4 Localhost Configuration.
# 定義 Loopback IP 及介面
LO_IFACE="lo"
LO_IP="127.0.0.1"

#
# 1.5 IPTables Configuration.
# 設定 iptables 指令路徑
IPTABLES="/sbin/iptables"

###########################################################################
#
# 2. Module loading.
#
# 整理核心支援模組之清單
/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
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_nat_ftp

#
# 2.2 Non-Required modules
#
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
#/sbin/modprobe ip_conntrack_irc
#/sbin/modprobe ip_nat_irc
###########################################################################
#
# 3. /proc set up.
#
#
# 3.1 Required proc configuration
#
# 啟動 Forward 介面
# trying to stop some smurf attacks.
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# Don't accept source routed packets. 
echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route
# Syncookies (if they are really needed any more?)
echo "1" > /proc/sys/net/ipv4/tcp_syncookies
# We don't like ICMP redirect,
echo "0" > /proc/sys/net/ipv4/conf/default/accept_redirects
echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
# Enable bad error message protection.
echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 
# Enabling IP forwarding.
echo "1" > /proc/sys/net/ipv4/ip_forward

#
# 3.2 Non-Required proc configuration
#
# We don't like IP spoofing,
#echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
#echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
# This enables dynamic IP address following
#echo "7" > /proc/sys/net/ipv4/ip_dynaddr
# Maximum limit of ip_conntrack
# This is RAM dependant so be careful with this.
# The max, which is the valuehere, needs around 32M RAM to work properly.
#echo "65535" > /proc/sys/net/ipv4/ip_conntrack_max
# This is commented out and will be an option when we have a "LOG_STUFF" 
# config option.
#echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
###########################################################################
#
# 4. rules set up.
#
######
# 4.1 Filter table
#
#
# 4.1.0 Reset all rules
#
# 清除所有已設定之規則,回復到不設防狀態
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -t nat -P PREROUTING ACCEPT
$IPTABLES -t nat -P POSTROUTING ACCEPT
$IPTABLES -t mangle -P POSTROUTING ACCEPT
$IPTABLES -t mangle -P PREROUTING ACCEPT
$IPTABLES -t mangle -P FORWARD ACCEPT
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X
 

# 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
#
# 新增使用者自訂規則鍊 tcp_allowed
# tcp_allowed 規則鍊的功能是:允許要求連線封包或回應封包進入,將其餘封包丟棄
$IPTABLES -N tcp_allowed
$IPTABLES -A tcp_allowed -p TCP --syn -j ACCEPT
$IPTABLES -A tcp_allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A tcp_allowed -p TCP -j DROP

# icmp_allowed 規則鍊的功能是:允許 ping 封包進入,將其餘封包丟棄
$IPTABLES -N icmp_allowed
$IPTABLES -A icmp_allowed -p ICMP --
icmp-type 11 -j ACCEPT
$IPTABLES -A icmp_allowed -p ICMP --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_allowed -p ICMP -j DROP

#
# 4.1.3 Anti hacker
#
# 防駭偵測
#
# null-scan
#
#$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL NONE -j LOG \
#--log-prefix "IPTABLES NULL-SCAN:"
$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL NONE -j DROP

#
# xmas-scan
#
#$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL ALL -j LOG \
#--log-prefix "IPTABLES XMAS-SCAN:"
$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL ALL -j DROP

#
# synfin-scan
#
#$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL SYN,FIN -j LOG \
#--log-prefix "IPTABLES SYNFIN-SCAN:"
$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL SYN,FIN -j DROP

#
# nmap-xmas-scan
#
#$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL URG,PSH,FIN -j LOG \
#--log-prefix "IPTABLES NMAP-XMAS-SCAN:"
$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL URG,PSH,FIN -j DROP

#
# fin-scan
#
#$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL FIN -j LOG \
#--log-prefix "IPTABLES FIN-SCAN:"
$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL FIN -j DROP

#
# nmap-id
#
#$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL URG,PSH,SYN,FIN -j LOG \
#--log-prefix "IPTABLES NMAP-ID:"
$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags ALL URG,PSH,SYN,FIN -j DROP

#
# syn-rst
#
#$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags SYN,RST SYN,RST -j LOG \
#--log-prefix "IPTABLES SYN-RST:"
$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags SYN,RST SYN,RST -j DROP

#
# new-without-syn
#
#$IPTABLES -t nat -A PREROUTING -p TCP ! --syn -m state --state NEW -j LOG \
#--log-prefix "IPTABLES NEW-WITHOUT-SYN:"
$IPTABLES -t nat -A PREROUTING -p TCP ! --syn -m state --state NEW -j DROP

#
# syn-flood
#
#$IPTABLES -t nat -N syn_flood
#$IPTABLES -t nat -A syn_flood -m limit --limit 3/m --limit-burst 3 -j RETURN
#$IPTABLES -t nat -A syn_flood -j \
#LOG --log-level INFO --log-prefix "IPTABLES SYN-FLOOD:"
#$IPTABLES -t nat -A syn_flood -j DROP
#$IPTABLES -t nat -A PREROUTING -p TCP --syn -j syn_flood

#
# port-scan
#
$IPTABLES -t nat -N port_scan
$IPTABLES -t nat -A port_scan -m limit --limit 1/s --limit-burst 4 -j RETURN
#$IPTABLES -t nat -A port_scan -j \
#LOG --log-level INFO --log-prefix "IPTABLES PORT-SCAN:"
$IPTABLES -t nat -A port_scan -j DROP
$IPTABLES -t nat -A PREROUTING -p TCP --tcp-flags SYN,ACK,FIN,RST RST -j port_scan

#
# ping-death
#
$IPTABLES -t nat -N ping_death
$IPTABLES -t nat -A ping_death -m limit --limit 1/s --limit-burst 4 -j RETURN
#$IPTABLES -t nat -A ping_death -j \
#LOG --log-level INFO --log-prefix "IPTABLES PING-DEATH:"
$IPTABLES -t nat -A ping_death -j DROP
$IPTABLES -t nat -A PREROUTING -p ICMP --icmp-type 8 -j ping_death

#
# ip spoofing
#
$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s 10.0.0.0/8 -j DROP
$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s 127.0.0.0/8 -j DROP
$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s 172.16.0.0/12 -j DROP
$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s 192.168.0.0/16 -j DROP
#$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s 224.0.0.0/4 -j DROP
$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s 240.0.0.0/5 -j DROP
#$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s $LAN_IP_RANGE -j DROP
#$IPTABLES -t nat -A PREROUTING -i $INET_IFACE -s $DMZ_IP_RANGE -j DROP
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE ! -s $LAN_IP_RANGE -j DROP
#$IPTABLES -t nat -A PREROUTING -i $DMZ_IFACE ! -s $DMZ_IP_RANGE -j DROP

#
# 4.1.4 INPUT chain(過濾要到達防火牆的封包)
#
#
# 從 LAN 進入防火牆主機的全部 unicast 和 broadcast 封包,通通放行;額外檢查目的地 IP 可以將 multicast 封包濾除
$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -d $LAN_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -d $LAN_BROADCAST_ADDRESS -j ACCEPT

# 從 DMZ 進入防火牆主機的全部 unicast 和 broadcast 封包,通通放行;額外檢查目的地 IP 可以將 multicast 封包濾除
#$IPTABLES -A INPUT -p ALL -i $DMZ_IFACE -d $DMZ_IP -j ACCEPT
#$IPTABLES -A INPUT -p ALL -i $DMZ_IFACE -d $DMZ_BROADCAST_ADDRESS -j ACCEPT
 

# 從 Loopback 介面進入防火牆主機的所有封包,檢查是否來自本機,若是則放行;此規則去檢查來源 IP ,似乎有些畫蛇添足,因為只有來自本機的封包才有機會進入 Loopback 介面
$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 $DMZ_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT

# 從 LAN 進入防火牆主機的 DHCP 封包,予以放行,只有當防火牆擔任 DHCP 時才使用
#$IPTABLES -A INPUT -p UDP -i $LAN_IFACE --dport $DHCP_SERVER --sport \
#$DHCP_CLIENT -j ACCEPT

# 從 WAN 進入防火牆主機的所有封包,檢查是否為回應封包,若是則予以放行
$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \
-j ACCEPT

# 限制過濾規則的比對頻率為每分鐘平均流量三個封包(超過上限的封包將暫停比對),並將瞬間流量設定為一次最多處理三個封包(超過上限的封包將丟棄不予處理),這類封包通常是駭客用來進行阻斷式攻擊 
#$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
#--log-level INFO --log-prefix "IPT INPUT packet died: "

#
# 4.1.5 FORWARD chain(過濾要通過防火牆的封包)
#
#
$IPTABLES -A FORWARD -p ALL -m mac --mac-source $BAD -j DROP

#
# 阻擋 Hacker's IP
#
for client in `cat bad-ip`
do
$IPTABLES -A FORWARD -p ALL -s $client -j DROP
done

# 阻擋微軟的 RPC 掃描漏洞
################# microsoft RPC SCAN block ###########################
$IPTABLES -A FORWARD -p TCP -m multiport \
--dport $WINS,$RPC1,$RPC2,$NETBIOS1,$NETBIOS2,$NETBIOS3 -j DROP
$IPTABLES -A FORWARD -p UDP -m multiport \
--dport $WINS,$RPC1,$RPC2,$NETBIOS1,$NETBIOS2,$NETBIOS3 -j DROP
######################################################################

# 從 LAN 要到 WAN 的封包通通放行
$IPTABLES -A FORWARD -i $LAN_IFACE -o $INET_IFACE -j ACCEPT

# 從 DMZ 要到 WAN 的封包通通放行
$IPTABLES -A FORWARD -i $DMZ_IFACE -o $INET_IFACE -j ACCEPT

# 從 WAN 要到 LAN或DMZ 的封包僅放行回應封包
$IPTABLES -A FORWARD -i $INET_IFACE -m state \
--state ESTABLISHED,RELATED -j ACCEPT

# 從 DMZ 要到 LAN 的封包僅放行回應封包
$IPTABLES -A FORWARD -i $DMZ_IFACE -m state \
--state ESTABLISHED,RELATED -j ACCEPT

# 放行國家資通安全中心的弱點測試 IP,詳細 IP 內容請查閱機密公文
############# Nation Infomation Security ScanIP #####################
#$IPTABLES -A FORWARD -s xxx.xxx.xxx.xxx -j ACCEPT
#$IPTABLES -A FORWARD -s xxx.xxx.xxx.xxx/29 -j ACCEPT
#####################################################################

# 允許來自 WAN 的 Ping 封包,遞送到校內所有的伺服器
for server in `cat server-ping`
do
$IPTABLES -A FORWARD -p ICMP -d $server -j icmp_allowed
done

# 允許來自 WAN 的 HTTP、HTTPS 封包,遞送到校內所有的 WEB 伺服器
for server in `cat server-web`
do
$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -d $server \
-m multiport --dport $HTTP,$HTTPS -j tcp_allowed
done

# 允許來自 WAN 的 FTP 封包,遞送到校內所有的 FTP 伺服器
for server in `cat server-ftp`
do
$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -d $server \
-m multiport --dport $FTP,$FTP_DATA -j tcp_allowed
done

# 允許來自 WAN 的 SMTP、POP3、IMAP 封包,遞送到校內所有的 MAIL 伺服器
for server in `cat server-mail`
do
$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -d $server \
-m multiport --dport $SMTP,$POP3,$IMAP,$AUTH -j tcp_allowed
done

# 允許來自 WAN 的 SSH、TELNET、WEBMIN、WAM 封包,遞送到校內所有的 LINUX 伺服器
for server in `cat server-wam`
do
$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -d $server \
-m multiport --dport $SSH,$WEBMIN,$WAM -j tcp_allowed
done

# 允許來自 WAN 的 PCanywhere 封包,遞送到校內所有的 PCanywhere 伺服器,這樣做風險很大
#for server in `cat server-pcaw`
#do
#$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -d $server \
#--dport $PCAW_TCP -j tcp_allowed
#$IPTABLES -A FORWARD -p UDP -i $INET_IFACE -d $server \
#--dport $PCAW_UDP -j ACCEPT
#done

# 允許來自 WAN 的 DNS 封包,遞送到校內的 DNS 伺服器
for server in `cat server-dns`
do
$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -d $server \
--dport $DNS -j tcp_allowed
$IPTABLES -A FORWARD -p UDP -i $INET_IFACE -d $server \
--dport $DNS -j ACCEPT
done

# 允許來自 WAN 的 TFTP 封包,遞送到校內網路
#$IPTABLES -A FORWARD -p UDP -i $INET_IFACE -d $DMZ_IP_RANGE \
--dport $TFTP -j ACCEPT

# 這是為了維護校務行政資料庫而設的,平常不用時 REMARK 起來
######## ADD for SQL Server JSDB database #############
#for server in `cat server-sql`
#do
#$IPTABLES -A FORWARD -p TCP -i $INET_IFACE -s $REMOTE_SQL_IP \
#-d $server --dport $SQL -j tcp_allowed
#done
#######################################################

# 限制過濾規則的比對頻率為每分鐘平均流量三個封包(超過上限的封包將暫停比對),並將瞬間流量設定為一次最多處理三個封包(超過上限的封包將丟棄不予處理),這類封包通常是駭客用來進行阻斷式攻擊 
$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(過濾從防火牆送出的封包)
#
#
# 從防火牆網卡送出的所有封包,通通放行
$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 $DMZ_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT

# 限制過濾規則的比對頻率為每分鐘平均流量三個封包(超過上限的封包將暫停比對),並將瞬間流量設定為一次最多處理三個封包(超過上限的封包將丟棄不予處理),這類封包通常是駭客用來進行阻斷式攻擊 
#$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(定義目的地位址轉譯)
#
# 從 WAN 要到校內伺服器的封包,在封包過濾前先轉譯目的地 IP 為 NAT IP
for server in `cat server-nat`
do
nat_ip=${server%%:*}
nic_ip=${server##*:}
$IPTABLES -t nat -A PREROUTING -d $nic_ip -j DNAT --to-destination $nat_ip
done

#
# 4.2.5 POSTROUTING chain(定義來源位址轉譯)
#
#
# 從校內伺服器要到 WAN 的封包,在送出之前先轉譯來源 IP 為 NIC IP,配合上面區塊的設定,就可以做到一對一對應
for server in `cat server-nat`
do
nat_ip=${server%%:*}
nic_ip=${server##*:}
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -s $nat_ip -j SNAT --to-source $nic_ip
done

# 從校內一般單機要到 WAN 的封包,在送出之前先轉譯來源 IP 為預設的 NIC IP,這就是多對一對應,若指定成 IP 範圍,就變成多對多對應,例如本範例即是如此
$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

server-nat 設定檔寫法,舉例如下:

172.16.1.2:163.21.166.2
172.16.1.4:163.21.166.4
172.16.1.9:163.21.166.9
172.16.1.6:163.21.166.6
172.16.1.7:163.21.166.7
 

各種伺服器設定檔,舉 server-web 為例:

172.16.1.2
172.16.1.9
 

阻擋駭客 IP(bad-ip 設定檔),寫法如下:

211.234.125.92
209.152.169.143
 

注意:每個設定檔最後都要多空一行

、磁片防火牆實作

使用磁片版防火牆最大的好處是伺服器零管理,不用擔心停電造成硬碟壞軌的問題,因為那一台電腦上根本不必裝硬碟。

要製作磁片版防火牆,首先請先安裝 winimage 應用程式,這個程式用來製作磁片映像檔,也可以將映像檔還原為磁片。然後下載磁片映像檔,將它還原到一片格式化好的空白磁碟片上。

磁片做好後,先不要急著測試,請先使用 editplus 修改網路組態檔(檔名 config):

#
# 基礎設定
# 請選擇連線方式:
# CONNECT_TYPE=PPP #使用數據機上網時選用
# CONNECT_TYPE=PPPoE #使用 ADSL 上網時選用
# CONNECT_TYPE=DHCP #使用 cable modem 上網時選用
CONNECT_TYPE=STATIC #靜態 IP 使用
# CONNECT_TYPE=EXTERNAL #自訂撥接指令稿使用,須將程式寫在 /etc/ext-up.init 中

# 填入 ISP 提供的帳號密碼
USER_IDENT=
USER_PASSWORD=

# 預設不啟用 DHCP 做 IP 分享
DHCP_DAEMON=n

# Linux 登入密碼:使用純文字或是編成 DES 密碼格式
# This will give you "ffw" as login password.
# DES_PASSWORD=nCLm5JgCK0G5U
PASSWORD=

#-----------------------------------------------------------------------------
# 設定網卡編號
OUTSIDE_DEV=eth1
INSIDE_DEV=eth0

#-----------------------------------------------------------------------------
# 設定內部子網路遮罩
INSIDE_NETMASK=255.255.0.0

# 設定 DHCP 派送的 IP 範圍
#DHCP_RANGE_START=10.42.42.100
#DHCP_RANGE_END=10.42.42.200

#-----------------------------------------------------------------------------
# 設定防火牆對外網卡的 IP 位址及子網路遮罩
OUTSIDE_IP=163.21.166.253
OUTSIDE_NETMASK=255.255.255.128

# 設定對外路由器的 IP 位址
DEFAULT_GATEWAY=163.21.166.254

# 設定防火牆所使用的 DNS 伺服器
NAME_SERVER_IP="172.16.1.23"

# 設定外部網卡的實體位址,某些 ISP 會根據實體位址來配 IP,這時就必須設定此選項
# OUTSIDE_MAC=00:00:e8:48:6c:cb

#-----------------------------------------------------------------------------
# 定義 DMZ 相關設定
USE_DMZ=n
#DMZ_DEV=eth2
#DMZ_IP=10.42.69.1
#DMZ_NETMASK=255.255.255.0

# 定義 DMZ 是否使用 NAT 機制,為了安全最好是使用
#DMZ_USE_NAT=y


#-----------------------------------------------------------------------------
# 設定 ISP 提供的撥接電話號碼:
#TELEPHONE=

# 定義數據機所使用的 COM 埠相關設定,底下範例是使用 COM1
#SERIAL_PORT=/dev/tts/1
#PORT_SPEED=57600
#PPP_CONNECT_TIMEOUT=60
#PPP_CONNECT_POLL=3

# 是否使用 ISP 指派的 DNS 設定
#USEPEERDNS=yes

# 閒置多久自動斷線,"no" 代表永遠不斷線
#DEMAND=600
#DEMAND=no

#-----------------------------------------------------------------------------
# 主機名稱與網域尾碼設定
HOSTNAME=firewall.spps.tp.edu.tw
DOMAIN=spps.tp.edu.tw

# 使用 hosts 做靜態名稱解析,而停用 DNS,當啟用 DHCP 伺服器時會強迫開啟
DNSMASQ=n

# 定義變數,此裝置就是 /dev/null
DEBUG_LOG="/dev/vc/3"

# 是否執行 syslogd 和 klogd
USE_SYSLOG=n

# 將 log 寫入到哪裡,預設是丟到黑洞,如果設為 /dev/vc/4 則寫到 ramdisk
# SYSLOG_TTY="-O $DEBUG_LOG"
# 注意:使用底下設定很容易造成 ramdisk 空間耗盡,造成系統檔機
# SYSLOG_TTY="-O /dev/vc/4"
# 將 log 寫入到遠端 log server,如果非保留 log 不可,請使用此選項
SYSLOG_NET="-R 172.16.1.7:514"
# 紀錄 log 時,不要紀錄 mark 標頭
# SYSLOG_MARK="-m 0"

[ "$SYSLOG_TTY" -a "$SYSLOG_NET" ] && SYSLOG_BOTH="-L"
SYSLOG_FLAGS="$SYSLOG_MARK $SYSLOG_TTY $SYSLOG_NET $SYSLOG_BOTH"
 

遠端 log server 的做法為:從內部網路找一台 Linux,修改 /etc/sysconfig/syslog 為底下內容:

KLOGD_OPTIONS="-xr"

使用指令 service syslog restart,重新啟動 syslog 即可。

為了配合磁片版的 Linux 啟動程序,磁片上所附的 iptables 指令稿(檔名為 firewall.ini),已經修改為舊版本,也就是說 IP 設定和主程式是寫在一起而非分開定義的,因此必須直接修改主程式中的 IP 設定區塊:

...............(前面省略)...................
#
# 1.1 Internet Configuration.
#
INET_IP="163.21.166.253"
HTTP1_IP="163.21.166.2"
HTTP2_IP="163.21.166.4"
HTTP3_IP="163.21.166.9"
HTTP4_IP="163.21.166.6"
HTTP5_IP="163.21.166.7"
FTP1_IP="163.21.166.2"
FTP2_IP="163.21.166.6"
FTP3_IP="163.21.166.7"
MAIL1_IP="163.21.166.6"
MAIL2_IP="163.21.166.7"
PCAW1_IP="163.21.166.2"
PCAW2_IP="163.21.166.4"
WAM1_IP="163.21.166.6"
WAM2_IP="163.21.166.7"
DNS_IP="163.21.166.2"
ED_IP="163.21.166.72"
IP_POOL="163.21.166.240-163.21.166.250"
INET_IFACE="eth1"

#
# 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="172.16.1.253"
LAN_HTTP1_IP="172.16.1.2"
LAN_HTTP2_IP="172.16.1.4"
LAN_HTTP3_IP="172.16.1.9"
LAN_HTTP4_IP="172.16.1.6"
LAN_HTTP5_IP="172.16.1.7"
LAN_FTP1_IP="172.16.1.2"
LAN_FTP2_IP="172.16.1.6"
LAN_FTP3_IP="172.16.1.7"
LAN_MAIL1_IP="172.16.1.6"
LAN_MAIL2_IP="172.16.1.7"
LAN_PCAW1_IP="172.16.1.2"
LAN_PCAW2_IP="172.16.1.4"
LAN_WAM1_IP="172.16.1.6"
LAN_WAM2_IP="172.16.1.7"
LAN_DNS_IP="172.16.1.2"
LAN_ED_IP="172.16.1.72"
LAN_IP_RANGE="172.16.0.0/16"
LAN_BROADCAST_ADDRESS="172.16.255.255"
LAN_IFACE="eth0"

#
# 1.3 DMZ Network configuration.
#
# your DMZ's IP range and dmz IP. /24 means to only use the first 24
# bits of the 32 bit IP address. the same as netmask 255.255.255.0
#
#DMZ_IP="192.168.1.254"
#DMZ_HTTP6_IP="192.168.1.2"
#DMZ_HTTP7_IP="192.168.1.4"
#DMZ_FTP4_IP="192.168.1.2"
#DMZ_FTP5_IP="192.168.1.4"
#DMZ_MAIL3_IP="192.168.1.2"
#DMZ_MAIL4_IP="192.168.1.4"
#DMZ_WAM3_IP="192.168.1.2"
#DMZ_WAM4_IP="192.168.1.4"
#DMZ_DNS2_IP="192.168.1.2"
#DMZ_IP_RANGE="192.168.1.0/24"
#DMZ_BROADCAST_ADDRESS="192.168.1.255"
#DMZ_IFACE="eth2"
...............(後面省略)...................

由於磁片版的防火牆所支援的網卡比較少,因此請採購國外較知名的品牌,例如:3com 或 intel 網卡來組裝您的防火牆。

捌、大姆哥防火牆實作

大姆哥版的防火牆是筆者自行將磁片版防火牆的 kernal 納入 USB 驅動程式後,重新編譯完成的,為了適應 USB 開機並修改了若干系統設定,總容量約 5 MB。經過實際測試後,證實能相容於所有支援 USB 1.1 或 USB 2.0 規格的大姆哥,而實際作為防火牆的機器,其主機板 BIOS 須支援 USB ZIP 開機。

請先下載此壓縮檔,將它解壓縮在桌面上,資料夾名稱預設為 usbffw。接著請打開 usbffw/mkboot 目錄,你會看到裡面有三個資料夾,請根據您目前所在電腦的作業系統來選取資料夾,例如:您現在正在使用 XP 請選擇 WinNT2kXP 資料夾,將裡面的檔案拷貝到根目錄下,接著將格式化好的大姆哥插在 PC 上,讓系統辨識磁碟代號(假設是 G:),執行:

install g:

這個動作會在大姆哥上寫入 MBR,接著將 usbffw 內的所有檔案連同子資料夾,全部拷貝到大姆哥上就完成了。

大姆哥版的 config 和 firewall.ini 設定方式與磁片版相同,請自行參照修改。

玖、Log 分析

分析 iptables 防火牆 Log 的免費軟體相當多,底下僅介紹 iptables_logger_v0.3,這個軟體提供一個 perl 程式,可以讀取系統 LOG,並將資料寫入 MySql 資料庫,然後還提供 php 程式,可以從資料庫讀取資料,整理成網頁提供瀏覽,因此要安裝此分析軟體,必須先安裝 perlphpmysql apache,有關這些套件的安裝在這裡不再介紹,請自行參考相關文件,或參加 Linux 進階班課程。你可以從這裡取得 iptables_logger_v0.3 程式,其安裝程序如下:

安裝資料表:

這個套件解壓縮後,可以看到有一個資料夾叫做 sql,資料夾內有一個 sql 的指令稿叫做 db.sql,這個指令稿是用來建立擺放連線紀錄所需的資料表,請利用以下指令來安裝,如果您還不熟悉 mysql 的指令,請自行閱讀 man mysql 文件。

root@firewall sql# mysql -u root -p(以 root 身分登入 MySql 主控台)
mysql> create database iptables;(建立一個資料庫叫做 iptables,資料庫也可以自行命名,但是要記得修改相關程式)
mysql> grant create,select,insert on iptables.* to iptables_admin@localhost identified by 'xx';(將 iptables 資料庫新建、讀取和寫入權限授權給 iptables_admin 這個帳號,並限制只能從本機連線,密碼為 xx,請自行修改上述指令中之帳號與密碼)
mysql> grant create,select on iptables.* to iptables_user@localhost identified by 'xx';(將 iptables 資料庫讀取權限授權給 iptables_user 這個帳號,並限制只能從本機連線,密碼為 xx,請自行修改上述指令中之帳號與密碼)
root@firewall sql# cat db.sql | mysql -u iptables_admin -p iptables(以 iptables_admin 身分來執行 db.sql,如果你改了資料庫的名字,請記得修改 db.sql

修改 iptables 指令稿:

由於這支 Log 分析程式是以讀取系統 LOG 加以分析後才匯入到資料庫的方法,來處理連線紀錄,並非使用 ULOG 直接由 iptables 將紀錄寫入 mysql 資料庫,感覺上效能比較差,但在 ULOG 機制尚未被實體化之前,這也不失為一個好的解決方案。

原則上只要在 iptables 指令稿中有產生 LOG 的動作,這些資訊就會被分析匯入到資料表(由 feed_db.pl 負責這個工作),特別要注意的是 LOG 產生時會加入一個標頭(prefix),程式是透過標頭來分析這筆 LOG 的意義,請將 LOG 標頭取名為 IPTABLES DROP IPTABLES ACCEPT,以方便事後的統計。範例如下:

首先建立一個新的規則鍊 LOG_DROP,這個規則鍊用來將要丟棄的封包先 LOG 到系統日誌檔,然後再丟棄。

iptables -N LOG_DROP
iptables -A LOG_DROP -j LOG --log-tcp-options --log-ip-options --log-prefix '[IPTABLES DROP] : '
iptables -A LOG_DROP -j DROP

接著修改所有規則,只要是需進行 DROP 動作,都改為跳到 LOG_DROP 規則鍊,例如:

$IPTABLES -A bad_tcp_packets -p TCP ! --syn -m state --state NEW -j DROP

改為

$IPTABLES -A bad_tcp_packets -p TCP ! --syn -m state --state NEW -j LOG_DROP

至於需要進行 ACCEPT 處理的規則也如法炮製,先建立 LOG_ACCEPT 規則鍊:

iptables -N LOG_ACCEPT
iptables -A LOG_ACCEPT -j LOG --log-tcp-options --log-ip-options --log-prefix '[IPTABLES ACCEPT] : '
iptables -A LOG_ACCEPT -j ACCEPT

接著修改所有規則,例如:

$IPTABLES -A tcp_allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT

改為

$IPTABLES -A tcp_allowed -p TCP -m state --state ESTABLISHED,RELATED -j LOG_ACCEPT

安裝顯示分析結果的 PHP 程式:

在解壓縮的資料夾中,找到一個叫做 web 的子資料夾,裡面就是要給人從網頁瀏覽分析結果的 PHP 程式,如果你的 Apache 已經設定好支援 php php_mysql,那麼只要將此資料夾複製到 Apache 的根文件目錄就行了。方法如下:

cp -R web /var/www/iptables

拷貝完成後請修改 config.php ,目的是為了讓 PHP 程式執行時,能以正確的帳號密碼連上 MySql ,以便從資料庫讀取資料,請找到底下三行:

$db_host="localhost";(一般不需修改,除非資料庫在另一台主機上)
$db_user="iptables_user";(修改為僅具有讀取權限的帳號,如果之前安裝資料庫有自設帳號的話)
$db_password="xxxx";(請將密碼修改為自設的密碼)

安裝 feed_db.pl

前面已經介紹過這支程式的作用,請務必修改這支程式中有關資料庫連線的 SQL 指令,將指令中的帳號密碼,改成你當初所設定的帳號密碼,建議最好不要用 root 身分連線,以免影響防火牆的安全性。這支程式是放在解壓縮後資料夾內的 scripts 子資料夾,請修改下面這三行:

my $dsn = 'DBI:mysql:iptables:localhost';(請將 iptables 改成你自訂的資料庫名稱)
my $db_user_name = 'iptables_admin';(請將 iptables_admin 改成你自訂的管理帳號)
my $db_password = 'xxxx';(請將 xxxx 改成管理帳號的密碼)

程式修改好後,請將它拷貝到 /usr/local/bin 資料夾,接著將程式執行起來,注意:這支程式會跑一個無窮盡迴圈,持續分析系統 LOG,因此必須在背景執行,同時只能有一支程式執行,以避免造成 IO 過大的負載,執行方式如下:

tail --follow=name --retry /var/log/syslog | /usr/local/bin/feed_db.pl &

如果這些動作都作了,但程式並未執行成功,有可能是因為 perl_DBI:DBD 套件沒安裝,請自行用 rpm 補裝該套件。

查看分析結果:

完成以上所有安裝步驟後,就可以坐下來享受一下成果,請打開瀏覽器輸入底下網址

http://192.xx.1.254/iptables

看到的畫面,如下圖所示(請點選放大):

安裝 LOG 分析後的安全防範:

防火牆上安裝越多套件,系統安全性也就越低,改進的方法有兩個:

  1. apache mysql 架設在內部網路的一台機器上,防火牆上僅安裝 mysql client,這樣可以避免 apache mysql 的漏洞被駭客利用
  2. 在防火牆上設定規則,僅允許來自內部的網路,進行 HTTP MySql 連線,這個方法比較簡單,本文所介紹的 iptables 範例也是採用此法,缺點是無法在校外查看 LOG 分析結果