LINUX.ORG.RU
ФорумAdmin

nftables. не работает проброс (dnat) из внутренней сети (lan) через внешний адрес (wan)

 , , ,


0

1
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
nftables 0.9.0-2

Не работает проброс (dnat) трафика из внутренней сети (lan) через внешний адрес (wan) на внутренний ресурс. Лезем по #ssh xx.xx.xx.xx (wan) -p 23020 на 192.168.1.3:22 (lan) снаружи работает, с внутрянки нет.

https://funkyimg.com/i/32xic.jpg

В версии 0.7 nftables работало. Мысли и варианты кончились.

table inet filter {
        chain input {
                type filter hook input priority 0; policy drop;
                ct state {established, related} accept
                ct state invalid drop
                iifname {"lo","br0"} accept
                iifname "ppp0" tcp dport 23020 accept
	}

	chain forward {
		type filter hook forward priority 0; policy drop;
		oifname "ppp0" tcp flags syn tcp option maxseg size set rt mtu
		ct state {established, related} accept
		ct state invalid drop
		iifname "br0" accept
		tcp dport 22 accept
	}

	chain output {
		type filter hook output priority 0; policy accept;
	}
}

table ip nat {
	chain prerouting {
		type nat hook prerouting priority -100; policy accept;
		dnat to tcp dport map { 23020 : 192.168.1.3 }:tcp dport map { 23020 : ssh }
	}
	chain postrouting {
		type nat hook postrouting priority 100; policy accept;
		oifname "ppp0" counter packets 0 bytes 0 snat to xx.xx.xx.xx
	}
	chain input {
		type nat hook input priority 0; policy accept;
	}
	chain output {
		type nat hook output priority 0; policy accept;
	}
}

table ip mangle {
	chain input {
		type filter hook input priority -150; policy accept;
	}

	chain forward {
		type filter hook forward priority -150; policy accept;
	}

	chain output {
		type filter hook output priority -150; policy accept;
	}

	chain postrouting {
		type filter hook postrouting priority -150; policy accept;
	}
}

Честно до изучения nftables все ещё не добрался. Но судя по описанию (как понял я) не вижу почему у вас раньше это должно было работать.
Проблема стара как мир. Предположим что у клиента локалки адрес 192.168.1.20. Вы обращаетесь к xx.xx.xx.xx (wan), роутер подменяет адрес назначения с xx.xx.xx.xx на 192.168.1.3.
192.168.1.3 получает пакет от 192.168.1.20, и так как это одна локалка отвечает ему напрямую, через роутер этот пакет не полетит.
192.168.1.20 не ждет пакетов от 192.168.1.3, поэтому и не работает.
Решения.
1. на роутере snat для этих пакетов. Минус решения, все соединения из локалки на 192.168.1.3 пойдут от lan адреса роутера.
2. Обращаться не по ip xx.xx.xx.xx (wan) а по dns имени и соответственно использовать split dns.

anc ★★★★★ ()
Ответ на: комментарий от anc

не знаю на сколько эта проблема стара как мир, но это все прекрасно работало на iptables

# Generated by iptables-save v1.4.21 on Mon Dec 12 19:34:54 2016
*filter
:INPUT DROP [0:0]
:OUTPUT ACCEPT [0:0]
:FORWARD DROP [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -i br0 -j ACCEPT
-A INPUT -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp -m multiport -i ppp0 -j ACCEPT --dports 23020
-A FORWARD -i br0 -j ACCEPT
-A FORWARD -m conntrack -o br0 --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -p tcp -m tcp --dport 22 -j ACCEPT
COMMIT
# Generated by iptables-save v1.4.21 on Mon Dec 12 19:34:54 2016
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
COMMIT
# Generated by iptables-save v1.4.21 on Mon Dec 12 19:34:54 2016
*nat
:POSTROUTING ACCEPT [0:0]
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp -m tcp --dport 23020 -j DNAT --to-destination 192.168.1.3:22
-A POSTROUTING -o ppp0 -j SNAT --to-source xx.xx.xx.xx
COMMIT
siv62 ()
Ответ на: комментарий от siv62

Может вы нам схему не до конца описали. Но если сеть lan это только одна подсеть в которую входит как клиент так и сервер, например 192.168.1.0/24, даже это робить не должно.

anc ★★★★★ ()
Ответ на: комментарий от anc

давайте не будем голословными, даже сейчас, если я отправлю пакет с порта 23020 не на 192.168.1.3:22, а на на 192.168.1.1:22 (шлюз) то все сработает

siv62 ()
Ответ на: комментарий от siv62

даже сейчас, если я отправлю пакет с порта 23020

Не опечатались? Может «на порт» а не «с порта»? Это не более чем мелкое замечание.

не на 192.168.1.3:22, а на на 192.168.1.1:22 (шлюз) то все сработает

Логично. Это же локальный процесс. Вы и получите ответ от шлюза и обратный полетит ему.

anc ★★★★★ ()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от anc

Не опечатался. Меняется одна цифра в конфиге

dnat to tcp dport map { 23020 : 192.168.1.1 }:tcp dport map { 23020 : ssh }
Т.е. у локального процесса проблема с адресацией не возникает. Однако. А как же жестко не должно работать.

siv62 ()
Ответ на: комментарий от siv62

1. Таки опечатались. Это «на порт». А не «с порта».
2. Но сути не меняет. Да, так работать будет, выше уже описал почему. Вы обращаетесь к роутеру и он вам отвечает согласно таблицы роутинга а так же происходит обратное преобразование в dnat. Этого достаточно.
3. Но для случая компа из локалки 192.168.1.3 читайте мой первый пост.

ЗЫ Что бы двадцать раз не оспаривать, запустите tcpdump на всех трех машинках клиент(192.168.1.x) - роутер (192.168.1.1) - сервер (192.168.1.3) и поймете как летают пакеты.

anc ★★★★★ ()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от anc

это интерфейс бриджа

br0: подключено to br0
        "br0"
        bridge, 00:E0:27:E0:04:90, sw, mtu 1500
        inet4 192.168.1.1/24
        route4 169.254.0.0/16
        route4 192.168.1.0/24

enp2s0: подключено to bridge-slave-enp2s0
        "Intel 82583V"
        ethernet (e1000e), 00:E0:27:E0:04:90, hw, mtu 1500
        master br0
        route6 ff00::/8

enp3s0: подключено to bridge-slave-enp3s0
        "Intel 82583V"
        ethernet (e1000e), 00:E0:27:E0:04:91, hw, mtu 1500
        master br0
        route6 ff00::/8

enp4s0: подключено to bridge-slave-enp4s0
        "Intel 82583V"
        ethernet (e1000e), 00:E0:27:E0:04:92, hw, mtu 1500
        master br0
        route6 ff00::/8

enp5s0: подключено to bridge-slave-enp5s0
        "Intel 82583V"
        ethernet (e1000e), 00:E0:27:E0:04:93, hw, mtu 1500
        master br0
        route6 ff00::/8

enp6s0: подключено to bridge-slave-enp6s0
        "Intel 82583V"
        ethernet (e1000e), 00:E0:27:E0:04:94, hw, mtu 1500
        master br0
        route6 ff00::/8

enp7s0: подключено to bridge-slave-enp7s0
        "Intel 82583V"
        ethernet (e1000e), 00:E0:27:E0:04:95, hw, mtu 1500
        master br0
        route6 ff00::/8
siv62 ()
Ответ на: комментарий от siv62

Я правильно понял. Это отдельные сетевухи но в которые воткнуты разные устройства. Например 192.168.1.3 в enp2s0 а клиент с которого вы пытаетесь достучаться в топике в enp3s0 ?

anc ★★★★★ ()
Ответ на: комментарий от siv62

Вот тогда это больше похоже на правду. Надо вам было это в топике изначально описать. Больше времени потратили на ненужное обсуждение.

anc ★★★★★ ()
Ответ на: комментарий от siv62

Посмотрите все-таки tcpdump. Я бы начал с этого. Возможно что-то в пакетах увидите.
ЗЫ Поправьте топик. На тему что у вас бридж. vel может что подскажите в тему изменений в nftables?

anc ★★★★★ ()
Последнее исправление: anc (всего исправлений: 1)
Ответ на: комментарий от anc

ТС чего-то явно не договаривает в контексте «DNAT внутри бриджа». Оставлю здесь бессмысленый набор слов:

modprobe br_netfilter 
net.bridge.bridge-nf-call-iptables = 1

nft add table bridge nat
nft add chain bridge nat prerouting '{ type filter hook prerouting priority -300; policy accept; }'

mky ★★★★★ ()
Ответ на: комментарий от mky

это не dnat внутри бриджа. Бридж это многопортовка собранная в хаб, без подключения виртуальных машин. Все что в нее включено это физические устройства. dnat работает между ppp0 (wan) и br0 (lan) - см. картинку в первом посте.

# nmcli c s
NAME                 UUID                                  TYPE      DEVICE
br0                  0f3b5a0e-4ddd-4649-9b26-513bc98277bb  bridge    br0
bridge-slave-enp2s0  1f17afd9-344f-44dc-9871-47f74c752bad  ethernet  enp2s0
bridge-slave-enp3s0  d1d03346-9fc6-491f-a624-2f22683bb724  ethernet  enp3s0
bridge-slave-enp4s0  aa76d077-11a7-450f-9c07-364a8ce27dec  ethernet  enp4s0
bridge-slave-enp5s0  9707a850-7d66-4d34-ace0-dd86cf7feb0e  ethernet  enp5s0
bridge-slave-enp6s0  ffbc73ce-a9a3-4463-960a-ff22db0327ae  ethernet  enp6s0
bridge-slave-enp7s0  9b7063fb-4390-4342-864b-bda0f73a8f24  ethernet  enp7s0
dsl-provider         fec47cb8-edcc-4c0d-9259-37e9a26b9b0b  pppoe     enp1s0f1
iptv                 1feed3d3-378b-4dad-9561-fbadfdae8d90  macvlan   iptv

siv62 ()
Ответ на: комментарий от siv62

Не работает проброс (dnat) трафика из внутренней сети (lan) через внешний адрес (wan) на внутренний ресурс.

Из внутренней на внутренний. Именно так должны идти ответные пакеты. А вся внутреняя сеть у вас в бридже. В ядре давно для повышения производительности сделали, что пакеты между интерфесами бриджа просто так (без дополнительных настроек) не идут через iptables. Если у вас заработает nat в бридже, то и нужный вам проброс заработет.

mky ★★★★★ ()
Ответ на: комментарий от mky

Еще раз, у меня нет nat внутри br0, nat работает между ppp0 и br0. И я наконец нашел, что nftables не хватало. Передайте anc все что не должно было работать прекрасно работает -))). Тема закрыта. Всем спасибо.

oifname { "ppp0", "br0" } counter packets 0 bytes 0 snat to xx.xx.xx.xx

siv62 ()
Ответ на: комментарий от siv62

oifname { «ppp0», «br0» } counter packets 0 bytes 0 snat to xx.xx.xx.xx

гм. а зачем тут br0 ?

Есть смысл проверить два сценария

1) установить правила и после этого поднять ppp0

2) поднять ppp0 после этого установить правила

Если результат разный, то выкинуть nftables еще на пару лет.

vel ★★★★★ ()
Ответ на: комментарий от vel

тоже до конца не верил, что в этой строку правил nftables, что то не хватает. Но в лог-е однозначно видно, что именно этот интерфейс nat дропает.

kernel: [521185.351528] Drop_nat IN= OUT=br0 SRC=192.168.1.3 DST=192.168.1.3 LEN=52 TOS=0x00 PREC=0x00 TTL=127 ID=53628 DF PROTO=TCP SPT=4309 DPT=2WINDOW=64240 RES=0x00 SYN URGP=0
пришлось nftables дать то что он просит. Судя по тому что в ver. 0.7 этого не требовалось и в iptables не требовалось это может быть в следующих версиях изменено снова, с точки моего понимания работы логики описания этого правила это странно.

siv62 ()
Ответ на: комментарий от siv62

Первый ответ в этом посте:

1. на роутере snat для этих пакетов.

Вы когда поймёте как ходят ip-пакеты, может поймёте, про что писал anc.

mky ★★★★★ ()
Ответ на: комментарий от vel

br0 там, по идее, мог быть и с другим ip-адресом (локальным, а не внешним). Но, если он не сделает SNAT, то у него ответные пакеты от 192.168.1.3 на 192.168.1.x останутся в бридже и не попадут в conntrack.

mky ★★★★★ ()
Ответ на: комментарий от siv62

натить пакет у которого ip_src == ip_dst - глупо!

Есть подозрение, что у тебя «net.bridge.bridge-nf-call-iptables=1». Если ты не знаешь зачем оно - то лучше отключи.

https://wiki.nftables.org/wiki-nftables/index.php/Ruleset_debug/tracing

попробуй включить nftrace и посмотреть

vel ★★★★★ ()
Ответ на: комментарий от anc

Зачем из трёх машин? Из двух. Пусть без SNAT правила с сервера 192.168.1.3 достучится сам до себя через ssh xx.xx.xx.xx (wan) -p 23020.

mky ★★★★★ ()
Ответ на: комментарий от mky

Вы когда поймёте как ходят ip-пакеты, может поймёте, про что писал anc.

вы знаете, это как анекдоте вам шашечки или ехать. Поэтому понимаю я или не понимаю, как ходят пакетики у меня все заработало, а вот anc еще писал, что не знает про nftables ничего.

siv62 ()
Ответ на: комментарий от vel

натить пакет у которого ip_src == ip_dst - глупо!

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

Есть подозрение

нет подозрений

попробуй включить nftrace и посмотреть

как же без трейса и дебага, обязательно

siv62 ()
Ответ на: комментарий от siv62

nftables или iptables здесь не важно, ваш тест «заворот сам на себя» не заработал бы и с iptables.

То, что у вас раньше работало, работало только при условии, что клиенты были на одном физическом порту сетёвки, а сервер 192.168.1.3 на другом порту. Если бы клиенты были с сервером в одном физическом сегменте ethernet (в одном свиче), то и для показанных вами правил iptables потребовалося бы добавить SNAT.

mky ★★★★★ ()
Ответ на: комментарий от mky

не понимаю зачем эта дискуссия, все у меня работало как часы на том же железе (включая все физические линки), которое не менялось с 2015 года, а кусок iptables который я привел выше в ветке не менялся с 2016 года, ну а nftables.conf генерировался на его основе. Если вам хочется узнать зачем такой наворот в зоопарке, то пажалуйста. Есть домашнее облако с которым синхронизируются мобильные клиенты, которые выходят в интернет, или через домашний WiFi, или через сотовую сеть и что бы не править настройки каждый раз на кучи девайсов все они лезут на внешний адрес по назначенному порту (ssh конечно мне не сперся). Все бы ничего, но вот вдруг заворот с мобильных клиентов через WiFi отвалился.

siv62 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.