Итак, у меня есть сервер 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 и правил маршрутизации.