Вот моя сетевая диаграмма:
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
Netplan
, iptables и iproute2 для настройки сети.В конце концов я получил свое решение из статьи и комментариев в Политика маршрутизации в Linux на основе MAC-адреса отправителя и Справочник Netplan.io по маршрутизации политик.
Хитрость заключается в том, чтобы пометить и CONNTRACK входящие пакеты по MAC-адресу источника в отдельную таблицу маршрутизации через 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
е вуаля!
БОНУСНЫЙ ОТВЕТ
Если у вас более одной внутренней сети (например, VPN через нелокальный IP-адрес), используйте ipset
и iptables
-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