Вопрос или проблема
У меня есть сервер на Ubuntu. У него есть адаптер Wifi (интерфейс wlo1) и Ethernet-порт (интерфейс enp44s0). Сеть Wifi 10.42.1.0/24, а проводная сеть 10.42.0.0/24. У сервера IP 10.42.0.1 и 10.42.1.1.
У меня есть рабочая станция в проводной сети с работающим веб-сервером. Ее IP 10.42.0.216. С сервера я могу без проблем подключиться к веб-странице рабочей станции.
У меня есть телефон, подключенный к Wifi. Его IP 10.42.1.111.
Я хочу настроить переадресацию портов, чтобы при подключении к 10.42.1.1 с телефона, это перенаправлялось на рабочую станцию и веб-сервер, работающий на ней. Это легко, верно?
Я использую UFW на сервере (он идет с Ubuntu). Удивительно, но UFW не может настроить переадресацию портов (недостаточно сложный брандмауэр). Следуя онлайн-урокам, я попробовал следующее:
- Расположить строку
net/ipv4/ip_forward=1
в файле /etc/ufw/sysctl.conf. - Установить
DEFAULT_FORWARD_POLICY="ACCEPT"
в файле /etc/default/ufw. - Разрешить оба порта 80 и 443 с помощью правила UFW.
- Добавить следующее в начало файла /etc/ufw/before.rules:
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -d 10.42.1.1 -p tcp --dport 80 -j DNAT --to-destination 10.42.0.216:80
-A PREROUTING -d 10.42.1.1 -p tcp --dport 443 -j DNAT --to-destination 10.42.0.216:443
-A POSTROUTING -s 10.42.0.0/24 -j MASQUERADE
COMMIT
И вот результат:
ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] Anywhere on eno2 ALLOW FWD Anywhere on enp44s0
[ 2] Anywhere on enp44s0 ALLOW IN Anywhere
[ 3] 6881/tcp on eno2 ALLOW IN Anywhere
[ 4] 53 on wlo1 ALLOW IN Anywhere
[ 5] 67/udp on wlo1 ALLOW IN Anywhere
[ 6] 8888/tcp on wlo1 ALLOW IN Anywhere
[ 7] 445/tcp on wlo1 ALLOW IN Anywhere
[ 8] Anywhere on eno2 ALLOW FWD Anywhere on wlo1
[ 9] 443/tcp ALLOW IN Anywhere
[10] 80/tcp ALLOW IN Anywhere
[11] 443/tcp (v6) ALLOW IN Anywhere (v6)
[12] 80/tcp (v6) ALLOW IN Anywhere (v6)
Chain PREROUTING (policy ACCEPT 10211 packets, 579K bytes)
pkts bytes target prot opt in out source destination
11 660 DNAT tcp -- * * 0.0.0.0/0 10.42.1.1 tcp dpt:80 to:10.42.0.216:80
0 0 DNAT tcp -- * * 0.0.0.0/0 10.42.1.1 tcp dpt:443 to:10.42.0.216:443
9795 541K DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER all -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
2 120 MASQUERADE all -- * !br-1972fe7a2df1 172.18.0.0/16 0.0.0.0/0
6 1192 MASQUERADE all -- * * 10.42.0.0/24 0.0.0.0/0
0 0 MASQUERADE tcp -- * * 172.18.0.2 172.18.0.2 tcp dpt:9999
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
0 0 RETURN all -- br-1972fe7a2df1 * 0.0.0.0/0 0.0.0.0/0
1 60 DNAT tcp -- !br-1972fe7a2df1 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:9999 to:172.18.0.2:9999
И несмотря на все это, когда я ввожу 10.42.1.1 в адресной строке браузера телефона, я не могу подключиться. Что я упустил? Какую процедуру тестирования или инструменты я могу использовать для устранения проблемы?
Правка: Я посмотрел на это с помощью Wireshark и заметил, что когда я пытаюсь подключиться с телефона, SYN сразу же отвечает ICMP “назначение недоступно, порт недоступен”. Я не знаю, что это вызывает.
Я наконец-то выяснил, в чем была проблема. Тем, кто столкнется с такой же проблемой, вот объяснение и решение.
iptables мертв и был заменен на nftables. Команда iptables все еще существует, но это псевдоним для nftables. Iptables в основном работает, но это лишь верхушка айсберга. Если что-то другое устанавливает правила брандмауэра с помощью nftables, вы не увидите это в iptables, и вы останетесь в недоумении, почему ваши правила iptables не работают так, как должны.
И действительно, есть что-то, что устанавливает правила nftables за вашей спиной. Ubuntu поставляется с NetworkManager. Это то, что я использовал, чтобы позволить моему компьютеру на Ubuntu делиться своим интернет-соединением с другими компьютерами в локальной сети и настроить свою точку доступа Wifi. Чтобы поделиться интернет-соединением, NetworkManager должен установить правила nftables. Вы можете увидеть их, если ввести nft list ruleset
.
# Эта таблица предназначена для совместного использования интернет-соединения с компьютерами, подключенными к точке доступа Wifi
table ip nm-shared-wlo1 {
chain nat_postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.42.1.0/24 ip daddr != 10.42.1.0/24 masquerade
}
chain filter_forward {
type filter hook forward priority filter; policy accept;
ip daddr 10.42.1.0/24 oifname "wlo1" ct state { established, related } accept
ip saddr 10.42.1.0/24 iifname "wlo1" accept
iifname "wlo1" oifname "wlo1" accept
# Это и есть проблема
iifname "wlo1" reject
oifname "wlo1" reject
}
}
# Эта таблица предназначена для совместного использования интернет-соединения с компьютерами, подключенными к LAN
table ip nm-shared-enp44s0 {
chain nat_postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.42.0.0/24 ip daddr != 10.42.0.0/24 masquerade
}
chain filter_forward {
type filter hook forward priority filter; policy accept;
ip daddr 10.42.0.0/24 oifname "enp44s0" ct state { established, related } accept
ip saddr 10.42.0.0/24 iifname "enp44s0" accept
iifname "enp44s0" oifname "enp44s0" accept
# Это и есть проблема
iifname "enp44s0" reject
oifname "enp44s0" reject
}
}
NetworkManager установил правила так, чтобы пакеты не могли проходить от wifi (wlo1) к LAN (enp44s0) и наоборот. Вот почему переадресация портов не может работать.
Решение состоит в том, чтобы сказать NetworkManager не устанавливать никаких правил брандмауэра. Вы можете сделать это, отредактировав /etc/NetworkManager/NetworkManager.conf
и добавив следующую строку в разделе [main] firewall-backend=none
.
Но теперь вам нужно настроить свой брандмауэр самостоятельно, иначе у вас не будет общего доступа к интернет-соединению. Вы можете сделать это с помощью nftables или firewalld (я не пробовал последнее).
Для nftables все, что вам нужно, — это скрипт, подобный этому:
#!/usr/sbin/nft -f
# Очистить набор правил
flush ruleset
# Эта таблица предназначена для совместного использования интернет-соединения с компьютерами, подключенными к точке доступа Wifi
table ip nm-shared-wlo1 {
chain nat_postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.42.1.0/24 ip daddr != 10.42.1.0/24 masquerade
}
chain filter_forward {
type filter hook forward priority filter; policy accept;
ip daddr 10.42.1.0/24 oifname "wlo1" ct state { established, related } accept
ip saddr 10.42.1.0/24 iifname "wlo1" accept
iifname "wlo1" oifname "wlo1" accept
iifname "enp44s0" oifname "wlo1" accept
iifname "wlo1" oifname "enp44s0" accept
iifname "wlo1" reject
oifname "wlo1" reject
}
}
# Эта таблица предназначена для совместного использования интернет-соединения с компьютерами, подключенными к LAN
table ip nm-shared-enp44s0 {
chain nat_postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 10.42.0.0/24 ip daddr != 10.42.0.0/24 masquerade
}
chain filter_forward {
type filter hook forward priority filter; policy accept;
ip daddr 10.42.0.0/24 oifname "enp44s0" ct state { established, related } accept
ip saddr 10.42.0.0/24 iifname "enp44s0" accept
iifname "enp44s0" oifname "enp44s0" accept
iifname "enp44s0" oifname "wlo1" accept
iifname "wlo1" oifname "enp44s0" accept
iifname "enp44s0" reject
oifname "enp44s0" reject
}
}
Вы заметили, что я добавил правила, чтобы разрешить пакеты течь от Wifi к LAN и наоборот. Я уверен, что мог бы найти менее избыточный способ сделать это, но это работает.
Теперь вы можете настроить переадресацию портов с помощью iptables, nftables или firewalld. Чтобы сделать это с помощью nftables, вы можете добавить этот раздел в свой скрипт. Вам не нужен пост-роутинг.
# Переадресация входящих соединений на портах 80 и 443 по wifi на рабочую станцию в LAN
# Этот компьютер — 10.42.1.1 на wifi
# Рабочая станция — 10.42.0.216 в LAN
table ip nat {
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
meta l4proto tcp ip daddr 10.42.1.1 tcp dport 80 dnat to 10.42.0.216
meta l4proto tcp ip daddr 10.42.1.1 tcp dport 443 dnat to 10.42.0.216
}
}
Ответ или решение
Настройка пересылки портов с использованием UFW на Ubuntu
Настройка пересылки портов может показаться простой задачей, но с учетом специфических настроек фаервола и сетевых интерфейсов, она может стать сложной. Рассмотрим, как осуществить эту настройку на сервере под управлением Ubuntu с использованием Uncomplicated Firewall (UFW).
Шаг 1: Подготовка среды
На вашем сервере имеется два сетевых интерфейса:
- WiFi адаптер (wlo1) с сетью 10.42.1.0/24 и адресом 10.42.1.1
- Ethernet порт (enp44s0) с сетью 10.42.0.0/24 и адресом 10.42.0.1
Ваш рабочий компьютер в локальной сети имеет адрес 10.42.0.216 с запущенным веб-сервером. Вы хотите настроить пересылку трафика, чтобы подключаясь к адресам 10.42.1.1 из WiFi-сети, вы могли получить доступ к веб-серверу, расположенному в локальной сети.
Шаг 2: Включение IP-Forwarding
Для корректной работы пересылки портов необходимо разрешить пересылку IP-пакетов. Это можно сделать следующим образом:
-
Откройте файл
/etc/ufw/sysctl.conf
и раскомментируйте строку:net/ipv4/ip_forward=1
-
Убедитесь, что значение
DEFAULT_FORWARD_POLICY
в файле/etc/default/ufw
установлено наACCEPT
:DEFAULT_FORWARD_POLICY="ACCEPT"
Шаг 3: Настройка UFW
Запустите команды для разрешения трафика на порты 80 и 443:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Шаг 4: Изменения в файле before.rules
Перейдите в файл /etc/ufw/before.rules
и добавьте следующие правила в секцию *nat
в начале файла:
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -d 10.42.1.1 -p tcp --dport 80 -j DNAT --to-destination 10.42.0.216:80
-A PREROUTING -d 10.42.1.1 -p tcp --dport 443 -j DNAT --to-destination 10.42.0.216:443
-A POSTROUTING -s 10.42.0.0/24 -j MASQUERADE
COMMIT
Шаг 5: Перезапуск UFW
После всех изменений перезапустите UFW, чтобы применить настройки:
sudo ufw disable
sudo ufw enable
Шаг 6: Проверка работы правил
Убедитесь, что ваши правила настроены правильно. Используйте команду:
sudo ufw status
Устранение неполадок
Если вы всё равно не можете получить доступ к веб-серверу, выполните следующие шаги для диагностики:
-
Проверка NAT и маршрутизации: Убедитесь, что NAT правильно настроен, и используйте команду
nft list ruleset
, чтобы посмотреть текущие правила. Обратите внимание, что в Ubuntu может использоваться nftables, который может конфликтовать с iptables. -
Используйте Wireshark: Проверьте сетевой трафик на наличие ICMP-сообщений о недоступности порта. Это может указывать на неправильные правила маршрутизации или блокировку трафика.
-
Изменение параметров NetworkManager: Проверьте, не влияет ли NetworkManager на ваши правила NAT. Если он используется для общей настройки соединений, может понадобиться отключить бэкэнд фаервола, добавив
firewall-backend=none
в файл/etc/NetworkManager/NetworkManager.conf
.
Заключение
Настройка пересылки портов с использованием UFW может вызвать некоторые сложности, особенно в контексте сетевых взаимодействий и фаерволов. Следуя приведенным шагам и проводя систематическое устранение неполадок, вы сможете обеспечить доступ к веб-серверу в локальной сети через WiFi-адаптер.