Die Portumleitung von iptables funktioniert nicht für localhost


54

Ich möchte den gesamten Datenverkehr von Port 443 auf den internen Port 8080 umleiten. Ich verwende diese Konfiguration für iptables:

iptables -t nat -I PREROUTING --source 0/0 --destination 0/0 -p tcp \
         --dport 443 -j REDIRECT --to-ports 8080

Dies funktioniert für alle externen Clients. Wenn ich jedoch versuche, von derselben Maschine auf den Port 443 zuzugreifen, wird ein Verbindungsfehler zurückgewiesen.

wget https://localhost

Wie kann ich die iptables-Regel erweitern, um auch lokalen Datenverkehr umzuleiten?


Dieses Thema bietet eine allgemeinere Antwort: serverfault.com/questions/380447/iptables-preroute-localhost
Jeroen

1
Kann jemand mit rep dem Befehl vor dem Zeilenumbruch einen Backslash hinzufügen?
Ciro Santilli新疆改造中心法轮功六四事件

Antworten:


68

PREROUTING wird von der Loopback-Schnittstelle nicht verwendet. Sie müssen außerdem eine OUTPUT-Regel hinzufügen:

iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -o lo --dport 443 -j REDIRECT --to-ports 8080

3
Die erste Regel ist nicht erforderlich. Die lokal erzeugten Pakete werden nicht über die PREROUTING-Kette übertragen.
Khaled

9
Ich habe die anfängliche Regel aus Gründen der Vollständigkeit hinzugefügt, da er möchte, dass der externe Datenverkehr ebenfalls umgeleitet wird. Die Regel benötigt keine Quelle / Ziel, wenn sie nur sagen, dass alle IPs akzeptiert werden sollen
Andy

oh entschuldigung, ich habe deine antwort nicht gesehen, als ich geantwortet habe.
Andy

Hallo Andy, es wird immer noch eine Verbindung zu server.com hergestellt. | <Ip> |: 443 ... fehlgeschlagen: Verbindung abgelehnt.
Chris

Hallo Chris, ist das die Verbindung zu localhost | 127.0.0.1 | 443 oder ist das die Domain? Wenn letzteres von Ihrem Server ausgeführt wird, liegt möglicherweise ein internes Routingproblem vor. Sie könnten dies überprüfen, indem Sie wget server.com:8080 versuchen (obwohl ich davon ausgehe, dass der Grund für die Portweiterleitung darin besteht, dass es extern blockiert ist?). Meine eigene VPC hat dieses Problem, Sie können es jedoch möglicherweise umgehen, indem Sie die Domäne in Ihrer Datei / etc / hosts als 127.0.0.1 definieren.
Andy

10

So leiten Sie Pakete von localhost auf einen anderen Computer um:

 iptables -t nat -A OUTPUT -o lo -d 127.0.0.1 -p tcp --dport 443 -j DNAT  --to-destination 10.x.y.z:port

wird funktionieren, ABER Sie müssen auch diese Option im Kernel aktivieren:

sysctl -w net.ipv4.conf.all.route_localnet=1

Ohne diese Kerneleinstellung wird es nicht funktionieren.


Das würde auch funktionieren. Ich denke, dass es sauberer ist, alles in iptables zu machen.
Vierfach

Tatsächlich wird die Kernel-Einstellung nicht benötigt, wenn sich das Ziel auf einem anderen Computer befindet, auf einer VM oder einem Remote-Computer.

Es ist nicht so, wenn Sie die beiden Regeln haben, die Andy oben vorgeschlagen hat.
Vierfach

Entschuldigung, ich habe über den Fall der Weiterleitung an einen anderen Computer gesprochen, auf dem DNAT nicht funktioniert. Diese Antwort suchte nach einer Lösung für ein Problem, als ich versuchte, etwas weiterzuleiten, von dem angenommen wurde, dass es eine Verbindung zu localhost mit einem Container auf demselben Computer herstellt. zB den Nameserver in einem Container für lokale Abfragen laufen lassen.

Tatsächlich ist es anscheinend 'abhängig von der Kernel-Version> = 3.6.
Vierfach

3

Wie wäre es damit?

iptables -t nat -A OUTPUT -d 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to-port 8080


2

Sie sagten, Sie bekommen einen Verbindungsfehler verweigert . Dies bedeutet, dass auf dem Port, zu dem Sie eine Verbindung herstellen möchten, kein lokaler Prozess lauscht! Verwenden Sie den folgenden Befehl, um die Empfangsvorgänge zu überprüfen:

$ sudo netstat -lnp | grep 8080

Nachdem Sie die Regel angewendet haben, sollte ein Prozess den Port 8080 überwachen, um eine Verbindung herzustellen.

Es scheint, dass Sie stattdessen die folgende Regel haben sollten:

$ iptables -t nat -I OUTPUT --source 0/0 --destination 0/0 -p tcp
                                       --dport 443 -j REDIRECT --to-ports 8080

Denken Sie daran, dass Sie vom lokalen Host senden. Sie müssen also das Ausgabepaket umleiten.


1
Danke für deine Antwort. Der Prozess lauscht auf Port 8080. Daher möchte ich den gesamten Datenverkehr auf diesen Port umleiten.
Chris

Sind Sie sicher, dass der Prozess auch die Loop-Schnittstelle überwacht? Möglicherweise hört es nur auf Ihrer physischen Schnittstelle. In der Regel muss Ihr Webserver
0.0.0.0
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.