Вопрос или проблема
Я пытаюсь настроить свой фаервол (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
. Вот несколько шагов по отладке и проверке конфигурации:
-
Проверьте статус интерфейса Wireguard
wg0
. Убедитесь, что интерфейсwg0
действительно активен и правильно настроен на вашем сервере. Это можно сделать с помощью команды:wg show
-
Проверьте список интерфейсов и IP-адресов. Убедитесь, что обрабатываете правильные интерфейсы и что нет непредвиденных маппингов между IP-адресами.
ip a
-
Убедитесь, что правила iptables применены. Иногда изменения могут сохраняться, но не применяться. Используйте следующую команду для применения:
sudo iptables-restore < ваш_файл_с_правилами
-
Детальная проверка логов. Включите логирование на уровне фаервола, чтобы понять, какой именно правил действует, когда вы подключаетесь. Это можно сделать добавлением правил логирования перед правилами DROП:
-A INPUT -p tcp --dport 8080 -j LOG --log-prefix "Dropping 8080: "
-
Проверка фирменной маршрутизации. Иногда конфигурация маршрутизации на клиенте или сервере может обходить Wireguard, ведущей к "обходному" пути маршрутизации. Убедитесь, что весь трафик направляется через интерфейс
wg0
:- Проверьте, нет ли каких-либо других интерфейсов, которые могут категоризироваться компанией как "vpn".
- Убедитесь, что все клиенты добавлены в конфигурацию Wireguard, и их маршрут установлен правильно.
-
После внесения изменений в iptables проверьте конфигурацию еще раз. Запустите тесты, включая дополнительные проверки, что доступ возможен только через Wireguard.
Таким образом, вы можете убедиться, что ваши правила iptables настраиваются соответствующим образом, ограничивая доступ к портам 81, 8080 и 53 только через интерфейс Wireguard. Корректная настройка этих параметров защитит ваши серверы от несанкционированного доступа извне и обеспечит надежность при работе с сервисами, такими как Nginx Proxy Manager и PiHole, подключенных к VPN.