SSH-Tunnel mit Linux


Prof. Jürgen Plate

SSH-Tunnel mit Linux

Der Optimist sieht ein Licht am Ende des Tunnels,
der Pessimist sieht eine Lokomotive auf sich zurasen,
der Lockführer sieht zwei Idioten auf den Schienen rumstolpern.

Ein SSH-Tunnel ist ein gesicherter Kanal, der Netzwerk-Protokolle einbetten und verschlüsselt übertragen kann. Der Tunnel führt dabei in der Regel von einem Rechner innerhalb eines unsicheren Netzwerks zu einem Server/Netz des Vertrauens. Durch diese Form der Portweiterleitung können TCP-Protokolle wie HTTP (Webseiten) oder SMTP (E-Mail) durch ein fremdes Netz (meist das Internet) hindurch gesichert verwendet bzw. überhaupt erst zugänglich gemacht werden.

Die Secure Shell (SSH)

Bei der Entwicklung von SSH wurde besonderer Wert auf folgende Punkte gelegt:

SSH speichert alle wichtigen Informationen im Unterverzeichnis .ssh des Heimatverzeichnisses des jeweiligen Benutzers. Das Directory sollte deshalb nur für den Besitzer der Kennung zugänglich sein (chmod 700 .ssh). Einige Dinge funktionieren auch nicht, wenn das Zugriffsrecht falsch gesetzt ist.

Mit SSH kann man:

Bereits durch diese einfache Nutzung der SSH werden alle Daten einer Verbindung komplett verschlüsselt. Damit sind die Sicherheits-Probleme von telnet und ftp behoben, d. h. Passwörter und Daten werden nicht mehr im Klartext übertragen und es findet eine strenge Authentifizierung statt.

Bei jeder neuen Verbindung laufen am Anfang folgende Schritte ab:

Bei SSH kommen kryptographische Verfahren an mehreren Stellen zum Einsatz. Das asymmetrische RSA-Verfahren wird für die Authentifizierung der Kommunikations-Partner und für die sichere Übertragung eines zufällig erzeugten und nur einemal verwendeten Sitzungs-Schlüssel eingesetzt. Dabei werden Key-Längen zwischen 768 und 1024 Bit empfohlen. Zur Verschlüsselung der Daten während der Verbindung wird wegen des höheren Durchsatzes ein symmetrisches Verfahren verwendet. Je nach Installation der SW hat der Benutzer i.a. die Auswahl zwischen verschiedenen Algorithmen: DES (Data Encryption Standard) mit 56 Bit Schlüssellänge, 3DES (Tripple DES) mit 112 Bit Schlüssellänge, IDEA (International Data Encryption Algorithm) mit 128 Bit Schlüssellänge, Blowfisch mit 128 Bit Schlüssellänge und Arcfour mit 128 Bit Schlüssellänge.

Der SSH-Tunnel

Der Aufbau eines SSH-Tunnels ist beispielsweise dann sinnvoll, wenn man sich als mobiler Nutzer mit einem Notebook in unbekannten Netzen bewegt (Hotel, Internet-Cafe etc.) und deshalb eine Verschlüsselung des Netzverkehrs wünscht. Ein anderer Grund für einen SSH-Tunnels kann eine Firewall oder ein anderer Filtermechanismus eines fremden Netzes sein, der den Zugriff auf bestimmte Dienste des entfernten Servers verweigert. Der SSH-Tunnel kann diese Einschränkung umgehen, indem er die Daten des blockierten Protokolls über den SSH-Port (normalerweise Port 22) schickt, und sich so mit dem gewünschten Dienst verbindet.

Ein SSH-Tunnel ist also die Port-Weiterleitung eines lokalen Ports zu einem (anderen oder gleichen) Port auf dem fernen Server. Die Weiterleitung erfolgt über eine SSH-Verbindung. Das Ganze ist nicht auf bestimmte Ports oder Dienste beschränkt, sondern kann beliebig eingesetzt werden. Grundvoraussetzung zum Aufbau des SSH-Tunnels ist lediglich eine SSH-Verbindung zum Zielserver, auf dem natürlich ein SSH-Server-Dienst laufen muss.

SSH-Tunnel unter Linux

Der Aufbaus des Tunnels erfolgt nach folgenden Muster:

ssh benutzer@FernerHost -L <lokaler Port>:<Ziel-Host>:<ferner Port>
Eine alternavie Schreibweise des Kommandos wäre ("-l" ist das kleine L, keine 1):
ssh -L <lokaler Port>:<Ziel-Host>:<ferner Port> -l benutzer FernerHost 
benutzer@FernerHost ersetzen Sie durch die Logindaten am Zielserver. Der Parameter -L <lokaler Port>:<Ziel-Host>:<ferner Port> ist für das Binden der Ports verantwortlich. Hier definieren Sie den Port auf Ihrem lokalen System und den Port für die Weiterleitung auf dem Zielserver. Ziel-Host und FernerHost könne auch ein und derselbe Server sein. In diesem Fall geht es nur darum, dass alles auf dem Ferne Server abläuft (wie im Putty-Beispiel weiter unten). Sind Ziel-Host und FernerHost unterschiedlich, bildet FernerHost den Router für die Daten, wie das folgende Bild schematisch zeigt.

Da man als Normal-User keinen Port kleiner 1024 verwenden kann (das darf nur root), addiert man beispielsweise 2000 zum fernen Port und nimmt das als lokalen Port. Dazu ein Beispiel: Für den ersten Test wird ein Tunnel zu einem Webserver aufgebaut:

ssh user@www.netzmafia.de -L 2080:localhost:80
Nach der Eingabe des Passworts auf www.netzmafia.de ist der Tunnel etabliert, was ganz einfach mit dem Browser getestet werden kann. Wenn man im Browser als Adresse localhost:2080 eingibt, wird der Port 2080 per SSH-Tunnel auf den www.netzmafia.de, Port 80 weitergeleitet. So erhält man die Homepage des Webservers auf www.netzmafia.de. Beim Beenden der SSH-Verbindung wird der Tunnel wieder geschlossen.

Optionen

Anmerkungen

Sonderfall X11-Forwarding

Möchte man Programme mit grafischer Benutzeroberfläche auf einem anderen Rechner ausführen, aber deren Fenster auf dem lokalen Rechner sehen, so geht dies mittels

ssh -X <ferner Server>
Man beachte das große -X, denn ein kleines -x würde das X11-Forwarding deaktivieren. Der Befehl stellt eine SSH-Verbindung zum fernen Server her. Sobald man im Shell-Fenster das Passwort eingegeben hat, werden alle X11-Verbindungen zum lokalen Rechner umgeleitet. SSH regelt automatisch die Verwendung von X-Window. Man muß also auf dem Remote-Rechner weder eine X-Window-Authorisierung noch die Environment-Variable DISPLAY setzen. Gegebenenfalls muss in der Datei /etc/ssh/sshd_config die Zeile
ForwardX11 yes
ergänzt oder ent-kommentiert werden. Gegebenenfalls muss der Zugriff auf das X11-Display erlaubt werden (xauth oder xhost +).

Automatischer Login durch RSA-Schlüsselpaare

Der Benutzer kann seine Identität nicht nur per Username und Passwort, sondern auch durch eine individuelle RSA-Authentifikation nachweisen (automatischer Login). Dafür muss auf dem internen Rechner ein Zertifikat erstellt und auf den externen Computer übertragen werden, was mit Hilfe der beiden Kommandos ssh-keygen und ssh-copy-id erledigt werden kann. Zuerst wird ein Schlüssel-Paar (Public- und Private-Key) erstellt und dann der öffentliche Schüssel zum Remote-Rechner übertragen. Dieser speichert ihn in der Datei $HOME/.ssh/authorized_keys .

Für die Authentifizierung des Clients benötigt der Benutzer ein individuelles RSA-Key-Paar, das im Directory $HOME/.ssh abgelegt und mit dem Kommando ssh-keygen verwaltet wird:

ssh-keygen [-f <KEY_FILE>] [-C <COMMENT>] [-b <KEY_LENGTH>]
Mit diesem Aufruf erzeugt man ein neues Key-Paar, wobei folgende Informationen interaktiv abgefragt werden: Damit das neue Key-Paar wirksam wird, muß man noch jeweils auf allen Remote-Rechnern den neuen Public-Key an die Datei $HOME/.ssh/authorized_keys anhängen. Ab da ist ein SSH-Login ohne Angabe der Login-Daten (Username und Passwort) möglich (lediglich das Passwort für den Secret-Key muss angegeben werden, sofern ein Secret-Key definiert wurde.

Nun muss man den erzeugten Schlüssel (RSA 2048 Bit) auf den fernen Host kopieren. Dazu gibt man folgenden Befehl ein:

ssh-copy-id -i ~/.ssh/id_rsa.pub <ferner Host>
Hier muss noch einmal das Passwort für den Login auf dem fernen Rechner eingegeben werden. Danach kann man sich ohne Passworteingabe einloggen und nun könne auch Shell-Scripte oder andere Programme sich automatisch einloggen. Sehr beliebt ist z. B. das automatische Kopieren von Dateien per crontab.

Das folgende Shellscript erzeugt die Schlüssel und übertägt sie dann (den Account "user@remote.netzmafia.de" gibt es natürlich nicht, er dient nur als Beispiel):

#!/bin/bash
# Generiert Public/Private-Keys und kopiert sie zur Netzmafia
# damit ein Login bzw. Aufbau eines SSH-Tunnels dorthin ohne
# Passwort-Eingabe moeglich ist

# Hier den fernen Server in der Form "user@server" eintragen:
REMOTE="user@remote.netzmafia.de"

#
# zuerst wird der Key generiert

ssh-keygen -t rsa

# Nun befinden sich im Verzeichnis ~/.ssh zwei Dateien, der 
# private und der oeffentliche Schluessel:
# id_rsa   id_rsa.pub
#
# Jetzt wird der public key zum fernen Server kopiert und dort
# an die Datei ~/.ssh/authorized_keys angehaengt

ssh-copy-id -i ~/.ssh/id_rsa.pub $REMOTE

# ab sofort kann sich der User vom internen System als
# "user@www.netzmafia.de" ohne Passworteingabe auf
# dem fernen Server einloggen

SSH Reverse Tunnel - ich bohre ein Loch in die Firewall

Einen SSH-Reverestunnel benötigt man z. B. wenn man auf einen Rechner zugreifen will, der hinter einem Firewallsystem steht und zwar selbst ins Internet kommt, jedoch eine sogenannte private IP-Adresse besitzt. Da man den Rechner von ausserhalb nicht erreichen kann, muss dieser von innen einen SSH-Tunnel (ggf. durch die Firewall) zu einem externen Rechner aufbauen. Bis dahin wäre das ein "normaler" SSH-Tunnel. Dieser wird aber so eingerichtet, dass er auch Verbindungen von externen Rechner nach innen zulässt.

Dazu muss der folgende Befehl am internen Rechner ausgeführt werden:

ssh -Nf -R 2222:localhost:22 user@externer.rechner
Das -R ist somit das Gegenstück zum -L oben. 2222 ist der Port über den die Verbindung vom externen Rechner aus geöffnet werden muss, 22 ist der Port, der dann vom internen System verwendet wird (in diesem Fall SSH). Nachdem der Tunnel steht, kann man sich vom externen System aus mit dem Befehl
ssh localhost -p 2222
zum internen Rechner verbinden. Zu bedenken ist, dass man quasi ein Loch in die Firmenfirewall bohrt, was nicht jeder Admin und nicht jede Firmenleitung gerne sieht.

Im folgenden Beispiel bietet der Reversetunnel die Möglichkeit, sich per SSH auf einem System einzuloggen, das über einen sogenannten Surfstick am Internet hängt, obwohl es eine private Adresse besitzt (bei der Telekom ist die in der Regel ein 10.x.x.x-Netz. Solange der Tunnel steht, ist das Surfstick-System natürlich auch angreifbar.

Insofern ist es günstig, durch crontab gesteuert den Tunnel nur für eine bestimmte Zeit aufzumachen. In dieser Zeit kann dann das Surfstick-System aus der Ferne administriert werden. In diesem Fall muss der Login automatisiert werden, denn sonst hinge der cron-Job mit einer Passwortabfrage. Deshalb erfolgt der Login des Surfstick-Systems auf dem externen Rechner per ssh-key und Zertifikat wie oben geschildert.

Auch beim Reverse-Tunnel ist es möglich, mehrere Ports zu bedienen, z. B. für den zusätzlichen Zugriff auf einen Webserver:

ssh -Nf -R 8080:localhost:80 -R 2222:localhost:22 user@externer.rechner
Will man nur aus dem lokalen Netzwerk auf den fernen Server zugreifen, gibt man im Browser den Port mit an, z. B.: http://localhost:8080.

SSH für Cluster

Polyshell

Mit der polysh (Polyshell) lassen sich mehrere Systeme per SSH administrieren. Di polysh ist ein Python-Script und wurde von Guillaume Chazarain entwickelt. Die polysh baut eine SSH-Verbindung (ssh) zu mehreren Maschinen auf, sendet allen gleichzeitig die auf der Kommandozeile eingegebenen Befehle und liefert die Ergebnisse zurück. Über einen :upload-Befehl können auch Dateien und Ordner auf die Zielmaschinen übertragen werden.

Dazu ein Beispiel. Nach dem Abschicken des Kommandos zeigt der polysh-Prompt an, auf wieviele der insgesamt 12 Remote-Shells gewartet wird:

$ polysh 'lbs-pc-<01-12>'
waiting (7/12)>
Irgendwann zeigt der Prompt dann an, dass alle 12 Remote-Verbindungen aufgebaut wurden und auf weitere Kommandos warten. Zum Test wird das date-Kommando eingegeben:
ready (12)> date
lbs-pc-01 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-03 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-06 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-07 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-10 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-11 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-12 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-09 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-13 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-14 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-02 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-04 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-05 : Mon Dec 21 10:17:06 CET 2015
lbs-pc-08 : Mon Dec 21 10:17:06 CET 2015
ready (12)>

Kommandos, die mit einem ':' beginnen, sind interne Befehle der polysh. Kommandos, die mit '!' beginnen richten sich an den lokalen Rechner (z. B. !ls).

polysh benötigt Python > 2.4 und die ssh. Auf der Homepage von polysh sind .tgz- und .rpm-Installationspakete verfügbar. Auf RPM-basierten Systemen installiert man das RPM-Paket mittels rpm -i .... Da es kein .deb-Paket gibt, installiert man unter Debian/Ubuntu/Raspbian RPM-Paket am Besten mit alien:

$ wget http://guichaz.free.fr/polysh/files/polysh-0.4-1.noarch.rpm
$ sudo alien -i polysh-0.4-1.noarch.rpm

Cluster-SSH

Im Gegensatz zur Polyshell ist die Clusterssh grafisch. Für jeden Rechner wird ein X-Terminal geöffnet. In einem kleinen Steuerfenster können Befehle eingegeben werden, die dann parallel auf allen Rechnern ausgeführt werden. Jeder Rechner kann aber auch individuell über das zugehörige xterm angesprochen werden. Auch muss die DISPLAY-Variable gesetzt sein und der Zugriff auf das X11-Display erlaubt werden (xauth oder xhost +). Beim Start empfängt Clusterssh eine Reihe von Rechnernamen, zu denen es SSH-Verbindungen aufbaut. Zum Beispiel:
cssh user@lbs-pc-1 user@lbs-pc-2 user@lbs-pc-3
In der Konfigurationsdatei /etc/clusters lassen sich Rechner unter einem Stichwort zu Gruppen zusammenfassen, z. B:
workstations user@lbs-pc-1 user@lbs-pc-2 user@lbs-pc-3 user@lbs-pc-4 user@lbs-pc-5 user@lbs-pc-6
server admin@mail admin@donnerwetter admin@blackhole
alle server workstations
Dann genügt der Aufruf cssh server, um die Login-Terminals aller definierten Server erscheinen zu lassen. Die Tags darf man ebenfalls wieder in einer Serverliste verwenden, wie die letzte Zeile oben zeigt.

Clusterssh spendiert jedem Server eine andere Schriftfarbe. Das kann sinnvoll sein, denn die Fontfarbe bleibt pro Server stets gleich und nach einer gewissen Eingewöhnungszeit erkennt man jeden Rechner allein an der Farbe. In der Konfigutrationsdatei kann man dies neben anderen Optionen abschalten:

terminal_colorize = 0       # Farbe abschalten
terminal_size = 120x32      # Terminalgroesse festlegen
terminal_bg_style = light   # Heller Hintergrund (light statt dark)
...

Die cssh benötigt für die grafische Oberfläche die perl-Tk- und die X11::Protocol-Bibliothek. Unter Debian/Ubuntu kann auf Pakete zugegriffen werden. Die Installation erfolgt mittels

sudo apt-get -y install perl-tk clusterssh
Ansonsten gibt es einen TAR-Ball bei http://sourceforge.net/projects/clusterssh/.

Copyright © Hochschule München, FK 04, Prof. Jürgen Plate
Letzte Aktualisierung: