參考網址:http://linux.vbird.org/linux_server/0250simple_firewall.php
防火牆就是透過訂定一些有順序的規則,並管制進入到我們網域內的主機
(或者可以說是網域) 資料封包的一種機制!更廣義的來說,
只要能夠分析與過濾進出我們管理之網域的封包資料, 就可以稱為防火牆。
由以下的圖可以發現, 封包進入本機時,會先通過防火牆:
因此防火牆最大的功能就是幫助你『限制某些服務的存取來源』
所以鳥哥認為,防火牆最重要的任務就是在規劃出:
所謂的封包過濾,亦即是分析進入主機的網路封包,將封包的表頭資料捉出來進行分析,
以決定該連線為放行或抵擋的機制。
在 Linux 上面我們使用核心內建的 Netfilter 這個機制,而 Netfilter 提供了 iptables
這個軟體來作為防火牆封包過濾的指令。由於 Netfilter 是核心內建的功能,因此他的效率非常的高。
這種機制主要是分析誰對某程式進行存取,然後透過規則去分析該伺服器程式誰能夠連線、誰不能連線。
由於主要是透過分析伺服器程式來控管,因此與啟動的埠口無關,只與程式的名稱有關。
舉例來說,我們知道 FTP 可以啟動在非正規的 port 21 進行監聽,當你透過 Linux 內建的
TCP wrappers 限制 FTP 時, 那麼你只要知道 FTP 的軟體名稱 (vsftpd) ,然後對他作限制,
則不管 FTP 啟動在哪個埠口,都會被該規則管理的。
可以『代理』使用者的需求,而代為前往伺服器取得相關的資料。
以上圖為例,當 Client 端想要前往 Internet 取得 Google 的資料時,他取得資料的流程是這樣的:
在這邊client 並沒有直接連上 Internet,此時的 client 甚至不需要擁有 public IP 。
防火牆除了可以『保護防火牆機制本身所在的那部主機』之外,還可以『保護防火牆後面的主機』。
也就是說,防火牆除了可以防備本機被入侵之外,
還可以架設在路由器上面藉以控管進出本地端網域的網路封包。
接下來我們來看一些網路部線的示意圖。
有特別重要的部門需要更安全的保護網路環境,那麼將LAN裡面再加設一個防火牆,
將安全等級分類,那麼將會讓你的重要資料獲得更佳的保護,整體架構如上圖。
透過防火牆的封包分析後,將 WWW 的要求封包轉送到 Web 主機,將 Mail 送給 Mail Server去處理而已(透過 port 的不同來轉遞)。
因為四部主機在 Internet 上面看到的 IP 都相同,但是事實上卻是四部不同的主機, 而當有攻擊者想要入侵你的 FTP 主機好了,他使用各種分析方法去進攻的主機,其實是『防火牆』那一部, 攻擊者想要攻擊你內部的主機,除非他能夠成功的搞定你的防火牆,否則就很難入侵你的內部主機。
而且,由於主機放置在兩部防火牆中間,內部網路如果發生狀況時 (例如某些使用者不良操作導致中毒啊、 被社交工程攻陷導致內部主機被綁架啊等等的) ,是不會影響到網路伺服器的正常運作的。 這種方式適用在比較大型的企業當中,因為對這些企業來說,網路主機能否提供正常穩定的服務是很重要的。
不過,某些情況下,他並不能保證我們的網路一定就很安全。 舉幾個例子來談一談:
TCP wrappers 是透過用戶端想要連結的程式檔名,然後分析用戶端的 IP ,看看是否需要放行。
TCP wrappers 就是透過 /etc/hosts.allow,/etc/hosts.deny這兩個檔案來管理的一個類似防火牆的機制, 但並非所有的軟體都可以透過這兩個檔案來控管,只有底下的軟體才能夠透過這兩個檔案來管理防火牆規則
上述結果最終輸出的部分就是 xinetd 所管理的服務群,上述的服務之防火牆簡易設定,都可以透過 TCP wrappers 來管理的。
上述的結果中,在該檔名檔下有出現 libwrap 的,代表有找到該函式庫,才有支援 tcp wrappers。
所以, sshd, xinetd 有支援,但是 rsyslogd, httpd 這兩支程式則不支援。也就是說,
httpd 與 rsyslogd 不能夠使用 /etc/hosts.{allow|deny} 來進行防火牆機制的控管。
我們知道防火牆的規則都是有順序的,這兩個檔案與規則的順序優先如下:
防火牆規則會根據封包的分析資料 "比對" 你預先定義的規則內容,
若封包資料與規則內容相同則進行動作,否則就繼續下一條規則的比對。
當 Internet 來了一個封包想要進入我的主機,
那麼防火牆是如何分析這個封包的呢?我們以底下的圖示來說明好了
上圖中主要的目的在告知你:『規則是有順序的』!例如當網路封包進入 Rule 1 的比對時,
如果比對結果符合 Rule 1 ,此時這個網路封包就會進行 Action 1 的動作,
而不會理會後續的 Rule 2, Rule 3.... 等規則的分析了。
如果所有的規則都不符合,此時就會透過預設動作 (封包政策, Policy) 來決定這個封包的去向。
接下來我們來看一個iptables規則的例子:
假設你的 Linux 主機提供了 WWW 的服務,那麼自然就要針對 port 80
來啟用通過的封包規則,但是你發現 IP 來源為 192.168.100.100
老是惡意的嘗試入侵你的系統,所以你想要將該 IP 拒絕往來,最後,所有的非 WWW
的封包都給他丟棄,就這三個規則來說,你要如何設定防火牆檢驗順序呢?
Rule 1 先抵擋 192.168.100.100 ;
Rule 2 再讓要求 WWW 服務的封包通過;
Rule 3 將所有的封包丟棄。
這樣的排列順序就能符合你的需求,不過,萬一你的順序排錯了,變成:
Rule 1 先讓要求 WWW 服務的封包通過;
Rule 2 再抵擋 192.168.100.100 ;
Rule 3 將所有的封包丟棄。
此時,那個 192.168.100.100 『可以使用你的 WWW 服務』喔!只要他對你的主機送出 WWW
要求封包,就可以使用你的WWW功能了,因為你的規則順序定義
第一條就會讓他通過,而不去考慮第二條規則。
iptables這個防火牆軟體裡面有多個表格 (table),每個表格都定義出自己的預設政策與規則
(這就是鏈的概念),且每個表格的用途都不相同,以下是iptables 的表格與相關鏈示意圖。
以上每個表格與其中鏈的用途分別是這樣的:
filter (過濾器):主要跟進入 Linux 本機的封包有關,這個是預設的 table
INPUT:主要與想要進入我們 Linux 本機的封包有關;
OUTPUT:主要與我們 Linux 本機所要送出的封包有關;
FORWARD:這個與 Linux 本機比較沒有關係, 他可以『轉遞封包』到後端的電腦中,與下列 nat table 相關性較高。
nat (位址轉換):是 Network Address Translation 的縮寫,
這個表格主要在進行來源與目的之 IP 或 port 的轉換,與 Linux 本機較無關,主要與 Linux 主機後的區域網路內電腦較有相關。
PREROUTING:在進行路由判斷之前所要進行的規則(DNAT/REDIRECT)
POSTROUTING:在進行路由判斷之後所要進行的規則(SNAT/MASQUERADE)
OUTPUT:與發送出去的封包有關
mangle (破壞者):這個表格主要是與特殊的封包的路由旗標有關,
由於這個表格與特殊旗標相關性較高,所以像我們這種單純的環境當中,較少使用 mangle 這個表格。
其實各個表格的鏈結之間是有關係的簡單的關係可以由下圖這麼看:
基本上你依舊可以看出來,我們的 iptables 可以控制三種封包的流向:
由於 mangle 這個表格很少被使用,如果將上圖的 mangle 拿掉的話,那就容易看的多了:
由上圖可了解,事實上與本機最有關的其實是 filter 這個表格內的 INPUT 與 OUTPUT 這兩條鏈,
如果你的 iptables 只是用來保護 Linux 主機本身的話,那 nat
的規則根本就不需要理他,直接設定為開放即可。
因為 iptables 的指令會將網路封包進行過濾及抵擋的動作,所以,
請不要在遠端主機上進行防火牆的練習,因為你很有可能一不小心將自己關在家門外!
盡量在本機前面登入 tty1-tty6 終端機進行練習。
我們先來看看目前本機的防火牆規則是如何
在上表中,每一個 Chain 就是前面提到的每個鏈。接下來我們來看一些重要的關鍵字。
舉例來說, 我們將 INPUT 的 5 條規則依據輸出結果來說明一下,結果會變成:
最有趣的應該是第 3 條規則了,怎麼會所有的封包資訊都予以接受?
如果都接受的話,那麼後續的規則根本就不會有用嘛!
其實那條規則是僅針對每部主機都有的內部迴圈測試網路(lo)介面(即127.0.0.1, localhost), 如果沒有列出介面,那麼我們就很容易搞錯,
所以,近來鳥哥都建議使用 iptables-save 這個指令來觀察防火牆規則,
因為 iptables-save 會列出完整的防火牆規則,只是並沒有規格化輸出而已。
如何修改規則呢?鳥哥建議,先刪除規則再慢慢建立各個需要的規則!那如何清除規則?這樣做就對了:
由於這三個指令會將本機防火牆的所有規則都清除,但卻不會改變預設政策 (policy) ,
所以如果你不是在本機下達這三行指令時,很可能你會被自己擋在家門外 (若 INPUT 設定為 DROP 時)。
還記得政策指的是什麼嗎?
『 當你的封包不在你設定的規則之內時,則該封包的通過與否,是以 Policy 的設定為準』。
下圖的語法要看得懂,但其實不難記,因為
A = Append, I = Insert, i = INPUT, o = OUTPUT, p = protocal,
s = source, d = destination, j=job
接下來舉個例子,開放 lo 這個本機的介面以及某個 IP 來源
仔細看上面並沒有列出 -s, -d 等等的規則,這表示:不論封包來自何處或去到哪裡,
只要是來自 lo 這個介面,就予以接受!這個觀念挺重要的,
就是『沒有指定的項目,則表示該項目完全接受』的意思,即是所謂的信任裝置。
假如你的主機有兩張乙太網路卡,其中一張是對內部的網域,假設該網卡的代號為 eth1 好了,
如果內部網域是可信任的,那麼該網卡的進出封包就通通會被接受,
那你就能夠用:『iptables -A INPUT -i eth1 -j ACCEPT』 來將該裝置設定為信任裝置。
不過,下達這個指令前要特別注意,因為這樣等於該網卡沒有任何防備了。
這就是最單純簡單的防火牆規則的設定與觀察方式。不過,在上面的案例中,
其實你也發現到有兩條規則可能有問題,那就是上面的特殊字體圈起來的規則順序。
明明已經放行了 192.168.100.0/24 了,所以那個 192.168.100.230
的規則就不可能會被用到,這就是有問題的防火牆設定,所以必須清除全部再重新加入。
如果你想要記錄某個規則的應用怎麼辦?可以這樣做:
看到輸出結果的最左邊,會出現的是 LOG 喔!只要有封包來自 192.168.2.200 這個 IP 時,
那麼該封包的相關資訊就會被寫入到核心訊息,亦即是 /var/log/messages 這個檔案當中。
然後該封包會繼續進行後續的規則比對。
在談到 TCP 與 UDP 時,比較特殊的就是埠口 (port),在 TCP 方面則另外有所謂的連線封包狀態,
包括最常見的 SYN 主動連線的封包格式。那麼如何針對這兩種封包格式進行防火牆規則的設定呢?
事實上就是多了那個 --sport(來源port) 及 --dport (目標port)這兩個設定
因為僅有 tcp 與 udp 封包具有埠口,所以 -p 要加上 tcp 或 -p udp
的參數才會成功。
底下讓我們來進行幾個小測試:
你可以利用 UDP 與 TCP 協定所擁有的埠口號碼來進行某些服務的開放或關閉喔。
你還可以綜合處理呢!例如:只要來自 192.168.1.0/24 的 1024:65535 埠口的封包,
且想要連線到本機的 ssh port 就予以抵擋,可以這樣做:
(冒號':'表示從A~B的意思)
如果忘記加上 -p tcp 就使用了 --dport 時,會發生啥問題呢?
你應該會覺得很奇怪,怎麼『 --dport 』會是未知的參數 (arg) 呢?
這是因為你沒有加上 -p tcp 或 -p udp 的緣故啊!很重要喔!
除了埠口之外,在 TCP 還有特殊的旗標啊!最常見的就是那個主動連線的 SYN 旗標了。
我們在 iptables 裡面還支援『 --syn 』的處理方式,我們以底下的例子來說明好了:
一般來說,client 端啟用的 port 都是大於 1024 以上的埠口,
而 server 端則是啟用小於 1023 以下的埠口在監聽的。(所以port後面接1:1023)
所以我們可以讓來自遠端的小於 1023 以下的埠口資料的主動連線都給他丟棄。
但不適用在 FTP 的主動連線中!
我們要如何知道,『這個想要進入的封包是否為剛剛我發出去的回應?』
如果是剛剛我發出去的回應,那麼就可以予以接受放行,這樣就不用管遠端主機是否連線進來的問題了。
底下我們繼續談一下 iptables 的另一個外掛, 那就是針對網卡(mac)來進行放行與防禦:
如果不是做為路由器的主機時,通常我們會把 ICMP type 8 (echo request)拿掉,
讓遠端主機不知道我們是否存在,也不會接受 ping 的回應就是了。
ICMP 封包格式的處理是這樣的:
這樣就能夠開放部分的ICMP封包格式進入本機進行網路檢測的工作了。
不過,如果你的主機是作為區網的路由器,那麼建議icmp封包還是要通通放行才好。
這是因為用戶端檢測網路時,常常會使用 ping 來測試到路由器的線路是否暢通之故
(智v補一個:擋icmp其實還只是第一步,我看過一個可以無視像這樣擋icmp的工具,
有興趣我們私下聊唄!)
經過上述的本機 iptables 語法分析後,接下來我們來想想,
如果站在用戶端且不提供網路服務的Linux本機角色時,你應該要如何設計你的防火牆呢?
老實說,你只要分析過 CentOS 預設的防火牆規則就會知道了,
理論上, 應該要有的規則如下:
這就是最最陽春的防火牆,你可以透過第二步驟抵擋所有遠端的來源封包,
而透過第四步驟讓你要求的遠端主機回應封包可以進入,
加上讓本機的 lo 這個內部迴圈裝置可以放行,這樣一部 client 專用的防火牆規則就 OK 了。
其實防火牆也是一個服務,你可以透過『chkconfig --list iptables』去察看就知道了。
因此,你這次修改的各種設定想要在下次開機還保存,那就得要進行
『 /etc/init.d/iptables save 』這個指令加參數。
因此,鳥哥現在都是將儲存的動作寫入這個 firewall.sh 腳本中,比較單純些。
制訂好規則後當然就是要測試囉!那麼如何測試呢?
除了 iptables 這個防火牆軟體之外,其實咱們 Linux kernel 2.6
提供很多核心預設的攻擊抵擋機制喔! 由於是核心的網路功能,
所以相關的設定資料都是放置在 /proc/sys/net/ipv4/ 這個目錄當中。
我們在前一章談到所謂的阻斷式服務 (DoS) 攻擊法當中的一種方式,
就是利用 TCP 封包的 SYN 三向交握原理所達成的,這種方式稱為SYN Floodin。
那如何預防這種方式的攻擊呢?我們可以啟用核心的 SYN Cookie 模組。
當啟動 SYN Cookie 時,主機在發送 SYN/ACK 確認封包前,
會要求 Client 端在短時間內回覆一個序號,這個序號包含許多原本SYN封包內的資訊,包括IP、port等。 若Client端可以回覆正確的序號,那麼主機就確定該封包為可信的,
因此會發送 SYN/ACK 封包,否則就不理會此一封包。
但是這個設定值由於違反 TCP 的三向交握 (因為主機在發送 SYN/ACK 之前需要先等待
client 的序號回應), 所以可能會造成某些服務的延遲現象,例如 SMTP (mail server)。
不過總歸來說,這個設定值還是不錯用的! 只是不適合用在負載已經很高的伺服器內喔!
因為負載太高的主機有時會讓核心誤判遭受 SYN Flooding 的攻擊呢。
我們知道系統其實可以接受使用 ping 的回應, 而 ping 的封包資料量是可以給很大的!
想像一個狀況, 如果有個搞破壞的人使用 1000 台主機傳送 ping 給你的主機,
而且每個 ping 都高達數百Kbytes時,你的網路頻寬會怎樣?要嘛就是頻寬被吃光,
要嘛可能系統會當機! 這種方式分別被稱為 ping flooding (不斷發 ping)
及 ping of death (發送大的 ping 封包)。
核心取消 ping 回應的設定值有兩個,分別是:/proc/sys/net/ipv4內的
鳥哥建議設定 icmp_echo_ignore_broadcasts 就好了。 你可以這麼做:
咱們的核心還可以針對不同的網路介面進行不一樣的參數設定喔!
網路介面的相關設定放置在 /proc/sys/net/ipv4/conf/ 當中,
每個介面都以介面代號做為其代表,例如eth0介面的相關設定資料在/proc/sys/net/ipv4/conf/eth0/內。 那麼網路介面的設定資料有哪些比較需要注意的呢? 大概有底下這幾個:
雖然你可以使用『 echo "1" /proc/sys/net/ipv4/conf/???/rp_filter』之類的方法來啟動這個項目,
不過, 鳥哥比較建議修改系統設定值,那就是 /etc/sysctl.conf 這個檔案!
假設我們僅有 eth0 這個乙太介面,而且上述的功能要通通啟動, 那你可以這樣做:
接下來都是實戰的部分了,重點都是概念的部分,我不好整理。
如果上面的內容都了解的同學,相信就有能力前往鳥哥的網站自行觀看,加油!
http://linux.vbird.org/linux_server/0250simple_firewall.php#local