Linux:使來自同一主機的流量看起來來自不同的 IP 地址
我正在使用客戶端庫(https://github.com/Beckhoff/ADS)通過 TCP 從 Linux 機器連接到 PLC。但是,該庫只能在 PLC 的源 IP 和目標 IP 地址之間執行單一連接。我的目標是連接到具有多個客戶端的遠端 IP/PLC,即遠端 PLC 必須能夠根據客戶端的(不同)IP 地址區分客戶端連接。
我希望通過一些巧妙的
iptables
規則來實現這一點;或者,也許 Linux 網路命名空間也可以工作。對於
iptables
路由(雙關語?),我的計劃是為 Linux 機器上的同一個 NIC 分配多個 IP 地址。由於遠端服務偵聽單個埠 (48898),因此我不能簡單地在iptables
規則中使用不同的目標埠。因此,我在想這樣的事情:遠端 PLC:192.168.1.10/24
Linux PC:192.168.1.20/24(ip addr add 192.168.1.20/24 dev enp2s0)
Linux PC:192.168.1.21/24(ip addr add 192.168.1.21/24 dev enp2s0)
- Client-A 只是從 192.168.1.20 連接到 192.168.1.10
- Client-A 簡單地從 192.168.1.21 連接到(虛擬)192.168.1.11
通過為遠端 PLC 使用“虛擬”IP 地址,我希望能夠區分 TCP 連接,因此我知道哪些數據包來自客戶端 A,哪些數據包來自客戶端 B。現在我需要做一些
iptables
魔術:
- 傳出:如果目標 IP 地址 == 192.168.1.11 1.1 -> 重寫為目標 IP 地址 192.168.1.10 1.1 -> 重寫/確保源 IP 地址為 192.168.1.21
- 傳入:如果目標 IP 地址 == 192.168.1.21 2.1 -> 將源 IP 地址重寫為 192.168.1.11(遠端 PLC 的虛擬 IP)
也許甚至可以“標記” TCP 連接,以便更容易區分哪個是哪個(步驟 2)。
對於這種情況,conntrack的 NAT 足以正確更改、標記和處理連接的回复流量。可以同時使用 DNAT 和 SNAT 並將它們的使用結合在一起,或者混合使用 DNAT 和適當的路由。
此目標僅在 nat 表、
PREROUTING
**andOUTPUT
**鍊和僅從這些鏈呼叫的使用者定義鏈中有效。它指定應該修改數據包的目標地址(並且此連接中的所有未來數據包也將被破壞),並且應該停止檢查規則。$$ … $$
此目標僅在 nat 表、and
POSTROUTING
鍊INPUT
和僅從這些鏈呼叫的使用者定義鏈中有效。它指定應該修改數據包的源地址(並且此連接中的所有未來數據包也將被破壞),並且應該停止檢查規則。$$ … $$
iptables -t nat -A OUTPUT -d 192.168.1.11 -j DNAT --to-destination 192.168.1.10 iptables -t nat -A OUTPUT -d 192.168.1.12 -j DNAT --to-destination 192.168.1.10 iptables -t nat -A OUTPUT -d 192.168.1.13 -j DNAT --to-destination 192.168.1.10 iptables -t nat -A OUTPUT -d 192.168.1.14 -j DNAT --to-destination 192.168.1.10
在客戶端設置額外的源地址:
ip address add 192.168.1.21/24 dev enp2s0 ip address add 192.168.1.22/24 dev enp2s0 ip address add 192.168.1.23/24 dev enp2s0 ip address add 192.168.1.24/24 dev enp2s0
- 並且要麼有條件地將 SNAT 操作綁定到初始目標地址(在 DNAT 完成之前),使用適當的過濾器和iptables匹配
conntrack
:iptables -t nat -A POSTROUTING -m conntrack --ctorigdst 192.168.1.11 -j SNAT --to-source 192.168.1.21 iptables -t nat -A POSTROUTING -m conntrack --ctorigdst 192.168.1.12 -j SNAT --to-source 192.168.1.22 iptables -t nat -A POSTROUTING -m conntrack --ctorigdst 192.168.1.13 -j SNAT --to-source 192.168.1.23 iptables -t nat -A POSTROUTING -m conntrack --ctorigdst 192.168.1.14 -j SNAT --to-source 192.168.1.24
- 或者代替 SNAT,更簡潔,使用直接提示每個目的地的預期源地址的路由(即使 nat/OUTPUT 重新路由,源地址一旦設置就不會再改變)。這將允許客戶和客戶
ss -tn dport == 48898
知道並顯示正確的源地址。這變成:ip route add 192.168.1.11/32 dev enp2s0 src 192.168.1.21 ip route add 192.168.1.12/32 dev enp2s0 src 192.168.1.22 ip route add 192.168.1.13/32 dev enp2s0 src 192.168.1.23 ip route add 192.168.1.14/32 dev enp2s0 src 192.168.1.24
這必須像這樣完成:一次一個地址(DNAT 可以被簡化/分解,但不是處理源的第二部分)。
與實際
192.168.1.10
地址的連接保持不變。