Secure Shell

Die Secure Shell ist ein Ersatz für Dienste wie telnet, ftp und rlogin, bzw. den darauf aufbauenden Diensten rcp und rexec. Nachteilig an diesen Diensten ist, daß Passwörter im Klartext übermittelt werden und so von jedem, der physikalischen Zugang zum Netzwerk hat, mitgelesen werden können.

TCP Stack Es existieren verschiedene Verfahren, dieses Manko zu umgehen: IPsec setzt auf eine Verschlüsselung auf der IP Ebene, SSL (Secure Socket Layer) bzw. TLS (Transport Layer Security) verschlüsselt die Daten zwischen der Anwendungs- und Transportebene. SSH ersetzt andere Programme durch eine sichere Variante und sort so für Sicherheit auf der Anwendungsebene.

Die Secure Shell ersetzt die Dienste telnet, rlogin, rexec, rcp und ftp durch die Programme ssh und scp. Ursprünglich stammt das Programm von Tatu Ylonen. Während Version 1 noch frei benutzbar war, verlangte der Autor für Version 2 bei kommerziellen Einsatz Gebühren, was der weiteren Verbreitung eher schadete. Deshalb schuf eine Gruppe von BSD-Entwicklern auf Basis einer alten Version eine freie Variante mit dem namen OpenSSH, die inzwischen auch die Version 2 unterstützt.

Für Windows existieren mehrere verschiedene Programme, von denen einige frei erhältlich sind. Die Unterstützung für Dateitransfers per scp ist aber in den seltensten Fällen implementiert.

Benutzung

Anstatt rlogin und telnet benutzt man das Kommando ssh. Als Parameter gibt man den Namen des Rechners an, auf dem man sich anmelden will. Zusätzlich kann man über die Option -l den Benutzernamen auf dem entfernten Rechner angeben, falls dieser nicht mit dem lokalen Namen übereinstimmt.

ssh -l marry bar

Statt rsh und rexec benutzt man ebenfalls ssh und gibt als letztes das auszuführende Kommando nach dem Hostnamen an.

ssh john@foo ls -lR

Für Datentransfers benutzt man statt rcp und ftp das Kommando scp. Dieses erwartet als Argument Quelle und Ziel, die um den Benutzernamen und Hostnamen erweitert werden können.

scp marry@bar:/tmp/baz john@foo:.

Die ssh kann zudem auch dazu benutzt werden, beliebige TCP-Verbindungen über einen sicheren Tunnel von einem Rechner auf einen anderen weiterzuleiten. Dies ist besonders bei Protokollen wie FTP oder UUCP sinnvoll, da diese ebenfalls Passwörter im Klartext benutzen und deshalb unsicher sind. Es gibt sowohl die Möglichkeit, Verbindungen vom lokalen Rechner auf einen entfernten Rechner weiterzuleiten, als auch Verbindungen vom Server auf einen lokalen Rechner weiterzuleiten.

Local Forward Über die Option -L läßt sich eine Verbindung auf den lokalen Port über den sicheren Tunnel auf einen anderen Rechner weiterleiten. Der Parameter erwartet ein durch Doppelpunkte getrenntes Tripel: Die erste Angabe bezeichnet den lokalen Port, der weitergeleitet werden soll. Der zweite Parameter gibt den Host an, auf den die Verbindung weitergeleitet werden soll. Dieser kann sich vom Rechner unterscheiden, auf den sich per ssh eingewählt wurde. Die dritte Angabe bezeichnet den Port auf dem entfernten Rechner, zu dem die Verbindung aufgebaut werden soll.

ssh -L 1111:ftp.other.org:ftp login.other.org

Remote Forward In umgekehrter Richtung lassen sich Verbindungen auf den Server über den Tunnel auf einen lokalen Rechner weiterleiten. Hier bezeichnet die erste Angabe nach der Option -R den Port auf dem Server, während der zweite Parameter einen Rechner im eigenen Netz bezeichnet, zu dem der lokale Rechner die Daten weiterleiten soll. Der dritte Parameter bezeichnet den Port auf dem Rechner, zu dem die Daten geschickt werden.

ssh -R 6000:my.host.net:6000 server.other.org

Authentifizierung

SSH ist als Ersatz für die R-Dienste gedacht und verhält sich so, daß diese Problemlos ersetzt werden können. Im Falle, daß auf dem entfernten Rechner kein SSH-Daemon läuft, fällt SSH auf die unsichere rsh zurück und benutzt ggf. nach einer Warnmeldung diese. Darüber hinaus bietet die ssh aber noch folgende Varianten zur Authentifizierung:

rhosts.equiv

Wenn sich ein Benutzer über ssh auf dem Rechner anmeldet, überprüft der Daemon, ob der Rechner, von dem aus die Verbindung hergestellt wird, in der Datei /etc/rhosts.equiv bzw. $HOME/.rhosts aufgeführt ist. Ist dies der Fall, so wird dem Benutzer der Zugang ohne Passwortabfrage gewährt.

Diese Methode ist sehr unsicher, da ein Angreifer sich lediglich als einer der Rechner ausgeben muß, die in der Datei aufgeführt sind. Deshalb ist diese Art der Authentifizierung in der Regel abgeschaltet und wird nicht verwendet.

Aufpassen muß man zudem bei der unterschiedlichen Bedeutung des Benutzernamens, der hinter dem Eintrag in den Dateien angegeben werden kann: In der Datei $HOME/.rhosts sorgt der Benutzername dafür, daß sich nur dieser Benutzer vom angegebenen Rechner aus ohne Passwort anmelden kann. In der Datei /etc/rhosts.equiv erlaubt die Angabe eines Namens diesem Benutzer, sich untern einem beliebigen Namen anzumelden.

known_hosts

Um den Host-Spoofing vorzubeugen erweitert die ssh das Konzept um einen Host-Key: Für jeden Rechner wir mit dem Programm ssh-keygen ein Schlüsselpaar ohne Passwort generiert. Der private Schlüssel wird in /etc/ssh/ssh_host_key abgelegt und ist nur für root lesbar. Der öffentliche Teil ssh_host_key.pub wird systemweit an die Dateien /etc/ssh_known_hosts bzw. deren benutzereigenen Variante $HOME/.ssh/known_hosts angehängt.

Server Authentifizierung

Server Authentifizierung Um Sicherzustellen, daß der kontaktierte Rechner auch der gewünschte Rechner ist und nicht durch einen kompromittierten Rechner ersetzt wurde, um an die Passwörter von Benutzern zu kommen, überprüft die ssh bei jedem Verbindungsaufbau den Schlüssel des Servers. Der dazu passende öffentliche Schlüssel muß dazu beim verbindungsherstellenden Rechner in den Dateien /etc/ssh_known_hosts bzw. $HOME/.ssh/known_hosts hinterlegt sein. Je nach Konfiguration wird beim fehlen des öffentlichen Schlüssels oder bei Nichtübereinstimmung die Verbindung grundsätzlich verweigert oder nach Rückfrage beim Benutzer trotzdem hergestellt.

Client Authentifizierung

Client Authentifizierung Umgekehrt kann der Daemon bei einer Authentifizierung wie bei den R-Diensten neben dem Hostnamen auch deren Schüssel überprüfen. Dazu wertet der ssh-Daemon die Datei /etc/ssh/shosts.equiv bzw. $HOME/.shosts aus und überprüft über die Dateien /etc/ssh_known_hosts bzw. $HOME/.ssh/known_hosts des verbindenden Rechners. Dazu muß die ssh allerdings den geheimen Schlüssel auf diesem Rechner lesen können, der normalerweise nur von root gelesen werden kann. Es ist daher notwendig, das ssh-Programm SUID-ROOT zu installieren.

authorized_keys

RSA Authentifizierung Neben diesen rein auf Hostnamen basierenden Möglichkeiten kann man sich ein Schlüsselpaar generieren und dieses ggf. mit einem Passwort verschlüsseln. Der private Schlüssel wird normalerweise in der Datei $6HOME/.ssh/identity abgelegt, während der öffentliche Schlüssel auf dem anzumeldenden Rechner an die Datei $HOME/.ssh/authorized_keys angehängt. Beim einloggen fragt ssh dann ggf. nach dem Passwort für den geheimen Schlüssel und meldet sich damit an. Bei dieser Variante genügt also der Zugriff auf den geheimen Schlüssel für eine Anmeldung, weshalb man diese Datei gut schützen sollte.

Um nicht jedesmal das Passwort eingeben zu müssen, kann mit dem Programm ssh-agent ein Programm im Hintergrund gestartet werden, dem das Passwort über ssh-add mitgeteilt wird.

Passwort

Wenn keine der vorherigen drei Möglichkeiten greift, fragt die ssh nach dem Passwort auf dem entfernten Rechner und meldet sich damit an. Im Gegensatz zu den R-Diensten wird das Passwort hierbei aber Verschlüsselt übertragen, so daß das Passwort nicht mitgehört werden kann.

Konfiguration

Je nachdem, ob die Programme selbst übersetzt werden oder eine fertige Distribution verwendet wird, liegen die Konfigurationsdateien in /etc/, /etc/ssh/ oder /usr/local/etc/. Die Konfigurationsdateien der Benutzer liegen normalerweise in $HOME/.ssh/ und werden im folgenden kurz beschrieben. Für jede Datei wird kurz deren Funktion und ein Vorschlag für die Rechte gemacht.

Server

Der Server sshd wird vollständig über Dateien konfiguriert, die im Verzeichnis /etc/ssh/ liegen. Einige können jedoch von Benutzern bei entsprechender Konfiguration lokal erweitert werden. Alle globalen Dateien sollten dem Benutzer root und der Gruppe root gehören.

/etc/ssh/shosts.equiv 644
Diese Datei enthält in jeder Zeile einen Hostnamen, von dem aus sich Benutzer ohne Eingabe eines weiteren Passwortes einloggen können. Zusätzlich können Benutzernamen angegeben werden, die sich dann als jeder beliebige Benutzer anmelden können.
$HOME/.shosts 600
Diese Datei erweitert die globale Datei um benutzerspezifische Hosts. Die Namensangabe hier kann dazu verwendet werden, falls sich der Benutzername auf dem entfernten Rechner vom Namen des lokalen Accounts unterscheidet.
/etc/ssh/ssh_host_key 600
Diese Datei enthält den geheimen Schlüssel des Rechners und wird durch den Aufruf von ssh-keygen ohne Vergabe eines Passwortes erzeugt.
/etc/ssh/ssh_host_key.pub 644
Diese Datei enthält den öffentlichen Schlüssel des Rechners.
/etc/ssh/ssh_random_seed 600
Diese Datei enthält Zufallsdaten und dient zur Initialisierung des Pseudozufallszahlengenerators. Diese Datei wird beim Beenden des ssh-Daemons mit neuen Zeichen gefüllt, um einen Angriff zu erschweren.
/etc/ssh/sshd_config 644
Diese Datei enthält die eigentliche Konfiguration. Eine ausführliche Beschreibung aller Einträge finden sich in der Manualpage zu sshd(8).
HostKey /etc/ssh/ssh_host_key
Pfadangabe zum geheimen Host-Schlüssel
PermitRootLogin no
Verbietet, daß sich root direkt auf dem Rechner anmelden kann
PermitEmptyPasswords no
Verbietet die Verwendung von leeren Passwörtern auf dem lokalen Rechner
X11Forwarding yes
Erlaubt die automatische Weiterleitung einer X11 Verbindung
StrictModes yes
Überprüft die Dateirechte aller Dateien und verweigert bei einer Fehlkonfiguration aus Sicherheitsgründen den Dienst
IgnoreRhosts yes
Ignoriert die benutzerspezifischen Erweiterungen in $HOME/.rhosts und $HOME/.shosts. Die globalen Dateien /etc/rhosts.equiv und /etc/ssh/shosts.equiv werden weiterhin benutzt
IgnoreUserKnownHosts no
Erlaubt die Verwendung der benutzerspezifischen Datei $HOME/.ssh/known_hosts
RhostsAuthentication no
Verbietet die Verwendung von lediglich /etc/rhosts.equiv
RhostsRSAAuthentication yes
Erlaubt die Verwendung von /etc/hosts.equiv zusammen mit einer zusätzlichen Überprüfung des Host-Schlüssels
RSAAuthentication yes
Erlaubt das Anmelden über ein vom Benutzer generiertes Schlüsselpaar
PasswordAuthentication yes
Erlaubt das Anmelden mit dem Benutzerpasswort auf dem lokalen Rechner
SkeyAuthentication no
Verbietet die Verwendung von Einmalpasswörtern
/etc/ssh_known_hosts 644
In dieser Datei werden die öffentlichen Schlüssel anderer Rechner gesammelt, um deren Identität überprüfen zu können. Dies ist vor allem bei der Verwendung von /etc/ssh/shosts.equiv notwendig, um gegen Host-Spoofing zu vermeiden. Jeder Eintrag beginnt mit den Namen bzw. IP-Adressen des Rechners gefolgt vom öffentlichen Schlüssel.
$HOME/.ssh/known_hosts 644
Diese Datei erweitert die globale Datei um weitere öffentliche Schlüssel von Rechnern. Diese werden benutzt, um die Authentizität des Clients sicherzustellen.
$HOME/.ssh/authorized_keys 600
Diese Datei enthält eine Liste alle öffentlichen Schlüssel. Über den passenden geheimen Schlüssel kann man sich auf dem lokalen Rechner anmelden und wird dabei ggf. nach dem Passwort des geheimen Schlüssels gefragt.

Client

Auf der Seite des Client benutzt die ssh vorwiegend die Dateien des Benutzers, greift jedoch auf einige globale Dateien zurück. Überschrieben werden diese von etwaigen Kommandozeilenparametern, die beim Aufruf von ssh angegeben werden können.

$HOME/.ssh/config 644
Diese Datei enthält die benutzerspezifische Konfiguration der ssh. Es wird jeweils die erste passende Option benutzt, so daß speziellere Einstellungen am Anfang der Datei stehen sollten.
Host foo
Leitet einen neuen Abschnitt, so daß alle folgenden Optionen nur noch für diesen Host gelten. Die Hostnamen können auch die Joker * und ? enthalten oder als Abkürzung für lange Hostnamen verwendet werden.
HostName foo.bar
Bezeichnet den tatsächlichen Namen des Rechners, falls dieser nicht beim Host-Eintrag verwendet wurde.
User foo (-l)
Benutzt den angegebenen Benutzernamen bei der Anmeldung anstatt des lokalen Namens
IdentityFile $HOME/.ssh/identity (-i)
Verwendet einen anderen geheimen Schlüssel für die Authentifizierung als den standardmäßigen Schlüssel. Dadurch können mehrere geheime Schlüssel für unterschiedliche Rechner verwendet werden.
RhostAuthentication no
Deaktiviert die Anmeldung über die alleinige Verwendung von /etc/rhosts.equiv
RhostRSAAuthentication yes
Versucht eine Anmeldung über /etc/ssh/shosts.equiv und einer zusätzlichen Überprüfung des Host-Schlüssels.
RSAAuthentication yes
Verwendet das vom Benutzer generierte Schlüsselpaar zur Anmeldung
PasswordAuthentication yes
Erlaubt die Verwendung des Passwortes auf dem Server zur Authentifizierung.
SKeyAuthentication no
Verwendet keine Einmalpasswörter zum Anmelden.
CheckHostIP yes
Überprüft zusätzlich, ob die IP-Adresse zum angegebenen Namen passt.
StrictHostKeyChecking yes
Verweigert den Login auf Rechnern, deren Host-Schlüssel unbekannt oder verändert ist.
FallBackToRsh no
Im Falle, daß auf dem Server kein ssh-Daemon läuft, wird nicht auf die Verwendung der R-Dienste zurückgegriffen.
UseRsh no
Benutzt keine rsh, wenn auf dem Server der ssh-Daemon nicht läuft.
ForwardX11 yes (-X|-x)
Leitet alle X11-Verbindungen vom Server über einen sicheren Kanal zurück auf den lokalen Rechner.
ForwardAgent yes (-A|-a)
Leitet anfragen an das Authentifizierungsprogramm auf dem Server zurück an das lokale Programm.
LocalForward 1111 bar:2222 (-L)
Leitet alle TCP-Zugriffe auf den lokalen Port 1111 über einen sicheren Kanal zum Server und öffnet von dort eine Verbindung zum Rechner bar auf dem Port 2222.
RemoteForward 1111 bar:2222 (-R)
Leitet alle TCP-Zugriffe auf den Port 1111 auf dem Server über einen sicheren Kanal auf den lokalen Rechner und öffnet von hier eine Verbindung zum Rechner bar auf den Port 2222.
Compression no (-C)
Schaltet die komprimierte Datenübertragung ab.
CompressionLevel
Setzt den Grad der Komprimierung von 1 (schnell) bis 9 (kompakt).
/etc/ssh/ssh_config 644
Diese Datei enthält die Grundkonfiguration, auf die nur dann zugegriffen wird, wenn die Option nicht in der benutzerspezifischen Datei oder mit einem Kommandozeilenparameter überschrieben wurde.
$HOME/.ssh/identity 600
Diese Datei enthält den geheimen Schlüssel, mit dem man sich auf einem entfernten Rechner anmeldet. Ist für den Schlüssel kein Passwort vergeben, so reicht allein der Besitz dieser Datei, um sich auf einem entfernten Rechner anzumelden, solang dort der passende öffentliche Schlüssel in der Datei $HOME/.ssh/authorized_keys vorhanden ist.
$HOME/.ssh/known_hosts 600
Diese Datei erweitert die globale Datei um weitere öffentliche Schlüssel von Rechnern. Diese werden benutzt, um die Authentizität des Servers sicherzustellen.

SSH 2

Das alte SSH1 Protokoll besitzt einige Probleme bezüglich Man-in-the-Middle Attacken. Deshalb wurde SSH2 entwickelt, das neben der RSA-Authentifizierung auch DSA-Authentifizierung nach Diffie-Hellman unterstützt. Um diesem neuen Format gerecht zu werden, wurden einige alte Dateien in SSH2 durch äquivalente neue Dateien ersetzt. Die folgende Tabelle stellt diese Unterschiede gegenüber:

SSH1 SSH2
/etc/ssh_known_hosts /etc/ssh/ssh_known_hosts2
/etc/ssh/ssh_host_key.pub /etc/ssh/ssh_host_rsa_key.pub, /etc/ssh/ssh_host_dsa_key.pub
/etc/ssh/ssh_host_key /etc/ssh/ssh_host_rsa_key, /etc/ssh/ssh_host_dsa_key
$HOME/.ssh/authorized_keys $HOME/.ssh/authorized_keys2
$HOME/.ssh/known_hosts $HOME/.ssh/known_hosts2
$HOME/.ssh/identity $HOME/.ssh/id_rsa, $HOME/.ssh/id_dsa
$HOME/.ssh/identity.pub $HOME/.ssh/id_rsa.pub, $HOME/.ssh/id_dsa.pub

Wenn zwei SSH2-fähige Versionen miteinander in Kontakt treten, werden die alten SSH1-Dateien teilweise ignoriert. Dies fällt meißtens dann unangenehm auf, wenn nacheinander die Versionen auf Client und Server aktualisiert werden und die Authentifizierung per $HOME/.ssh/identity nicht mehr funktioniert. Durch die Angabe von -1 bzw. von Protocol 1 als Option kann man das Verwenden des alten Protokolls noch erzwingen, bis man die Konfiguration entsprechend aktualisiert hat.

Verfügbare Versionen

Inzwischen gibt es verschiedene kommerzielle und freie Versionen für alle gängigen Betriebssysteme:

TeraTerm
TeraTerm ist eigentlich ein Terminal-Programm für Windows, daß aber neben em Umgang mit der seriellen Schnittstelle auch eine Telnet-Emulation besitzt. Als Erweiterung dazu gibt es ein ssh-Plugin, was dieses Programm universell einsetzbar macht. Einziges Manko ist die fehlende Unterstützung von Dateitransfers.
CERT DFN
Auf dem FTP-Servers des DFN befindet sich eine SSH-Version für Windows, die sich sehr einfach installieren läßt und einen guten Eindruck macht. Auch hier fehlt leider die Unterstützung für Dateitransfers.
PuTTY
PuTTY ist eine freie Implementierung eines Telnet/SSH Clients für Windows. Im Gegensatz zu den anderen Varianten bietet diese Version auch Unterstützung für scp.
MindTerm
MindTerm ist eine Java Implementierung der ssh und ist somit universell auf allen Plattformen einsetzbar, auf denen eine Java Virtual Machine vorhanden ist. Das Programm läuft auch als Applet im Browser und ist damit überall einsetzbar.
SSH
Die original ssh aus Finnland.
OpenSSH
OpenSSH ist eine freie Implementierung es SSH-Protokolls und kann inzwischen das Original vollständig ersetzen.
NiftySSH
NiftySSH ist eine Implementierung für den Macintosh. Sie bietet auch scp Unterstützung.
F-Secure
F-Secure bietet mehrere kommerzielle SSH-Klienten für Windows, Macintosh und verschiedene Unix-Derivate.

Literatur

Weitere Infos zu ssh gibt es z.B. unter