iptables leiten lokale Verbindungen zum Remote-System / Port weiter


7

Ich versuche, SSH zu verwenden, um den lokalen Port 3389 von Windows-Maschinen an einen Redhat-Server an einem beliebigen Port (in der nicht privilegierten Region) zu portieren, den ich hinter einer Firewall geschützt habe, und dann den nicht privilegierten Port auf dem Redhat-Server an den Remotedesktop des Benutzers weiterzuleiten. Erstellen Sie im Wesentlichen ein hochspezialisiertes VPN, das nur eine Aufgabe erledigt: Bringen Sie Benutzer mithilfe eines verschlüsselten Tunnels, über den ich die Kontrolle habe, hinter einer Firewall zu ihren Systemen.

Ich weiß, dass dies vor Jahren mit dem folgenden Befehl möglich war:

iptables -A OUTPUT -t nat --dport ${LOCAL UNPRIV PORT} \
           -j DNAT ${ANOTHER SYSTEM}:${REMOTE PORT}

Aber nach dem, was ich gelesen habe, wurde diese Fähigkeit anscheinend entfernt und ich erhalte die Nachricht in / var / log / messages

      kernel: NAT: no longer support implicit source local NAT 

Ich habe Ressourcen gefunden, die darauf hindeuten, dass es von Kernel 2.6.X - 2.6.10 eine Möglichkeit gab, dies im Kernel mithilfe von IP_NF_NAT_LOCAL zu aktivieren, aber anscheinend wurde es in neueren Kerneln entfernt. Ich habe versucht, den gesamten lokalen Datenverkehr weiterzuleiten, damit er in die PREROUTING-Kette gelangt, und hatte nur begrenzten Erfolg. Das ist einfach eine schlechte Idee, da ich dann den nicht privilegierten Port auf dem Server öffnen muss, damit ich ihn wieder in den Server einspeisen kann eth0-Schnittstelle. Ich bin mir sicher, dass ich mehr Zeit habe, um einen bizarren Kludge oder eine Problemumgehung herauszufinden, aber ich würde meine Firewall-Skripte lieber nicht so sehr hacken. Es scheint, dass es einen viel einfacheren Weg geben muss, dies zu tun, den ich nicht sehe. Jede Hilfe oder Anleitung, die die Community geben könnte, wäre sehr hilfreich! Danke im Voraus


Warum versuchen Sie, den lokalen Verkehr weiterzuleiten? Ihre Frage scheint darauf hinzudeuten, dass Sie bestimmten eingehenden Datenverkehr weiterleiten möchten.

Ich versuche, lokalen Datenverkehr weiterzuleiten, da dies bei ssh -L $ {lokaler Port}: $ {Remote-Host}: $ {Remote-Port} $ {Remote-Server} nicht funktioniert, wenn Sie den Remote-Host als IP-Adresse eingeben dasselbe Subnetz des Systems, von dem aus Sie sich anmelden. Also habe ich stattdessen localhost für das Remote-System eingegeben. Dies hat zur Folge, dass der Remote-Server, auf den ich SSH'ing, denkt, dass der Datenverkehr lokal generiert wird. Daher verwende ich die OUTPUT-Routing-Kette.

Antworten:


11

Ich bin mir nicht ganz sicher, ob ich verstanden habe, aber ich denke, du bist nur in der falschen Kette. :-) Ich war auch verwirrt, als ich das erste Mal iptables benutzte. Der Weg zum Weiterleiten des lokalen Ports $ {LOCAL UNPRIV PORT} ist jedoch die folgende Anweisung:

$IPT -t nat -A PREROUTING -i eth0 -p tcp --dport ${LOCAL UNPRIV PORT} 
     -j DNAT --to ${ANOTHER SYSTEM}:${REMOTE PORT}

Es ist eine Mischung aus einem semantischen Problem und der Funktionsweise von Netfilter: Früher umfasste das Weiterleiten eines lokalen Ports eine Verbindung zu der weiterzuleitenden Box sowie eine zweite Verbindung zum Ziel. Iptables erledigt dies in einem Schritt. Anstelle von zwei Verbindungen leiten Sie den Datenverkehr an diesen Port direkt an das Ziel weiter. Netfilter führt alle Überprüfungen und die Buchhaltung durch: Nur Pakete, die zu einer gültigen Verbindung gehören, sind NATted und können daher weitergeleitet werden.

Durch Aktivieren von DNAT können keine Pakete weitergeleitet werden. Sie müssen auch eine Regel hinzufügen:

$IPT -N INET-PRIV
$IPT -A FORWARD -i eth0 -o eth1 -j INET-PRIV
$IPT -A FORWARD -j DROP

$IPT -A INET-PRIV -p tcp -d ${ANOTHER SYSTEM} --dport ${REMOTE PORT} -j ACCEPT

$IPT -A INET-PRIV -j DROP

Und Sie müssen natürlich die Weiterleitung aktivieren.

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

Pro iptables : sicherer, flexibler, weniger Speicher und weniger CPU pro Verbindung

Contra iptables : Das Weiterleiten einer Verbindung von einem internen Computer an einen internen Computer (Rückmeldung an eth0) ist bei iptables nicht sinnvoll (natürlich können Sie immer eine direkte Verbindung herstellen). Das Weiterleiten von lokal generiertem Datenverkehr funktioniert nicht ( Ein Portweiterleitungsdämon könnte helfen - macht aber normalerweise keinen Sinn.)

Genau dies könnte das Problem sein : Sie versuchen, NAT auf einem Nicht-Router zu verwenden, daher sollten Sie einen Weiterleitungsdämon verwenden oder diese zusätzliche Portweiterleitung vollständig überspringen und Folgendes tun:

ssh -L 1234:${ANOTHER SYSTEM}:${REMOTE PORT} special-vpn-box

Auf der Special-VPN-Box können Sie nur eingehende Verbindungen vom Router und ausgehende Verbindungen zu $ ​​{ANOTHER SYSTEM}: $ {REMOTE PORT} mithilfe von iptables zulassen. Auf diese Weise können Benutzer der Special-VPN-Box nur auf $ {ANOTHER SYSTEM}: $ {REMOTE PORT} zugreifen und können nichts anderes tun, wenn ihnen nicht vertraut wird.


Ich habe das SSH auf die von Ihnen beschriebene Weise ausprobiert und es automatisch an die nächste Maschine weitergeleitet. Wenn das System hinter der Firewall eine IP von 192.168.0.2 hat, führen Sie ssh -L 3389: 192.168.0.2: 3389 für eine spezielle VPN-Box aus. Was mir jedoch bleibt, ist, wenn Sie versuchen, eine Verbindung zu 192.168.0.2 3389 herzustellen, wird beim Versuch von Telnet nur "Kein Pfad zum Host" angezeigt. Ich habe versucht, die von Ihnen vorgeschlagene Konfiguration vorzunehmen (was ziemlich nahe an dem liegt, was ich bereits habe), aber wenn ich / var / log / messages überprüfe, hat das Paket nie die PREROUTING-Regel getroffen (wenn ich zu log vs acept wechsle)

Können Sie bitte Ihre Hosts auflisten, was Sie auf welchem ​​Host tun und wie sie verbunden sind? Ich vermute, wir reden immer noch nicht über dasselbe.
Ganwell

Erstens Ganwell, vielen Dank für Ihre Zeit. Ich schätze deine Hilfe sehr. Ok, hier ist mein Layout. Ich habe einen Remote-Benutzer, ich werde $ {RU} aufrufen. Ich habe einen Redhat-Server mit einem offenen SSH-Port in der darauf gerichteten Firewall. Ich werde $ {RHS} aufrufen, und ein lokales System hinter der Firewall werde ich $ {LS} aufrufen. Ich möchte $ {RU} -> SSH -> $ {RHS} -> RDP -> $ {LS} haben. Zu diesem Zweck habe ich die SSH-Portweiterleitung verwendet, um zum $ {RHS} zu gelangen, und dann versucht, diesen offensichtlichen DNAT (zum $ {RHS} "lokalen" Verkehr auf den $ {LS} auf Port 3389 (RDP) zu DNATEN.
dynamphorous

Ich habe versucht, die Ausgabe zu verwenden, um das Ziel zurück an die Adresse von eth0 zu DNAT, dann Postrouting zu SNAT zu verwenden und dies auch auf eth0 zu setzen. Dann wollte ich die Prerouting-Kette verwenden, um sie an die richtige Quelle zu senden. Scheint viel zu komplex. Wenn die Ausgabekette sie jedoch direkt an die Adresse des $ {LS} DNAT, trifft sie niemals die Postrouting-Kette (ich habe verschiedene Protokollierungsoptionen ausprobiert und sie gelangen definitiv nie dorthin). Und nach meinem Verständnis verlassen sie das System nicht, wenn sie es nicht bis zur Postrouting-Kette schaffen.
dynamphorous

OK. Ich glaube, ich habe das Problem, Sie machen DNAT auf dem $ {RHS} -System, oder? Sie können keinen DNAT-Verkehr generieren, der auf dem lokalen System generiert wird. Sie können DNAT in der Firewall verwenden, aber sobald Sie die Firewall passiert haben, benötigen Sie keine Portweiterleitung (DNAT) mehr. Sie müssen nur ändern: ssh -L 3389: 192.168.0.2: 3389 zu ssh -L 3389: $ {LS}: 3389
Ganwell

4

Folgendes mache ich speziell für die Localhost-Weiterleitung:

iptables -t nat -A OUTPUT -m addrtype --src-type LOCAL --dst-type LOCAL -p tcp --dport 3306 -j DNAT --to-destination ip.ip.ip.ip
iptables -t nat -A POSTROUTING -m addrtype --src-type LOCAL --dst-type UNICAST -j MASQUERADE

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

Stellen Sie sicher, dass Sie ip.ip.ip.ipIhre echte öffentliche IP-Adresse und auch --dport 3306den Port, den Sie weiterleiten möchten, ersetzen.

Führen Sie abschließend den Befehl sysctl aus und aktualisieren Sie auch Ihren /etc/sysctl.conf

Sie können sysctl.ctlmit dem folgenden Befehl aktualisieren , um das Routing von localhost zu ermöglichen:

echo "net.ipv4.conf.all.route_localnet=1" >> /etc/sysctl.conf

Nun, das alles scheint einfach und gut zu sein, aber es hat einige Nachforschungen und die Jagd gekostet. Seien Sie gewarnt und verstehen Sie, dass für die Weiterleitung von localhost / 127.0.0.1 diese Methode erforderlich ist und die typischen anderen Beispiele nicht funktionieren. Einige Beispiele für Lösungen, die mit localhost nicht funktionieren:

iptables -t nat -A PREROUTING -p tcp --dport 3306 -j DNAT --to ip.ip.ip.ip:3306
iptables -t nat -A POSTROUTING -d ip.ip.ip.ip -j MASQUERADE

http://realtechtalk.com/iptables_how_to_forward_localhost_port_to_remote_public_IP-1788-articles


2
# Enable IP Forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

iptables -t nat -A PREROUTING  -p tcp \
--dport ${LOCAL UNPRIV PORT} -j DNAT --to-destination ${ANOTHER SYSTEM}:${REMOTE PORT}

iptables -t nat -A POSTROUTING -p tcp \
--dst ${ANOTHER SYSTEM} --dport ${REMOTE PORT} -j SNAT --to-source ${LOCAL SYSTEM}
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.