DenKn

Vorgeschichte und Alternativen

Früher gab es einen Supercomputer mit mehreren angeschlossenen Terminals über Monitor und Tastatur als eine Einheit. Dies änderte sich in den 80ern, als die PCs vermehrt auftraten.

Innerhalb eines Unternehmens gab es durch aus mehrere Supercomputer und zentralisierte Server, die gewisse Aufgaben besser erledigen konnten als PCs, also lebten die Terminals wieder auf, aber diesmal in virtualisierter Form.

Um von einem PC, welcher als virtuelles Terminal dient, auf einen zentralen Server zugreifen zu können, etablierte sich telnet. Es war in etwa die selbe Verbindung eines Terminals zum Server, nur über eine Netzwerkverbindung.

Dies stellte Anfangs an sich kein Sicherheitsrisiko dar, obwohl keinerlei Verschlüsselung stattfand. Doch dann kam das Internet und man wollte auch über das Internet eine solche Verbindung aufbauen können, ohne dass jeder mitlauschen konnte.

Man nahm verschiedene Techniken um dieses Problem zu lösen, doch zum Schluss setzte sich SSH - Secure SHell - durch. Eine Alternative entstand relativ gleichzeitig mit SSL - Secure Sockets Layer -, welches von Netscape eigentlich für HTTP-Verbindungen gedacht war. SSL etablierte sich aber auch als allgemeiner Tunnel für jegliche unverschlüsselten Verbindungen um sie zu sichern, wie etwa bei IMAP, SMTP oder POP3. Man nennt es heute auch TLS - Transport Layer Security -, unter diesem Namen wurde es als Standard erklärt und nun wird unter diesem Namen weiterentwickelt.

SSH und TLS haben ähnliche Einsatzgebiete und ähnliche Techniken. TLS und telnet bieten die selbe Sicherheit und Vergleichbares ist möglich wie mit SSH, aber SSH bleibt komfortabler und somit eindeutig erstere Wahl.

Um die Übersichtlichkeit zu erhalten, wird im Folgenden nur auf OpenSSH und PuTTy eingegangen. Auf Wikipedia lässt sich Weiteres über das Original SSH, welches bald ein kommerzielles Produkt war, lesen, womit 1995 alles anfing.

SSH, das Protokoll und der Aufbau von OpenSSH

SSH ist ein Protokoll, welches über TCP - Transmission Control Protocol - transportiert wird. Die beiden aktuellen Implementationen unterstützen IPv4 und IPv6. Nach der IANA - Internet Assigned Numbers Authority - wird Port 22 für SSH reserviert.

Es gibt insgesamt 3 Versionen des Protokolls. Das erste SSH1 besitzt Schwachstellen, weswegen es heute nicht mehr verwendet werden soll. SSH2 wird aktuell verwendet, auch wenn es SSH3 schon gibt, welches von OpenSSH noch nicht unterstützt wird. Es ist angedacht, SSH2 zum Internetstandard zu machen.

OpenSSH setzt sich aus dem Serverprozess sshd und dem Klientprozess ssh zusammen. Beide können durch andere Programme ersetzt werden, wie zB. durch den Klient PuTTy oder den Server dropbear.

Der Server kann beliebig viele Verbindungen gleichzeitig bedienen.

Verwendung von ssh

Der Klient wird über eine Konsole – Terminal – gestartet. Ich unterscheide im Weiteren zwischen der lokalen Maschine und dem Server indem ich "A#" für lokal bzw. "T#" für entfernt voranstelle.

Eine einfache Verbindung zum Server

A# ssh uwprak@troubadix.nt.fh.koeln.de
        

uwprak steht für den Benutzer und troubadix.nt.fh-koeln.de für den Server. Man wird anschließend nur noch nach dem Passwort gefragt.

Nicht erschrecken: Bei der Eingabe des Passwortes sieht man garnichts, bis man Enter drückt. Nun ist man aut dem Server troubadix.nt.fh-koeln.de als uwprak angemeldet.

Ebenfalls erlaubt sind:

A# ssh -l uwprak troubadix.nt.fh-koeln.de
        A# ssh uwprak@troubadix   # Nicht immer möglich
        

Beim ersten Verbinden wird man gefragt, ob man dem Serverkey vertrauen möchte. Bestätigen.

X-Forwarding

SSH erlaubt ebenso das Tunneln von anderen TCP-Verbindungen. Insbesondere ist dabei das Tunneln vom X-Protokoll interessant, welches in SSH-Implementationen transparent eingebaut ist:

A# ssh -X uwprak@troubadix
        

Durch das -X wird ssh angewiesen, das X-Protokoll mitzuübertragen. So sind auch Aufrufe von X-Klienten möglich, die dann vom lokalen X-Server dargestellt werden können.

Weitere Optionen

Wenn die Internetverbindung nur wenig Durchsatz erlaubt, hilft -C weiter:

A# ssh -CXl uwprak troubadix
        

Dies weist ssh an, die Verbindung zu komprimieren.

Ein einziger Befehl

A# ssh -l uwprak troubadix echo 'Hallo Welt!'
        

SCP

Diese Technik setzt auf SSH auf und erlaubt ein Kopieren von Dateien über SSH. Dazu muss keine Verbindung bestehen; sie wird bei jedem Aufruf von scp etabliert und danach terminiert.

Datei auf den Server kopieren:

A# scp text.txt uwprak@troubadix:~/text.txt
        

Vom Server zum Klient:

A# scp uwprak@troubadix:~/.bashrc ~
        

Ebenfalls möglich ist eine Verbindung von Server zu einem anderen Server:

A# scp uwprak@troubadix:~/lied.ogg uwprak@asterix:~
        

Man wird jedesmal nach dem Passwort gefragt.

Schlüssel

SSH erlaubt es, Schlüssel zu verwenden, über die der Benutzer sich authentisiert. Dabei ist der Schlüssel optional mit einem Passwort gesichert - sehr zu empfehlen!

Die Vorteile gegenüber dem einfachen Passwort sind, dass ein Schlüssel für mehrere Server verwendet werden kann und desweiteren in Kombination mit den Programmen ssh-agent und ssh-add eine einfachere Authentisierung ermöglicht.

Insgesamt werden 2 Schlüssel benötigt: Ein privater Schlüssel, den man unbedingt schützen muss, und ein öffentlicher Schlüssel, der auf die Server gelegt wird.

Diese Schlüssel werden mit ssh-keygen auf der lokalen Maschine erzeugt.

Schlüssel generieren und verteilen

Die lokale Maschine heißt hier Argentum. Dies muss natürlich an jeden Klienten angepasst werden. Einfaches Generieren:

A# ssh-keygen
        Generating public/private rsa key pair.
        Enter file in which to save the key (/home/deac/.ssh/id_rsa): <leer>
        Enter passphrase (empty for no passphrase): <Passphrase>
        Enter same passphrase again: <Passphrase>
        Your identification has been saved in /home/deac/.ssh/id_rsa.
        Your public key has been saved in /home/deac/.ssh/id_rsa.pub.
        The key fingerprint is: bb:32:ab:a5:7e:49:0b:76:46:22:a1:a5:1b:53:2c:6a deac@Argentum
        

In ~/.ssh/id_rsa wurde der private und in ~/.ssh/id_rsa.pub der öffentliche Schlüssel gespeichert.

Existiert bereits ein Sclüsselpaar, wird dies bemerkt. Neben RSA wird auch DSA angeboten, sollte aber nicht benutzt werden.

Der öffentlichen Schlüssel von Argentum muss nun dem Server bekannt gemacht werden.

Falls das Zielverzeichnis auf dem Server noch nicht existiert, legt man es zuvor an und passt die Rechte an:

T# mkdir -p ~/.ssh
        T# chmod 700 ~/.ssh
        

Die Rechte müssen unbedingt gesetzt sein, ansonsten verweigert sshd die öffentlichen Schlüssel zu benutzen.

… und anschließend den Schlüssel kopieren:

A# scp ~/.ssh/id_rsa.pub uwprak@troubadix:~/.ssh/Argentum.pub
        A# ssh uwprak@troubadix
        T# cat ~/.ssh/Argentum.pub >> ~/.ssh/authorized_keys
        

Diese Datei ~/.ssh/authorized_keys enthält zeilenweise alle öffentlichen Schlüssel, die erlaubt sind, für diesen Benutzer.

Wer das Kopieren des Schlüssels in einem kurzen Befehl haben möchte, ohne die Datei erst zu kopieren, kann dies so machen:

A# ssh uwprak@troubadix 'mkdir ~/.ssh -p; chmod 700 ~/.ssh; cat >> ~/.ssh/authorized_keys' <~/.ssh/id_rsa.pub
        

Ab jetzt wird man nicht mehr nach dem Passwort des Benutzers auf dem Servers gefragt, sprich das Passwort von uwprak auf troubadix, sondern nach dem Passwort des privaten Schlüssels ~/.ssh/id_rsa.

SSH-Agent

Als Agent zum Authentisieren kann ssh-agent verwendet werden um das ständige Eingeben des Passworts stark zu optimieren. Man wird nur noch einmal gefragt und ssh-agent übernimmt die Aufgabe dann für eine gewisse Zeit.

ssh-agent ist ein Hintergrundprozess und wird nur einmal pro Shell gestartet:

A# eval $(ssh-agent)
        

Diese Zeile startet den Agent und legt Variablen in der Shell an, in denen steht, wie dieser Agent erreicht werden kann.

Einige [GNU][]/[Linux][]-Distributionen und [BSD][]-Betriebssysteme haben bereits ssh-agent gestartet, so dass dies nicht mehr nötig ist. Bei anderen ist ein Hilfsprogramm namens keychain dabei, welches dafür sorgt, dass sogar verschiedene Instanzen der Shells ein und den selben Agent nutzen können, wodurch auch das Starten von ssh in diesen ohne Passwort ermöglicht wird, wenn man zuvor in einer anderen Shell sich beim Agent authentisierte.

Dieses Authentisieren beim Agent ist mit ssh-add möglich:

A# ssh-add
        

Liegt der Schlüssel nicht in ~/.ssh/id_rsa, muss der Pfad mitangegeben werden:

A# ssh-add ~/PrivaterSchl&#xFC;ssel
        

Ab jetzt wird ssh den Agent kontaktieren und dieser wird das Authentisieren mit Hilfe des Schlüssels übernehmen. Ist der Agent nicht mehr erreichbar, wird wieder nach dem Schlüsselpasswort gefragt.

ssh-agent kann ebenfalls von scp, sshfs, fish und rsync verwendet werden.

keychain

Alternativ zum direkten Nutzen von ssh-agent, kann man auch keychain nutzen. Der Vortail von keychain ist, dass nur ein ssh-agent pro Benutzer gestartet wird und somit in jeder Shell ein und der selbe ssh-agent genutzt wird. Also muss man nur einmal ssh-add aufrufen, statt in jeder Shell. Der Wildwuchs der ganzen ssh-agent ist auch gestoppt.

Und so sieht es aus:

A# keychain
        
        KeyChain 2.6.8; http://www.gentoo.org/proj/en/keychain/
        Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL
        
         * Initializing /home/user/.keychain/Argentum-sh file...
         * Initializing /home/user/.keychain/Argentum-csh file...
         * Initializing /home/user/.keychain/Argentum-fish file...
         * Starting ssh-agent
         * Initializing /home/user/.keychain/Argentum-sh-gpg file...
         * Initializing /home/user/.keychain/Argentum-csh-gpg file...
         * Initializing /home/user/.keychain/Argentum-fish-gpg file...
         * Starting gpg-agent
        

Man sieht, dass für ssh und gpg die Agents gestartet wurden und je für verschiedene Shells Scripte angelegt wurden. Wenn man die jeweiligen Scripte für die Shells läd, hat man automatisch Zugriff zum Agent. Wie das geht lasse ich hier aus, ich hab was besseres. ;)

Startet man keychain erneut, ist die Ausgabe kürzer:

A# keychain
        
        KeyChain 2.6.8; http://www.gentoo.org/proj/en/keychain/
        Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL
        
         * Found existing ssh-agent (3474)
         * Found existing gpg-agent (3500)
        

Keychain erkannte, dass die beiden Agents schon liefen, also werden sie nicht noch einmal gestartet.

Aber nun wollen wir dies auch ausnutzen:

A# eval $(keychain --eval)
        
        KeyChain 2.6.8; http://www.gentoo.org/proj/en/keychain/
        Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL
        
         * Found existing ssh-agent (3474)
         * Found existing gpg-agent (3500)
        

Durch –eval wird erreicht, dass die nötigen Befehle, die ausgeführt werden müssen um den Agent zu nutzen, ausgegeben werden. Und diese Ausgabe ist ein und die Selbe wie bei ssh-agent und gpg-agent selbst. Durch eval wird dies dann auch ausgeführt.

Meines Wissens erkennt keychain, welche Shell man nutzt, es sollte also in jeder Shell auf anhieb funktionieren, wenn sie von keychain erkannt wird.

Nun wollen wir keychain immer nutzen, wenn die Shell gestartet wird.

Dazu legen wir ein Script an, welches /etc/profile.d/keychain.sh heiszt, mit der simplen Zeile:

eval $(keychain --eval --quiet)
        

sshfs/fish

Nicht nur das Kopieren von Dateien über scp ist möglich, sogar das Einhängen - mounten - von Verzeissen lokal ist möglich. sshfs wird bei einigen Distributionen bereits mitgeliefert und kann benutzt werden:

A# sshfs uwprak@troubadix:~ ~/troubadix
        

betritt man nun ~/troubadix, findet man sich im Heimatverzeichnis von uwprak auf troubadix wieder.

Ähnliches ist auch mit fish möglich. fish ist ein Quasiprotokoll des KDE und ursprünglich von mc. Über eine URI lässt sich zB. im konqueror der Inhalt des entfernten Verzeichnis darstellen. Die URI sieht dann so aus: fish://uwprak@troubadix/home/uwprak

Es fällt auf, dass kein ":" verwendet wird, daher ist auch "~" nicht nutzbar.

.ssh/config

Diese Konfigurationsdatei auf der lokalen Maschine A, hilft insbesondere bei oft wiedergekehrenden Verbindungen. Sozusagen ssh-Aliase.

Standardwerte sollten am Kopf der Datei definiert werden:

Compression yes
        ForwardX11 yes
        

Kompression sollte für heutige Maschinen kein Problem mehr darstellen. Das Internet ist langsamer als jede Maschine. Selbst Mobiltelefone profitieren von Kompression, insbesondere über GSM-Verbindungen.

Falls man gerade kein X11-Server laufen hat (etwa weil man auf einem "Hardware"-Terminal arbeitet), bewirkt diese Option nichts, hat also keine Nachteile. Wenn Remote keine X11-Programme vorhanden sind, ebenso wenig.

Als nächstes ein elaboriertes Beispiel:

Host troubadix
        Compression no
        ForwardX11 no
        Port 2222
        Hostname localhost
        User somebody
        

Host leitet sozusagen unser Alias ein. Man definiert den Namen, den man als Host beim Aufruf von ssh angiebt:

A# ssh troubadix
        

Die Verbindung soll nicht komprimiert werden und X11 soll auch nicht weitergeleitet werden.

Die 3 letzten Zeilen vereinfachen zusätzlich die Angabe, wohin wir uns verbinden wollen. Statt:

A# ssh -p 2222 somebody@localhost
        

Weshalb ich dieses Beispiel wählte ist, dass man dies wunderbar mit Tunneln verbinden kann. Der Server troubadix baut beispielsweiße einen Remotetunnel (-R) zu A auf und kann dann auf localhost auf Port 2222 erreicht werden.

Jede Option ist wirklich optional. Wenn man nur die Kompression abschalten möchte, ist es also nicht nötig Hostname anzugeben.

Für diese Datei gibt es sogar eine eigene Manpage: ssh_config Dort sind weitere Optionen zu finden.

PuTTy

Mit PuTTy ist es möglich von Windows aus eine SSH-Verbindung zu einem Server aufzubauen. Zwar liefe es auch unter anderen Betriebssystemen, doch hat es sich dort nie durchgesetzt und wird es wohl auch nicht.

Im Vorraus: PuTTy unterstützt zwar X-Forwarding, aber dies ist nicht ohne Weiteres unter Windows nutzbar, deswegen weise ich hier nur auf freie Lösungen hin: X/Cygwin, Anleitung zu Xming

PuTTy muss nicht installiert werden, sondern wird einfach heruntergeladen und gestartet: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

Man kann auch den Installer herunterladen und installieren, wenn man möchte, aber es reicht, wenn man nur PuTTy herunterlädt.

PuTTy bietet ein Programm PSCP an, welches das Kopieren wie mit scp anbietet. Es bedient sich genauso.

Verbinden

PuTTy einfach starten.

Bei "Host Name" muss der Server angegeben werden. Man sollte darauf achten, dass "Connection type" auf SSH steht.

Optional kann man die Session speichern, damit man später diese Daten nicht wieder eingeben muss. Dazu gibt man bei "Saved Sessions" einen passenden Namen an und klickt auf "Save". Ein Doppelklick auf die gespeicherte Session "Troubadix" startet dann sofort die Verbindung.

Wenn man die Daten selbst ausgefüllt hat, klickt man auf "Open".

Auch hier wird man beim ersten Mal gefragt, ob man dem "Serverkey" vertrauen will. Bestätigen.

Erst jetzt erscheint eine Art Konsolenfenster, in welches man als Erstes den Benutzernamen eingeben muss und anschließend versteckt das Passwort.

WinSCP

Eine Dokumentation zu WinSCP gibt es hier. Es ist komfortabler als PSCP, da es grafisch ist.