系統管理員需知的 16 個 iptables 使用技巧
現代 Linux 內核帶有一個叫 Netfilter 的數據包過濾框架。Netfilter 提供了允許、丟棄以及修改等操作來控制進出系統的流量數據包。基於 Netfilter 框架的用戶層命令行工具 iptables
提供了強大的防火牆配置功能,允許你添加規則來構建防火牆策略。iptables 豐富複雜的功能以及其巴洛克式命令語法可能讓人難以駕馭。我們就來探討一下其中的一些功能,提供一些系統管理員解決某些問題需要的使用技巧。
避免封鎖自己
應用場景:假設你將對公司伺服器上的防火牆規則進行修改,你需要避免封鎖你自己以及其他同事的情況(這將會帶來一定時間和金錢的損失,也許一旦發生馬上就有部門打電話找你了)
技巧 #1: 開始之前先備份一下 iptables 配置文件。
用如下命令備份配置文件:
/sbin/iptables-save > /root/iptables-works
技巧 #2: 更妥當的做法,給文件加上時間戳。
用如下命令加時間戳:
/sbin/iptables-save > /root/iptables-works-`date +%F`
然後你就可以生成如下名字的文件:
/root/iptables-works-2018-09-11
這樣萬一使得系統不工作了,你也可以很快的利用備份文件恢復原狀:
/sbin/iptables-restore < /root/iptables-works-2018-09-11
技巧 #3: 每次創建 iptables 配置文件副本時,都創建一個指向最新的文件的鏈接。
ln –s /root/iptables-works-`date +%F` /root/iptables-works-latest
技巧 #4: 將特定規則放在策略頂部,底部放置通用規則。
避免在策略頂部使用如下的一些通用規則:
iptables -A INPUT -p tcp --dport 22 -j DROP
你在規則中指定的條件越多,封鎖自己的可能性就越小。不要使用上面非常通用的規則,而是使用如下的規則:
iptables -A INPUT -p tcp --dport 22 –s 10.0.0.0/8 –d 192.168.100.101 -j DROP
此規則表示在 INPUT
鏈尾追加一條新規則,將源地址為 10.0.0.0/8
、 目的地址是 192.168.100.101
、目的埠號是 22
(--dport 22
) 的 TCP(-p tcp
)數據包通通丟棄掉。
還有很多方法可以設置更具體的規則。例如,使用 -i eth0
將會限制這條規則作用於 eth0
網卡,對 eth1
網卡則不生效。
技巧 #5: 在策略規則頂部將你的 IP 列入白名單。
這是一個有效地避免封鎖自己的設置:
iptables -I INPUT -s <your IP> -j ACCEPT
你需要將該規則添加到策略首位置。-I
表示則策略首部插入規則,-A
表示在策略尾部追加規則。
技巧 #6: 理解現有策略中的所有規則。
不犯錯就已經成功了一半。如果你了解 iptables 策略背後的工作原理,使用起來更為得心應手。如果有必要,可以繪製流程圖來理清數據包的走向。還要記住:策略的預期效果和實際效果可能完全是兩回事。
設置防火牆策略
應用場景:你希望給工作站配置具有限制性策略的防火牆。
技巧 #1: 設置默認規則為丟棄
# Set a default policy of DROP
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
技巧 #2: 將用戶完成工作所需的最少量服務設置為允許
該策略需要允許工作站能通過 DHCP(-p udp --dport 67:68 -sport 67:68
)來獲取 IP 地址、子網掩碼以及其他一些信息。對於遠程操作,需要允許 SSH 服務(-dport 22
),郵件服務(--dport 25
),DNS 服務(--dport 53
),ping 功能(-p icmp
),NTP 服務(--dport 123 --sport 123
)以及 HTTP 服務(-dport 80
)和 HTTPS 服務(--dport 443
)。
# Set a default policy of DROP
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
# Accept any related or established connections
-I INPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-I OUTPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT
# Allow all traffic on the loopback interface
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
# Allow outbound DHCP request
-A OUTPUT –o eth0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT
# Allow inbound SSH
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT
# Allow outbound email
-A OUTPUT -i eth0 -p tcp -m tcp --dport 25 -m state --state NEW -j ACCEPT
# Outbound DNS lookups
-A OUTPUT -o eth0 -p udp -m udp --dport 53 -j ACCEPT
# Outbound PING requests
-A OUTPUT –o eth0 -p icmp -j ACCEPT
# Outbound Network Time Protocol (NTP) requests
-A OUTPUT –o eth0 -p udp --dport 123 --sport 123 -j ACCEPT
# Outbound HTTP
-A OUTPUT -o eth0 -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp --dport 443 -m state --state NEW -j ACCEPT
COMMIT
限制 IP 地址範圍
應用場景:貴公司的 CEO 認為員工在 Facebook 上花費過多的時間,需要採取一些限制措施。CEO 命令下達給 CIO,CIO 命令 CISO,最終任務由你來執行。你決定阻止一切到 Facebook 的訪問連接。首先你使用 host
或者 whois
命令來獲取 Facebook 的 IP 地址。
host -t a www.facebook.com
www.facebook.com is an alias for star.c10r.facebook.com.
star.c10r.facebook.com has address 31.13.65.17
whois 31.13.65.17 | grep inetnum
inetnum: 31.13.64.0 - 31.13.127.255
然後使用 CIDR 到 IPv4 轉換 頁面來將其轉換為 CIDR 表示法。然後你得到 31.13.64.0/18
的地址。輸入以下命令來阻止對 Facebook 的訪問:
iptables -A OUTPUT -p tcp -i eth0 –o eth1 –d 31.13.64.0/18 -j DROP
按時間規定做限制 - 場景1
應用場景:公司員工強烈反對限制一切對 Facebook 的訪問,這導致了 CEO 放寬了要求(考慮到員工的反對以及他的助理提醒說她負責更新他的 Facebook 頁面)。然後 CEO 決定允許在午餐時間訪問 Facebook(中午 12 點到下午 1 點之間)。假設默認規則是丟棄,使用 iptables 的時間功能便可以實現。
iptables –A OUTPUT -p tcp -m multiport --dport http,https -i eth0 -o eth1 -m time --timestart 12:00 –timestop 13:00 –d 31.13.64.0/18 -j ACCEPT
該命令中指定在中午12點(--timestart 12:00
)到下午 1 點(--timestop 13:00
)之間允許(-j ACCEPT
)到 Facebook.com (-d [31.13.64.0/18][5]
)的 http 以及 https (-m multiport --dport http,https
)的訪問。
按時間規定做限制 - 場景2
應用場景:在計劃系統維護期間,你需要設置凌晨 2 點到 3 點之間拒絕所有的 TCP 和 UDP 訪問,這樣維護任務就不會受到干擾。使用兩個 iptables 規則可實現:
iptables -A INPUT -p tcp -m time --timestart 02:00 --timestop 03:00 -j DROP
iptables -A INPUT -p udp -m time --timestart 02:00 --timestop 03:00 -j DROP
該規則禁止(-j DROP
)在凌晨2點(--timestart 02:00
)到凌晨3點(--timestop 03:00
)之間的 TCP 和 UDP (-p tcp and -p udp
)的數據進入(-A INPUT
)訪問。
限制連接數量
應用場景:你的 web 伺服器有可能受到來自世界各地的 DoS 攻擊,為了避免這些攻擊,你可以限制單個 IP 地址到你的 web 伺服器創建連接的數量:
iptables –A INPUT –p tcp –syn -m multiport -–dport http,https –m connlimit -–connlimit-above 20 –j REJECT -–reject-with-tcp-reset
分析一下上面的命令。如果單個主機在一分鐘之內新建立(-p tcp -syn
)超過 20 個(-connlimit-above 20
)到你的 web 伺服器(--dport http,https
)的連接,伺服器將拒絕(-j REJECT
)建立新的連接,然後通知對方新建連接被拒絕(--reject-with-tcp-reset
)。
監控 iptables 規則
應用場景:由於數據包會遍歷鏈中的規則,iptables 遵循 「首次匹配獲勝」 的原則,因此經常匹配的規則應該靠近策略的頂部,而不太頻繁匹配的規則應該接近底部。 你怎麼知道哪些規則使用最多或最少,可以在頂部或底部附近監控?
技巧 #1: 查看規則被訪問了多少次
使用命令:
iptables -L -v -n –line-numbers
用 -L
選項列出鏈中的所有規則。因為沒有指定具體哪條鏈,所有鏈規則都會被輸出,使用 -v
選項顯示詳細信息,-n
選項則顯示數字格式的數據包和位元組計數器,每個規則開頭的數值表示該規則在鏈中的位置。
根據數據包和位元組計數的結果,你可以將訪問頻率最高的規則放到頂部,將訪問頻率最低的規則放到底部。
技巧 #2: 刪除不必要的規則
哪條規則從來沒有被訪問過?這些可以被清除掉。用如下命令查看:
iptables -nvL | grep -v "0 0"
注意:兩個數字 0 之間不是 Tab 鍵,而是 5 個空格。
技巧 #3: 監控正在發生什麼
可能你也想像使用 top
命令一樣來實時監控 iptables 的情況。使用如下命令來動態監視 iptables 中的活動,並僅顯示正在遍歷的規則:
watch --interval=5 'iptables -nvL | grep -v "0 0"'
watch
命令通過參數 iptables -nvL | grep -v 「0 0「
每隔 5 秒輸出 iptables 的動態。這條命令允許你查看數據包和位元組計數的變化。
輸出日誌
應用場景:經理覺得你這個防火牆員工的工作質量杠杠的,但如果能有網路流量活動日誌最好了。有時候這比寫一份有關工作的報告更有效。
使用工具 FWLogwatch 基於 iptables 防火牆記錄來生成日誌報告。FWLogwatch 工具支持很多形式的報告並且也提供了很多分析功能。它生成的日誌以及月報告使得管理員可以節省大量時間並且還更好地管理網路,甚至減少未被注意的潛在攻擊。
這裡是一個 FWLogwatch 生成的報告示例:
不要滿足於允許和丟棄規則
本文中已經涵蓋了 iptables 的很多方面,從避免封鎖自己、配置 iptables 防火牆以及監控 iptables 中的活動等等方面介紹了 iptables。你可以從這裡開始探索 iptables 甚至獲取更多的使用技巧。
via: https://opensource.com/article/18/10/iptables-tips-and-tricks
作者:Gary Smith 選題:lujun9972 譯者:jrg 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive