
我有一個使用 iptables 的網路網關係統來允許/拒絕進出內部網路的流量。我必須iptables
根據內部網路中實體的要求手動新增和刪除規則,包括對其流量進行 NAT。內部網路上的可信任實體可以根據需要請求新增和刪除規則。最終結果是nat
和表中的一堆規則filter
,包括POSTROUTING
帶有目標的規則SNAT
,將來源 IP 設定為網關係統的 IP,以及其他表中網關外部 IP 位址為 的規則dst
。
我希望能夠動態設定網關係統的 IP。這當然會對 TCP 會話等產生破壞性後果,但我們不要考慮這一點。系統透過其他機制處理這些問題。
問題是防火牆表中未知數量的規則仍然引用這個舊的來源 IP 位址。
有沒有一種方法可以輕鬆更改所有這些規則以使用新的 IP 位址而不是舊的 IP 位址?當然,如果你比我更像 bash 嚮導,我也可以接受一些使用 sed/awk 或類似腳本的奇特腳本...
答案1
如果進行 SNAT 的流量始終使用出介面的 IP 位址,則替換-j SNAT
為-j MASQUERADE
。這將使用相同的基於 conntrack 的 SNAT,但會自動選擇替換來源位址。
iptables-save
您可以使用和批次編輯 iptables 規則iptables-restore
:
例如,以互動方式編輯規則集(特別是如果您的編輯器具有良好的搜尋和替換功能):
iptables-save > /tmp/rules vim /tmp/rules iptables-restore < /tmp/rules
使用 moreutils 中的“vipe”:
iptables-save | vipe | iptables-restore
要將一個確切的 IP 位址批次替換為另一個(請記住,這
.
是正規表示式中的通配符,並使用它\b
來確保「12.34」不會意外匹配「112.34」):iptables-save | sed 's/\b12\.34\.56\.78\b/12.34.56.99/g' | iptables-restore
但在我看來,任何編輯 iptables 規則(包括基於腳本的“iptables -A”設定)是一個不好的方法。相反,保留一個iptables.rules
文件(以 iptables-save 格式)作為「來源」並始終從該檔案載入規則集。然後,您可以開始使用某種形式的巨集/模板語言來定義 IP 位址一次並在任何地方引用它 - 類似於透過 Salt/Ansible 部署設定檔時的操作方式(如果有人仍然使用這些檔案)。
例如(實際上不要這樣做;它會很快陷入難以管理的情況):
cat /etc/iptables.rules | sed 's/%CUST_IP%/12.34.56.78/g' | iptables-restore
我還建議看一下 Ferm,它實現了 iptables 規則的替代語法 - 一般而言更具可讀性,而且還內建了宏,因此您可以
@def $cust_ip
一次並在任何地方引用它。domain (ip ip6) { @def dns_host4 = 10.10.0.53; @def ntp_host4 = 10.10.0.123; table filter { chain FORWARD { daddr ($dns_host4 $ntp_host4) accept; } } table nat { chain PREROUTING { proto (tcp udp) dport 53 DNAT to-destination $dns_host4; proto udp dport 123 DNAT to-destination $ntp_host4; } } }
這與 iptables-restore 的工作原理類似 - 您無需進行即時更改,而是編輯
/etc/ferm.conf
並運行ferm
以在完成後重新加載整個規則集。如果 IP 位址發生變化,只需編輯 ferm.conf 中的 @def 巨集並重新載入即可。(另外,如果你最終切換到 nftables,最好習慣這一點,因為它的工作原理與 Ferm 幾乎相同 - 當然語法有點不同,但它也有 $macros 並且你編輯 /etc/ nftables.conf 並立即重新加載整個內容。
答案2
我建議將 iptables 與 ipset 結合使用。
在 iptables 中,您將擁有自己的規則,但然後新增 --match-set setname src
iptables -I PREROUTING -s whatever ... --match-set setname src
iptables -I PREROUTING -s whatever ... --match-set setname dst
然後,要停用該規則,您可以從名為「setname」的集合中刪除 IP 位址。
然後 iptables 保持不變,您只需從 setname 中新增和減去條目
根據需要,每個規則都有不同的名稱。