Portforwarding mit Iptables unter Debian/Linux

Szenario 1: Rechner im internen Netz soll über Router/Firewall erreicht werden

Beispiel: Webserver steht mit interner IP hinter einer Router-Firewall.Die Standardvariante leitet nur http weiter, alternativ: Formulierung wenn auch FTP weitergeleitet werden soll.Dies bezeichnet man auch als DMZ (Demilitarisierte Zone), da auf diese Weise der Webserver nur für ausgewählte Dienste erreichbar ist. Bei einer Beschränkung auf http z.B. ist er damit von außen nicht (direkt) angreifbar.

Dazu müssen die Adressen für jedes Daten-Paket mehrfach umgeschrieben werden.

So funktionert es:

Header enthält:

Anfrage: Absender (Source) Empfänger (Destination)

Paket kommt am Router an -> ABSENDER_IP | EXTERNE_IP

PREROUTING -> ABSENDER_IP | WEBSERVER_IP

FORWARD-Prüfung (Routing)

POSTROUNTING -> INTERNE_IP | WEBSERVER_IP

Weiterleitung an Webserver

Antwort:(Webserver schickt an den Absender des Pakets)

Paket kommt innen an Router an -> WEBSERVER_IP | INTERNE_IP

FORWARD-Prüfung (Routing)

POSTROUTING -> EXTERNE_IP | ABSENDER_IP die Standardfunktion des Routers (Snat)

  1. Den Port 80, bzw. 80,20,21 für WEBSERVER_IP forwarden:
    1. iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination WEBSERVER_IP:80
    2. oder
    3. iptables -t nat -A PREROUTING -p tcp --m multiports -dports 80,20,21 -j DNAT --to-destination WEBSERVER_IP
    4. "Leite Daten, die über das externe Interface (IF_EXTERN=z.B. "eth0")
    5. für die IP des externen Interfaces (EXTERNE_IP) an Port xx eingehen,
    6. vor dem Routen an entsprechenden Port des Webservers (WEBSERVER_IP) weiter
    7. (=Destination-Nat=Übersetzung der Netzadresse in eine andere Zieladresse)..
  2. Damit der Router überhaupt für den Webserver (=WEBSERVER_IP) forwarded:
  3. a) Daten von WEBSERVER_IP
  4. iptables -A FORWARD -s WEBSERVER_IP -p tcp --sport 80 -j ACCEPT
  5. oder
  6. iptables -A FORWARD -s WEBSERVER_IP -p tcp -m multiports --sports 80,20,21 -j ACCEPT
  7. b) Daten zu WEBSERVER
  8. iptables -A FORWARD -d WEBSERVER_IP -p tcp --dport 80 -j ACCEPT
  9. oder
  10. iptables -A FORWARD -d WEBSERVER_IP -p tcp -m multiports --dports 80,20,21 -j ACCEPT
  11. Die Antwort des Webservers erfolgt mit der -privaten- WEBSERVER_IP. Soweit die Anfrage von außen kommt, sorgt das NAT des Routers für die Umschreibung. Internen Rechnern, die aber gar keine Verbindung zum Webserver WEBSERVER_IP, sondern lediglich zu EXTERNE_IP aufgebaut haben, wird mit WEBSERVER_IP geantwortet; die ANTWORT würde also nie ankommen. Daher ist ausnahmsweise SNAT nach innen nötig.
    1. Also: "Verändere nach abgeschlossener Routing-Entscheidung (POSTROUTING),
    2. wenn Daten zu Port xxx des Webservers gehen
    3. den Absender der Daten in die eigene interne IP"
    4. (= Source-Nat = Übersetzung der Absenderadresse in die des Routers) .
    5. iptables -t nat -A POSTROUTING -o IF_INTERN -p tcp -d WEBSERVER_IP --dport 80 -j SNAT --to-source INTERNE_IP
    6. oder
    7. iptables -t nat -A POSTROUTING -o IF_INTERN -p tcp -d WEBSERVER_IP -m multiports --dports 80,20,21 -j SNAT --to-source INTERNE_IP

Achtung: Der Router selbst erreicht hiermit nur seinen eigenen Webserver, da er sich selbst nicht routet.

Szenario 2: Anfragen für einen Dienst sollen an einen anderen Rechner im WWW weitergeleitet werden

Beispiel: Eine HTTPS-Webseite eines anderen Rechners soll erscheinen, wenn man https auf dem Router aufruft.

Weg: CLIENT:xx <--> EXTERNE_IP:443 |ROUTING/NAT| EXTERNE_IP:xx <-->FREMD_IP:443

  1. Den Port 443 zu FREMD_IP forwarden:
    1. iptables -t nat -A PREROUTING -i IF_EXTERN(1) -p tcp -d EXTERNE_IP --dport 443 -j DNAT --to-destination FREMD_IP:443
    2. "Leite Daten, die über das externe Interface (IF_EXTERN=z.B. "eth0")
    3. für die IP des externen Interfaces (EXTERNE_IP) an Port 443 eingehen,
    4. vor dem Routen an Port 443 des Zielrechners (FREMD_IP) weiter
    5. (=Destination-Nat=Übersetzung der Netzadresse in eine andere Zieladresse)..
  2. Damit der Router überhaupt für den anderen Rechner (=FREMD_IP) forwarded:
    1. a) Daten von FREMD_IP
    2. iptables -A FORWARD -s FREMD_IP -p tcp --sport 443 -j ACCEPT
    3. b) Daten zu ANDERE_IP
    4. iptables -A FORWARD -d FREMD_IP -p tcp --dport 443 -j ACCEPT
  3. Die weitergeleiteten Daten enthalten jetzt noch immer die Adresse des anfragenden Client Rechners, der aber gar keine Verbindung zu FREMD_IP, sondern lediglich zu EXTERNE_IP aufgebaut hat. Antworten von FREMD_IP würden daher nie ankommen.'
    1. Also: "Verändere nach abgeschlossener Routing-Entscheidung (POSTROUTING),
    2. wenn Daten zu Port 443 des Zielrechners
    3. über das externe Interface rausgehen
    4. den Absender der Daten in die eigene externe IP".
    5. iptables -t nat POSTROUTING -o IF_EXTERN (2) -p tcp -d FREMD_IP --dport 443 (3) -j SNAT --to-source EXTERNE_IP

Mit den Parametern "-i ..."/"-o ..." und "--dport ..." kann man hier ein bisschen spielen:

  • (1) wenn die Weiterleitung auch für interne Rechner gelten soll: in 2. "-i IF_EXTERN" weglassen
  • (2) das "-o IF_EXTERN" in 3. kann man auch weglassen, denn wo sollen die Daten sonst rausgehen?
  • (3) wenn man keinen Fall hat, in dem interne Rechner den Zielrechner unter der eigenen internen IP erreichen sollen (also meistens), kann man in 3 "--dport 443" weglassen.