nftables / iptables 規則通過介面重寫源IP
我有一個帶有 Linux 伺服器(Ubuntu 16.04,核心 4.13)和幾個小工具的物理網路。每個小工具都有相同的不可更改的靜態 IP,例如 192.168.0.222/24。我想通過任意 IP 協議(例如 ICMP ping 或自定義 UDP 協議)與所有這些小工具進行通信
幸運的是,我有一個連接伺服器和小工具的託管網路交換機。我已將交換機配置為具有用於伺服器的中繼埠和用於每個小工具的訪問埠,每個小工具位於不同的 VLAN(VID 11、12 等)上。
我已添加
8021q
到 /etc/modules 並在 /etc/network/interfaces 中設置 VLAN 條目:auto eno2 # For switch management interface iface eno2 inet static address 192.168.2.2/24 auto eno2.11 # Gadget 1 (only) iface eno2 inet static address 192.168.0.1/24 #auto eno2.12 # Gadget 2 - disabled #iface eno2 inet static # address 192.168.0.1/24
使用如上所示的條目,我可以與小工具 1(例如
ping 192.168.0.222
)通信,但看不到來自小工具 2 的任何流量。但我希望能夠同時與所有小工具進行通信,並且能夠區分其中一個。他們不需要互相交談。我正在考慮為每個小工具創建一個唯一的主機 IP 和子網,例如
Host IP & subnet "Fake" gadget IP Actual gadget IP VLAN Interface 192.168.101.1/24 192.168.101.222 192.168.0.222 eno2.11 192.168.102.1/24 192.168.102.222 192.168.0.222 eno2.12
我會使用
iptables
ornftables
來處理每個方向的翻譯。然後我可以ping 192.168.101.222
到達小工具 1 和ping 192.168.102.222
小工具 2。從每個小工具的角度來看,它自己的 IP 仍然是 192.168.0.222,它會看到來自 192.168.0.1 的 ICMP 回應要求。這似乎是 NAT 上的一個不尋常的變體。請注意,帶有“假”IP 的流量不需要(也不應該)離開伺服器——我們不會轉發到網路上的其他東西。
- 這是解決問題的合理方法嗎?
- 如何設置 /etc/network/interfaces 和 iptables 或 nftables 來實現這一點?
我能夠使用以下
nftables
規則集來實現這一點(我必須nft
從原始碼建構為 Ubuntu 16.04 附帶的 v0.5 不支持數據包欄位修改):table ip mytable { chain prerouting { type filter hook prerouting priority -300; policy accept; iifname "eno2.11" ip saddr 192.168.0.222 ip saddr set 192.168.101.222 iifname "eno2.12" ip saddr 192.168.0.222 ip saddr set 192.168.102.222 iifname "eno2.13" ip saddr 192.168.0.222 ip saddr set 192.168.103.222 } chain output { type filter hook output priority -300; policy accept; ip daddr 192.168.101.222 ip daddr set 192.168.0.222 ip daddr 192.168.102.222 ip daddr set 192.168.0.222 ip daddr 192.168.103.222 ip daddr set 192.168.0.222 } }
以及以下條目
/etc/network/interfaces
:auto eno2 # For switch management interface iface eno2 inet static address 192.168.2.2/24 auto eno2.11 iface eno2.11 inet static address 192.168.101.1 netmask 255.255.255.0 auto eno2.12 iface eno2.12 inet static address 192.168.102.1 netmask 255.255.255.0 auto eno2.13 iface eno2.13 inet static address 192.168.103.1 netmask 255.255.255.0
這不會“解開”傳出數據包的源 IP,即小工具仍將來自伺服器的請求視為來自
192.168.101.1
等,192.168.102.1
而不是192.168.0.1
- 在我的應用程序中,這無關緊要,但它可能會通過附加規則來解決output
鏈。
- 是的,這是合理的。
- 不幸的是,Linux DNAT(“目標重寫 NAT”)僅限於預路由鏈。在您的情況下,這是一個 PITA,因為這意味著您:
(一種)。在您的伺服器上執行 DNAT,但是您只能從伺服器外部使用這些地址,而不能從伺服器本身使用這些地址;或者
(b)。您通過製作網路命名空間來人為地創建上述情況,將網路命名空間通過 veth-pair 連接到伺服器主命名空間,然後在網路命名空間內進行 DNAT。這意味著您的所有 VLAN 介面也都位於網路命名空間內。
我不知道為什麼 Linux 網路的人會這樣做,但事實就是如此。只重寫數據包的一般方法會非常方便……
Google搜尋“網路命名空間”和“iptables DNAT”,這應該足以讓你開始(除非其他人比我有更多的時間寫一個逐步的答案……)