Linux 防火牆:關於 iptables 和 firewalld 的那些事

發表於2018-10-03

以下是如何使用 iptables 和 firewalld 工具來管理 Linux 防火牆規則。

Linux 防火牆:關於 iptables 和 firewalld 的那些事

這篇文章摘自我的書《Linux in Action》,尚未釋出的第二個曼寧出版專案。

防火牆

防火牆是一組規則。當資料包進出受保護的網路區域時,進出內容(特別是關於其來源、目標和使用的協議等資訊)會根據防火牆規則進行檢測,以確定是否允許其通過。下面是一個簡單的例子:

防火牆過濾請求

防火牆可以根據協議或基於目標的規則過濾請求。

一方面, iptables 是 Linux 機器上管理防火牆規則的工具。

另一方面,firewalld 也是 Linux 機器上管理防火牆規則的工具。

你有什麼問題嗎?如果我告訴你還有另外一種工具,叫做 nftables,這會不會糟蹋你的美好一天呢?

好吧,我承認整件事確實有點好笑,所以讓我來解釋一下。這一切都從 Netfilter 開始,它在 Linux 核心模組級別控制訪問網路棧。幾十年來,管理 Netfilter 鉤子的主要命令列工具是 iptables 規則集。

因為呼叫這些規則所需的語法看起來有點晦澀難懂,所以各種使用者友好的實現方式,如 ufw 和 firewalld 被引入,作為更高階別的 Netfilter 直譯器。然而,ufw 和 firewalld 主要是為解決單獨的計算機所面臨的各種問題而設計的。構建全方面的網路解決方案通常需要 iptables,或者從 2014 年起,它的替代品 nftables (nft 命令列工具)。

iptables 沒有消失,仍然被廣泛使用著。事實上,在未來的許多年裡,作為一名管理員,你應該會使用 iptables 來保護的網路。但是 nftables 通過操作經典的 Netfilter 工具集帶來了一些重要的嶄新的功能。

從現在開始,我將通過示例展示 firewalld 和 iptables 如何解決簡單的連線問題。

使用 firewalld 配置 HTTP 訪問

正如你能從它的名字中猜到的,firewalld 是 systemd 家族的一部分。firewalld 可以安裝在 Debian/Ubuntu 機器上,不過,它預設安裝在 RedHat 和 CentOS 上。如果您的計算機上執行著像 Apache 這樣的 web 伺服器,您可以通過瀏覽伺服器的 web 根目錄來確認防火牆是否正在工作。如果網站不可訪問,那麼 firewalld 正在工作。

你可以使用 firewall-cmd 工具從命令列管理 firewalld 設定。新增 –state 引數將返回當前防火牆的狀態:

預設情況下,firewalld 處於執行狀態,並拒絕所有傳入流量,但有幾個例外,如 SSH。這意味著你的網站不會有太多的訪問者,這無疑會為你節省大量的資料傳輸成本。然而,這不是你對 web 伺服器的要求,你希望開啟 HTTP 和 HTTPS 埠,按照慣例,這兩個埠分別被指定為 80 和 443。firewalld 提供了兩種方法來實現這個功能。一個是通過 –add-port 引數,該引數直接引用埠號及其將使用的網路協議(在本例中為TCP)。 另外一個是通過 –permanent 引數,它告訴 firewalld 在每次伺服器啟動時載入此規則:

–reload 引數將這些規則應用於當前會話:

檢視當前防火牆上的設定,執行 –list-services

假設您已經如前所述新增了瀏覽器訪問,那麼 HTTP、HTTPS 和 SSH 埠現在都應該是和 dhcpv6-client 一樣開放的 —— 它允許 Linux 從本地 DHCP 伺服器請求 IPv6 IP 地址。

使用 iptables 配置鎖定的客戶資訊亭

我相信你已經看到了資訊亭——它們是放在機場、圖書館和商務場所的盒子裡的平板電腦、觸控式螢幕和 ATM 類電腦,邀請顧客和路人瀏覽內容。大多數資訊亭的問題是,你通常不希望使用者像在自己家一樣,把他們當成自己的裝置。它們通常不是用來瀏覽、觀看 YouTube 視訊或對五角大樓發起拒絕服務攻擊的。因此,為了確保它們沒有被濫用,你需要鎖定它們。

一種方法是應用某種資訊亭模式,無論是通過巧妙使用 Linux 顯示管理器還是控制在瀏覽器級別。但是為了確保你已經堵塞了所有的漏洞,你可能還想通過防火牆新增一些硬性的網路控制。在下一節中,我將講解如何使用iptables 來完成。

關於使用 iptables,有兩件重要的事情需要記住:你給出的規則的順序非常關鍵;iptables 規則本身在重新啟動後將無法保持。我會一次一個地在解釋這些。

資訊亭專案

為了說明這一切,讓我們想象一下,我們為一家名為 BigMart 的大型連鎖商店工作。它們已經存在了幾十年;事實上,我們想象中的祖父母可能是在那裡購物並長大的。但是如今,BigMart 公司總部的人可能只是在數著亞馬遜將他們永遠趕下去的時間。

儘管如此,BigMart 的 IT 部門正在盡他們最大努力提供解決方案,他們向你發放了一些具有 WiFi 功能資訊亭裝置,你在整個商店的戰略位置使用這些裝置。其想法是,登入到 BigMart.com 產品頁面,允許查詢商品特徵、過道位置和庫存水平。資訊亭還允許進入 bigmart-data.com,那裡儲存著許多影像和視訊媒體資訊。

除此之外,您還需要允許下載軟體包更新。最後,您還希望只允許從本地工作站訪問 SSH,並阻止其他人登入。下圖說明了它將如何工作:

資訊亭流量IP表

*資訊亭業務流由 iptables 控制。 *

指令碼

以下是 Bash 指令碼內容:

我們從基本規則 -A 開始分析,它告訴 iptables 我們要新增規則。OUTPUT 意味著這條規則應該成為輸出鏈的一部分。-p 表示該規則僅使用 TCP 協議的資料包,正如 -d 告訴我們的,目的地址是 bigmart.com-j 引數的作用是當資料包符合規則時要採取的操作是 ACCEPT。第一條規則表示允許(或接受)請求。但,往下的規則你能看到丟棄(或拒絕)的請求。

規則順序是很重要的。因為 iptables 會對一個請求遍歷每個規則,直到遇到匹配的規則。一個向外發出的瀏覽器請求,比如訪問 bigmart.com 是會通過的,因為這個請求匹配第一條規則,但是當它到達 dport 80dport 443 規則時——取決於是 HTTP 還是 HTTPS 請求——它將被丟棄。當遇到匹配時,iptables 不再繼續往下檢查了。(LCTT 譯註:此處原文有誤,徑改。)

另一方面,向 ubuntu.com 發出軟體升級的系統請求,只要符合其適當的規則,就會通過。顯然,我們在這裡做的是,只允許向我們的 BigMart 或 Ubuntu 傳送 HTTP 或 HTTPS 請求,而不允許向其他目的地傳送。

最後兩條規則將處理 SSH 請求。因為它不使用埠 80 或 443 埠,而是使用 22 埠,所以之前的兩個丟棄規則不會拒絕它。在這種情況下,來自我的工作站的登入請求將被接受,但是對其他任何地方的請求將被拒絕。這一點很重要:確保用於埠 22 規則的 IP 地址與您用來登入的機器的地址相匹配——如果不這樣做,將立即被鎖定。當然,這沒什麼大不了的,因為按照目前的配置方式,只需重啟伺服器,iptables 規則就會全部丟失。如果使用 LXC 容器作為伺服器並從 LXC 主機登入,則使用主機 IP 地址連線容器,而不是其公共地址。

如果機器的 IP 發生變化,請記住更新這個規則;否則,你會被拒絕訪問。

在家玩(是在某種一次性虛擬機器上)?太好了。建立自己的指令碼。現在我可以儲存指令碼,使用 chmod 使其可執行,並以 sudo 的形式執行它。不要擔心“igmart-data.com 沒找到”之類的錯誤 —— 當然沒找到;它不存在。

你可以使用 cURL 命令列測試防火牆。請求 ubuntu.com 奏效,但請求 manning.com 是失敗的 。

配置 iptables 以在系統啟動時載入

現在,我如何讓這些規則在每次資訊亭啟動時自動載入?第一步是將當前規則儲存。使用 iptables-save 工具儲存規則檔案。這將在根目錄中建立一個包含規則列表的檔案。管道後面跟著 tee 命令,是將我的sudo 許可權應用於字串的第二部分:將檔案實際儲存到否則受限的根目錄。

然後我可以告訴系統每次啟動時執行一個相關的工具,叫做 iptables-restore 。我們在上一章節(LCTT 譯註:指作者的書)中看到的常規 cron 任務並不適用,因為它們在設定的時間執行,但是我們不知道什麼時候我們的計算機可能會決定崩潰和重啟。

有許多方法來處理這個問題。這裡有一個:

在我的 Linux 機器上,我將安裝一個名為 anacron 的程式,該程式將在 /etc/ 目錄中為我們提供一個名為 anacrontab 的檔案。我將編輯該檔案並新增這個 iptables-restore 命令,告訴它載入那個 .rule 檔案的當前內容。當引導後,規則每天(必要時)01:01 時載入到 iptables 中(LCTT 譯註:anacron 會補充執行由於機器沒有執行而錯過的 cron 任務,因此,即便 01:01 時機器沒有啟動,也會在機器啟動會盡快執行該任務)。我會給該任務一個識別符號(iptables-restore),然後新增命令本身。如果你在家和我一起這樣,你應該通過重啟系統來測試一下。

我希望這些實際例子已經說明了如何使用 iptables 和 firewalld 來管理基於 Linux 的防火牆上的連線問題。

 

相關文章