iptables: как перенаправить порт UDP и TCP на сервер за VPN-подключением Wireguard

iptables: как перенаправить порт UDP и TCP на сервер за VPN-подключением Wireguard

Итак, у меня есть сервер VPS (KVM) с Debian bullseye и публичным IP. На этом сервере также запущен сервер Wireguard. Дома у меня есть еще один сервер (за NAT) с клиентом Wireguard, который подключен к моему VPS. Туннель запущен и работает, то есть я могу нормально общаться через VPN Wireguard.

+----------------------------------+             +-------------------------------
| Homeserver (behind NAT)          |             | VPS (KVM) with public IP     |
| 192.168.1.10                     |             | 1.2.3.4                      |
|         +------------------------|             |--------------------+         |
|         | wg-homeserver          | - - - - - - | wg-vps             |         |
|         | 192.168.200.2          |             | 192.168.200.1      |         |
|         +------------------------|             |--------------------+         |
|                                  |             |                              |
+----------------------------------+             +------------------------------+

Мой домашний сервер запускает несколько контейнеров Docker, которые прослушивают порты (на всех IP-адресах), что означает, что эти порты доступны из 192.168.1.0/24. Теперь мне нужно перенаправить один порт TCP и один порт UDP на публичный IP-адрес моего VPS и перенаправить трафик по каналу Wireguard на те же порты на моем домашнем сервере:

1.2.3.4:10000/tcp -> 192.168.200.2:10000/tcp
1.2.3.4:10001/udp -> 192.168.200.2:10001/udp

Переадресация IP включена на обоих компьютерах, то есть cat /proc/sys/net/ipv4/ip_forwardотображается 1.

Для переадресации TCP-порта у меня есть следующие правила:

iptables -A FORWARD -d 192.168.200.2/32 -i wg-vps -p tcp --dport 10000 -j ACCEPT
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 10000 -j DNAT --to-destination 192.168.200.2:10000

Когда я пытаюсь, ssh -p 10000 1.2.3.4я не вижу никаких пакетов, регистрируемых wireguard -i wg-vps. Я пробовал много других вещей, но так и не смог понять, что я делаю неправильно или что упускаю.

В любом случае, для порта UDP я создал следующее правило, и оно оказалось немного более успешным:

iptables -t nat -A PREROUTING -d 1.2.3.4/32 -i eth0 -p udp --dport 10001 -j DNAT --to-destination 192.168.200.2:10001

Вот как я отправляю свой тестовый пакет UDP:

echo -n test | nc -4 -u 1.2.3.4 10001

Когда я это делаю, я вижу tcpdump -i wg-vpsв журнале своего VPS следующее ( 4.5.6.7это мой публичный IP-адрес):

11:35:47.497622 IP 4.5.6.7.43357 > 192.168.200.2.10001: UDP, length 4

Что, похоже, пытается сделать правильно и взять пакет, обновить пункт назначения на 192.168.200.2, а затем поместить его на интерфейс Wireguard wg-vps. Но tcpdump -i wg-homeserverна моем домашнем сервере никогда не отображается прибытие этого пакета.

На самом деле, я заметил, что когда я watch ip -s link show wg-homeserverбыл на своем Homeserver, каждый раз, когда я отправлял пакет udp на этот порт, ошибки RX увеличивались на единицу. Так чточто-нибудьдоходит до туда, но что бы это ни было, оно не отображается tcpdumpи, похоже, теряется где-то ниже. Что странно, потому что и UDP, и TCP по каналу Wireguard работают отлично в обоих направлениях.

Насколько я понимаю, tcpdumpпакеты отображаются до iptables, поэтому я предполагаю, что даже если пакет, по-видимому, записывается в интерфейс Wireguard, он где-то теряется.

ОБНОВЛЯТЬ: Итак, я нашел способ включить ведение журнала Wireguard:

echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control

А при просмотре журналов dmesg --followвыясняется, что Wireguard сбрасывает пакет по следующей причине:

wireguard: wg-homeserver: Packet has unallowed src IP (4.5.6.7) from peer 20 (xxxxxx)

Так что я думаю, это означает, что ему не нравится тот факт, что исходный адрес является оригиналом, откуда бы ни пришел запрос. Я не хочу делать SNAT, поэтому я думаю, что мне просто нужно будет как-то научить его, что он должен разрешать любой исходный адрес.

Который оказывается настройкой AllowedIPsв [Peer]​​разделе конфигурации моего wireguard. Это решает проблему:

AllowedIPs = 0.0.0.0/0, ::0/0

До этого я ставил маски интерфейсов, аналогичные тем, что в [Interface]разделе, не понимая, что это ограничит исходные адреса пакетов.

Однако это перехватывает весь трафик и пытается направить его через соединение Wireguard, поскольку wg-quickсмотрит AllowedIPsи думает, что должен добавить маршрут и перенаправить весь трафик через VPN. Это, очевидно, нежелательно, но, к счастью, есть решение: добавление Table = offв [Interface]раздел предотвратит это.

решение1

Ознакомьтесь с таблицей правил, чтобы понять, как исходящие пакеты маршрутизируются на домашнем сервере. wg-quick добавит несколько правил.

ip rule show

Мне пришлось удалить некоторые правила, сгенерированные wg-quick (которые заставляют его пересылать все пакеты в wg), а затем добавить правила, которые пересылают требуемые порты. Вы можете увидеть таблицу wg# из команды выше.

ip -4 rule add sport 80 table XXXXX
ip -4 rule add sport 443 table XXXXX

Вышеуказанное работало некоторое время. Но systemd-networkd удалит пользовательские правила, когда истекает срок аренды dhcp или кабель lan отключается и снова подключается. Поэтому я полностью удалил wg-quick и использую systemd-networkd для настройки интерфейса wg и правил маршрутизации.

Связанный контент