Имеется узел, который обычно находится в локальной подсети (10.0.0.0/24), а иногда подключен через openvpn туннель (тогда он переносится в подсеть VPN 10.0.1.0/24).
Требуется организовать доступность узла по IP адресу из локальной подсети 10.0.0.0/24 или по DNS имени, в независимости от того как узел подключен, локально или по VPN. Думаю ситуация часто встречается но я не смог найти стабильного и быстро работающего готового решения.
VPN сервер установлен на устройстве под управлением openwrt c OpenVPN сервером и dnsmasq демоном который идет по умолчанию, как DHCP и DNS. dnsmasq не хотелось бы менять на какой либо другой DNS сервер, но варианты рассматриваются. По совместительству устройство занимается маршрутизацией.
Собственно вопрос я уже решил способом который ниже опишу. Но меня очень беспокоит сложность решения. Я убежден, что есть более простой и очевидный путь, прошу поделиться мыслями и покритиковать следующие решение.
Решил при помощи iptables путем переадресации всего трафика с IP A.A.A.A из локальной подсети 10.0.0.0/24 на IP B.B.B.B из VPN подсети 10.0.1.0/24 в момент подключения узла по vpn.
Для этого в openvpn.conf был добавлен параметр
script-security 2
learn-address /etc/openvpn/scripts/redirect.sh
iptables -t nat -I PREROUTING -d A.A.A.A -j DNAT --to-destination B.B.B.B # Собственно перенаправление
iptables -I FORWARD -d B.B.B.B -j ACCEPT
ifconfig br-lan:1 A.A.A.A netmask 255.255.255.0 up # Самое интересное! Что бы перенаправление работало для узлов из локальной подсети приходится поднимать виртуальный интерфейс на VPN сервере с IP A.A.A.A. Иначе узлы в локальной подсети не пользуются шлюзом и правила перенаправления для них не работают, и их ARP запросы к IP A.A.A.A обречены...
ifconfig br-lan:1 down # Удаляем интерфейс заглушку, чтобы узел снова смог получить свой A.A.A.A IP и не было конфликта
iptables -t nat -D PREROUTING -d A.A.A.A -j DNAT --to-destination B.B.B.B # Удаляем перенаправление трафика
iptables -D FORWARD -d B.B.B.B -j ACCEPT
В bind-e для подобного случая используются views.
Т. е. для одной подсети зона отдается, к примеру, как internal, для другой - external.
Не уверен, конечно, что вам такой вариант подойдет.