HTTP-Portforwarding über SSH

3 Februar 2010 von Alexander Jackson Kommentieren »

Mit Portforwarding via ssh ist es möglich auf recht einfache Weise den Port eines externen Hosts auf den lokalen Host und einen beliebigen/freien Port “umzubiegen”. Folgendes Beispiel ermöglicht den Webserverport 80 auf dem Remotehost mit der IP 2.2.2.2 an die lokale Maschine mit der IP 1.1.1.1 weiterzuleiten. Danach sollten der weitergeleitete Port und die dort angebotenen Webseiten auf der lokalen Maschine (1.1.1.1) über das LAN/WLAN/WAN durch dritten erreichbar sein. Diese Ereichbarkeit funktioniert natürlich nur, wenn keine Firwall “dazwischenfunkt” und eventuell nötige Portfreigaben vom Router zum lokalen Rechner eingerichtet wurden.

Um uns den HTTP Port vom externen Webserver (2.2.2.2) zu “holen”, führen wir nun folgendes auf unseren lokalen Maschine (1.1.1.1) aus:

ssh -g -L 80:2.2.2.2:80 USER@2.2.2.2 -p22

Nun noch ohne Werte:

ssh -g -L [bind_address:]port:host:hostport

Infos zu Bedeutung der Schalter gibts in der ssh Manpage.

Nun sollte der externe Webserver der physikalisch auf dem Remotehost mit der IP 2.2.2.2 läuft, ebenfalls auf der lokalen Maschine im Webbrowser unter http://1.1.1.1 antworten. Dies gilt ebenfalls für die Domains, die auf die IP des lokalen Rechners (1.1.1.1) auflösen.

Nach meinen Beobachtungen ist der Webserver gleichzeitig auf beiden IPs unter http://1.1.1.1 und http://2.2.2.2 erreichbar. Ich hatte kurzzeitig bedenken, dass der Webserver nach der Umleitung ausschliesslich über die IP 2.2.2.2 erreichbar sei – dem war jedoch nicht so.

Verwendet der externe Host, auf dem der Webserver (2.2.2.2) läuft, weitere IPs, sollte die IP für die bind_address verwendet werden, welche ebenfalls in der Apache Konfigurationsdatei auf die gewünschte(n) Website(s) auf dem Remotehost auflöst. Diese könnten nämlich von 2.2.2.2 abweichen.

In meinem konkreten Fall hatte ich beim Aufruf der vhosts-Webseiten im Browser zuerst nur die Apache Default Page angezeigt bekommen, nicht jedoch die Seiten der virtuellen Hosts. Nachdem ich die bind_address entsprechend editiert habe war auch dieses Problem gelöst.

Um dem beschriebenen Problem völlig aus dem Weg zu gehen, kann man auch ANY anstelle der IP des zuständigen Dienstes des Remotehosts eintragen.

ssh -g -L 80:ANY:80 USER@2.2.2.2 -p22

Mit ANY werden alle verfügbaren IPs des enfernten Hosts durch den Tunnel geforwarded.
Warum ANY funktioniert und 0.0.0.0 nicht, ist mir momentan ein Rätsel. Die Verwendung von 0.0.0.0 bindet den Port bei meinen Tests ausschliesslich an die localhost IP 127.0.0.1

Das gezeigte Beispiel sollte relativ einfach an unterschiedliche Dienste anpassen lassen.

Ich benötigte in diesem speziellen Fall eine Möglichkeit einen schwachbrüstigen vServer zu entlasten und habe die eingehenden Anfragen auf diese Weise an einen wesentlich performanteren Server durchgeschleift. Alternativ könnte ich natürlich auch die DNS Einträge direkt auf den leistungsstarken Server zeigen lassen. Ich will jedoch die unterschiedlichen IPs in entfernte Rechenzentren genießen – daher dieser etwas ungewöhnliche Lösungsansatz.

Nachtrag!

Das Problem bei dieser Lösung ist, dass es keine vernünftige Auswertung der Logfiles mehr ermöglicht. Für den Webserver kommen sämtliche Anfragen vom Host mit der IP 2.2.2.2 und nicht vom eigentlichen Besucher mit dessen (öffentlicher) IP. Legt man also Wert auf Besucherstatistiken, sollte man zu eine alternativen Lösung greifen. Eventuell bietet sich hier ein OpenVPN Tunnel mit NAT an.

Werbung

Hinterlasse eine Antwort