鳥哥的 Linux 私房菜

第九章、防火牆與 NAT 伺服器
切換解析度為 800x600
最近更新日期:2011/07/22
從第七章的圖 7.1-1 我們可以發現防火牆是整個封包要進入主機前的第一道關卡,但,什麼是防火牆?Linux 的防火牆有哪些機制? 防火牆可以達到與無法達到的功能有哪些?防火牆能不能作為區域防火牆而不是僅針對單一主機而已呢?其實,Linux 的防火牆主要是透過 Netfilter 與 TCP Wrappers 兩個機制來管理的。其中,透過 Netfilter 防火牆機制,我們可以達到讓私有 IP 的主機上網 (IP 分享器功能) ,並且也能夠讓 Internet 連到我內部的私有 IP 所架設的 Linux 伺服器 (DNAT 功能)!真的很不賴喔! 這一章對您來說,也真的有夠重要的啦!

9.1 認識防火牆
  9.1.1 開始之前來個提醒事項
  9.1.2 為何需要防火牆
  9.1.3 Linux 系統上防火牆的主要類別
  9.1.4 防火牆的一般網路佈線示意
  9.1.5 防火牆的使用限制
9.2 TCP Wrappers
  9.2.1 哪些服務有支援: ldd
  9.2.2 /etc/hosts.{allow|deny} 的設定方式
9.3 Linux 的封包過濾軟體: iptables
  9.3.1 不同 Linux 核心版本的防火牆軟體
  9.3.2 封包進入流程:規則順序的重要性!
  9.3.3 iptables 的表格 (table) 與鏈 (chain)
  9.3.4 本機的 iptables 語法
  9.3.4-1 規則的觀察與清除
  9.3.4-2 定義預設政策 (policy)
  9.3.4-3 封包的基礎比對:IP, 網域及介面裝置: 信任裝置, 信任網域
  9.3.4-4 TCP, UDP 的規則比對:針對埠口設定
  9.3.4-5 iptables 外掛模組:mac 與 state
  9.3.4-6 ICMP 封包規則的比對:針對是否回應 ping 來設計
  9.3.4-7 超陽春用戶端防火牆設計與防火牆規則儲存
  9.3.5 IPv4 的核心管理功能:/proc/sys/net/ipv4/*
9.4 單機防火牆的一個實例
  9.4.1 規則草擬
  9.4.2 實際設定
9.5 NAT 伺服器的設定
  9.5.1 什麼是 NAT? SNAT? DNAT?
  9.5.2 最陽春 NAT 伺服器: IP 分享功能
  9.5.3 iptables 的額外核心模組功能
  9.5.4 在防火牆後端之網路伺服器 DNAT 設定
9.6 重點回顧
9.7 本章習題
9.8 參考資料與延伸閱讀
9.9 針對本文的建議:http://phorum.vbird.org/viewtopic.php?p=114475
大標題的圖示 9.1 認識防火牆

網路安全除了隨時注意相關軟體的漏洞以及網路上的安全通報之外,你最好能夠依據自己的環境來訂定防火牆機制! 這樣對於你的網路環境,會比較有保障一點喔!那麼什麼是防火牆呢?其實防火牆就是透過訂定一些有順序的規則,並管制進入到我們網域內的主機 (或者可以說是網域) 資料封包的一種機制!更廣義的來說,只要能夠分析與過濾進出我們管理之網域的封包資料, 就可以稱為防火牆

防火牆又可以分為硬體防火牆與本機的軟體防火牆。硬體防火牆是由廠商設計好的主機硬體, 這部硬體防火牆內的作業系統主要以提供封包資料的過濾機制為主,並將其他不必要的功能拿掉。因為單純作為防火牆功能而已, 因此封包過濾的效率較佳。至於軟體防火牆呢?那就是我們這個章節要來談論的啊! 軟體防火牆本身就是在保護系統網路安全的一套軟體(或稱為機制),例如 Netfilter 與 TCP Wrappers 都可以稱為軟體防火牆。

無論怎麼分,反正防火牆就是用來保護我們網路安全的咚咚就對啦!我們這個章節主要在介紹 Linux 系統本身提供的軟體防火牆的功能,那就是 Netfilter 。至於 TCP Wrappers 雖然在基礎篇的第十八章認識系統服務裡面談過了,我們這裡還會稍微簡單的介紹啦!


小標題的圖示 9.1.1 開始之前來個提醒事項

由於本章主要的目的在介紹 Netfilter 這種封包過濾式的防火牆機制,因此網路基礎裡面的許多封包與訊框的概念要非常清楚, 包括網域的概念, IP 網域的撰寫方式等,均需有一定的基礎才行。請到第二章加強一下 MAC, IP, ICMP, TCP, UDP 等封包表頭資料的認識,以及 Network/Netmask 的整體網域 (CIDR) 寫法等。

另外,雖然 Netfilter 機制可以透過 iptables 指令的方式來進行規則的排序與修改,不過鳥哥建議你利用 shell script 來撰寫屬於你自己的防火牆機制比較好,因為對於規則的排序與彙整有比較好的觀察性, 可以讓你的防火牆規則比較清晰一點。所以在你開始瞭解底下的資料之前,希望你可以先閱讀過相關的資料了:

  • 已經認識 Shell 以及 Shell script;
  • 已經閱讀過第二章網路基礎的內容;
  • 已經閱讀過第七章認識網路安全的內容;
  • 已經閱讀過第八章路由器的內容,瞭解重要的路由概念;
  • 最好擁有兩部主機以上的小型區域網路環境,以方便測試防火牆;
  • 做為區域防火牆的 Linux 主機最好有兩張實體網卡,可以進行多種測試,並架設 NAT 伺服器;
小標題的圖示 9.1.2 為何需要防火牆

仔細分析第七章的圖 7.1-1 可以發現, 封包進入本機時,會通過防火牆、伺服器軟體程序、SELinux與檔案系統等。所以基本上,如果你的系統 (1)已經關閉不需要而且危險的服務; (2)已經將整個系統的所有軟體都保持在最新的狀態; (3)權限設定妥當且定時進行備份工作; (4)已經教育使用者具有良好的網路、系統操作習慣。 那麼你的系統實際上已經頗為安全了!要不要架設防火牆?那就見仁見智囉!

不過,畢竟網路世界是很複雜的,而 Linux 主機也不是一個簡單的東西,說不定哪一天你在進行某個軟體的測試時, 主機突然間就啟動了一個網路服務,如果你沒有管制該服務的使用範圍,那麼該服務就等於對所有 Internet 開放, 那就麻煩了!因為該服務可能可以允許任何人登入你的系統,那不是挺危險?

所以囉,防火牆能作什麼呢?防火牆最大的功能就是幫助你『限制某些服務的存取來源』! 舉例來說: (1)你可以限制檔案傳輸服務 (FTP) 只在子網域內的主機才能夠使用,而不對整個 Internet 開放; (2)你可以限制整部 Linux 主機僅可以接受客戶端的 WWW 要求,其他的服務都關閉; (3)你還可以限制整部主機僅能主動對外連線。反過來說,若有用戶端對我們主機發送主動連線的封包狀態 (TCP 封包的 SYN flag) 就予以抵擋等等。這些就是最主要的防火牆功能了!

所以鳥哥認為,防火牆最重要的任務就是在規劃出:

  • 切割被信任(如子網域)與不被信任(如 Internet)的網段;
  • 劃分出可提供 Internet 的服務與必須受保護的服務;
  • 分析出可接受與不可接受的封包狀態;

當然啦,咱們 Linux 的 iptables 防火牆軟體還可以進行更細部深入的 NAT (Network Address Translation) 的設定,並進行更彈性的 IP 封包偽裝功能,不過,對於單一主機的防火牆來說, 最簡單的任務還是上面那三項就是了!所以,你需不需要防火牆呢?理論上,當然需要! 而且你必須要知道『你的系統哪些資料與服務需要保護』,針對需要受保護的服務來設定防火牆的規則吧! 底下我們先來談一談,那在 Linux 上頭常見的防火牆類型有哪些?

小標題的圖示 9.1.3 Linux 系統上防火牆的主要類別

基本上,依據防火牆管理的範圍,我們可以將防火牆區分為網域型與單一主機型的控管。在單一主機型的控管方面, 主要的防火牆有封包過濾型的 Netfilter 與依據服務軟體程式作為分析的 TCP Wrappers 兩種。若以區域型的防火牆而言, 由於此類防火牆都是當作路由器角色,因此防火牆類型主要則有封包過濾的 Netfilter 與利用代理伺服器 (proxy server) 進行存取代理的方式了。

  • Netfilter (封包過濾機制)

    所謂的封包過濾,亦即是分析進入主機的網路封包,將封包的表頭資料捉出來進行分析,以決定該連線為放行或抵擋的機制。 由於這種方式可以直接分析封包表頭資料,所以包括硬體位址(MAC), 軟體位址 (IP), TCP, UDP, ICMP 等封包的資訊都可以進行過濾分析的功能,因此用途非常的廣泛。(其實主要分析的是 OSI 七層協定的 2, 3, 4 層啦)

    在 Linux 上面我們使用核心內建的 Netfilter 這個機制,而 Netfilter 提供了 iptables 這個軟體來作為防火牆封包過濾的指令。由於 Netfilter 是核心內建的功能,因此他的效率非常的高! 非常適合於一般小型環境的設定呢!Netfilter 利用一些封包過濾的規則設定,來定義出什麼資料可以接收, 什麼資料需要剔除,以達到保護主機的目的喔!

  • TCP Wrappers (程式控管)

    另一種抵擋封包進入的方法,為透過伺服器程式的外掛 (tcpd) 來處置的!與封包過濾不同的是, 這種機制主要是分析誰對某程式進行存取,然後透過規則去分析該伺服器程式誰能夠連線、誰不能連線。 由於主要是透過分析伺服器程式來控管,因此與啟動的埠口無關,只與程式的名稱有關。 舉例來說,我們知道 FTP 可以啟動在非正規的 port 21 進行監聽,當你透過 Linux 內建的 TCP wrappers 限制 FTP 時, 那麼你只要知道 FTP 的軟體名稱 (vsftpd) ,然後對他作限制,則不管 FTP 啟動在哪個埠口,都會被該規則管理的。

  • Proxy (代理伺服器)

    其實代理伺服器是一種網路服務,它可以『代理』使用者的需求,而代為前往伺服器取得相關的資料。就有點像底下這個圖示吧: 


    圖 9.1-1、Proxy Server 的運作原理簡介

    以上圖為例,當 Client 端想要前往 Internet 取得 Google 的資料時,他取得資料的流程是這樣的:

    1. client 會向 proxy server 要求資料,請 proxy 幫忙處理;
    2. proxy 可以分析使用者的 IP 來源是否合法?使用者想要去的 Google 伺服器是否合法? 如果這個 client 的要求都合法的話,那麼 proxy 就會主動的幫忙 client 前往 Google 取得資料;
    3. Google 所回傳的資料是傳給 proxy server 的喔,所以 Google 伺服器上面看到的是 proxy server 的 IP 囉;
    4. 最後 proxy 將 Google 回傳的資料送給 client。

    這樣瞭解了嗎?沒錯, client 並沒有直接連上 Internet ,所以在實線部分(步驟 1, 4)只要 Proxy 與 Client 可以連線就可以了!此時 client 甚至不需要擁有 public IP 哩!而當有人想要攻擊 client 端的主機時, 除非他能夠攻破 Proxy server ,否則是無法與 client 連線的啦!

    另外,一般 proxy 主機通常僅開放 port 80, 21, 20 等 WWW 與 FTP 的埠口而已,而且通常 Proxy 就架設在路由器上面,因此可以完整的掌控區域網路內的對外連線!讓你的 LAN 變的更安全啊! 由於一般小型網路環境很少會用到代理伺服器,因此本書並沒有談到 proxy server 的設定,有興趣的話可以參考一下第十七章 squid (註1) 這個軟體的官網或 google 一下吧!

小標題的圖示 9.1.4 防火牆的一般網路佈線示意

由前面的說明當中,你應該可以瞭解到一件事,那就是防火牆除了可以『保護防火牆機制本身所在的那部主機』之外,還可以『保護防火牆後面的主機』。也就是說,防火牆除了可以防備本機被入侵之外, 他還可以架設在路由器上面藉以控管進出本地端網域的網路封包。 這種規劃對於內部私有網域的安全也有一定程度的保護作用呢!底下我們稍微談一談目前常見的防火牆與網路佈線的配置吧:

  • 單一網域,僅有一個路由器:

    防火牆除了可以作為 Linux 本機的基本防護之外,他還可以架設在路由器上面以管控整個區域網路的封包進出。 因此,在這類的防火牆上頭通常至少需要有兩個介面,將可信任的內部與不可信任的 Internet 分開, 所以可以分別設定兩塊網路介面的防火牆規則啦!簡單的環境如同下列圖 9.1-2 所示。

    在圖 9.1-2 中,由於防火牆是設定在所有網路封包都會經過的路由器上頭, 因此這個防火牆可以很輕易的就掌控到區域網路內的所有封包, 而且你只要管理這部防火牆主機,就可以很輕易的將來自 Internet 的不良網路封包抵擋掉吶。 只要管理一部主機就能夠造福整的 LAN 裡面的 PC,很划算的啦。

    如果你想要將區域網路控管的更嚴格的話,那你甚至可以在這部 Linux 防火牆上面架設更嚴格的代理伺服器, 讓用戶端僅能連上你所開放的 WWW 伺服器而已,而且還可以透過代理伺服器的登錄檔分析功能, 明確的查出來那個使用者在某個時間點曾經連上哪些 WWW 伺服器,你瞧瞧!厲害吧! 如果在這個防火牆上面再加裝類似 MRTG 的流量監控軟體,還能針對整個網域的流量進行監測。這樣配置的優點是:

    • 因為內外網域已經分開,所以安全維護在內部可以開放的權限較大!
    • 安全機制的設定可以針對 Linux 防火牆主機來維護即可!
    • 對外只看的到 Linux 防火牆主機,所以對於內部可以達到有效的安全防護!

    鳥哥的 Linux 私房菜_第1张图片
    圖 9.1-2、單一網域,僅有一個路由器的環境示意圖

  • 內部網路包含安全性更高的子網路,需內部防火牆切開子網路:

    一般來說,我們的防火牆對於 LAN 的防備都不會設定的很嚴格,因為是我們自己的 LAN 嘛!所以是信任網域之一囉!不過,最常聽到的入侵方法也是使用這樣的一個信任漏洞! 因為你不能保證所有使用企業內部電腦的使用者都是公司的員工,也無法保證你的員工不會『搞破壞!』 更多時候是由於某些外來訪客利用移動式裝置 (筆記型電腦) 連接到公司內部的無線網路來加以竊取企業內部的重要資訊。

    呵呵!所以,如果你有特別重要的部門需要更安全的保護網路環境,那麼將 LAN 裡面再加設一個防火牆,將安全等級分類,那麼將會讓你的重要資料獲得更佳的保護喔!整個架構有點像下圖所示。


    圖 9.1-3、內部網路包含需要更安全的子網路防火牆

  • 在防火牆的後面架設網路伺服器主機

    還有一種更有趣的設定,那就是將提供網路服務的伺服器放在防火牆後面,這有什麼好處呢? 如下圖所示,Web, Mail 與 FTP 都是透過防火牆連到 Internet 上面去,所以, 底下這四部主機在 Internet 上面的 Public IP 都是一樣的!(這個觀念我們會在本章底下的 NAT 伺服器的時候再次的強調)。 只是透過防火牆的封包分析後,將 WWW 的要求封包轉送到 Web 主機,將 Mail 送給 Mail Server 去處理而已(透過 port 的不同來轉遞)。

    好了,因為四部主機在 Internet 上面看到的 IP 都相同,但是事實上卻是四部不同的主機, 而當有攻擊者想要入侵你的 FTP 主機好了,他使用各種分析方法去進攻的主機,其實是『防火牆』那一部, 攻擊者想要攻擊你內部的主機,除非他能夠成功的搞定你的防火牆,否則就很難入侵你的內部主機呢!

    而且,由於主機放置在兩部防火牆中間,內部網路如果發生狀況時 (例如某些使用者不良操作導致中毒啊、 被社交工程攻陷導致內部主機被綁架啊等等的) ,是不會影響到網路伺服器的正常運作的。 這種方式適用在比較大型的企業當中,因為對這些企業來說,網路主機能否提供正常穩定的服務是很重要的!

    不過,這種架構下所進行的設定就得包含 port 的轉遞,而且要有很強的網路邏輯概念, 可以釐清封包雙向溝通時的流動方式。對於新手來說,設定上有一定的難度, 鳥哥個人不太建議新手這麼做,還是等以後有經驗之後再來玩這種架構吧!

    鳥哥的 Linux 私房菜_第2张图片
    圖 9.1-4、架設在防火牆後端的網路伺服器環境示意圖

    通常像上圖的環境中,將網路伺服器獨立放置在兩個防火牆中間的網路,我們稱之為非軍事區域 (DMZ)。 DMZ 的目的就如同前面提到的,重點在保護伺服器本身,所以將 Internet 與 LAN 都隔離開來,如此一來不論是伺服器本身,或者是 LAN 被攻陷時,另一個區塊還是完好無缺的!

小標題的圖示 9.1.5 防火牆的使用限制

從前面的分析中,我們已經知道過封包濾式防火牆主要在分析 OSI 七層協定當中的 2, 3, 4 層,既然如此的話, Linux 的 Netfilter 機制到底可以做些什麼事情呢?其實可以進行的分析工作主要有:

  • 拒絕讓 Internet 的封包進入主機的某些埠口
    這個應該不難瞭解吧!例如你的 port 21 這個 FTP 相關的埠口,若只想要開放給內部網路的話,那麼當 Internet 來的封包想要進入你的 port 21 時,就可以將該資料封包丟掉!因為我們可以分析的到該封包表頭的埠口號碼呀!

  • 拒絕讓某些來源 IP 的封包進入
    例如你已經發現某個 IP 主要都是來自攻擊行為的主機,那麼只要來自該 IP 的資料封包,就將他丟棄!這樣也可以達到基礎的安全呦!

  • 拒絕讓帶有某些特殊旗標 (flag) 的封包進入
    最常拒絕的就是帶有 SYN 的主動連線的旗標了!只要一經發現,嘿嘿!你就可以將該封包丟棄呀!

  • 分析硬體位址 (MAC) 來決定連線與否
    如果你的區域網路裡面有比較搗蛋的但是又具有比較高強的網路功力的高手時,如果你使用 IP 來抵擋他使用網路的權限,而他卻懂得反正換一個 IP 就好了,都在同一個網域內嘛! 同樣還是在搞破壞~怎麼辦?沒關係,我們可以鎖死他的網路卡硬體位址啊!因為 MAC 是銲在網路卡上面的,所以你只要分析到該使用者所使用的 MAC 之後,可以利用防火牆將該 MAC 鎖住,呵呵!除非他能夠一換再換他的網路卡來取得新的 MAC,否則換 IP 是沒有用的啦!

雖然 Netfilter 防火牆已經可以做到這麼多的事情,不過,還是有很多事情沒有辦法透過 Netfilter 來完成喔! 什麼?設定防火牆之後還不安全啊!那當然啦!誰說設定了防火牆之後你的系統就一定安全? 防火牆雖然可以防止不受歡迎的封包進入我們的網路當中,不過,某些情況下,他並不能保證我們的網路一定就很安全。 舉幾個例子來談一談:

  • 防火牆並不能很有效的抵擋病毒或木馬程式
    假設你已經開放了 WWW 的服務,那麼你的 WWW 主機上面,防火牆一定得要將 WWW 服務的 port 開放給 Client 端登入才行吧!否則你的 WWW 主機設定了等於沒有用對吧!也就是說,只要進入你的主機的封包是要求 WWW 資料的,就可以通過你的防火牆。那好了,『萬一你的 WWW 伺服器軟體有漏洞,或者本身向你要求 WWW 服務的該封包就是病毒在偵測你的系統』時,你的防火牆可是一點辦法也沒有啊! 因為本來設定的規則就是會讓他通過啊。

  • 防火牆對於來自內部 LAN 的攻擊較無承受力
    一般來說,我們對於 LAN 裡面的主機都沒有什麼防火牆的設定,因為是我們自己的 LAN 啊,所以當然就設定為信任網域了!不過, LAN 裡面總是可能有些網路小白啊,雖然他們不是故意要搞破壞, 但是他們就是不懂嘛!所以就亂用網路了。這個時候就很糟糕,因為防火牆對於內部的規則設定通常比較少, 所以就容易造成內部員工對於網路誤用或濫用的情況。

所以啦,還是回到第七章的圖 7.1-1 的說明去看看,分析一下該圖示,你就會知道,在你的 Linux 主機實地上網之前,還是得先:

  • 關閉幾個不安全的服務;
  • 升級幾個可能有問題的套件;
  • 架設好最起碼的安全防護--防火牆--

其他相關的訊息還是請到第七章認識網路安全裡面去看一看怎麼增加自身的安全吧!

大標題的圖示 9.2 TCP Wrappers

在進入主題之前,我們先來玩一個簡單的防火牆機制,那就是 TCP Wrappers 這玩意兒。如同前面說的, TCP wrappers 是透過用戶端想要連結的程式檔名,然後分析用戶端的 IP ,看看是否需要放行。那麼哪些程式支援 TCP wrappers 的功能?這個 TCP wrappers 又該如何設定?我們這裡先簡單的談談吧!(這個小節僅是簡單的介紹過 TCP wrappers ,更多相關功能請參考基礎學習篇的第十八章內容喔!)


小標題的圖示 9.2.1 哪些服務有支援

說穿了, TCP wrappers 就是透過 /etc/hosts.allow, /etc/hosts.deny 這兩個寶貝蛋來管理的一個類似防火牆的機制, 但並非所有的軟體都可以透過這兩個檔案來控管,只有底下的軟體才能夠透過這兩個檔案來管理防火牆規則,分別是:

  • 由 super daemon (xinetd) 所管理的服務;
  • 有支援 libwrap.so 模組的服務。

經由 xinetd 管理的服務還好理解,就是設定檔在 /etc/xinetd.d/ 裡面的服務就是 xinetd 所管理的啊! 那麼什麼是有支援 libwrap.so 模組呢?就讓我們來進行底下的例題,你就比較容易明白囉:

例題:
請查出你的系統有沒有安裝 xinetd ,若沒有請安裝。安裝完畢後,請查詢 xinetd 管理的服務有哪些?
答:
[root@www ~]# yum install xinetd
Setting up Install Process
Package 2:xinetd-2.3.14-29.el6.x86_64 already installed and latest version
Nothing to do
# 畫面中顯示,已經是最新的 xinetd !所以,已經有安裝囉!
# 接下來找出 xinetd 所管理的服務群!

[root@www ~]# chkconfig xinetd on   <==要先讓 xinetd on 後才能看到底下的
[root@www ~]# chkconfig --list
....(前面省略)....
xinetd based services:
        chargen-dgram:  off
        chargen-stream: off
....(中間省略)....
        rsync:          off   <==下一小節的範例就用這玩意兒來解釋
        tcpmux-server:  off
        telnet:         on
上述結果最終輸出的部分就是 xinetd 所管理的服務群囉!上述的服務之防火牆簡易設定,都可以透過 TCP wrappers 來管理的嚕!

例題:
請問, rsyslogd, sshd, xinetd, httpd (若該服務不存在,請自行安裝軟體),這四個程式有沒有支援 tcp wrappers 的抵擋功能?
答:
由於支援 tcp wrappers 的服務必定包含 libwrap 這一個動態函式庫,因此可以使用 ldd 來觀察該服務即可。 簡單的使用方式為:
[root@www ~]# ldd $(which rsyslogd sshd xinetd httpd)
# 這個方式可以將所有的動態函式庫取出來查閱,不過需要眼睛搜尋。
# 可以透過底下的方式來處理更快!

[root@www ~]# for name in rsyslogd sshd xinetd httpd; do echo $name; \
> ldd $(which $name) | grep libwrap; done
rsyslogd
sshd
        libwrap.so.0 => /lib64/libwrap.so.0 (0x00007fb41d3c9000)
xinetd
        libwrap.so.0 => /lib64/libwrap.so.0 (0x00007f6314821000)
httpd
上述的結果中,在該檔名檔下有出現 libwrap 的,代表有找到該函式庫,才有支援 tcp wrappers。 所以, sshd, xinetd 有支援,但是 rsyslogd, httpd 這兩支程式則不支援。也就是說, httpd 與 rsyslogd 不能夠使用 /etc/hosts.{allow|deny} 來進行防火牆機制的控管。

小標題的圖示 9.2.2 /etc/hosts.{allow|deny} 的設定方式

那如何透過這兩個檔案來抵擋有問題的 IP 來源呢?這兩個檔案的語法都一樣,很簡單的:

<service(program_name)> : <IP, domain, hostname> 
<服務   (亦即程式名稱)> : <IP 或領域 或主機名稱>
# 上頭的 > < 是不存在於設定檔中的喔!

我們知道防火牆的規則都是有順序的,那這兩個檔案與規則的順序優先是怎樣呢?基本上是這樣的:

  • 先以 /etc/hosts.allow 為優先比對,該規則符合就予以放行;
  • 再以 /etc/hosts.deny 比對,規則符合就予以抵擋;
  • 若不在這兩個檔案內,亦即規則都不符合,最終則予以放行。

我們拿 rsync 這個 xinetd 管理的服務來進行說明好了,請參考底下的例題吧:

例題:
先開放本機的 127.0.0.1 可以進行任何本機的服務,然後,讓區網 (192.168.1.0/24) 可以使用 rsync , 同時 10.0.0.100 也能夠使用 rsync ,但其他來源則不允許使用 rsync 喔。
答:
我們得要先知道 rsync 的服務啟動的檔名為何,因為 tcp wrappers 是透過啟動服務的檔名來管理的。 當我們觀察 rsync 的設定檔時,可以發現:
[root@www ~]# cat /etc/xinetd.d/rsync
service rsync
{
        disable = yes
        flags           = IPv6
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync   <==檔名叫做 rsync
        server_args     = --daemon
        log_on_failure  += USERID
}
因此程式欄位的項目要寫的是 rsync 喔!因此,我們應該要這樣設定的:
[root@www ~]# vim /etc/hosts.allow
ALL: 127.0.0.1    <==這就是本機全部的服務都接受!
rsync: 192.168.1.0/255.255.255.0 10.0.0.100

[root@www ~]# vim /etc/hosts.deny
rsync: ALL

上面的例題有幾個重點,首先, tcp wrappers 理論上不支援 192.168.1.0/24 這種透過 bit 數值來定義的網域, 只支援 netmask 的位址顯示方式。另外,如果有多個網域或者是單一來源,可以透過空格來累加。 如果想要寫成多行呢?也可以啊!多寫幾行『 kshd: IP 』的方式也可以,不必要將所有資料集中在一行啦!因為 tcp wrappers 也是一條一條規則比對嘛!

基本上,你只要理解這些資料即可!因為絕大部分的時刻,我們都會建議使用底下介紹的 Netfilter 的機制來抵擋封包。 那讓我們準備開始來玩玩 iptables 封包過濾防火牆吧!

大標題的圖示 9.3 Linux 的封包過濾軟體:iptables

上面談了這麼多,主要還是希望你能瞭解到防火牆是什麼這個議題!而且也希望你知道防火牆並非萬能的。 好了,那麼底下我們終於可以來瞧一瞧,那目前我們的 2.6 版這個 Linux 核心到底使用什麼核心功能來進行防火牆設定?


小標題的圖示 9.3.1 不同 Linux 核心版本的防火牆軟體

Linux 的防火牆為什麼功能這麼好?這是因為他本身就是由 Linux 核心所提供,由於直接經過核心來處理,因此效能非常好! 不過,不同核心版本所使用的防火牆軟體是不一樣的!因為核心支援的防火牆是逐漸演進而來的嘛!

  • Version 2.0:使用 ipfwadm 這個防火牆機制;
  • Version 2.2:使用的是 ipchains 這個防火牆機制;
  • Version 2.4 與 2.6 :主要是使用 iptables 這個防火牆機制,不過在某些早期的 Version 2.4 版本的 distributions 當中,亦同時支援 ipchains (編譯成為模組),好讓使用者仍然可以使用來自 2.2 版的 ipchains 的防火牆規劃。不過,不建議在 2.4 以上的核心版本使用 ipchains 喔!

因為不同的核心使用的防火牆機制不同,且支援的軟體指令與語法也不相同,所以在 Linux 上頭設定屬於你自己的防火牆規則時,要注意啊,先用 uname -r 追蹤一下你的核心版本再說!如果你是安裝 2004 年以後推出的 distributions ,那就不需要擔心了,因為這些 distributions 幾乎都使用 kernel 2.6 版的核心啊! ^_^

小標題的圖示 9.3.2 封包進入流程:規則順序的重要性!

前面的幾個小節裡面我們一直談到:『防火牆規則』,咦!啥是規則啊?因為 iptables 是利用封包過濾的機制, 所以他會分析封包的表頭資料。根據表頭資料與定義的『規則』來決定該封包是否可以進入主機或者是被丟棄。 意思就是說:『根據封包的分析資料 "比對" 你預先定義的規則內容, 若封包資料與規則內容相同則進行動作,否則就繼續下一條規則的比對!』 重點在那個『比對與分析順序』上。

舉個簡單的例子,假設我預先定義 10 條防火牆規則好了,那麼當 Internet 來了一個封包想要進入我的主機, 那麼防火牆是如何分析這個封包的呢?我們以底下的圖示來說明好了:

鳥哥的 Linux 私房菜_第3张图片
圖 9.3-1、封包過濾的規則動作及分析流程

當一個網路封包要進入到主機之前,會先經由 NetFilter 進行檢查,那就是 iptables 的規則了。 檢查通過則接受 (ACCEPT) 進入本機取得資源,如果檢查不通過,則可能予以丟棄 (DROP) ! 上圖中主要的目的在告知你:『規則是有順序的』!例如當網路封包進入 Rule 1 的比對時, 如果比對結果符合 Rule 1 ,此時這個網路封包就會進行 Action 1 的動作,而不會理會後續的 Rule 2, Rule 3.... 等規則的分析了

而如果這個封包並不符合 Rule 1 的比對,那就會進入 Rule 2 的比對了!如此一個一個規則去進行比對就是了。 那如果所有的規則都不符合怎辦?此時就會透過預設動作 (封包政策, Policy) 來決定這個封包的去向。 所以啦,當你的規則順序排列錯誤時,就會產生很嚴重的錯誤了。 怎麼說呢?讓我們看看底下這個例子:

假設你的 Linux 主機提供了 WWW 的服務,那麼自然就要針對 port 80 來啟用通過的封包規則,但是你發現 IP 來源為 192.168.100.100 老是惡意的嘗試入侵你的系統,所以你想要將該 IP 拒絕往來,最後,所有的非 WWW 的封包都給他丟棄,就這三個規則來說,你要如何設定防火牆檢驗順序呢?

  1. Rule 1 先抵擋 192.168.100.100 ;
  2. Rule 2 再讓要求 WWW 服務的封包通過;
  3. Rule 3 將所有的封包丟棄。

這樣的排列順序就能符合你的需求,不過,萬一你的順序排錯了,變成:

  1. Rule 1 先讓要求 WWW 服務的封包通過;
  2. Rule 2 再抵擋 192.168.100.100 ;
  3. Rule 3 將所有的封包丟棄。

此時,那個 192.168.100.100 『可以使用你的 WWW 服務』喔!只要他對你的主機送出 WWW 要求封包,就可以使用你的 WWW 功能了,因為你的規則順序定義第一條就會讓他通過,而不去考慮第二條規則!這樣可以理解規則順序的意義了嗎! 現在再來想一想,如果 Rule 1 變成了『將所有的封包丟棄』,Rule 2 才設定『WWW 服務封包通過』,請問,我的 client 可以使用我的 WWW 服務嗎?呵呵!答案是『否~』想通了嗎? ^_^

小標題的圖示 9.3.3 iptables 的表格 (table) 與鏈 (chain)

事實上,那個圖 9.3-1 所列出的規則僅是 iptables 眾多表格當中的一個鏈 (chain) 而已。 什麼是鏈呢?這得由 iptables 的名稱說起。為什麼稱為 ip"tables" 呢? 因為這個防火牆軟體裡面有多個表格 (table) ,每個表格都定義出自己的預設政策與規則, 且每個表格的用途都不相同。我們可以使用底下這張圖來稍微瞭解一下:


圖 9.3-2、iptables 的表格與相關鏈示意圖

剛剛圖 9.3-1 的規則內容僅只是圖 9.3-2 內的某個 chain 而已! 而預設的情況下,咱們 Linux 的 iptables 至少就有三個表格,包括管理本機進出的 filter 、管理後端主機 (防火牆內部的其他電腦) 的 nat 、管理特殊旗標使用的 mangle (較少使用) 。更有甚者,我們還可以自訂額外的鏈呢! 真是很神奇吧!每個表格與其中鏈的用途分別是這樣的:

  • 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 (破壞者):這個表格主要是與特殊的封包的路由旗標有關, 早期僅有 PREROUTING 及 OUTPUT 鏈,不過從 kernel 2.4.18 之後加入了 INPUT 及 FORWARD 鏈。 由於這個表格與特殊旗標相關性較高,所以像咱們這種單純的環境當中,較少使用 mangle 這個表格。

所以說,如果你的 Linux 是作為 www 服務,那麼要開放用戶端對你的 www 要求有回應,就得要處理 filter 的 INPUT 鏈; 而如果你的 Linux 是作為區域網路的路由器,那麼就得要分析 nat 的各個鏈以及 filter 的 FORWARD 鏈才行。也就是說, 其實各個表格的鏈結之間是有關係的!簡單的關係可以由下圖這麼看:


圖 9.3-3、iptables 內建各表格與鏈的相關性

上面的圖示很複雜喔!不過基本上你依舊可以看出來,我們的 iptables 可以控制三種封包的流向:

  • 封包進入 Linux 主機使用資源 (路徑 A): 在路由判斷後確定是向 Linux 主機要求資料的封包,主要就會透過 filter 的 INPUT 鏈來進行控管;

  • 封包經由 Linux 主機的轉遞,沒有使用主機資源,而是向後端主機流動 (路徑 B): 在路由判斷之前進行封包表頭的修訂作業後,發現到封包主要是要透過防火牆而去後端,此時封包就會透過路徑 B 來跑動。 也就是說,該封包的目標並非我們的 Linux 本機。主要經過的鏈是 filter 的 FORWARD 以及 nat 的 POSTROUTING, PREROUTING。 這路徑 B 的封包流向使用情況,我們會在本章的 9.5 小節來跟大家作個簡單的介紹。

  • 封包由 Linux 本機發送出去 (路徑 C): 例如回應用戶端的要求,或者是 Linux 本機主動送出的封包,都是透過路徑 C 來跑的。先是透過路由判斷, 決定了輸出的路徑後,再透過 filter 的 OUTPUT 鏈來傳送的!當然,最終還是會經過 nat 的 POSTROUTING 鏈。
Tips:
有沒有發現有兩個『路由判斷』呢?因為網路是雙向的,所以進與出要分開來看!因此,進入的封包需要路由判斷, 送出的封包當然也要進行路由判斷才能夠發送出去啊!瞭解乎?
鳥哥的 Linux 私房菜_第4张图片

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

鳥哥的 Linux 私房菜_第5张图片
圖 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 』,不論是設定還是觀察防火牆規則喔!
鳥哥的 Linux 私房菜_第6张图片
小標題的圖示 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 -n
Chain 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-prohibited

Chain FORWARD (policy ACCEPT)  <==針對 FORWARD 鏈,且預設政策為可接受
target  prot opt source     destination
REJECT  all  --  0.0.0.0/0  0.0.0.0/0   reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)  <==針對 OUTPUT 鏈,且預設政策為可接受
target  prot opt source     destination

範例:列出 nat table 三條鏈的規則
[root@www ~]# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

Chain 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 DROP
COMMIT
# 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 -n
target prot opt source         destination
LOG    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 DROP
iptables v1.4.7: unknown option `--dport'
Try `iptables -h' or 'iptables --help' for more information.

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

除了埠口之外,在 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 外部的來源唷!
鳥哥的 Linux 私房菜_第7张图片
小標題的圖示 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/bash
icmp_type="0 3 4 11 12 14 16 18"
for typeicmp in $icmp_type
do
   iptables -A INPUT -i eth0 -p icmp --icmp-type $typeicmp -j ACCEPT
done

[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/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin; export PATH

# 1. 清除規則
iptables -F
iptables -X
iptables -Z

# 2. 設定政策
iptables -P   INPUT DROP
iptables -P  OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

# 3~5. 制訂各項規則
iptables -A INPUT -i lo -j ACCEPT
iptables -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.sh
iptables: 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 就是了。
鳥哥的 Linux 私房菜_第8张图片

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

  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/28
    net.ipv4.tcp_syncookies = 1
    net.ipv4.icmp_echo_ignore_broadcasts = 1
    net.ipv4.conf.all.rp_filter = 1
    net.ipv4.conf.default.rp_filter = 1
    net.ipv4.conf.eth0.rp_filter = 1
    net.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 等等;
鳥哥的 Linux 私房菜_第9张图片
圖 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


# 第二部份,針對後端主機的防火牆設定!###############################
# 1. 先載入一些有用的模組
  modules="ip_tables iptable_nat ip_nat_ftp ip_nat_irc ip_conntrack 
ip_conntrack_ftp ip_conntrack_irc"
  for mod in $modules
  do
      testmod=`lsmod | grep "^${mod} " | awk '{print $1}'`
      if [ "$testmod" == "" ]; then
            modprobe $mod
      fi
  done

# 2. 清除 NAT table 的規則吧!
  iptables -F -t nat
  iptables -X -t nat
  iptables -Z -t nat
  iptables -t nat -P PREROUTING  ACCEPT
  iptables -t nat -P POSTROUTING ACCEPT
  iptables -t nat -P OUTPUT      ACCEPT

# 3. 若有內部介面的存在 (雙網卡) 開放成為路由器,且為 IP 分享器!
  if [ "$INIF" != "" ]; then
    iptables -A INPUT -i $INIF -j ACCEPT
    echo "1" > /proc/sys/net/ipv4/ip_forward
    if [ "$INNET" != "" ]; then
        for innet in $INNET
        do
            iptables -t nat -A POSTROUTING -s $innet -o $EXTIF -j MASQUERADE
        done
    fi
  fi
  # 如果你的 MSN 一直無法連線,或者是某些網站 OK 某些網站不 OK,
  # 可能是 MTU 的問題,那你可以將底下這一行給他取消註解來啟動 MTU 限制範圍
  # iptables -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss \
  #          --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu

# 4. NAT 伺服器後端的 LAN 內對外之伺服器設定
# iptables -t nat -A PREROUTING -p tcp -i $EXTIF --dport 80 \
#          -j DNAT --to-destination 192.168.1.210:80 # WWW

# 5. 特殊的功能,包括 Windows 遠端桌面所產生的規則,假設桌面主機為 1.2.3.4
# iptables -t nat -A PREROUTING -p tcp -s 1.2.3.4  --dport 6000 \
#          -j DNAT --to-destination 192.168.100.10
# iptables -t nat -A PREROUTING -p tcp -s 1.2.3.4  --sport 3389 \
#          -j DNAT --to-destination 192.168.100.20

# 6. 最終將這些功能儲存下來吧!
  /etc/init.d/iptables save

特別留意上面程式碼的特殊字體部分,基本上,你只要修改一下最上方的介面部分, 應該就能夠運作這個防火牆了。不過因為每個人的環境都不相同, 因此你在設定完成後,依舊需要測試一下才行喔!不然,出了問題不要怪我啊!.... 再來看一下關於 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 伺服器是如何處理這個封包的呢?

    鳥哥的 Linux 私房菜_第10张图片
    圖 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) 的封包對應寫入暫存記憶體當中, 然後將此封包傳送出去了

    此時 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 機器上去!

    經過這個流程,你就可以發現到,所有內部 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。
    鳥哥的 Linux 私房菜_第11张图片
  • 目標 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 後,就可以傳送出去了!

    其實整個步驟幾乎就等於 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 應該要如何設定相關的網路參數?
答:
答案其實很簡單啊,將 NAT 伺服器作為 PC 的 GATEWAY 即可!只要記得底下的參數值:
  • 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 封包傳到該主機上?
答:
假設 public IP 所在的介面為 eth0 ,那麼你的規則就是:
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 囉!

至於更多的用途,那就有待你自己的發掘囉! ^_^

大標題的圖示 9.6 重點回顧
  • 要擁有一部安全的主機,必須要有良好的主機權限設定;隨時的更新套件;定期的重要資料備份;完善的員工教育訓練。 僅有防火牆是不足夠的;
  • 防火牆最大的功能就是幫助你『限制某些服務的存取來源』,可以管制來源與目標的 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 會有漏洞~或者是規則規劃不良!
大標題的圖示 9.7 本章習題
  • 為什麼我架設了防火牆,我的主機還是可能中毒?
    防火牆不是萬靈丹,他還是可能被病毒或者是木馬程式所入侵的! 此外,如果你的主機本身就已經提供了多個網路服務,則當該網路服務的軟體有漏洞時, 防火牆仍然無法克服該服務的漏洞的!因此仍然需要持續的進行主機的監視與後端分析工作
  • 請說明為何架設了防火牆,我的主機還是可能被入侵?入侵的依據可能是什麼方法?
    因為防火牆僅是抵擋某些不受歡迎的封包,如果你有開放 WWW 的服務時,則要求你主機 port 80 的封包將可直接進入你的主機,萬一 WWW 套件有漏洞時,那麼就可能被入侵了!所以軟體的更新很重要!
  • 我們知道核心為 2.6 的 Linux 使用的防火牆機制為 iptables ,請問,如何知道我的 Linux 核心版本?
    利用 uname -r 可以查得!
  • 請列出 iptables 預設的兩個主要的 table ,以及各個 table 裡面的 chains 與各個 chains 所代表的意義;
    filter 為預設的 Table,裡頭預設的鏈有:
    • INPUT:為來自外部,想要進入主機的封包;
    • OUTPUT:為來自主機,想要離開主機的封包;
    • FORWARD:為主機內部網域與外部網域的封包(不論進或者出),但該封包不會進入主機。
    還有 nat 這個 table:
    • PREROUTING:進行路由之前的封包傳送過程
    • OUTPUT:離開主機的封包傳送過程;
    • POSTROUTING:已經經過路由了,然後才進行的過濾規則。
  • 什麼是 iptables 的預設政策 (Policy)?若我要針對 filter 的 INPUT 做成 DROP 的預設政策,指令如何下達?
    當封包的所有屬性都不在防火牆的規則當中時,那麼這個封包能否順利的通過防火牆,則以 Policy 作為這個封包的最終動作了! 
    iptables -P INPUT DROP
  • 假設今天我的 Linux 僅是作為 Client 之用,並沒有對 Internet 進行任何服務, 那麼你的防火牆規劃應該如何設定比較好?
    既然沒有對 Internet 提供任何服務,那麼(1)請將所有的對外埠口先關閉吧!(2)防火牆規則當中,最重要的是 INPUT 的 Policy 一定要 DROP ,然後將『 iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 』即可!
  • 我要將來自 192.168.1.50 這個 IP 來源的封包,只要是向我的 21~23 埠口要求的封包,就將他抵擋,應該如何下達 iptables 指令?
    iptables -A INPUT -p tcp -s 192.168.1.50 --dport 21:23 -j DROP
  • 我要將我自己主機 ping 的回應功能取消,應該如何下達 iptables 的指令?
    因為 ping 能否回應用的是 icmp 的 type 8 (請參考網路基礎內的 ICMP 相關內容),所以我可以這樣做:
    iptables -I INPUT -p icmp --icmp-type 8 -j DROP
  • 請說明為何這個指令是錯誤的?『iptables -A INPUT -p udp --syn -s 192.168.0.20 -j DROP』?
    因為只有 TCP 封包才會具有 SYN 的標誌, UDP 並沒有 SYN 的標誌啊!所以上面的指令是錯誤的
  • DNS 的要求是必須的,那麼我該如何設定我的主機可以接受要求 DNS 的回應呢?
    因為 DNS 的來源是 port 53 ,因此要接受來自 port 53 的封包就成為了:
    iptables -A INPUT -p udp --sport 53 -j ACCEPT
    iptables -A INPUT -p tcp --sport 53 -j ACCEPT
  • 如何取消 iptables 在我的系統上面?
    先要清除規則後,才能夠將 iptables 移除!不過,我們主要將規則清除即可!
    iptables -F; iptables -X; iptables -Z
    iptables -t nat -F; iptables -t nat -X; iptables -t nat -Z
  • 如何儲存目前的防火牆機制,以及如何將上次儲存下來的機制回復到目前的系統中?
    請利用 iptables-save 以及 iptables-restore 這兩個指令,配合命令重導向即可! 也可以使用 /etc/init.d/iptables save 來儲存喔!
  • 如果你的區網當中有個 PC 使用者老是連上 Internet 亂搞,你想要將他的 IP 鎖住,但他總是有辦法修改成其他 IP 來連外, 那你該怎麼辦?讓他無法繼續連外?
    可以利用封鎖網路卡卡號 MAC 來處理!
大標題的圖示 9.8 參考資料與延伸閱讀
  • 註1: squid 官網:http://www.squid-cache.org/
    鳥哥的舊版文章:http://linux.vbird.org/linux_server/0420squid.php
  • 註2: 與 iptables 相關的網站與書籍:
    中文網站:
    • http://www.study-area.org/linux/servers/linux_nat.htm
    英文網站:
    • http://www.netfilter.org/
    • http://www.netfilter.org/documentation/HOWTO//packet-filtering-HOWTO.html
    • http://www.interhack.net/pubs/fwfaq/
    • http://www.sysresccd.org/Sysresccd-Networking-EN-Destination-port-routing
    其他書籍與資料:
    • Robert L. Ziegler 著,朱亮愷等譯,『實戰 Linux 防火牆--iptables 應用全蒐錄』,上奇出版社,2004。
    • 本機的核心文件:/usr/src/linux-{version}/networking/ip-sysctl.txt
    • iptables 的內建 tables 與各個 chain 的相關性: http://ebtables.sourceforge.net/br_fw_ia/bridge3b.png
    • 核心參數的相關說明:http://www.study-area.org/tips/adv-route/Adv-Routing-HOWTO-12.html
    • 使用 PPPoE 導致的 MTU 問題:http://www.akadia.com/services/pppoe_iptables.html

你可能感兴趣的:(鳥哥的 Linux 私房菜)