天天看點

規則 防火牆 iptables input accept

由于 mangle 這個表格很少被使用,如果将圖 9.3-3 的 mangle 拿掉的話,那就容易看的多了:

圖 9.3-4、iptables 内建各表格與鍊的相關性(簡圖)

透過圖 9.3-4 你就可以更輕松的了解到,事實上與本機最有關的其實是 filter 這個表格内的 INPUT 與 OUTPUT 這兩條鍊,如果你的 iptables 隻是用來保護 Linux 主機本身的話,那 nat 的規則根本就不需要理他,直接設定為開放即可。

不過,如果你的防火牆事實上是用來管制 LAN 内的其他主機的話,那麼你就必須要再針對 filter 的 FORWARD 這條鍊,還有 nat 的 PREROUTING, POSTROUTING 以及 OUTPUT 進行額外的規則訂定才行。 nat 表格的使用需要很清晰的路由概念才能夠設定的好,建議新手先不要碰!最多就是先玩一玩最陽春的 nat 功能『IP 分享器的功能』就好了! ^_^!這部份我們在本章的最後一小節會介紹的啦!

9.3.4 本機的 iptables 文法

理論上,當你安裝好 Linux 之後,系統應該會主動的幫你啟動一個陽春的防火牆規則才是, 不過這個陽春防火牆可能不是我們想要的模式,是以我們需要額外進行一些修訂的行為。不過,在開始進行底下的練習之前 鳥哥這裡有個很重要的事情要告知一下。因為 iptables 的指令會将網絡封包進行過濾及抵擋的動作,是以,請不要在遠端主機上進行防火牆的練習,因為你很有可能一不小心将自己關在家門外! 盡量在本機前面登入 tty1-tty6 終端機進行練習,否則常常會發生悲劇啊!鳥哥以前剛剛在玩 iptables 時,就常常因為不小心規則設定錯誤,導緻常常要請遠端的朋友幫忙重新啟動...

剛剛提到咱們的 iptables 至少有三個預設的 table (filter, nat, mangle),較常用的是本機的 filter 表格, 這也是預設表格啦。另一個則是後端主機的 nat 表格,至于 mangle 較少使用,是以這個章節我們并不會讨論 mangle。 由于不同的 table 他們的鍊不一樣,導緻使用的指令文法或多或少都有點差異。 在這個小節當中,我們主要将針對 filter 這個預設表格的三條鍊來做介紹。底下就來玩一玩吧!

Tips:

防火牆的設定主要使用的就是 iptables 這個指令而已。而防火牆是系統管理者的主要任務之一, 且對于系統的影響相當的大,是以『隻能讓 root 使用 iptables 』,不論是設定還是觀察防火牆規則喔!

9.3.4-1 規則的觀察與清除

如果你在安裝的時候選擇沒有防火牆的話,那麼 iptables 在一開始的時候應該是沒有規則的,不過, 可能因為你在安裝的時候就有選擇系統自動幫你建立防火牆機制,那系統就會有預設的防火牆規則了! 無論如何,我們先來看看目前本機的防火牆規則是如何吧!

[root@www ~]# iptables [-t tables] [-L] [-nv]選項與參數:-t :後面接 table ,例如 nat 或 filter ,若省略此項目,則使用預設的 filter-L :列出目前的 table 的規則-n :不進行 IP 與 HOSTNAME 的反查,顯示訊息的速度會快很多!-v :列出更多的資訊,包括通過該規則的封包總位數、相關的網絡接口等範例:列出 filter table 三條鍊的規則[root@www ~]# iptables -L -nChain INPUT (policy ACCEPT) <==針對 INPUT 鍊,且預設政策為可接受target prot opt source destination <==說明欄ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED <==第 1 條規則ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 <==第 2 條規則ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 <==第 3 條規則ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 <==以下類推REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibitedChain FORWARD (policy ACCEPT) <==針對 FORWARD 鍊,且預設政策為可接受target prot opt source destinationREJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibitedChain OUTPUT (policy ACCEPT) <==針對 OUTPUT 鍊,且預設政策為可接受target prot opt source destination範例:列出 nat table 三條鍊的規則[root@www ~]# iptables -t nat -L -nChain PREROUTING (policy ACCEPT)target prot opt source destinationChain POSTROUTING (policy ACCEPT)target prot opt source destinationChain OUTPUT (policy ACCEPT)target prot opt source destination

在上表中,每一個 Chain 就是前面提到的每個鍊啰~ Chain 那一行裡面括号的 policy 就是預設的政策, 那底下的 target, prot 代表什麼呢?

  • target:代表進行的動作, ACCEPT 是放行,而 REJECT 則是拒絕,此外,尚有 DROP (丢棄) 的項目!
  • prot:代表使用的封包協定,主要有 tcp, udp 及 icmp 三種封包格式;
  • opt:額外的選項說明
  • source :代表此規則是針對哪個『來源 IP』進行限制?
  • destination :代表此規則是針對哪個『目标 IP』進行限制?

在輸出結果中,第一個範例因為沒有加上 -t 的選項,是以預設就是 filter 這個表格内的 INPUT, OUTPUT, FORWARD 三條鍊的規則啰。若針對單機來說,INPUT 與 FORWARD 算是比較重要的管制防火牆鍊, 是以你可以發現最後一條規則的政策是 REJECT (拒絕) 喔!雖然 INPUT 與 FORWARD 的政策是放行 (ACCEPT), 不過在最後一條規則就已經将全部的封包都拒絕了!

不過這個指令的觀察隻是作個格式化的查閱,要詳細解釋每個規則會比較不容易解析。舉例來說, 我們将 INPUT 的 5 條規則依據輸出結果來說明一下,結果會變成:

  1. 隻要是封包狀态為 RELATED,ESTABLISHED 就予以接受
  2. 隻要封包協定是 icmp 類型的,就予以放行
  3. 無論任何來源 (0.0.0.0/0) 且要去任何目标的封包,不論任何封包格式 (prot 為 all),通通都接受
  4. 隻要是傳給 port 22 的主動式聯機 tcp 封包就接受
  5. 全部的封包資訊通通拒絕

最有趣的應該是第 3 條規則了,怎麼會所有的封包資訊都予以接受?如果都接受的話,那麼後續的規則根本就不會有用嘛! 其實那條規則是僅針對每部主機都有的内部循環測試網絡 (lo) 接口啦!如果沒有列出接口,那麼我們就很容易搞錯啰~ 是以,近來鳥哥都建議使用 iptables-save 這個指令來觀察防火牆規則啦!因為 iptables-save 會列出完整的防火牆規則,隻是并沒有規格化輸出而已。

[root@www ~]# iptables-save [-t table]選項與參數:-t :可以僅針對某些表格來輸出,例如僅針對 nat 或 filter 等等[root@www ~]# iptables-save# Generated by iptables-save v1.4.7 on Fri Jul 22 15:51:52 2011*filter <==星号開頭的指的是表格,這裡為 filter:INPUT ACCEPT [0:0] <==冒号開頭的指的是鍊,三條内建的鍊:FORWARD ACCEPT [0:0] <==三條内建鍊的政策都是 ACCEPT 啰!:OUTPUT ACCEPT [680:100461]-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT <==針對 INPUT 的規則-A INPUT -p icmp -j ACCEPT-A INPUT -i lo -j ACCEPT <==這條很重要!針對本機内部接口開放!-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT-A INPUT -j REJECT --reject-with icmp-host-prohibited-A FORWARD -j REJECT --reject-with icmp-host-prohibited <==針對 FORWARD 的規則COMMIT# Completed on Fri Jul 22 15:51:52 2011

由上面的輸出來看,有底線且内容含有 lo 的那條規則當中,『 -i lo 』指的就是由 lo 适配卡進來的封包! 這樣看就清楚多了!因為有寫到接口的關系啊!不像之前的 iptables -L -n 嘛!這樣了解乎! 不過,既然這個規則不是我們想要的,那該如何修改規則呢?鳥哥建議,先删除規則再慢慢建立各個需要的規則! 那如何清除規則?這樣做就對了:

[root@www ~]# iptables [-t tables] [-FXZ]選項與參數:-F :清除所有的已訂定的規則;-X :殺掉所有使用者 "自定義" 的 chain (應該說的是 tables )啰;-Z :将所有的 chain 的計數與流量統計都歸零範例:清除本機防火牆 (filter) 的所有規則[root@www ~]# iptables -F[root@www ~]# iptables -X[root@www ~]# iptables -Z

由于這三個指令會将本機防火牆的所有規則都清除,但卻不會改變預設政策 (policy) , 是以如果你不是在本機下達這三行指令時,很可能你會被自己擋在家門外 (若 INPUT 設定為 DROP 時)!要小心啊!

一般來說,我們在重新定義防火牆的時候,都會先将規則給他清除掉。還記得我們前面談到的, 防火牆的『規則順序』是有特殊意義的,是以啰, 當然先清除掉規則,然後一條一條來設定會比較容易一點啦。底下就來談談定義預設政策吧!

9.3.4-2 定義預設政策 (policy)

清除規則之後,再接下來就是要設定規則的政策啦!還記得政策指的是什麼嗎?『 當你的封包不在你設定的規則之内時,則該封包的通過與否,是以 Policy 的設定為準』,在本機方面的預設政策中,假設你對于内部的使用者有信心的話, 那麼 filter 内的 INPUT 鍊方面可以定義的比較嚴格一點,而 FORWARD 與 OUTPUT 則可以訂定的松一些!通常鳥哥都是将 INPUT 的 policy 定義為 DROP 啦,其他兩個則定義為 ACCEPT 至于 nat table 則暫時先不理會他。

[root@www ~]# iptables [-t nat] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP]選項與參數:-P :定義政策( Policy )。注意,這個 P 為大寫啊!ACCEPT :該封包可接受DROP :該封包直接丢棄,不會讓 client 端知道為何被丢棄。範例:将本機的 INPUT 設定為 DROP ,其他設定為 ACCEPT[root@www ~]# iptables -P INPUT DROP[root@www ~]# iptables -P OUTPUT ACCEPT[root@www ~]# iptables -P FORWARD ACCEPT[root@www ~]# iptables-save# Generated by iptables-save v1.4.7 on Fri Jul 22 15:56:34 2011*filter:INPUT DROP [0:0]:FORWARD ACCEPT [0:0]:OUTPUT ACCEPT [0:0]COMMIT# Completed on Fri Jul 22 15:56:34 2011# 由于 INPUT 設定為 DROP 而又尚未有任何規則,是以上面的輸出結果顯示:# 所有的封包都無法進入你的主機!是不通的防火牆設定!(網絡聯機是雙向的)

看到輸出的結果了吧?INPUT 被修改了設定喔!其他的 nat table 三條鍊的預設政策設定也是一樣的方式,例如:『 iptables -t nat -P PREROUTING ACCEPT 』就設定了 nat table 的 PREROUTING 鍊為可接受的意思!預設政策設定完畢後,來談一談關于各規則的封包基礎比對設定吧。

9.3.4-3 封包的基礎比對:IP, 網域及接口裝置

開始來進行防火牆規則的封包比對設定吧!既然是網際網路,那麼我們就由最基礎的 IP, 網域及埠口,亦即是 OSI 的第三層談起,再來談談裝置 (網絡卡) 的限制等等。這一小節與下一小節的文法你一定要記住,因為這是最基礎的比對文法喔!

[root@www ~]# iptables [-AI 鍊名] [-io 網絡接口] [-p 協定] \> [-s 來源IP/網域] [-d 目标IP/網域] -j [ACCEPT|DROP|REJECT|LOG]選項與參數:-AI 鍊名:針對某的鍊進行規則的 "插入" 或 "累加" -A :新增加一條規則,該規則增加在原本規則的最後面。例如原本已經有四條規則, 使用 -A 就可以加上第五條規則! -I :插入一條規則。如果沒有指定此規則的順序,預設是插入變成第一條規則。 例如原本有四條規則,使用 -I 則該規則變成第一條,而原本四條變成 2~5 号 鍊 :有 INPUT, OUTPUT, FORWARD 等,此鍊名稱又與 -io 有關,請看底下。-io 網絡接口:設定封包進出的接口規範 -i :封包所進入的那個網絡接口,例如 eth0, lo 等接口。需與 INPUT 鍊配合; -o :封包所傳出的那個網絡接口,需與 OUTPUT 鍊配合;-p 協定:設定此規則适用于哪種封包格式 主要的封包格式有: tcp, udp, icmp 及 all 。-s 來源 IP/網域:設定此規則之封包的來源項目,可指定單純的 IP 或包括網域,例如: IP :192.168.0.100 網域:192.168.0.0/24, 192.168.0.0/255.255.255.0 均可。 若規範為『不許』時,則加上 ! 即可,例如: -s ! 192.168.100.0/24 表示不許 192.168.100.0/24 之封包來源;-d 目标 IP/網域:同 -s ,隻不過這裡指的是目标的 IP 或網域。-j :後面接動作,主要的動作有接受(ACCEPT)、丢棄(DROP)、拒絕(REJECT)及記錄(LOG)

iptables 的基本參數就如同上面所示的,僅隻談到 IP 、網域與裝置等等的資訊, 至于 TCP, UDP 封包特有的埠口 (port number) 與狀态 (如 SYN 旗标) 則在下小節才會談到。 好,先讓我們來看看最基礎的幾個規則,例如開放 lo 這個本機的接口以及某個 IP 來源吧!

範例:設定 lo 成為受信任的裝置,亦即進出 lo 的封包都予以接受[root@www ~]# iptables -A INPUT -i lo -j ACCEPT

仔細看上面并沒有列出 -s, -d 等等的規則,這表示:不論封包來自何處或去到哪裡,隻要是來自 lo 這個界面,就予以接受!這個觀念挺重要的,就是『沒有指定的項目,則表示該項目完全接受』的意思! 例如這個案例當中,關于 -s, -d...等等的參數沒有規定時,就代表不論什麼值都會被接受啰。

這就是所謂的信任裝置啦!假如你的主機有兩張以太網絡卡,其中一張是對内部的網域,假設該網卡的代号為 eth1 好了, 如果内部網域是可信任的,那麼該網卡的進出封包就通通會被接受,那你就能夠用:『iptables -A INPUT -i eth1 -j ACCEPT』 來将該裝置設定為信任裝置。不過,下達這個指令前要特别注意,因為這樣等于該網卡沒有任何防備了喔!

範例:隻要是來自内網的 (192.168.100.0/24) 的封包通通接受[root@www ~]# iptables -A INPUT -i eth1 -s 192.168.100.0/24 -j ACCEPT# 由于是内網就接受,是以也可以稱之為『信任網域』啰。範例:隻要是來自 192.168.100.10 就接受,但 192.168.100.230 這個惡意來源就丢棄[root@www ~]# iptables -A INPUT -i eth1 -s 192.168.100.10 -j ACCEPT[root@www ~]# iptables -A INPUT -i eth1 -s 192.168.100.230 -j DROP# 針對單一 IP 來源,可視為信任主機或者是不信任的惡意來源喔![root@www ~]# iptables-save# Generated by iptables-save v1.4.7 on Fri Jul 22 16:00:43 2011*filter:INPUT DROP [0:0]:FORWARD ACCEPT [0:0]:OUTPUT ACCEPT [17:1724]-A INPUT -i lo -j ACCEPT-A INPUT -s 192.168.100.0/24 -i eth1 -j ACCEPT-A INPUT -s 192.168.100.10/32 -i eth1 -j ACCEPT-A INPUT -s 192.168.100.230/32 -i eth1 -j DROPCOMMIT# Completed on Fri Jul 22 16:00:43 2011

這就是最單純簡單的防火牆規則的設定與觀察方式。不過,在上面的案例中,其實你也發現到有兩條規則可能有問題~ 那就是上面的特殊字型圈起來的規則順序。明明已經放行了 192.168.100.0/24 了,是以那個 192.168.100.230 的規則就不可能會被用到!這就是有問題的防火牆設定啊!了解乎?那該怎辦?就重打啊!@_@! 那如果你想要記錄某個規則的紀錄怎麼辦?可以這樣做:

[root@www ~]# iptables -A INPUT -s 192.168.2.200 -j LOG[root@www ~]# iptables -L -ntarget prot opt source destinationLOG all -- 192.168.2.200 0.0.0.0/0 LOG flags 0 level 4

看到輸出結果的最左邊,會出現的是 LOG 喔!隻要有封包來自 192.168.2.200 這個 IP 時, 那麼該封包的相關資訊就會被寫入到核心訊息,亦即是 /var/log/messages 這個檔案當中。 然後該封包會繼續進行後續的規則比對。是以說, LOG 這個動作僅在進行記錄而已,并不會影響到這個封包的其他規則比對的。 好了,接下來我們分别來看看 TCP,UDP 以及 ICMP 封包的其他規則比對吧!

9.3.4-4 TCP, UDP 的規則比對:針對埠口設定

我們在​​第二章網絡基礎​​談過各種不同的封包格式, 在談到 TCP 與 UDP 時,比較特殊的就是那個埠口 (port),在 TCP 方面則另外有所謂的聯機封包狀态, 包括最常見的 SYN 主動聯機的封包格式。那麼如何針對這兩種封包格式進行防火牆規則的設定呢?你可以這樣看:

[root@www ~]# iptables [-AI 鍊] [-io 網絡接口] [-p tcp,udp] \> [-s 來源IP/網域] [--sport 埠口範圍] \> [-d 目标IP/網域] [--dport 埠口範圍] -j [ACCEPT|DROP|REJECT]選項與參數:--sport 埠口範圍:限制來源的端口号碼,端口号碼可以是連續的,例如 1024:65535--dport 埠口範圍:限制目标的端口号碼。

事實上就是多了那個 --sport 及 --dport 這兩個玩意兒,重點在那個 port 上面啦! 不過你得要特别注意,因為僅有 tcp 與 udp 封包具有埠口,是以你想要使用 --dport, --sport 時,得要加上 -p tcp 或 -p udp 的參數才會成功喔!底下讓我們來進行幾個小測試:

範例:想要聯機進入本機 port 21 的封包都抵擋掉:[root@www ~]# iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP範例:想連到我這部主機的網芳 (upd port 137,138 tcp port 139,445) 就放行[root@www ~]# iptables -A INPUT -i eth0 -p udp --dport 137:138 -j ACCEPT[root@www ~]# iptables -A INPUT -i eth0 -p tcp --dport 139 -j ACCEPT[root@www ~]# iptables -A INPUT -i eth0 -p tcp --dport 445 -j ACCEPT

瞧!你可以利用 UDP 與 TCP 協定所擁有的端口号碼來進行某些服務的開放或關閉喔!你還可以綜合處理呢!例如:隻要來自 192.168.1.0/24 的 1024:65535 埠口的封包,且想要聯機到本機的 ssh port 就予以抵擋,可以這樣做:

[root@www ~]# iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 \> --sport 1024:65534 --dport ssh -j DROP

如果忘記加上 -p tcp 就使用了 --dport 時,會發生啥問題呢?

[root@www ~]# iptables -A INPUT -i eth0 --dport 21 -j DROPiptables v1.4.7: unknown option `--dport'Try `iptables -h' or 'iptables --help' for more information.

你應該會覺得很奇怪,怎麼『 --dport 』會是未知的參數 (arg) 呢?這是因為你沒有加上 -p tcp 或 -p ud 的緣故啊!很重要喔!

除了埠口之外,在 TCP 還有特殊的旗标啊!最常見的就是那個主動聯機的 SYN 旗标了。 我們在 iptables 裡面還支援『 --syn 』的處理方式,我們以底下的例子來說明好了:

範例:将來自任何地方來源 port 1:1023 的主動聯機到本機端的 1:1023 聯機丢棄[root@www ~]# iptables -A INPUT -i eth0 -p tcp --sport 1:1023 \> --dport 1:1023 --syn -j DROP

一般來說,client 端啟用的 port 都是大于 1024 以上的埠口,而 server 端則是啟用小于 1023 以下的埠口在監聽的。是以我們可以讓來自遠端的小于 1023 以下的端口資料的主動聯機都給他丢棄! 但不适用在 FTP 的主動聯機中!這部份我們未來在二十一章的 FTP 伺服器再來談吧!

9.3.4-5 iptables 外挂子產品:mac 與 state

在 kernel 2.2 以前使用 ipchains 管理防火牆時,通常會讓系統管理者相當頭痛!因為 ipchains 沒有所謂的封包狀态子產品,是以我們必須要針對封包的進、出方向進行管控。舉例來說,如果你想要聯機到遠端主機的 port 22 時,你必須要針對兩條規則來設定:

  • 本機端的 1024:65535 到遠端的 port 22 必須要放行 (OUTPUT 鍊);
  • 遠端主機 port 22 到本機的 1024:65535 必須放行 (INPUT 鍊);

這會很麻煩!因為如果你要聯機到 10 部主機的 port 22 時,假設 OUTPUT 為預設開啟 (ACCEPT), 你依舊需要填寫十行規則,讓那十部遠端主機的 port 22 可以聯機到你的本地端主機上。 那如果開啟全部的 port 22 呢?又擔心某些惡意主機會主動以 port 22 聯機到你的機器上! 同樣的道理,如果你要讓本地端主機可以連到外部的 port 80 (WWW 服務),那就更不得了~ 這就是網絡聯機是雙向的一個很重要的概念!

好在我們的 iptables 免除了這個困擾!他可以透過一個狀态子產品來分析 『這個想要進入的封包是否為剛剛我發出去的響應?』 如果是剛剛我發出去的響應,那麼就可以予以接受放行!哇!真棒!這樣就不用管遠端主機是否聯機進來的問題了! 那如何達到呢?看看底下的文法:

[root@www ~]# iptables -A INPUT [-m state] [--state 狀态]選項與參數:-m :一些 iptables 的外挂子產品,主要常見的有: state :狀态子產品 mac :網絡卡硬體位址 (hardware address)--state :一些封包的狀态,主要有: INVALID :無效的封包,例如資料破損的封包狀态 ESTABLISHED:已經聯機成功的聯機狀态; NEW :想要建立立聯機的封包狀态; RELATED :這個最常用!表示這個封包是與我們主機發送出去的封包有關範例:隻要已建立或相關封包就予以通過,隻要是不合法封包就丢棄[root@www ~]# iptables -A INPUT -m state \> --state RELATED,ESTABLISHED -j ACCEPT[root@www ~]# iptables -A INPUT -m state --state INVALID -j DROP

如此一來,我們的 iptables 就會主動分析出該封包是否為響應狀态,若是的話,就直接予以接受。呵呵! 這樣一來你就不需要針對響應的封包來撰寫個别的防火牆規則了!這真是太棒了!底下我們繼續談一下 iptables 的另一個外挂, 那就是針對網卡來進行放行與防禦:

範例:針對區域網路絡内的 aa:bb:cc:dd:ee:ff 主機開放其聯機[root@www ~]# iptables -A INPUT -m mac --mac-source aa:bb:cc:dd:ee:ff \> -j ACCEPT選項與參數:--mac-source :就是來源主機的 MAC 啦!

如果你的區網當中有某些網絡高手,老是可以透過修改 IP 去嘗試透過路由器往外跑,那你該怎麼辦? 難道将整個區網拒絕?并不需要的,你可以透過之前談到的 ARP 相關概念,去捉到那部主機的 MAC ,然後透過上頭的這個機制, 将該主機整個 DROP 掉即可。不管他改了什麼 IP ,除非他知道你是用網卡的 MAC 來管理,否則他就是出不去啦!了解乎?

Tips:

其實 MAC 也是可以僞裝的,可以透過某些軟體來修改網卡的 MAC。不過,這裡我們是假設 MAC 是無法修改的情況來說明的。 此外,MAC 是不能跨路由的,是以上述的案例中才特别說明是在區網内,而不是指 Internet 外部的來源唷!

9.3.4-6 ICMP 封包規則的比對:針對是否響應 ping 來設計

在​​第二章 ICMP 協定當中​​我們知道 ICMP 的類型相當的多,而且很多 ICMP 封包的類型都是為了要用來進行網絡檢測用的!是以最好不要将所有的 ICMP 封包都丢棄!如果不是做為路由器的主機時,通常我們會把 ICMP type 8 (echo request) 拿掉而已,讓遠端主機不知道我們是否存在,也不會接受 ping 的響應就是了。ICMP 封包格式的處理是這樣的:

[root@www ~]# iptables -A INPUT [-p icmp] [--icmp-type 類型] -j ACCEPT選項與參數:--icmp-type :後面必須要接 ICMP 的封包類型,也可以使用代号, 例如 8 代表 echo request 的意思。範例:讓 0,3,4,11,12,14,16,18 的 ICMP type 可以進入本機:[root@www ~]# vi somefile#!/bin/bashicmp_type="0 3 4 11 12 14 16 18"for typeicmp in $icmp_typedo iptables -A INPUT -i eth0 -p icmp --icmp-type $typeicmp -j ACCEPTdone[root@www ~]# sh somefile

這樣就能夠開放部分的 ICMP 封包格式進入本機進行網絡檢測的工作了!不過,如果你的主機是作為區網的路由器, 那麼建議 icmp 封包還是要通通放行才好!這是因為用戶端檢測網絡時,常常會使用 ping 來測試到路由器的線路是否暢通之故呦! 是以不要将路由器的 icmp 關掉,會有狀況啦!

9.3.4-7 超陽春用戶端防火牆設計與防火牆規則儲存

經過上述的本機 iptables 文法分析後,接下來我們來想想,如果站在用戶端且不提供網絡服務的 Linux 本機角色時, 你應該要如何設計你的防火牆呢?老實說,你隻要分析過 CentOS 預設的防火牆規則就會知道了,理論上, 應該要有的規則如下:

  1. 規則歸零:清除所有已經存在的規則 (iptables -F...)
  2. 預設政策:除了 INPUT 這個自定義鍊設為 DROP 外,其他為預設 ACCEPT;
  3. 信任本機:由于 lo 對本機來說是相當重要的,是以 lo 必須設定為信任裝置;
  4. 回應封包:讓本機主動向外要求而響應的封包可以進入本機 (ESTABLISHED,RELATED)
  5. 信任使用者:這是非必要的,如果你想要讓區網的來源可用你的主機資源時

這就是最最陽春的防火牆,你可以透過第二步驟抵擋所有遠端的來源封包,而透過第四步驟讓你要求的遠端主機響應封包可以進入, 加上讓本機的 lo 這個内部循環裝置可以放行,嘿嘿!一部 client 專用的防火牆規則就 OK 了!你可以在某個 script 上面這樣做即可:

[root@www ~]# vim bin/firewall.sh#!/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/bin; export PATH# 1. 清除規則iptables -Fiptables -Xiptables -Z# 2. 設定政策iptables -P INPUT DROPiptables -P OUTPUT ACCEPTiptables -P FORWARD ACCEPT# 3~5. 制訂各項規則iptables -A INPUT -i lo -j ACCEPTiptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT#iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT# 6. 寫入防火牆規則配置檔案/etc/init.d/iptables save[root@www ~]# sh bin/firewall.shiptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]

其實防火牆也是一個服務,你可以透過『chkconfig --list iptables』去察看就知道了。 是以,你這次修改的各種設定想要在下次開機還儲存,那就得要進行『 /etc/init.d/iptables save 』這個指令加參數。 是以,鳥哥現在都是将儲存的動作寫入這個 firewall.sh 腳本中,比較單純些啰!現在,你的 Linux 主機已經有相當的保護了, 隻是如果想要作為伺服器,或者是作為路由器,那就得要自行加上某些自定義的規則啰。

Tips:

老實說,如果你對 Linux 夠熟悉的話,直接去修改 /etc/sysconfig/iptables 然後将 iptables 這個服務 restart 那你的防火牆規則就是會在開機後持續存在啰!不過,鳥哥個人還是喜歡寫 scripts 就是了。

制訂好規則後當然就是要測試啰!那麼如何測試呢?

  1. 先由主機向外面主動聯機試看看;
  2. 再由私有網域内的 PC 向外面主動聯機試看看;
  3. 最後,由 Internet 上面的主機,主動聯機到你的 Linux 主機試看看;

一步一步作下來,看看問題出在哪裡,然後多多的去改進、改良!基本上,網絡上目前很多的資料可以提供你不錯的參考了! 這一篇的設定寫的是很簡單,大部分都還在介紹階段而已!希望對大家有幫助! 鳥哥在​​參考資料(注2)​​當中列出幾個有用的防火牆網頁,希望大家有空真的要多多的去看看!會很有幫助的!

9.3.5 IPv4 的核心管理功能: /proc/sys/net/ipv4/*

除了 iptables 這個防火牆軟體之外,其實咱們 Linux kernel 2.6 提供很多核心預設的攻擊抵擋機制喔! 由于是核心的網絡功能,是以相關的設定資料都是放置在 /proc/sys/net/ipv4/ 這個目錄當中。 至于該目錄下各個檔案的詳細資料,可以參考核心的說明檔案 (你得要先安裝 kernel-doc 軟體):

  • /usr/share/doc/kernel-doc-2.6.32/Documentation/networking/ip-sysctl.txt

鳥哥這裡也放一份備份:

  • ​​http:/linux.vbird.org/linux_server/0250simple_firewall/ip-sysctl.txt​​

有興趣的話應該要自行去查一查比較好的喔!我們底下就拿幾個簡單的檔案來作說明吧!

  • /proc/sys/net/ipv4/tcp_syncookies

    我們在前一章談到所謂的​​​阻斷式服務 (DoS)​​​ 攻擊法當中的一種方式,就是利用 TCP 封包的 ​​SYN 三向交握​​​原理所達成的, 這種方式稱為 SYN Flooding 。那如何預防這種方式的攻擊呢?我們可以啟用核心的 SYN Cookie 子產品啊! 這個 SYN Cookie 子產品可以在系統用來啟動随機聯機的埠口 (1024:65535) 即将用完時自動啟動。

    當啟動 SYN Cookie 時,主機在發送 SYN/ACK 确認封包前,會要求 Client 端在短時間内回複一個序号,這個序号包含許多原本 SYN 封包内的資訊,包括 IP、port 等。若 Client 端可以回複正确的序号,那麼主機就确定該封包為可信的,是以會發送 SYN/ACK 封包,否則就不理會此一封包。

    透過此一機制可以大大的降低無效的 SYN 等待埠口,而避免 SYN Flooding 的 DoS 攻擊說! 那麼如何啟動這個子產品呢?很簡單,這樣做即可:

[root@www ~]# echo "1" > /proc/sys/net/ipv4/tcp_syncookies
  • 但是這個設定值由于違反 TCP 的三向交握 (因為主機在發送 SYN/ACK 之前需要先等待 client 的序号響應), 是以可能會造成某些服務的延遲現象,例如 SMTP (mail server)。 不過總的來說,這個設定值還是不錯用的! 隻是不适合用在負載已經很高的伺服器内喔! 因為負載太高的主機有時會讓核心誤判遭受 SYN Flooding 的攻擊呢。

    如果是為了系統的 TCP 封包聯機優化,則可以參考 tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow 這幾個設定值的意義。

  • /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

    阻斷式服務常見的是 SYN Flooding ,不過,我們知道系統其實可以接受使用 ping 的響應, 而 ​​​ping​​​ 的封包資料量是可以給很大的!想象一個狀況, 如果有個搞破壞的人使用 1000 台主機傳送 ping 給你的主機,而且每個 ping 都高達數百 K bytes時, 你的網絡帶寬會怎樣?要嘛就是帶寬被吃光,要嘛可能系統會當機! 這種方式分别被稱為 ping flooding (不斷發 ping) 及 ping of death (發送大的 ping 封包)。

    那如何避免呢?取消 ICMP 類型 8 的 ICMP 封包回應就是了。我們可以透過防火牆來抵擋, 這也是比較建議的方式。當然也可以讓核心自動取消 ping 的響應。不過你必須要了解, 某些區域網路絡内常見的服務 (例如動态 IP 配置設定 DHCP 協定) 會使用 ping 的方式來偵測是否有重複的 IP ,是以你最好不要取消所有的 ping 響應比較好。

    核心取消 ping 回應的設定值有兩個,分别是:/proc/sys/net/ipv4 内的 icmp_echo_ignore_broadcasts (僅有 ping broadcast 位址時才取消 ping 的回應) 及 icmp_echo_ignore_all (全部的 ping 都不回應)。鳥哥建議設定 icmp_echo_ignore_broadcasts 就好了。 你可以這麼做:

[root@www ~]# echo "1" > \> /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
  • /proc/sys/net/ipv4/conf/網絡接口/*

    咱們的核心還可以針對不同的網絡接口進行不一樣的參數設定喔!網絡接口的相關設定放置在 /proc/sys/net/ipv4/conf/ 當中,每個接口都以接口代号做為其代表,例如 eth0 接口的相關設定資料在 /proc/sys/net/ipv4/conf/eth0/ 内。那麼網絡接口的設定資料有哪些比較需要注意的呢? 大概有底下這幾個:

  • rp_filter:稱為逆向路徑過濾 (Reverse Path Filtering), 可以藉由分析網絡接口的路由資訊配合封包的來源位址,來分析該封包是否為合理。舉例來說,你有兩張網卡,eth0 為 192.168.1.10/24 ,eth1 為 public IP 。那麼當有一個封包自稱來自 eth1 ,但是其 IP 來源為 192.168.1.200 , 那這個封包就不合理,應予以丢棄。這個設定值建議可以啟動的。
  • log_martians:這個設定資料可以用來啟動記錄不合法的 IP 來源, 舉例來說,包括來源為 0.0.0.0、127.x.x.x、及 Class E 的 IP 來源,因為這些來源的 IP 不應該應用于 Internet 啊。 記錄的資料預設放置到核心放置的登入檔 /var/log/messages。
  • accept_source_route:或許某些路由器會啟動這個設定值, 不過目前的裝置很少使用到這種來源路由,你可以取消這個設定值。
  • accept_redirects:當你在同一個實體網域内架設一部路由器, 但這個實體網域有兩個 IP 網域,例如 192.168.0.0/24, 192.168.1.0/24。此時你的 192.168.0.100 想要向 192.168.1.100 傳送訊息時,路由器可能會傳送一個 ICMP redirect 封包告知 192.168.0.100 直接傳送資料給 192.168.1.100 即可,而不需透過路由器。因為 192.168.0.100 與 192.168.1.100确實是在同一個實體線路上 (兩者可以直接互通),是以路由器會告知來源 IP 使用最短路徑去傳遞資料。但那兩部主機在不同的 IP 段,卻是無法實際傳遞訊息的!這個設定也可能會産生一些輕微的安全風險,是以建議關閉他。
  • send_redirects:與上一個類似,隻是此值為發送一個 ICMP redirect 封包。 同樣建議關閉。(事實上,鳥哥就曾經為了這個 ICMP redirect 的問題傷腦筋!其實關閉 redirect 的這兩個項目即可啊!)
  • 雖然你可以使用『 echo "1" > /proc/sys/net/ipv4/conf/???/rp_filter 』之類的方法來啟動這個項目,不過, 鳥哥比較建議修改系統設定值,那就是 /etc/sysctl.conf 這個檔案!假設我們僅有 eth0 這個以太接口,而且上述的功能要通通啟動, 那你可以這樣做:
[root@www ~]# vim /etc/sysctl.conf# Adding by VBird 2011/01/28net.ipv4.tcp_syncookies = 1net.ipv4.icmp_echo_ignore_broadcasts = 1net.ipv4.conf.all.rp_filter = 1net.ipv4.conf.default.rp_filter = 1net.ipv4.conf.eth0.rp_filter = 1net.ipv4.conf.lo.rp_filter = 1....(以下省略)....[root@www ~]# sysctl -p

9.4 單機防火牆的一個執行個體

介紹了這麼多的防火牆文法與相關的注意事項後,終于要來架設防火牆了。鳥哥還是比較偏好使用腳本來撰寫防火牆, 然後透過最終的 /etc/init.d/iptables save 來将結果儲存到 /etc/sysconfig/iptables 去! 而且此一特色還可以用在呼叫其他的 scripts ,可以讓防火牆規則具有較為靈活的使用方式。 好了,那就來談談如何設定咱們的防火牆規則吧!

9.4.1 規則草拟

鳥哥底下介紹的這個防火牆,其實可以用來作為路由器上的防火牆,也可以用來作為本機的防火牆。 假設硬體聯機如同下圖所示, Linux 主機本身也是内部 LAN 的路由器!亦即是一個簡單的 IP 分享器的功能啦!依據第三章的​​圖 3.2-1​​ 假設鳥哥網絡接口有底下這些:

  • 外部網絡使用 eth0 (如果是撥接,有可能是 ppp0,請針對你的環境來設定);
  • 内部網絡使用 eth1 ,且内部使用 192.168.100.0/24 這個 Class ;
  • 主機預設開放的服務有 WWW, SSH, https 等等;

圖 9.4-1、一個區域網路絡的路由器架構示意圖

由于希望将信任網域 (LAN) 與不信任網域 (Internet) 整個分開的完整一點, 是以希望你可以在 Linux 上面安裝兩塊以上的實體網卡,将兩塊網卡接在不同的網域,這樣可以避免很多問題。 至于最重要的防火牆政策是:『關閉所有的聯機,僅開放特定的服務』模式。 而且假設内部使用者已經受過良好的訓練,是以在 filter table 的三條鍊個預設政策是:

  • INPUT 為 DROP
  • OUTPUT 及 FORWARD 為 ACCEPT

鳥哥底下預計提供的防火牆流程是這樣的:

圖 9.4-2、本機的防火牆規則流程示意圖

原則上,内部 LAN 主機與主機本身的開放度很高,因為 Output 與 Forward 是完全開放不理的!對于小家庭的主機是可以接受的,因為我們内部的計算機數量不多,而且人員都是熟悉的, 是以不需要特别加以控管!但是:『在大企業的内部,這樣的規劃是很不合格的, 因為你不能保證内部所有的人都可以按照你的規定來使用 Network !』也就是說『家賊難防』呀! 是以,那樣的環境連 Output 與 Forward 都需要特别加以管理才行!

9.4.2 實際設定

事實上,我們在設定防火牆的時候,不太可能會一個一個指令的輸入,通常是利用 shell scripts 來幫我們達成這樣的功能吶!底下是利用上面的流程圖所規劃出來的防火牆腳本,你可以參考看看, 但是你需要将環境修改成适合你自己的環境才行喔!此外,為了未來修改維護的友善,鳥哥将整個 script 拆成三部分,分别是:

  • iptables.rule:設定最基本的規則,包括清除防火牆規則、加載子產品、設定服務可接受等;
  • iptables.deny:設定抵擋某些惡意主機的進入;
  • iptables.allow:設定允許某些自定義的後門來源主機!

鳥哥個人習慣是将這個腳本放置到 /usr/local/virus/iptables 目錄下,你也可以自行放置到自己習慣的位置去。 那底下就來瞧瞧這支腳本是怎麼寫的吧!

[root@www ~]# mkdir -p /usr/local/virus/iptables[root@www ~]# cd /usr/local/virus/iptables[root@www iptables]# vim iptables.rule#!/bin/bash# 請先輸入您的相關參數,不要輸入錯誤了! EXTIF="eth0" # 這個是可以連上 Public IP 的網絡接口 INIF="eth1" # 内部 LAN 的連接配接接口;若無則寫成 INIF="" INNET="192.168.100.0/24" # 若無内部網域接口,請填寫成 INNET="" export EXTIF INIF INNET# 第一部份,針對本機的防火牆設定!########################################### 1. 先設定好核心的網絡功能: echo "1" > /proc/sys/net/ipv4/tcp_syncookies echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts for i in /proc/sys/net/ipv4/conf/*/{rp_filter,log_martians}; do echo "1" > $i done for i in /proc/sys/net/ipv4/conf/*/{accept_source_route,accept_redirects,\send_redirects}; do echo "0" > $i done# 2. 清除規則、設定預設政策及開放 lo 與相關的設定值 PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin; export PATH iptables -F iptables -X iptables -Z iptables -P INPUT DROP iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT# 3. 啟動額外的防火牆 script 子產品 if [ -f /usr/local/virus/iptables/iptables.deny ]; then sh /usr/local/virus/iptables/iptables.deny fi if [ -f /usr/local/virus/iptables/iptables.allow ]; then sh /usr/local/virus/iptables/iptables.allow fi if [ -f /usr/local/virus/httpd-err/iptables.http ]; then sh /usr/local/virus/httpd-err/iptables.http fi# 4. 允許某些類型的 ICMP 封包進入 AICMP="0 3 3/4 4 11 12 14 16 18" for tyicmp in $AICMP do iptables -A INPUT -i $EXTIF -p icmp --icmp-type $tyicmp -j ACCEPT done# 5. 允許某些服務的進入,請依照你自己的環境開啟# iptables -A INPUT -p TCP -i $EXTIF --dport 21 --sport 1024:65534 -j ACCEPT # FTP# iptables -A INPUT -p TCP -i $EXTIF --dport 22 --sport 1024:65534 -j ACCEPT # SSH# iptables -A INPUT -p TCP -i $EXTIF --dport 25 --sport 1024:65534 -j ACCEPT # SMTP# iptables -A INPUT -p UDP -i $EXTIF --dport 53 --sport 1024:65534 -j ACCEPT # DNS# iptables -A INPUT -p TCP -i $EXTIF --dport 53 --sport 1024:65534 -j ACCEPT # DNS# iptables -A INPUT -p TCP -i $EXTIF --dport 80 --sport 1024:65534 -j ACCEPT # WWW# iptables -A INPUT -p TCP -i $EXTIF --dport 110 --sport 1024:65534 -j ACCEPT # POP3# iptables -A INPUT -p TCP -i $EXTIF --dport 443 --sport 1024:65534 -j ACCEPT # HTTPS

特别留意上面程式代碼的特殊字型部分,基本上,你隻要修改一下最上方的接口部分, 應該就能夠運作這個防火牆了。不過因為每個人的環境都不相同, 是以你在設定完成後,依舊需要測試一下才行喔!不然,出了問題不要怪我啊!.... 再來看一下關于 iptables.allow 的内容是如何?假如我要讓一個 140.116.44.0/24 這個網域的所有主機來源可以進入我的主機的話,那麼這個檔案的内容可以寫成這樣:

[root@www iptables]# vim iptables.allow#!/bin/bash# 底下則填寫你允許進入本機的其他網域或主機啊! iptables -A INPUT -i $EXTIF -s 140.116.44.0/24 -j ACCEPT# 底下則是關于抵擋的檔案設定法![root@www iptables]# vim iptables.deny#!/bin/bash# 底下填寫的是『你要抵擋的那個咚咚!』 iptables -A INPUT -i $EXTIF -s 140.116.44.254 -j DROP[root@www iptables]# chmod 700 iptables.*

将這三個檔案的權限設定為 700 且隻屬于 root 的權限後,就能夠直接執行 iptables.rule 啰! 不過要注意的是,在上面的案例當中,鳥哥預設将所有的服務的通道都是關閉的! 是以你必須要到​​本機防火牆的第 5 步驟​​處将一些批注符号 (#) 解開才行。 同樣的,如果有其他更多的 port 想要開啟時,一樣需要增加額外的規則才行喔!

不過,還是如同前面我們所說的,這個 firewall 僅能提供基本的安全防護,其他的相關問題還需要再測試測試呢! 此外,如果你希望一開機就自動執行這個 script 的話,請将這個檔案的完整檔名寫入 /etc/rc.d/rc.local 當中,有點像底下這樣:

[root@www ~]# vim /etc/rc.d/rc.local....(其他省略)....# 1. Firewall/usr/local/virus/iptables/iptables.rule

事實上,這個腳本的最底下已經加入寫入防火牆預設規則檔案的功能,是以你隻要執行一次,就擁有最正确的規則了! 上述的 rc.local 僅是預防萬一而已。 ^_^!上述三個檔案請你不要在 Windows 系統上面編輯後才傳送到 Linux 上運作,因為 Windows 系統的斷行字元問題,将可能導緻該檔案無法執行。建議你直接到底下去下載下傳,傳送到 Linux 後可以利用 ​​dos2unix​​ 指令去轉換斷行字元!就不會有問題!

  • ​​http://linux.vbird.org/download/index.php?action=detail&fileid=43​​

這就是一個最簡單、陽春的防火牆。同時,這個防火牆還可以具有最陽春的 IP 分享器的功能呢! 也就是在 ​​iptables.rule​​ 這個檔案當中的第二部分了。 這部分我們在下一節會再繼續介紹的。

9.5 NAT 伺服器的設定

呼呼!終于來到這個地方了!我們準備要架設一個​​路由器​​的延伸伺服器,就稱之為 NAT 伺服器。 NAT 是什麼呢?簡單的說,你可以稱他為内部 LAN 主機的『 IP 分享器』啦!

NAT 的全名是 Network Address Translation,字面上的意思是『網絡位址的轉換』。由字面上的意思我們來想一想, TCP/IP 的網絡封包不是有 IP 位址嗎?那 IP 位址不是有來源與目的嗎?我們的 iptables 指令就能夠修改 IP 封包的表頭資料, 嘿嘿!連目标或來源的 IP 位址都可以修改呢!甚至連 TCP 封包表頭的 port number 也能修改!真是有趣!

NAT 伺服器的功能可以達到類似​​圖 9.1-2​​​所介紹的類似 IP 分享的功能之外, 還可以達到類似​​圖 9.1-4​​所介紹的 DMZ (非軍事區) 的功能!這完全取決于我們的 NAT 是修改: (1)來源 IP 還是 (2)目标 IP !底下我們就來聊一聊吧! ^_^

9.5.1 什麼是 NAT? SNAT? DNAT?

在談到 NAT 的實際運作之前,讓我們再來看一下比較簡單的封包透過 iptables 而傳送到後端主機的表格與鍊流程(請往前參考​​圖 9.3-4​​​)。 當網絡布線如​​圖 9.1-2​​的架構,若内部 LAN 有任何一部主機想要傳送封包出去時, 那麼這個封包要如何透過 Linux 主機而傳送出去?他是這樣的:

  1. 先經過 NAT table 的 PREROUTING 鍊;
  2. 經由路由判斷确定這個封包是要進入本機與否,若不進入本機,則下一步;
  3. 再經過 Filter table 的 FORWARD 鍊;
  4. 通過 NAT table 的 POSTROUTING 鍊,最後傳送出去。

NAT 伺服器的重點就在于上面流程的第 1,4 步驟,也就是 NAT table 的兩條重要的鍊:PREROUTING 與 POSTROUTING。 那這兩條鍊有什麼重要的功能呢?重點在于修改 IP 嘛!但是這兩條鍊修改的 IP 是不一樣的! POSTROUTING 在修改來源 IP ,PREROUTING 則在修改目标 IP 。 由于修改的 IP 不一樣,是以就稱為來源 NAT (Source NAT, SNAT) 及目标 NAT (Destination NAT, DNAT)。我們先來談一談 IP 分享器功能的 SNAT 吧!

  • 來源 NAT, SNAT:修改封包表頭的『來源』項目

    你應該有聽說過 IP 分享器這個玩意兒,他可以讓你家庭裡的好幾部主機同時透過一條 ADSL 網絡聯機到 Internet 上面, 例如​​​圖 9.1-2​​​聯機的方式來說,那個 Linux 主機就是 IP 分享器啦!那麼他是如何達到 IP 分享的功能?就是透過 NAT 表格的 POSTROUTING 來處理的。假設你的網絡布線如​​圖 9.1-2​​​所示, 那麼 NAT 伺服器是如何處理這個封包的呢?

    圖 9.5-1、SNAT 封包傳送出去的示意圖

    如上圖所示,在用戶端 192.168.1.100 這部主機要聯機到 http://tw.yahoo.com 去時,他的封包表頭會如何變化?

  1. 用戶端所發出的封包表頭中,來源會是 192.168.1.100 ,然後傳送到 NAT 這部主機;
  2. NAT 這部主機的内部接口 (192.168.1.2) 接收到這個封包後,會主動分析表頭資料, 因為表頭資料顯示目的并非 Linux 本機,是以開始經過路由, 将此封包轉到可以連接配接到 Internet 的 Public IP 處;
  3. 由于 private IP 與 public IP 不能互通,是以 Linux 主機透過 iptables 的 NAT table 内的 Postrouting 鍊将封包表頭的來源僞裝成為 Linux 的 Public IP ,并且将兩個不同來源 (192.168.1.100 及 public IP) 的封包對應寫入暫存記憶體當中, 然後将此封包傳送出去了;
  4. 此時 Internet 上面看到這個封包時,都隻會知道這個封包來自那個 Public IP 而不知道其實是來自内部啦。 好了,那麼如果 Internet 回傳封包呢?又會怎麼作?

    圖 9.5-2、SNAT 封包接收的示意圖

  1. 在 Internet 上面的主機接到這個封包時,會将響應資料傳送給那個 Public IP 的主機;
  2. 當 Linux NAT 伺服器收到來自 Internet 的回應封包後,會分析該封包的序号,并比對剛剛記錄到記憶體當中的資料, 由于發現該封包為後端主機之前傳送出去的,是以在 NAT Prerouting 鍊中,會将目标 IP 修改成為後端主機,亦即那部 192.168.1.100,然後發現目标已經不是本機 (public IP), 是以開始透過路由分析封包流向;
  3. 封包會傳送到 192.168.1.2 這個内部接口,然後再傳送到最終目标 192.168.1.100 機器上去!
  4. 經過這個流程,你就可以發現到,所有内部 LAN 的主機都可以透過這部 NAT 伺服器聯機出去, 而大家在 Internet 上面看到的都是同一個 IP (就是 NAT 那部主機的 public IP 啦!), 是以,如果内部 LAN 主機沒有連上不明網站的話,那麼内部主機其實是具有一定程度的安全性的啦! 因為 Internet 上的其他主機沒有辦法主動攻擊你的 LAN 内的 PC 嘛!是以我們才會說, NAT 最簡單的功能就是類似 IP 分享器啦!那也是 SNAT 的一種。

Tips:

NAT 伺服器與路由器有啥不同?基本上,NAT 伺服器一定是路由器,不過, NAT 伺服器由于會修改 IP 表頭資料, 是以與單純轉遞封包的路由器不同。最常見的 IP 分享器就是一個路由器,但是這個 IP 分享器一定會有一個 Public IP 與一個 Private IP,讓 LAN 内的 Private IP 可以透過 IP 分享器的 Public IP 傳送出去喔! 至于路由器通常兩邊都是 Public IP 或同時為 Private IP。

  • 目标 NAT, DNAT:修改封包表頭的『目标』項目

    SNAT 主要是應付内部 LAN 連接配接到 Internet 的使用方式,至于 DNAT 則主要用在内部主機想要架設可以讓 Internet 存取的伺服器啦! 就有點類似​​​圖 9.1-4​​​的 DMZ 内的伺服器啊!底下也先來談一談 DNAT 的運作吧!

    圖 9.5-3、DNAT 的封包傳送示意圖

    如上圖所示,假設我的内部主機 192.168.1.210 啟動了 WWW 服務,這個服務的 port 開啟在 port 80 , 那麼 Internet 上面的主機 (61.xx.xx.xx) 要如何連接配接到我的内部伺服器呢?當然啦, 還是得要透過 Linux NAT 伺服器嘛!是以這部 Internet 上面的機器必須要連接配接到我們的 NAT 的 public IP 才行。

  1. 外部主機想要連接配接到目的端的 WWW 服務,則必須要連接配接到我們的 NAT 伺服器上頭;
  2. 我們的 NAT 伺服器已經設定好要分析出 port 80 的封包,是以當 NAT 伺服器接到這個封包後, 會将目标 IP 由 public IP 改成 192.168.1.210 ,且将該封包相關資訊記錄下來,等待内部伺服器的響應;
  3. 上述的封包在經過路由後,來到 private 接口處,然後透過内部的 LAN 傳送到 192.168.1.210 上頭!
  4. 192.186.1.210 會響應資料給 61.xx.xx.xx ,這個回應當然會傳送到 192.168.1.2 上頭去;
  5. 經過路由判斷後,來到 NAT Postrouting 的鍊,然後透過剛剛第二步驟的記錄,将來源 IP 由 192.168.1.210 改為 public IP 後,就可以傳送出去了!
  6. 其實整個步驟幾乎就等于 SNAT 的反向傳送哩!這就是 DNAT 啰!很簡單吧!

9.5.2 最陽春 NAT 伺服器: IP 分享功能

在 Linux 的 NAT 伺服器服務當中,最常見的就是類似​​圖 9.1-2​​的 IP 分享器功能了。 而由剛剛的介紹你也該知道,這個 IP 分享器的功能其實就是 SNAT 啦!作用就隻是在 iptables 内的 NAT 表格當中,那個路由後的 POSTROUTING 鍊進行 IP 的僞裝就是了。另外, 你也必須要了解,你的 NAT 伺服器必須要有一個 public IP 接口,以及一個内部 LAN 連接配接的 private IP 界面才行。底下的範例中,鳥哥的假設是這樣的:

  • 外部接口使用 eth0 ,這個接口具有 public IP 喔;
  • 内部接口使用 eth1 ,假設這個 IP 為 192.168.100.254 ;

記住!當你利用前面幾章談到的資料來設定你的網絡參數後,務必要進行路由的檢測, 因為在 NAT 伺服器的設定方面,最容易出錯的地方就是路由了!尤其是在撥接産生 ppp0 這個對外接口的環境下, 這個問題最嚴重。反正你要記得:『如果你的 public IP 取得的方式是撥接或 cable modem 時,你的配置檔案 /etc/sysconfig/network, ifcfg-eth0, ifcfg-eth1 等檔案,千萬不要設定 GATEWAY 啦!』否則就會出現兩個 default gateway ,反而會造成問題。

如果你剛剛已經下載下傳了 ​​iptables.rule​​​ ,那麼該檔案内已經含有 NAT 的腳本了! 你可以看到該檔案的​​第二部份關于 NAT 伺服器的部分​​,應該有看到底下這幾行:

iptables -A INPUT -i $INIF -j ACCEPT# 這一行為非必要的,主要的目的是讓内網 LAN 能夠完全的使用 NAT 伺服器資源。# 其中 $INIF 在本例中為 eth1 接口echo "1" > /proc/sys/net/ipv4/ip_forward# 上頭這一行則是在讓你的 Linux 具有 router 的能力iptables -t nat -A POSTROUTING -s $innet -o $EXTIF -j MASQUERADE# 這一行最關鍵!就是加入 nat table 封包僞裝!本例中 $innet 是 192.168.100.0/24# 而 $EXTIF 則是對外界面,本例中為 eth0

重點在那個『 MASQUERADE 』!這個設定值就是『 IP 僞裝成為封包出去 (-o) 的那塊裝置上的 IP 』!以上面的例子來說,就是 $EXTIF ,也就是 eth0 啦! 是以封包來源隻要來自 $innet (也就是内部 LAN 的其他主機) ,隻要該封包可透過 eth0 傳送出去, 那就會自動的修改 IP 的來源表頭成為 eth0 的 public IP 啦!就這麼簡單! 你隻要将 ​​iptables.rule​​ 下載下傳後,并設定好你的内、外網絡接口, 執行 iptables.rule 後,你的 Linux 就擁有主機防火牆以及 NAT 伺服器的功能了!

例題:

如同上面所述的案例,那麼你的 LAN 内的其他 PC 應該要如何設定相關的網絡參數?

答:

  • NETWORK 為 192.168.100.0
  • NETMASK 為 255.255.255.0
  • BROADCAST 為 192.168.100.255
  • IP 可以設定 192.168.100.1 ~ 192.168.100.254 間,不可重複!
  • 通訊閘 (Gateway) 需要設定為 192.168.100.254 (NAT 伺服器的 Private IP)
  • DNS (/etc/resolv.conf) 需設定為 168.95.1.1 (Hinet) 或 139.175.10.20 (Seed Net),這個請依你的 ISP 而定;

事實上,除了 IP 僞裝 (MASQUERADE) 之外,我們還可以直接指定修改 IP 封包表頭的來源 IP 呢! 舉例來說,如下面這個例子:

例題:

假設對外的 IP 固定為 192.168.1.100 ,若不想使用僞裝,該如何處理?

答:

iptables -t nat -A POSTROUTING -o eth0 -j SNAT \ --to-source 192.168.1.100

例題:

假設你的 NAT 伺服器對外 IP 有好幾個,那你想要輪流使用不同的 IP 時,又該如何設定?舉例來說,你的 IP 範圍為 192.168.1.210~192.168.1.220

答:

iptables -t nat -A POSTROUTING -o eth0 -j SNAT \ --to-source 192.168.1.210-192.168.1.220

這樣也可以修改網絡封包的來源 IP 資料喔!不過,除非你使用的是固定 IP ,且有多個 IP 可以對外聯機,否則一般使用 IP 僞裝即可,不需要使用到這個 SNAT 啦!當然,你也可能有自己的獨特的環境啦! ^_^

9.5.3 iptables 的額外核心子產品功能

如果你剛剛在 ​​iptables.rule​​​ 内的​​第二部分​​有仔細看的話, 那有沒有覺得很奇怪,為何我們需要加載一些有用的子產品?舉例來說, ip_nat_ftp 及 ip_nat_irc ? 這是因為很多通訊協定使用的封包傳輸比較特殊,尤其是 FTP 檔案傳輸使用到兩個 port 來處理資料! 這個部分我們會在 FTP 章節再來詳談,在這裡你要先知道,我們的 iptables 提供很多好用的子產品, 這些子產品可以輔助封包的過濾用途,讓我們可以節省很多 iptables 的規則拟定,好棒的吶! ^_^

9.5.4 在防火牆後端之網絡伺服器 DNAT 設定

既然可以做 SNAT 的 IP 分享功能,我們當然可以使用 iptables 做出 DMZ 啦! 但是再次重申,不同的伺服器封包傳輸的方式可能有點差異,是以,建議新手不要玩這個咚咚! 否則很容易導緻某些服務無法順利對 Internet 提供的問題。

先來談一談,如果我想要處理 DNAT 的功能時, iptables 要如何下達指令? 另外,你必須要知道的是, DNAT 用到的是 nat table 的 Prerouting 鍊喔!不要搞錯了。

例題:

假設内網有部主機 IP 為 192.168.100.10 ,該主機是可對 Internet 開放的 WWW 伺服器。你該如何透過 NAT 機制,将 WWW 封包傳到該主機上?

答:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 \ -j DNAT --to-destination 192.168.100.10:80

那個『 -j DNAT --to-destination IP[:port] 』就是精髓啦!代表從 eth0 這個接口傳入的,且想要使用 port 80 的服務時, 将該封包重新傳導到 192.168.100.10:80 的 IP 及 port 上面!可以同時修改 IP 與 port 呢!真友善。 其他還有一些較進階的 iptables 使用方式,如下所示:

-j REDIRECT --to-ports <port number># 這個也挺常見的,基本上,就是進行本機上面 port 的轉換就是了!# 不過,特别留意的是,這個動作僅能夠在 nat table 的 PREROUTING 以及# OUTPUT 鍊上面實行而已喔!範例:将要求與 80 聯機的封包轉遞到 8080 這個 port[root@www ~]# iptables -t nat -A PREROUTING -p tcp --dport 80 \> -j REDIRECT --to-ports 8080# 這玩意最容易在你使用了非正規的 port 來進行某些 well known 的協定,# 例如使用 8080 這個 port 來啟動 WWW ,但是别人都以 port 80 來聯機,# 是以,你就可以使用上面的方式來将對方對你主機的聯機傳遞到 8080 啰!至于更多的用途,那就有待你自己的發掘啰! ^_^
  • 要擁有一部安全的主機,必須要有良好的主機權限設定;随時的更新套件;定期的重要資料備份;完善的員工教育訓練。 僅有防火牆是不足夠的;
  • 防火牆最大的功能就是幫助你『限制某些服務的存取來源』,可以管制來源與目标的 IP ;
  • 防火牆依據封包抵擋的階層,可以分為 Proxy 以及 IP Filter (封包過濾) 兩種類型;
  • 在防火牆内,但不在 LAN 内的伺服器所在網域,通常被稱為 DMZ (非軍事區),如​​圖 9.1-4​​所示;
  • 封包過濾機制的防火牆,通常至少可以分析 IP, port, flag (如 TCP 封包的 SYN), MAC 等等;
  • 防火牆對于病毒的抵擋并不敏感;
  • 防火牆對于來自内部的網絡誤用或濫用的抵擋性可能較不足;
  • 并不是架設防火牆之後,系統就一定很安全!還是需要更新套件漏洞以及管制使用者及權限設定等;
  • 核心 2.4 以後的 Linux 使用 iptables 作為防火牆的軟體;
  • 防火牆的訂定與『規則順序』有很大的關系;若規則順序錯誤,可能會導緻防火牆的失效;
  • iptables 的預設 table 共有三個,分别是 filter, nat 及 mangle ,慣用者為 filter (本機) 與 nat (後端主機)。
  • filter table 主要為針對本機的防火牆設定,依據封包流向又分為 INPUT, OUTPUT, FORWARD 三條鍊;
  • nat table 主要針對防火牆的後端主機,依據封包流向又分為 PREROUTING, OUTPUT, POSTROUTING 三條鍊, 其中 PREROUTING 與 DNAT 有關, POSTROUTING 則與 SNAT 有關;
  • iptables 的防火牆為規則比對,但所有規則都不符合時,則以預設政策 (policy) 作為封包的行為依據;
  • iptables 的指令列當中,可以下達的參數相當的多,當下達 -j LOG 的參數時,則該封包的流程會被紀錄到 /var/log/messages 當中;
  • 防火牆可以多重設定,例如雖然已經設定了 iptables ,但是仍然可以持續設定 TCP Wrappers ,因為誰也不曉得什麼時候 iptables 會有漏洞~或者是規則規劃不良!

繼續閱讀