portforwarding problem mit iptables

Einrichten des lokalen Netzes, Verbindung zu anderen Computern und Diensten.
Antworten
interpreter
Beiträge: 31
Registriert: 12.09.2003 11:12:02

portforwarding problem mit iptables

Beitrag von interpreter » 10.01.2006 10:55:35

hallo,

ich habe einen (noch-woody) router auf dem nur der sshd laeuft. auf diesen port kann ich sowohl mit interner IP als auch externer IP aus dem internen netz zugreifen.
nun will ich mittels portforwarding ftp und http von einer anderen kiste erreichbar machen. problem: die ports sind nur von aussen erreichbar vom internen netz komme ich nur ueber die interne IP heran. wo liegt der fehler im skript bzw. was fehlt?

Code: Alles auswählen

#!/bin/sh
set -e
EXTIF=eth1
INTIF=eth0

EXTIP=195.x.x.x
PRINTERIP=192.168.1.45
INTNET='192.168.1.0/24'

echo 1 >/proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD

iptables -t nat -F

iptables -A INPUT -i $EXTIF -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i $INTIF -o $EXTIF -s $INTNET -j ACCEPT
iptables -A FORWARD -i $EXTIF -o $INTIF -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -i $EXTIF -o $INTIF -p tcp --dport 21 -j ACCEPT
iptables -A FORWARD -j LOG

iptables -t nat -A POSTROUTING -o $EXTIF -s $INTNET -j MASQUERADE

iptables -t nat -A PREROUTING -p tcp -i $EXTIF --dport 80 -j DNAT --to $PRINTERIP:80
iptables -t nat -A PREROUTING -p tcp -i $EXTIF --dport 21 -j DNAT --to $PRINTERIP:21
EDIT: codetags eingefuegt wegen lesbarkeit
Zuletzt geändert von interpreter am 11.01.2006 11:36:30, insgesamt 1-mal geändert.

Benutzeravatar
herrchen
Beiträge: 3257
Registriert: 15.08.2005 20:45:28
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Re: portforwarding problem mit iptables

Beitrag von herrchen » 10.01.2006 14:26:23

interpreter hat geschrieben:wo liegt der fehler im skript bzw. was fehlt?
ich vermute, dass eine regel fehlt, die das forwarding erlaubt, wenn die pakete vom internen interface kommen.
es müsste aber was in den logs stehen ...

herrchen

nepos
Beiträge: 5238
Registriert: 05.01.2005 10:08:12

Beitrag von nepos » 10.01.2006 16:40:51

Wenn er denn was loggen wuerde...

Benutzeravatar
thorben
Beiträge: 722
Registriert: 14.09.2003 23:23:49

Beitrag von thorben » 10.01.2006 17:15:29

moin,

Code: Alles auswählen

iptables -A PREROUTING -t nat -i $EXT -d $IPADDRESS -p tcp --dport 22 -j DNAT --to 192.168.0.2
tuts bei mir

gruß
thorben

Benutzeravatar
mistersixt
Beiträge: 6601
Registriert: 24.09.2003 14:33:25
Lizenz eigener Beiträge: GNU Free Documentation License

Beitrag von mistersixt » 11.01.2006 09:38:41

thorben hat geschrieben:moin,

Code: Alles auswählen

iptables -A PREROUTING -t nat -i $EXT -d $IPADDRESS -p tcp --dport 22 -j DNAT --to 192.168.0.2
tuts bei mir
Na ja, sein Problem ist, daß es von aussen ja alles funktioniert, von innen aber nur mit der internen(!) IP und nicht per offiziellem DNS-Namen oder offizieller IP-Adresse. Ich versuche mir gerade vorzustellen, was der Kernel da anstellt: da kommt beispielsweise ein Packet mit Destination Port 80 und externer IP als Zieladresse am LAN(!)-Interface vom Router an. Der Kernel sollte ja wissen, daß die Zieladresse auch in seinem Zuständigkeitsbereich ist (ppp0 zum Beispiel). Daher leitet er das Paket nicht weiter an ppp0 und somit durchläuft es auch nicht die PREROUTING Regel, um dieses Paket wieder per DNAT an den Webserver weiterzuleiten. Was der Kernel nun mit diesem Paket macht, weiss ich nicht. Vermutlich will er einfach einen Connect auf localhost Port 80 aufmachen, wo aber nix lauscht. Protokolliere doch mal auf dem Router alles mit (per iptables mit -j LOG zum Beispiel), was auf Port 80 einen Connect machen will. Wenn Du da die Connect-Versuche mit Source-Adresse vom LAN siehst, haben wir es.

Gruss, mistersixt (Ende des Gedankenganges :wink: )
--
System: Debian Bookworm, 6.11.x.-x-amd64, ext4, AMD Ryzen 7 3700X, 8 x 3.8 Ghz., Radeon RX 5700 XT, 32 GB Ram, XFCE

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 11.01.2006 10:01:10

Die PREROUTING Regel wird duchlaufen.
Pakete von außen haben ja auch die Zieladresse des Routers und würden daher nach deinem Verständnis auch nicht durch die PREROUTING Tabelle gehen (Kernel muß ja auch hier erkennen, daß die Zieladresse in seinem Zuständigkeitsbereich ist)

Ich teile herrchen's Vermutung
Das Paket kommt am internen Interface an und geht wegen der PREROUTING Regel am internen Interface wieder raus. Daher muß auch forwarding von intern nach intern erlaubt sein

Gruß
gms

Benutzeravatar
mistersixt
Beiträge: 6601
Registriert: 24.09.2003 14:33:25
Lizenz eigener Beiträge: GNU Free Documentation License

Beitrag von mistersixt » 11.01.2006 10:46:34

Es wird nach obigen iptables-Regeln aber nur ein PREROUTING auf dem externen(!) Interface gemacht. Angenommen, der Router hat ff. IP-Adressen:

Code: Alles auswählen

 ... <---LAN---> [eth0=192.168.0.1, ppp0=80.80.80.80] <---WAN---> ...
Wenn jetzt ein Paket aus dem LAN kommt mit Zieladresse 80.80.80.80, dann wäre der Kernel doch eigentlich doof, wenn er es trotzdem durch das ppp0-Device laufen lassen würde. Daher meine Vermutung, daß die PREROUTING-Regel auf dem externen Interface einfach nicht durchlaufen wird.

Gruss, mistersixt.

PS: Ich habe gerade mal auf meinem Debian Router ein "tcpdump -i ppp0 tcp port 23" laufen lassen und dann vom LAN aus ein "telnet <IP-vom-ppp0-IF> 23" vom LAN aus gemacht: da kommt auf dem ppp0-Interface nix an, das Paket endet am LAN-Interface.
--
System: Debian Bookworm, 6.11.x.-x-amd64, ext4, AMD Ryzen 7 3700X, 8 x 3.8 Ghz., Radeon RX 5700 XT, 32 GB Ram, XFCE

interpreter
Beiträge: 31
Registriert: 12.09.2003 11:12:02

Beitrag von interpreter » 11.01.2006 12:40:16

hallo,

ich habe das logging mal eingeschaltet, soll ja beim debuggen durchaus helfen :D
das logging habe ich erstmal mit

Code: Alles auswählen

tail -f /var/log/syslog | grep 192.168.1.14 
gemacht um nur die pakete zu betrachten die vom anfragenden host gesendet wurden

szenario: 192.168.1.14 versucht http-request mit lynx auf 192.168.1.45 auf dessen externer IP. iptables skript (siehe erster post) bleibt erstmal unveraendert. lynx steigt sofort aus weil kein connect moeglich ist. das log sagt:

Code: Alles auswählen

 Jan 11 13:19:03 zaphod kernel: Nicht rein: IN=eth0 OUT= MAC=00:50:x:x:x:x:x:x:x:x:x:x:x SRC=192.168.1.14 DST=195.x.x.x LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=39907 DF PROTO=TCP SPT=34617 DPT=80 WINDOW=5840 RES=0x00 CWR ECE SYN URGP=0
Jan 11 13:19:03 zaphod kernel: Nicht raus: IN= OUT=eth0 SRC=195.x.x.x DST=192.168.1.14 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=34617 WINDOW=0 RES=0x00 ACK RST URGP=0
nun habe ich folgende idee gehabt: alles was auf dem internen iface mit externer IP fuer port 80 ankommt soll per PREROUTING auf den webserver umgeleitet werden. dazu habe ich folgende zeile an das ende des skriptes gehangen:

Code: Alles auswählen

iptables -A PREROUTING -t nat -i $INTIF -d $EXTIP -p tcp --dport 80 -j DNAT --to $PRINTERIP:80
lynx bleibt mit "Making HTTP connection to foobar" stehen, bricht aber nicht ab. der request kommt nicht bis zum webserver durch (sagt access.log). logfile von iptables:

Code: Alles auswählen

 Jan 11 13:20:23 zaphod kernel: IN=eth0 OUT=eth0 SRC=192.168.1.14 DST=192.168.1.45 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=37929 DF PROTO=TCP SPT=34618 DPT=80 WINDOW=5840 RES=0x00 CWR ECE SYN URGP=0
Jan 11 13:20:23 zaphod kernel: Nicht durch: IN=eth0 OUT=eth0 SRC=192.168.1.14 DST=192.168.1.45 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=37929 DF PROTO=TCP SPT=34618 DPT=80 WINDOW=5840 RES=0x00 CWR ECE SYN URGP=0
anscheinend ist die FORWARD regel noch nicht genug angepasst?

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 11.01.2006 12:49:00

interpreter hat geschrieben:

Code: Alles auswählen

Jan 11 13:20:23 zaphod kernel: Nicht durch: IN=eth0 OUT=eth0 SRC=192.168.1.14 DST=192.168.1.45 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=37929 DF PROTO=TCP SPT=34618 DPT=80 WINDOW=5840 RES=0x00 CWR ECE SYN URGP=0
wie "herrchen" schon vermutet hat, es fehlt eine Forward Regel von IN (=eth0) nach OUT (eth0)

Gruß
gms

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 11.01.2006 13:18:08

Code: Alles auswählen

Der Kernel sollte ja wissen, daß die Zieladresse auch in seinem Zuständigkeitsbereich ist (ppp0 zum Beispiel). Daher leitet er das Paket nicht weiter an ppp0 und somit durchläuft es auch nicht die PREROUTING Regel
Du verstehst darunter, daß die (spezielle) PREROUTING Regel für dieses Paket nicht erfüllt ist, stimmts ? Offenbar ein Mißverständnis.
Unter "durchläuft es auch nicht die PREROUTING Regel" verstehe ich, daß das Paket gar nicht soweit kommt und diese Regel daher gar nicht überprüft werden kann.
mistersixt hat geschrieben:Es wird nach obigen iptables-Regeln aber nur ein PREROUTING auf dem externen(!) Interface gemacht. .
Da hattest du natürlich Recht, diese PREROUTING Regel zieht nicht für das interne Interface

Gruß
gms

Benutzeravatar
mistersixt
Beiträge: 6601
Registriert: 24.09.2003 14:33:25
Lizenz eigener Beiträge: GNU Free Documentation License

Beitrag von mistersixt » 11.01.2006 13:35:28

gms hat geschrieben: Du verstehst darunter, daß die (spezielle) PREROUTING Regel für dieses Paket nicht erfüllt ist, stimmts ? Offenbar ein Mißverständnis.
Unter "durchläuft es auch nicht die PREROUTING Regel" verstehe ich, daß das Paket gar nicht soweit kommt und diese Regel daher gar nicht überprüft werden kann.
Na ja, das meinte ich eigentlich auch :) ! Das Paket kommt erst gar nicht soweit, daher hatte ich ja diesen kleinen Test mit tcpdump und telnet gemacht (siehe oben), das TCP-Paket kommt nicht bis zum externen Interface!

Gruss, mistersixt.
--
System: Debian Bookworm, 6.11.x.-x-amd64, ext4, AMD Ryzen 7 3700X, 8 x 3.8 Ghz., Radeon RX 5700 XT, 32 GB Ram, XFCE

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 11.01.2006 13:48:44

Dein Test beweist, daß die PREROUTING Tabelle nur einmal (vor INPUT bzw FORWARD) abgearbeitet wird und nicht noch ein zweitesmal, nachdem das Paket auf das externe Interface forgewardet wurde[edit], bzw in diesem Fall gar nicht forgewardet wird[/edit]
Überprüft wird diese (spezielle) Regel also genau einmal und zwar beim Einlangen des Pakets am internen Interface. Daher hat diese Regel auch nicht gezogen, weil dort das externe Interface als Bedingung aufscheint.
Einverstanden ?

Gruß
gms
Zuletzt geändert von gms am 11.01.2006 13:55:48, insgesamt 1-mal geändert.

Benutzeravatar
mistersixt
Beiträge: 6601
Registriert: 24.09.2003 14:33:25
Lizenz eigener Beiträge: GNU Free Documentation License

Beitrag von mistersixt » 11.01.2006 13:55:07

Soweit einverstanden, bis auf die Tatsache, daß ich meine, daß das Paket überhaupt nicht das externe Interface erreicht! Sonst hätte ich mit tcpdump auf dem externen IF doch in meinem telnet-Beispiel was sehen müssen ... oder bin ich jetzt total verwirrt :? !

Gruss, mistersixt.
--
System: Debian Bookworm, 6.11.x.-x-amd64, ext4, AMD Ryzen 7 3700X, 8 x 3.8 Ghz., Radeon RX 5700 XT, 32 GB Ram, XFCE

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 11.01.2006 13:57:43

habe ich soeben oben hinzugefügt. Das Paket lauft durch die PREROUTING Tabelle, dort wird es von keiner Regel erfaßt und landet daher in der INPUT (Zieladresse ist ja der Router) und eben nicht in der FORWARD Tabelle.

Benutzeravatar
mistersixt
Beiträge: 6601
Registriert: 24.09.2003 14:33:25
Lizenz eigener Beiträge: GNU Free Documentation License

Beitrag von mistersixt » 11.01.2006 14:00:07

Aah, jetzt sind wir beieinander ... 8) !

Gruss, mistersixt.
--
System: Debian Bookworm, 6.11.x.-x-amd64, ext4, AMD Ryzen 7 3700X, 8 x 3.8 Ghz., Radeon RX 5700 XT, 32 GB Ram, XFCE

interpreter
Beiträge: 31
Registriert: 12.09.2003 11:12:02

Beitrag von interpreter » 11.01.2006 14:20:12

ich habe mal folgende FORWARD regel mit eingetragen (bin mir jetzt aber nicht 100 % sicher ob die sinn macht) :

Code: Alles auswählen

iptables -A FORWARD -i $INTIF -o $INTIF -p tcp --dport 80 -j ACCEPT
zusammen mit

Code: Alles auswählen

iptables -A PREROUTING -t nat -i $INTIF -d $EXTIP -p tcp --dport 80 -j DNAT --to $PRINTERIP:80
wird laut log jetzt nichts mehr angemeckert, trotzdem keine verbindung (d.h. lynx bleibt mit "making http connection ..." stehen

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 11.01.2006 15:23:45

denke du brauchst noch zusätzlich eine SNAT bzw MASQUERADE Regel, ungefähr so:

Code: Alles auswählen

iptables -t nat -A POSTROUTING -p tcp -i $INTIF -s $INTNET -o $INTIF -d $PRINTERIP --dport 80 -j MASQUERADE
Gruß
gms

[edit]
möchte aber doch die Frage stellen, warum du dir das antust und den Webserver nicht über die interne IP anspricht, oder zumindest über die interne ip das portforwarding einrichtest
[/edit]

interpreter
Beiträge: 31
Registriert: 12.09.2003 11:12:02

Beitrag von interpreter » 11.01.2006 15:38:16

gms hat geschrieben:denke du brauchst noch zusätzlich eine SNAT bzw MASQUERADE Regel, ungefähr so:

Code: Alles auswählen

iptables -t nat -A POSTROUTING -p tcp -i $INTIF -s $INTNET -o $INTIF -d $PRINTERIP --dport 80 -j MASQUERADE
Gruß
gms

[edit]
möchte aber doch die Frage stellen, warum du dir das antust und den Webserver nicht über die interne IP anspricht, oder zumindest über die interne ip das portforwarding einrichtest
[/edit]
die POSTROUTING regel werde ich nacher gleich mal versuchen. den webserver kann ich nicht per IP ansprechen, da darauf mehrere namensbasierte virtuelle hosts laufen. ich wuerde dadurch immer nur den 1. virtuellen host bekommen. ich will eigentlich nur das der webserver per normaler url angesprochen werden kann.

Benutzeravatar
mistersixt
Beiträge: 6601
Registriert: 24.09.2003 14:33:25
Lizenz eigener Beiträge: GNU Free Documentation License

Beitrag von mistersixt » 11.01.2006 15:47:04

interpreter hat geschrieben:ich will eigentlich nur das der webserver per normaler url angesprochen werden kann.
Dann trag doch den DNS-Namen mit der LAN-Adresse in die /etc/hosts auf dem Rechner im LAN ein, von dem aus Du den Webserver erreichen willst ;) !

Gruss, mistersixt.
--
System: Debian Bookworm, 6.11.x.-x-amd64, ext4, AMD Ryzen 7 3700X, 8 x 3.8 Ghz., Radeon RX 5700 XT, 32 GB Ram, XFCE

interpreter
Beiträge: 31
Registriert: 12.09.2003 11:12:02

Beitrag von interpreter » 11.01.2006 16:02:50

mistersixt hat geschrieben:
interpreter hat geschrieben:ich will eigentlich nur das der webserver per normaler url angesprochen werden kann.
Dann trag doch den DNS-Namen mit der LAN-Adresse in die /etc/hosts auf dem Rechner im LAN ein, von dem aus Du den Webserver erreichen willst ;) !

Gruss, mistersixt.
so habe ich das auch im moment gemacht. problem ist halt das ich meinen laptop auch mal physisch aus dem netz bewege, dann muss ich den /etc/hosts eintrag wieder auskommentieren. ok, das koennte ich auch noch automagisieren, aber der richtige ansatz scheint mir doch zu sein das man die url eintippen kann ohne am client rumzuwerkeln :)

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 11.01.2006 16:25:04

das könnte aber auch z.b. über post-up/pre-down Kommandos in der /etc/network/interfaces gelöst werden (sofern dein Laptop Linux versteht)

Gruß
gms

interpreter
Beiträge: 31
Registriert: 12.09.2003 11:12:02

Beitrag von interpreter » 11.01.2006 16:41:23

gms hat geschrieben:das könnte aber auch z.b. über post-up/pre-down Kommandos in der /etc/network/interfaces gelöst werden (sofern dein Laptop Linux versteht)

Gruß
gms
mein laptop verteht das. mindestens 2 laptops an den nachbartischen wollen den eintrag aber in %windir%\system32\drivers\etc\hosts ;)

aber wie gesagt: der webserver soll ohne umstellungen aus dem internen netz erreichbar sein. ist ja auch mal ein ziel :)

Antworten