Как разрешить доступ к определённым портам только при подключении к Wireguard VPN?

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

Я пытаюсь настроить свой фаервол (iptables), чтобы разрешить только определенные порты только при подключении к VPN.

Я запускаю NginxProxyManager, PiHole и Wireguard на арендованном VPS, и я хочу настроить порт 81 (веб-интерфейс для NPM), порт 8080 (веб-интерфейс для PiHole) и порт 53 только при подключении к VPN на ноутбуке, например, и они не должны быть доступны с публичного IP VPS.

На данный момент у меня есть эти правила,

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Разрешить установленные подключения
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Разрешить SSH на порту 22
-A INPUT -p tcp --dport 22 -j ACCEPT

# Разрешить интерфейс loopback
-A INPUT -i lo -j ACCEPT

# Отбрасывать недопустимые пакеты
-A INPUT -m conntrack --ctstate INVALID -j DROP

# Отправляет ответ ICMP об недоступности порта вместо тихого отбрасывания пакетов
-A INPUT -j REJECT --reject-with icmp-port-unreachable

# Разрешить порт 80
-A INPUT -p tcp --dport 80 -j ACCEPT

# Разрешить порт 443
-A INPUT -p tcp --dport 443 -j ACCEPT

# Разрешить порт 53/tcp и 53/udp только на интерфейсе wg0
-A INPUT -i wg0 -p tcp --dport 53 -j ACCEPT
-A INPUT -i wg0 -p udp --dport 53 -j ACCEPT

# Разрешить порт 81 только на интерфейсе wg0
-A INPUT -i wg0 -p tcp --dport 81 -j ACCEPT

# Разрешить порт 8080 только на интерфейсе wg0
-A INPUT -i wg0 -p tcp --dport 8080 -j ACCEPT

# Разрешить порт 51820
-A INPUT -p udp --dport 51820 -j ACCEPT

# В противном случае заблокировать доступ к порту 53/tcp и 53/udp
-A INPUT -p tcp --dport 53 -j DROP
-A INPUT -p udp --dport 53 -j DROP

# В противном случае заблокировать доступ к порту 81
-A INPUT -p tcp --dport 81 -j DROP

# В противном случае заблокировать доступ к порту 8080
-A INPUT -p tcp --dport 8080 -j DROP

# Заблокировать весь другой входящий трафик
-A INPUT -j DROP

COMMIT

По сути, я хочу, чтобы PiHole действовал как DNS для подключенных клиентов Wireguard, в противном случае VPS может использовать обычный DNS.

На данный момент я тестирую это на виртуальной машине перед развертыванием. Теперь после применения этих правил, с моего ноутбука, я могу выполнить nc VM_IP 8080 или 81 или 53 без подключения к VPN, что не то, чего я хочу.

Что я делаю не так?

На другом VPS я использую UFW, и у меня есть такие правила,

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
51820/udp                  ALLOW IN    Anywhere
22/tcp                     ALLOW IN    Anywhere
53/tcp on wg0              ALLOW IN    Anywhere
53/udp on wg0              ALLOW IN    Anywhere
8080/tcp on wg0            ALLOW IN    Anywhere
53/tcp                     DENY IN     Anywhere
53/udp                     DENY IN     Anywhere
8080/tcp                   DENY IN     Anywhere
51820/udp (v6)             ALLOW IN    Anywhere (v6)
22/tcp (v6)                ALLOW IN    Anywhere (v6)
53/tcp (v6) on wg0         ALLOW IN    Anywhere (v6)
53/udp (v6) on wg0         ALLOW IN    Anywhere (v6)
8080/tcp (v6) on wg0       ALLOW IN    Anywhere (v6)
53/tcp (v6)                DENY IN     Anywhere (v6)
53/udp (v6)                DENY IN     Anywhere (v6)
8080/tcp (v6)              DENY IN     Anywhere (v6)

и это работает как ожидается, я могу получить доступ к веб-интерфейсу PiHole только при подключении к VPN. Я не применял правило для 81 здесь, но в остальном оно работает.

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

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

Теория

На базе Linux фаервол iptables позволяет настраивать правила, которые управляют входящим и исходящим трафиком. Идея состоит в том, чтобы разрешить доступ к определенным портам только из определенных интерфейсов, в вашем случае это интерфейс Wireguard, обозначенный как wg0. Это можно сделать с помощью правила, которое проверяет интерфейс источника запроса.

Пример

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

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Разрешаем установленные соединения
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Разрешаем SSH на порту 22
-A INPUT -p tcp --dport 22 -j ACCEPT

# Разрешаем интерфейс loopback
-A INPUT -i lo -j ACCEPT

# Отклоняем недействительные пакеты
-A INPUT -m conntrack --ctstate INVALID -j DROP

# Отправляем ICMP-сообщение о недоступности порта вместо тихого отклонения пакетов
-A INPUT -j REJECT --reject-with icmp-port-unreachable

# Разрешаем порт 80
-A INPUT -p tcp --dport 80 -j ACCEPT

# Разрешаем порт 443
-A INPUT -p tcp --dport 443 -j ACCEPT

# Разрешаем порт 53/tcp и 53/udp только на интерфейсе wg0
-A INPUT -i wg0 -p tcp --dport 53 -j ACCEPT
-A INPUT -i wg0 -p udp --dport 53 -j ACCEPT

# Разрешаем порт 81 только на интерфейсе wg0
-A INPUT -i wg0 -p tcp --dport 81 -j ACCEPT

# Разрешаем порт 8080 только на интерфейсе wg0
-A INPUT -i wg0 -p tcp --dport 8080 -j ACCEPT

# Разрешаем порт 51820
-A INPUT -p udp --dport 51820 -j ACCEPT

# Отклоняем доступ к порту 53/tcp и 53/udp вне интерфейса wg0
-A INPUT -p tcp --dport 53 -j DROP
-A INPUT -p udp --dport 53 -j DROP

# Отклоняем доступ к порту 81 вне интерфейса wg0
-A INPUT -p tcp --dport 81 -j DROP

# Отклоняем доступ к порту 8080 вне интерфейса wg0
-A INPUT -p tcp --dport 8080 -j DROP

# Отклоняем весь другой входящий трафик
-A INPUT -j DROP

COMMIT

Применение

Ваши правила выглядят правильно настроенными на первый взгляд. Тем не менее, поскольку вы отмечаете, что можете подключаться к указанным портам без соединения через VPN, это может свидетельствовать о наличии альтернативного пути доступа, или неправильно настроенного интерфейса wg0. Вот несколько шагов по отладке и проверке конфигурации:

  1. Проверьте статус интерфейса Wireguard wg0. Убедитесь, что интерфейс wg0 действительно активен и правильно настроен на вашем сервере. Это можно сделать с помощью команды:

    wg show
  2. Проверьте список интерфейсов и IP-адресов. Убедитесь, что обрабатываете правильные интерфейсы и что нет непредвиденных маппингов между IP-адресами.

    ip a
  3. Убедитесь, что правила iptables применены. Иногда изменения могут сохраняться, но не применяться. Используйте следующую команду для применения:

    sudo iptables-restore < ваш_файл_с_правилами
  4. Детальная проверка логов. Включите логирование на уровне фаервола, чтобы понять, какой именно правил действует, когда вы подключаетесь. Это можно сделать добавлением правил логирования перед правилами DROП:

    -A INPUT -p tcp --dport 8080 -j LOG --log-prefix "Dropping 8080: "
  5. Проверка фирменной маршрутизации. Иногда конфигурация маршрутизации на клиенте или сервере может обходить Wireguard, ведущей к "обходному" пути маршрутизации. Убедитесь, что весь трафик направляется через интерфейс wg0:

    • Проверьте, нет ли каких-либо других интерфейсов, которые могут категоризироваться компанией как "vpn".
    • Убедитесь, что все клиенты добавлены в конфигурацию Wireguard, и их маршрут установлен правильно.
  6. После внесения изменений в iptables проверьте конфигурацию еще раз. Запустите тесты, включая дополнительные проверки, что доступ возможен только через Wireguard.

Таким образом, вы можете убедиться, что ваши правила iptables настраиваются соответствующим образом, ограничивая доступ к портам 81, 8080 и 53 только через интерфейс Wireguard. Корректная настройка этих параметров защитит ваши серверы от несанкционированного доступа извне и обеспечит надежность при работе с сервисами, такими как Nginx Proxy Manager и PiHole, подключенных к VPN.

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

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