Правила iptables работают только, когда пакет приходит из локальной VPN.

Вопрос или проблема

Я новичок в iptables.

У меня есть docker-контейнер wg-easy с локальным IP 172.18.0.2. У моего VPS публичный IP 185.217.198.123. Также есть ip route add 10.8.0.0/24 via 172.18.0.2 для доступа к peer-ам wireguard напрямую с VPS. У них диапазон 10.8.0.0/24.

По сути, я хочу ‘перенаправить’ все udp пакеты, которые приходят с 185.217.198.123:19132 на 10.8.0.2:19132 и наоборот.

Назовем удаленное устройство, которое хочет получить доступ к 185.217.198.123:19132, клиентом.

iptables -t nat -L:

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       udp  --  anywhere             anywhere             udp dpt:19132 to:10.8.0.2:19132
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
DOCKER     all  --  anywhere            !localhost/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        anywhere            
MASQUERADE  all  --  172.18.0.0/16        anywhere            
MASQUERADE  udp  --  172.18.0.2           172.18.0.2           udp dpt:51820
MASQUERADE  tcp  --  172.18.0.2           172.18.0.2           tcp dpt:51821
SNAT       udp  --  anywhere             10.8.0.2             udp dpt:19132 to:185.217.198.123

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            
DNAT       udp  --  anywhere             anywhere             udp dpt:51820 to:172.18.0.2:51820
DNAT       tcp  --  anywhere             anywhere             tcp dpt:51821 to:172.18.0.2:51821

Когда клиент подключен к vpn (wg-easy docker-контейнер), все работает как предполагалось.

Логи tcpdump:

15:41:23.412635 IP 172.18.0.2.56489 > 185.217.198.123.19132: UDP, length 4
15:41:23.412666 IP 185.217.198.123.56489 > 10.8.0.2.19132: UDP, length 4
15:41:23.507247 IP 10.8.0.2.19132 > 185.217.198.123.56489: UDP, length 4
15:41:23.507275 IP 185.217.198.123.19132 > 172.18.0.2.56489: UDP, length 4

Обратите внимание, что все пакеты приходят из docker-контейнера wg-easy (172.18.0.2).

Но когда клиент не подключен к vpn и хочет получить прямой доступ к vps, происходит следующее:

15:58:31.459491 IP (ip клиента).(случайный порт) > 185.217.198.123.19132: UDP, length 4

и на этом все. Продолжения здесь нет. Почему это происходит и как это исправить?

Ответ или решение

Ваша ситуация с iptables связана с трансляцией и переадресацией сетевых пакетов; это проблема, которую часто встречают начинающие администраторы систем. Давайте рассмотрим вашу ситуация более детально и попытаемся определить, почему ваши правила iptables работают, когда запросы идут через VPN, и почему они не срабатывают, когда клиент пытается подключиться напрямую.

Теория

Сначала разберёмся, как работают iptables и как они взаимодействуют с сетевой топологией вашей системы. Iptables — это межсетевой экран, который управляет IP-трафиком в системе на Linux. Он состоит из нескольких цепочек, причем в вопросе задействованы такие как PREROUTING, POSTROUTING, INPUT, OUTPUT и FORWARD, каждая занимается обработкой пакетов на различных стадиях прохождения через ваш сервер.

PREROUTING и POSTROUTING цепи

  • PREROUTING — используется для изменения пакетов после того, как они поступают на интерфейс сети, но до маршрутизации.
  • POSTROUTING — применяется к пакетам после выполнения маршрутизации и перед тем, как они покинут интерфейс сети.

DNAT и SNAT

  • DNAT (Destination Network Address Translation) — изменяет адрес назначения пакета. Используется в цепочке PREROUTING для перенаправления входящего трафика на другой IP и порт.
  • SNAT (Source Network Address Translation) — изменяет адрес источника пакета. Это чаще всего делается в POSTROUTING, чтобы корректно возвращать трафик клиенту за NAT.

Пример

Например, вы имеете следующее правило для DNAT:

DNAT udp -- anywhere anywhere udp dpt:19132 to:10.8.0.2:19132

Это правило указывает, что любой UDP трафик, поступающий на порт 19132, должен быть перенаправлен на адрес 10.8.0.2 с тем же портом. Это работает идеально, когда ваш клиент подключён через VPN, так как сетевые пакеты проходят через интерфейс Docker и обрабатываются правилами это контейнера.

Однако, при непосредственном подключении проблема в том, что трафик от клиента достигает вашего публичного IP-адреса, но не перенаправляется корректно. Это может быть связано с тем, как пакет обрабатывается в цепочках iptables или какое конкретное назначение ему присваивается после прохождения NATа.

Применение

Для решения вашей проблемы, рассмотрите следующее:

  1. Убедитесь, что все пакеты корректно правая через цепочки PREROUTING и POSTROUTING. Добавьте журналирование (логирование) в iptables, чтобы определить, где именно пакеты "застревают":

    iptables -t nat -A PREROUTING -p udp --dport 19132 -j LOG --log-prefix "PREROUTING: "
    iptables -t nat -A POSTROUTING -p udp --dport 19132 -j LOG --log-prefix "POSTROUTING: "
  2. Убедитесь, что нет конфликтующих правил в других цепочках, таких как INPUT или FORWARD, которые могут блокировать или изменять пакеты. Проверьте политику по умолчанию для всех цепочек.

  3. Проверьте и исправьте правил SNAT. Возможно, они неправильно настроены для пакетов, которые должны возвращаться клиенту, что мешает им достигнуть нужного получателя.

  4. Маршрутизация. Проверьте, что ваша маршрутизация корректно настроена для всех интерфейсов и диапазонов адресов. ip route add действует только в контексте от интерфейса wireguard; убедитесь, что для других интерфейсов тоже существует корректная маршрутизация.

  5. Пересмотр NAT правил. Вместо использования SNAT и MASQUERADE для данной задачи, подумайте об использовании PAT (Port Address Translation), чтобы исключить нежелательные эффекты от NAT.

  6. Проверка сервисов. Убедитесь, что целевой сервис на IP 10.8.0.2 действительно слушает порт 19132 и в состоянии обработать входящие пакеты. Можете использовать nc для проверки доступности через контейнер.

  7. Таблица маршрутизации. Проверьте и перепроверьте свои статические маршруты с помощью команды ip route show, чтобы убедиться, что пересылка пакетов настроена корректно.

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

Оцените материал
Добавить комментарий

Капча загружается...