![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iM5YDN2MjZiNWMyYzMwEmY1ETO0cDZihzY2IjZyITYx8CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)
iptables 是專為 Linux 作業系統打造的極其靈活的防火牆工具。對 Linux 極客玩家和系統管理者來說,iptables 非常有用。本文将向你展示如何配置最通用的 Linux 防火牆。
關于 iptables
iptables 是一個基于指令行的防火牆工具,它使用規則鍊來允許/阻止網絡流量。當一條網絡連接配接試圖在你的系統中建立時,iptables 會查找其對應的比對規則。如果找不到,iptables 将對其采取預設操作。
幾乎所有的Linux發行版都預裝了 iptables。在 Ubuntu/Debian 中更新/安裝 iptables 的指令為:
sudo apt-get install iptables
現有的一些圖形界面軟體也可以替代 iptables,如 Firestarter。但 iptables 用起來并不難。配置 iptables 的規則時要特别小心,特别是在你遠端登陸伺服器的時候。因為這時的一個錯誤有可能讓你和伺服器永久失去連接配接,而你必須要到伺服器面前才能解決它。
iptables規則鍊的類型
iptables 的規則鍊分為三種:輸入、轉發和輸出。
- 輸入——這條鍊用來過濾目的位址是本機的連接配接。例如,如果一個使用者試圖使用 SSH 登陸到你的 PC/伺服器,iptables 會首先比對其 IP 位址和端口到 iptables 的輸傳入連結規則。
-
轉發——這條鍊用來過濾目的位址和源位址都不是本機的連接配接。例如,路由器收到的絕大數資料均需要轉發給其它主機。如果你的系統沒有開啟類似于路由器的功能,如 NATing,你就不需要使用這條鍊。
有一個安全且可靠的方法可以檢測你的系統是否需要轉發鍊:
iptables -L -v
- 上圖是對一台已經運作了幾個星期的伺服器的截圖。這台伺服器沒有對輸入和輸出做任何限制。從中可以看到,輸傳入連結和輸對外連結已經分别處理了 11 GB 和 17 GB 的資料,而轉發鍊則沒有處理任何資料。這是因為此伺服器沒有開啟類似于路由器的轉發功能。
- 輸出——這條鍊用來過濾源位址是本機的連接配接。例如,當你嘗試
時,iptables 會檢查輸對外連結中與 ping 和 howtogeek.com 相關的規則,然後決定允許還是拒絕你的連接配接請求。ping howtogeek.com
注意:當 ping 一台外部主機時,看上去好像隻是輸對外連結在起作用。但是請記住,外部主機傳回的資料要經過輸傳入連結的過濾。當配置 iptables 規則時,請牢記許多協定都需要雙向通信,是以你需要同時配置輸傳入連結和輸對外連結。人們在配置 SSH 的時候通常會忘記在輸傳入連結和輸對外連結都配置它。
鍊的預設行為
在配置特定的規則之前,也許你想配置這些鍊的預設行為。換句話說,當 iptables 無法比對現存的規則時,你想讓它作出何種行為。
你可以運作如下的指令來顯示目前 iptables 對無法比對的連接配接的預設動作:
iptables -L
正如上面所顯示的,我們可以使用 grep 來使輸出的結果變得更加簡潔。在上面的截圖中,所有的鍊預設情況下均接受所有的連接配接。
通常情況下,你會希望你的系統預設情況下接收所有的網絡資料。這種設定也是 iptables 的預設配置。接收網絡連接配接的配置指令是:
iptables --policy INPUT ACCEPT
iptables --policy OUTPUT ACCEPT
iptables --policy FORWARD ACCEPT
你也可以在使用預設配置的情況下,添加一些指令來過濾特定的 IP 位址或端口号。我們稍後在本文介紹這些指令。
如果你想預設情況下拒絕所有的網絡連接配接,然後在其基礎上添加允許的 IP 位址或端口号,你可以将預設配置中的 ACCEPT 變成 DROP,如下圖所示。這對于一些含有敏感資料的伺服器來說是極其有用的。通常這些伺服器隻允許特定的 IP 位址通路它們。
iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP
對特定連接配接的配置
下面來看看如何對特定的 IP 位址或端口作出設定。本文主要介紹三種最基本和常見的設定。
- Accept – 接收所有的資料。
- Drop – 丢棄資料。應用場景:當你不想讓資料的來源位址意識到你的系統的存在(最好的處理方法)。
- Reject – 不允許建立連接配接,但是傳回一個錯誤回應。應用場景:當你不想讓某個 IP 位址通路你的系統,但又想讓它們知道你的防火牆阻止了其通路。
為了直覺的區分上述三種情況,我們使用一台 PC 來 ping 一台配置了 iptables 的 Linux 電腦:
允許通路:
丢棄通路:
拒絕通路:
允許或阻止特定的連接配接
在配置完基本的規則鍊之後,你就可以配置 iptables 來允許或者阻止特定的 IP 位址或者端口。
注意:在這些例子中,我們使用
iptables -A
将額外的規則添加到現存的鍊中。Iptables 在執行比對的時候,會從清單的頂端開始搜尋。你可以使用
iptables -I [chain] [number]
将新的規則插入到清單的指定位置。
來自同一 IP 位址的連接配接
下面這個例子展示了如何阻止來自 IP 位址為 10.10.10.10 的所有連接配接。
iptables -A INPUT -s 10.10.10.10 -j DROP
來自一組 IP 位址的連接配接
下面這個例子展示了如何阻止來自子網 10.10.10.0/24 内的任意 IP 位址的連接配接。你可以使用子網路遮罩或者标準的/符号來标示一個子網:
iptables -A INPUT -s 10.10.10.0/24 -j DROP
或
iptables -A INPUT -s 10.10.10.0/255.255.255.0 -j DROP
特定端口的連接配接
這個例子展示了如何阻止來自 10.10.10.10 的 SSH 連接配接
iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -j DROP
你可以将“ssh”替換成其它任何協定或者端口号。上述指令中的
-p tcp
告訴 iptables 連接配接使用的是何種協定。
下面這個例子展示了如何阻止來自任意 IP 位址的 SSH 連接配接
iptables -A INPUT -p tcp --dport ssh -j DROP
連接配接狀态
我們之前提到過,許多協定均需要雙向通信。例如,如果你打算允許 SSH 連接配接,你必須同時配置輸入和輸對外連結。但是,如果你隻想允許來自外部的 SSH 請求,那該怎麼做?
下面這個例子展示了如何允許源 IP 位址為 10.10.10.10 同時阻止目的位址為 10.10.10.10 的 SSH 連接配接:
iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -d 10.10.10.10 -m state --state ESTABLISHED -j ACCEPT
儲存更改
上述方法對 iptables 規則作出的改變是臨時的。如果你想永久儲存這些更改,你需要運作額外的指令(不同 Linux 發行版下的儲存指令也不相同):
Ubuntu
sudo /sbin/iptables-save
Red Hat / CentOS
/sbin/service iptables save
或者
/etc/init.d/iptables save
其它指令
列出 iptables 的目前配置:
使用
-v
選項将顯示資料包和位元組資訊;使用
-n
選項将以數字形式列出資訊,即不将 IP 位址解析為域名。
換句話講,主機名,協定和網絡都以數字的形式列出。
清除目前所有的配置規則:
iptables -F