Назад | Перейти на главную страницу

Открытие udp-сервера за NAT с использованием openvpn

У меня есть сервер за nat, который требует публичного доступа к нему, и VPS с сервером OpenVPN на нем. Цель состоит в том, чтобы сделать возможным использование IP-адреса VPS для доступа к серверу за nat без каких-либо дополнительных действий на стороне клиента.

Мнимые IP-адреса для примеров:

Испытательная установка:

# on server behind nat:
socat -v -d -d - udp4-listen:5000,reuseaddr,fork
# on client
echo "test" | nc -up 2000 -w 600 1.2.3.4 5000

Что я уже сделал:

Попытка1: iptables DNAT + MASQUERADE

# on vps
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.route_localnet=1
iptables -t nat -A PREROUTING -d 1.2.3.4/32 -p udp -m udp --dport 5000 -j DNAT --to-destination 192.168.2.10
iptables -t nat -A POSTROUTING -d 192.168.2.10/32 -j MASQUERADE

Это работает, за исключением одного недостатка: он скрывает исходный ip.

$ socat -v -d -d - udp4-listen:5000,reuseaddr,fork
2020/05/26 21:27:34 socat[3082154] N reading from and writing to stdio
2020/05/26 21:27:34 socat[3082154] N listening on UDP AF=2 0.0.0.0:5000
2020/05/26 21:27:38 socat[3082154] N accepting UDP connection from AF=2 192.168.148.1:2000
                                                                           /\
                         # this is VPN gateway ip not client's original ---┘
2020/05/26 21:27:38 socat[3082154] N forked off child process 3082179
... more output

Attemp2: iptables DNAT + ovpn push "redirect-gateway def1 bypass-dhcp"

# same as above minus the MASQUERADE
# edit /etc/openvpn/server.conf to add push "redirect-gateway def1 bypass-dhcp"

Это также работает и не закрывает IP-адрес клиента. Но весь трафик сервера за nat проходит через VPN, а не только ответ клиентам, подключающимся через этот туннель.

Attemp3: iptables DNAT + SNAT

iptables -t nat -A PREROUTING -d 1.2.3.4/32 -p udp -m udp --dport 5000 -j DNAT --to-destination 192.168.2.10
iptables -t nat -A POSTROUTING -s 192.168.2.10/32 -p udp -j SNAT --to-source 1.2.3.4:5000

В этой настройке UDP-пакеты принимаются сервером правильно, но ответ не возвращается (счетчики правила SNAT не увеличиваются). Насколько я понимаю, поскольку шлюз по умолчанию не находится в VPN, ответ проходит через обычный шлюз, и поскольку исходный IP-адрес не будет IP-адресом VPS nc не будет принимать его как ответ на исходные пакеты.

Итак, я все делаю неправильно? Есть ли другой подход к этой проблеме, более простой?

Если я на правильном пути, есть ли способ пометить пакеты, поступающие из VPN, чтобы iptables запомнил, какие комбинации IP / исходных портов должны использовать VPN в качестве шлюза, не отправляя через него обычный трафик?

P.S. Я планирую использовать несколько «посредников» / «обратных прокси» VPS / OpenVPN одновременно для одного и того же внутреннего сервера, поэтому правило, основанное на порте сервера в качестве порта источника пакета для передачи его через VPN, не будет работать. Он должен запоминать каждое соединение (или, скорее, комбинацию IP / порта источника, поскольку соединение не является концепцией, определенной в UDP) независимо, чтобы ответить правильно.

[Server] < ---------------------OpenVpn-------------------------> [VPS (192.168.2.1)] < --- > [Client]
[Server] < --- > [pfsense with unreachable ip] < -- INTERNET -- > [VPS (1.2.3.4)] < --- > [Client]

Прокомментируйте, если я пропустил какую-либо информацию или вам требуется больше пояснений по поводу моей цели. Спасибо за ваше время.