У меня есть кабельное соединение с маршрутизатором на базе Linux. Маршрутизатор имеет два физических интерфейса:
enp1s0 (dhcp from cable provider)
enp2s0 (192.168.1.1)
с маскировкой на enp1s0. тогда у меня есть клиентское соединение OpenVPN:
tun0 (10.0.0.4)
Опять же с маскировкой на этот девайс. В обычной таблице маршрутизации нет записей, указывающих на это устройство, но у меня есть дополнительная таблица маршрутизации:
vpn-clients
так что я могу добавить маршрут по умолчанию с помощью этого устройства:
ip route add default via 10.0.0.1 dev tun0 table vpn-clients
а затем укажите для каждого клиента, какую таблицу использовать:
ip rule add from 192.168.1.200 lookup vpn-clients
ip rule add from 192.168.1.201 lookup vpn-clients
...
и перенаправление портов на tun0:
/sbin/iptables -t nat -A PREROUTING -i tun0 -p udp --dport 5555 -j DNAT --to-destination 192.168.1.200:5555
Похоже, он работает (по крайней мере, для исходящих соединений). Похоже, что весь трафик от клиентов с маршрутизацией от источника направляется через vpn.
А вот входящие подключения - это совсем другая история. Раньше у меня было много-много марсиан.
Я понял, что это может быть вызвано комбинацией исходной маршрутизации, переадресации портов и маскарадинга, то есть ядро может не знать, что место назначения входящего пакета будет изменено, и вместо этого предположить, что 10.0.0.4 является конечным пунктом назначения, что было бы невозможно, потому что не существует никаких установленных маршрутов, которые объясняли бы поступающие в этот пункт назначения из чего-либо, кроме его собственной подсети.
Итак, я добавил несколько фиктивный маршрут:
ip rule lookup from 10.0.0.4 lookup vpn-clients
так что «таблица маршрутизации» для этого интерфейса становится «vpn-clients», у которых ДЕЙСТВИТЕЛЬНО есть маршрут по умолчанию, указывающий в этом направлении.
Это остановило регистрацию и сброс марсиан. Входящие соединения сейчас работают нормально. Но является ли это «правильным» путем? Можно ли сделать это лучше?