Iptables
Netplan:通過埠轉發將多個並行網際網路連接路由到具有 1 個網路埠的單個伺服器
這是我的網路圖:
56.56.56.56 192.168.0.1/24 MAC:AA:BB:CC:DD:EE:01 ___________ ---| Modem 1 |------- | ___________ | ___________ Internet ---| | Switch |--------| Machine | | ___________ | ___________ ---| Modem 2 |------- 192.168.0.3/24 ___________ 67.67.67.67 192.168.0.2/24 MAC:AA:BB:CC:DD:EE:02
- 兩個調製解調器都將相同的埠從網際網路轉發到機器。
- 調製解調器後面的機器應該適當地響應來自網際網路的任何請求。例如,調製解調器 1 數據包通過調製解調器 1 返回,調製解調器 2 數據包通過調製解調器 2 返回。
- 機器只有一個網口,交換機不受管理。
- 機器使用
Netplan
、iptables 和 iproute2 進行網路配置。
我最終從基於 Sender MAC Address 的 Linux 上的 Policy Routing 中的文章和評論以及關於 Policy-Routing的Netplan.io 參考中得到了我的解決方案。
訣竅是通過源 MAC 地址標記和 CONNTRACK 傳入數據包到單獨的路由表
iptables -t mangle
,然後告訴 Netplan 使用該表適當地路由傳出數據包。首先,我們需要將數據包放入的表格:
將以下內容附加到文件中
/etc/iproute2/rt_tables
:1 modem1 2 modem2
然後,告訴 Netplan 表、路由和標記:
network: version: 2 ethernets: eth0: routes: - to: 0.0.0.0/0 via: 192.168.0.1 table: 1 - to: 0.0.0.0/0 via: 192.168.0.2 table: 2 routing-policy: - from: 0.0.0.0/0 mark: 1 table: 1 - from: 0.0.0.0/0 mark: 2 table: 2
第一部分告訴
netplan
這些不同表中的數據包需要不同的預設路由。第二部分說一些數據包將有一個fwmark
來自 iptables 的數據包,這些數據包應該被放入這些表中。然後,告訴
iptables
通過它們的原始 MAC 地址標記數據包,但前提是它不是來自本地網路(一個小腳本):#!/bin/bash -x MAC_MODEM1=AA:BB:CC:DD:EE:01 MAC_MODEM2=AA:BB:CC:DD:EE:02 MARK_MODEM1=0x1 MARK_MODEM2=0x2 LOCALNET=192.168.0.0/24 ## Optional - Clear everything first iptables -t mangle -F for MODEM in MODEM1 MODEM2; do MAC=MAC_$MODEM MARK=MARK_$MODEM iptables --table mangle --append INPUT \ --match state --state NEW \ --match mac --mac-source ${!MAC} \ ! --source $LOCALNET \ --jump CONNMARK --set-mark ${!MARK} done iptables --table mangle --append OUTPUT \ --jump CONNMARK --restore-mark
然後,告訴 netplan 生成並應用:
$ sudo netplan generate $ sudo netplan apply
瞧!
獎金答案
如果您有多個內部網路(例如通過非本地 IP 的 VPN),請使用
ipset
andiptables
-m set ! -match-set alias
,例如ipset destroy officenets #optional - to clear LOCALNET=192.168.0.0/24 VPNNET=10.10.10.0/29 ipset create privatenets hash:net ipset add privatenets $LOCALNET ipset add privatenets $VPNNET
然後在 iptables 腳本中……
iptables --table mangle --append INPUT \ --match state --state NEW \ --match mac --mac-source ${!MAC} \ -m set \ ! --match-set privatenets src \ --jump CONNMARK --set-mark ${!MARK}
確認
驗證路由表的 fwmark 規則:
$ ip rule 0: from all lookup local 0: from all fwmark 0x1 lookup modem1 0: from all fwmark 0x2 lookup modem2 32766: from all lookup main 32767: from all lookup default
驗證 iptables mangle 路由:
$ sudo iptables -t mangle -L ... Chain INPUT (policy ACCEPT) target prot opt source destination CONNMARK all -- anywhere anywhere state NEW MAC AA:BB:CC:DD:EE:01 ! source 192.168.0.1/24 CONNMARK set 0x1 CONNMARK all -- anywhere anywhere state NEW MAC AA:BB:CC:DD:EE:02 ! source 192.168.0.2/24 CONNMARK set 0x2 Chain OUTPUT (policy ACCEPT) target prot opt source destination CONNMARK all -- anywhere anywhere CONNMARK restore ...
驗證傳出表路由:
$ ip route list table modem1 default via 192.168.0.1 dev eth0 proto static $ ip route list table modem2 default via 192.168.0.2 dev eth0 proto static