NAT prerouting pravidlo iptables neotevře port

- -

NAT prerouting pravidlo iptables neotevře port
« kdy: 16. 04. 2020, 18:03:30 »
Ahoj, potřeboval bych pomoct s tím jak zjistit proč se mi neotevřel port.

Na Linux (CentOS 7) serveru, který slouží jako proxy (díky OpenVPN) jsem se pokusil otevřít port stejně jako se mi to povedlo na mém jiném serveru běžícím na CentOS 6. Pravidlo:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 48280 -j DNAT --to 10.8.0.2:48280

eth0 protože jediná síťová rozhraní "ifconfig" na serveru zobrazí lo, eth0 a tun0(VPN)
10.8.0.2 je rozhraní ukazující se na VPN klientu

no ale port se ukazuje jako uzavřený (pomocí software na klientu i pomocí online port checkeru)
Na klientu jsem i vypnul firewall ale nepomohlo

Jak tedy teď zjistit co je špatně a kde ten trafik naráží na zeď? Nevím jestli může nějak pomoci TCPdump
Jak už jsem zmínil prakticky stejné iptables pravidlo mi fungovalo na jiném openvpn serveru.

PS: pár dalších detailů (jako verze OS, iptables a kernel moduly, apod.) je zde
« Poslední změna: 17. 04. 2020, 20:00:31 od Petr Krčmář »


iptables NAT nijak „neotvírá“ port. NAT dělá jenom přesměrování, nic jiného. Aby paket prošel, musíte mít nastartovanou cílovou aplikaci a ta musí na příslušném portu naslouchat (to je skutečné otevření portu). A dále nesmíte mít na firewallu nastavená pravidla, která by ten paket zahodila nebo odmítla.

Jak vypadá topologie vaší sítě? Je to server někde v internetu, který je přes VPN připojen do vaší privátní sítě? Nejlepší je pouštět tcpdump postupně od rozhraní nejblíž ke klientovi (tj. na vašem serveru na rozhraní do internetu, asi eth0) a postupně se po rozhraních přibližovat k cílovému serveru. Tím zjistíte, kam až pakety dorazí a kde se ztrácí.

Kód: [Vybrat]
tcpdump -ni eth0 port 48280
tcpdump -ni tun0 port 48280

Příkaz ifconfig nepoužívejte. V linuxu je označen za zastaralý už snad od Říma a někdy nefunguje správně. Místo něj používejte příkaz ip.

Michal Stulík

  • *
  • 10
  • Mezi klávesnicí a židlí.
    • Zobrazit profil
    • Meziblog
A forwarding na serveru je povolený?

net.ipv4.ip_forward=1

a zkuste dočasně povolit vše v iptables:

iptables -P FORWARD ACCEPT

- -

Děkuji oběma za cennou reakci. Tak jsem se v tom babral asi další 4 hodiny a TCP stále není otevřený. Snažil jsem se to níže sepsat co nejčitelněji ale nepřeju vám tento příběh číst.

SOUHRN:
Podle tcpdump data na server přicházejí. Pravidlo, které je má přesměrovat tam zdá se je. iptables loguje data pro ten port, nemohu však najít žádná na protokolu TCP, jen UDP. Wireshark na klientu trafik zobrazuje, ale zdá se, že jen UDP a GVSP, ne TCP... Rád bych ověřil nějak že UDP port je skutečně otevřený, našel jsem následující příkazy ale potřebovaly bynejspíš upravit:
vpn klient: ncat -u -l -p 48280
jiný pc v internetu: nping --udp -p 48280 --data-string 'hello' -c 1 vpnserverIP
Nevím tedy A) proč se zdá že nefunguje TCP přesměrování portu a B) jestli funguje UDP a kterými příkazy to zjistím

PODROBNĚ:

Topologie je jak uvádíte - server v internetu a klient v síti LAN, kde je klient napojený na obyčejný WAN router (ten datový tok VPN šifrovaný na klientu jen předává na server a zpět na klienta).

Ano, net.ipv4.ip_forward je zapnutý v /etc/sysctl.conf
Aplikace na klientu je zapnutá a měla by na portu 48280 naslouchat. (je to Transmission a port je u toho nastavený správně)

Wireshark na klientu ukazuje u toho portu který chci přesměrovat záznamy (protokol GVSP) kde se objevuje "[RANGE_ERROR] [BLOCK_DROPPED]" někdy PACKET_RESEND a unknown payload type. Možná je to tak správně, nevím, je to šifrovaný VPN trafik na tun0. Pak jsou tam ještě záznamy protokolu ne GVSP ale UDP. Žádné záznamy TCP. (Transmission software na klientu při kontrole otevřenosti portu 48280 uvádí že kontroluje TCP port...; zkoušel jsem i jiný software a TCP port(+ forwarding), ale je také "zavřený")
Myslel jsem, že ten program Transmission by měl fungovat na UDP ale jeví známky, že nefunguje - možná že je to tím, že torrent vyžaduje pro navázání TCP, nevím.

"tcpdump -i eth0 port 48280" na serveru pak ukazuje packety:
Citace
15:34:28.123456 IP nejakehostname.61566 > mojehostname.48280: Flags \[S\], seq 857936979, win 64240, options [mss 1452,nop,wscale 8,nop,nop,sackOK], length 0

Zkoušel jsem zapnout logování na serveru (iptables -A INPUT -j LOG) - nevím zda správně (iptables ukazuje "LOG level warning"), ale ledackteré síťové záznamy se přidávají do kernel logu /var/log/messages, u toho UDP portu 48280 se našly záznamy jako:
Citace
Apr 17 15:11:40 let kernel: IN=eth0 OUT= MAC=*** SRC=ciziipadresa DST=mojeipadresaserveru LEN=132 TOS=0x00 PREC=0x20 TTL=113 ID=26107 PROTO=UDP SPT=33078 DPT=48280 LEN=112
v případě tcp protokolu se ale žádné záznamy nezalogovaly :-/, byť tcpdump trafik daného portu zobrazuje. (třeba "tcpdump -i eth0 tcp port 48280")
https://www.yougetsignal.com/tools/open-ports/ a software na klientu ale stále zobrazuje port jako uzavřený.

"iptables -P FORWARD ACCEPT" jsem zkusil, ale politika ale "Chain FORWARD (policy ACCEPT)" už tam bylo.

# iptables -L FORWARD
Citace
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     all  --  10.8.0.0/24          anywhere
DROP       all  --  anywhere             anywhere             ctstate INVALID
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  192.168.42.0/24      192.168.42.0/24
ACCEPT     all  --  anywhere             192.168.43.0/24      ctstate RELATED,ESTABLISHED
ACCEPT     all  --  192.168.43.0/24      anywhere
DROP       all  --  anywhere             anywhere

# iptables -L -t nat|grep DNAT
Citace
DNAT       tcp  --  anywhere             anywhere             tcp dpt:12345 to:127.0.0.1:1082
DNAT       tcp  --  ciziip.0/24       anywhere             tcp dpt:ftp to:ipmehoserveru:21
DNAT       udp  --  anywhere             anywhere             udp dpt:ddi-udp-2 to:10.8.0.2:8889
DNAT       tcp  --  anywhere             anywhere             tcp dpt:48280 to:10.8.0.2:48280
DNAT       tcp  --  anywhere             anywhere             tcp dpt:48281 to:10.8.0.2:48281
DNAT       udp  --  anywhere             anywhere             udp dpt:48281 to:10.8.0.2:48281
DNAT       udp  --  anywhere             anywhere             udp dpt:48280 to:10.8.0.2:48280

děkuji za reakce a případné nápady co zkusit

- -

Malá aktualizace.
https://check-host.net/check-udp ukazuje, že ty mnou přesměrované UDP porty se ukazují jako otevřené nebo filtrované, což je dobré znamení. Ostatní které jsem nesměroval se tam ukazují jako zavřené.
https://check-host.net/check-tcp ukazuje, že TCP porty, i ty mnou přesměrované jsou zavřené.
Nevím tedy kde je zádrhel že UDP jde a TCP se nepřesměruje (Wireshark na klientu TCP packety narozdíl od UDP neukazuje, při testu byl firewall na klientu vypnutý).


Viděl bych problém v následujícím. Vy na serveru změníte cíl paketu a pošlete ho do VPN. Zdroj ale zůstává stejný. Paket tedy dorazí do vaší LAN stále s původní zdrojovou IP adresou. Tam se přijme, vygeneruje se na něj odpověď – ta se ale pošle přímo původnímu zdroji. Vy potřebujete, aby se na tom Centosu změnila i zdrojová IP adresa, aby odpověď z LAN nešla přímo, ale vrátila se na ten Centos. Ten pak může vrátit hlavičky paketu do původního stavu (před NATováním) a poslat je původnímu odesílateli. Předpokládám, že o to jste se pokoušel tou maškarádou – tohle ale musíte dělat na paketech směřujících do VPN, tedy -o tun0 místo -o eth0.

- -

Předpokládám, že o to jste se pokoušel tou maškarádou – tohle ale musíte dělat na paketech směřujících do VPN, tedy -o tun0 místo -o eth0.
Děkuji za odpověď. Ten OpenVPN server u kterého mi otevření portu fungovalo, vypadal takto:

iptables-save|grep -i mas
Citace
-A POSTROUTING -o venet0 -j MASQUERADE

ten, který mi teď nefunguje:

iptables-save|grep -i mas
Citace
-A POSTROUTING -s 192.168.42.0/24 -o eth0 -j MASQUERADE
-A POSTROUTING -s 192.168.43.0/24 -o eth0 -m policy --dir out --pol none -j MASQUERADE
-A POSTROUTING -j MASQUERADE
-A POSTROUTING -o eth0 -j MASQUERADE

zkusil jsem tedy odebrat postupně ta 3 první MASQUERADE pravidla a pak i tomu poslednímu nastavit tun0 místo eth0 a ani jedno nefungovalo aby ten TCP port byl otevřený. Stále ta aplikace říká, že její port pro příchozí TCP spojení je zavřený. "sudo nmap -p 48280-48289 vpnserverIP" spuštěný z jiného počítače a IP ukazuje ten TCP port jako "filtered" a https://check-host.net/check-tcp "Connection timeout". Přitom firewall je na klientu vypnutý a wireshark na klientu nezachytil žádný packet odpovídající tomu tcp portu. Jinak na ten tcp port míří spoustu připojení podle toho co ukazuje na serveru spuštěný příkaz tcpdump -i eth0 tcp port 48280 ...

- -

Re:NAT prerouting pravidlo iptables neotevře port
« Odpověď #7 kdy: 18. 04. 2020, 11:27:04 »
AKTUALIZACE:

musíte dělat na paketech směřujících do VPN, tedy -o tun0 místo -o eth0.

Je možné, že to není nutné udělat, protože to funguje zdá se i bez toho (v iptables pravidlech na serveru nemám žádné tun ale jen eth). Začalo to fungovat, když jsem smazal zahazovací (DROP) pravidlo na konci FORWARD:

Citace
iptables -L FORWARD --line-numbers
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 10.8.0.0/24 anywhere
2 ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
3 DROP all -- anywhere anywhere ctstate INVALID
4 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
5 ACCEPT all -- anywhere anywhere
6 ACCEPT all -- 192.168.42.0/24 192.168.42.0/24
7 ACCEPT all -- anywhere 192.168.43.0/24 ctstate RELATED,ESTABLISHED
8 ACCEPT all -- 192.168.43.0/24 anywhere
9 DROP all -- anywhere anywhere

iptables -D FORWARD 9

Další detaily, (iptables -t nat -L --line-numbers):
Citace
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    PREROUTING_direct  all  --  anywhere             anywhere
2    PREROUTING_ZONES_SOURCE  all  --  anywhere             anywhere
3    PREROUTING_ZONES  all  --  anywhere             anywhere
4    DNAT       tcp  --  anywhere             anywhere             tcp dpt:12345 to:127.0.0.1:1082
5    DNAT       tcp  --  1.2.3.0/24       anywhere             tcp dpt:ftp to:1.2.3.5:21
6    DNAT       udp  --  anywhere             anywhere             udp dpt:ddi-udp-2 to:10.8.0.2:8889
7    DNAT       tcp  --  anywhere             anywhere             tcp dpts:48280:48285 to:10.8.0.2
8    DNAT       udp  --  anywhere             anywhere             udp dpts:48280:48285 to:10.8.0.2

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination
1    OUTPUT_direct  all  --  anywhere             anywhere

Chain POSTROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    POSTROUTING_direct  all  --  anywhere             anywhere
2    POSTROUTING_ZONES_SOURCE  all  --  anywhere             anywhere
3    POSTROUTING_ZONES  all  --  anywhere             anywhere
4    SNAT       all  --  10.8.0.0/24         !10.8.0.0/24          to:ipserveru
5    MASQUERADE  all  --  192.168.42.0/24      anywhere
6    MASQUERADE  all  --  192.168.43.0/24      anywhere             policy match dir out pol none
7    MASQUERADE  all  --  anywhere             anywhere
8    MASQUERADE  all  --  anywhere             anywhere
(pokus o přesměrování IP rozsahu tcp i udp jako jedno pravidlo)
« Poslední změna: 18. 04. 2020, 11:32:30 od - - »

Re:NAT prerouting pravidlo iptables neotevře port
« Odpověď #8 kdy: 18. 04. 2020, 15:01:01 »
Začalo to fungovat, když jsem smazal zahazovací (DROP) pravidlo na konci FORWARD
Aha, to jsem v předchozím komentáři nějak přehlédl. Obecně když ladíte síťové nastavení, je lepší mít na firewallu vše povolené, a teprve když vám funguje správně NAT a takové věci, nakonfigurovat i firewall. Jinak nikdy nevíte, zda je chyba v to NATu nebo ve firewallu.

A dále je zbytečné dávat na konec pravidlo, které něco dělá pro vše. K tomu slouží politika chainu – tou se řídí vše, co dojde až na konec. A také je jednodušší politiku změnit, než odebírat poslední pravidlo a přidávat místo něj jiné.