SSH Agent Forwarding #
Wenn man sich per Schlüssel passwortlos einloggt, erhöht das den Komfort und die Sicherheit. Allerdings möchte man dann manchmal von dem Rechner, auf den man sich eingeloggt hat, weiter auf einen anderen Rechner gelangen. Und dann fangen alle Authentifizierungs-Probleme wieder von vorne an.
Ein Beispiel ist, das man sich aus dem Internet mit der IP-Adresse des heimischen Netzwerks verbindet. Der Router (wenn man ihn entsprechend konfiguriert hat) leitet einen an eine Firewall oder einen DMS-Rechner weiter, der sozzusagen den Eingang ins lokale Netz darstellt. Von da aus möchte man dann aber z.B. auf seinen persönlichen Arbeitsplatz kommen. Also braucht man da schon wieder ein PAsswort bzw. einen Schlüssel. Nicht so schlau ist es natürlich, dafür einen Schlüssel auf dem DMZ-Rechner zu generieren - weil der ja potentiell angreifbar sein kann.
Für dieses Problem benutzt man Agent Forwarding. Im groben funktioniert das so, das auf dem lokalen System ein kleiner Server namens ssh-agent gestartet wird, der die privaten und öffentlichen Schlüssel (die normalerweise in ~/.ssh/ liegen) einliest und verwaltet. Über einige Umgebungsdvariablen veröffentlciht man, wie dieser zu erreichen ist (über einen Dateinamen eines Unix-Sockets, aber das braucht man im Grunde nicht zu wissen, um ihn zu benutzen). Jetzt kann man das ssh-Programm mit einer Option starten (-A), so das es bei der Suche nach Schlüsseln nicht nur in der normalen Datei sucht, sondern auch den ssh-agent befragt. So weit so gut. Der besondere Trick ist nun aber, das ssh nach dem Verbindungsaufbau mit dem fremden Rechner dort ebenfalls einen Socket einrichtet und die Umgebungsvariablen entsprechend setzt. Dort läuft allerdings kein eigener ssh-agent, sondern Anfragen an diesen Socket werden weitergeleitet an den lokalen Rechner und von dessen ssh-agent bearbeitet. Auf diese Art kann ein ssh-Befehl auf dem entfernten Rechner (sagen wir: dem DMZ-Eingang in unser heimisches Netzwerk), der ebenfalls mit der -A Option gestartet wird, den Socket benutzen und die Schlüssel prüfen lassen. Dabei verlässt der private Schlüssel allerdings niemals den eigenen PC, den man vor sich stehen hat.
Auf jeder normalen Linux-Distribution wird eine X-Session (also der graphische Desktop, auf dem man normalerweise arbeitet, in der Form gestartet, das als Mutterprozeß eine Instanz von ssh-agent läuft. Falls nicht (das ist z.B. so, wenn man in Debian Linux auf einer Textkonsole arbeitet), muss man den Agent manuell starten und die Variablen übernehmen. Das geht - für eine einmalige Anwendung - recht elegant mit:
eval $(ssh-agent -s)
Der eval-Trick funktioniert, weil der ssh-agent die benötigten Shellvariablen direkt in einem Format ausgibt, das eval verarbeiten kann. Wer das immer und fest haben möchtee, ohne den agent immer neu zu starten (und wo das nicht die X-Session schon beinhaltet), kann hier auf Stackoverflow gute Ideen sehen, wie man das automatisch starten kann.
Hat man den Agent gestartet, muss man mit dem Kommande "ssh-add" die aktuellen Schlüssel (oder andere, wenn man möchte - siehe manpage) dem Agent mitteilen, damit er sie nutzen kann. Wer das nicht jedes Mal machen möchte, kann in der Datei ~/.ssh/config folgendes setzen (ggf. auch per Host, denke ich):
AddKeysToAgent = yes
Dadurch macht ssh diesen Schritt automatisch vor jedem Verbindungsaufbau.
Außerdem kann man in dieser Datei auch noch dafür sorgen, das man die "-A"-Option nicht jedes Mal manuell setzen muss. Das geht mit
ForwardAgent = yes
welches man auch besser nur für die Hosts aktiviert, für die es sinnvoll ist.
Sicherheitsthemen #
Grundsätzlich kann keiner auf den entfernten Rechnern die privaten Schlüssel stehlen, da der ssh-agent diese nie direkt herausrückt. Allerdings kann während der Laufzeit der Verbindung jeder die Schlüssel benutzen, der Zugriff auf den Unix-Socket hat. Das ist normalerweise der eigene Benutzer, könnte aber auch root sein. Beides sind Accounts, die vielleicht gehackt werden könnten. Das sollte man bedenken. Wen das nervös macht, der kann den ssh-agent weiter absichern, indem er ihn abschliesst (lock) oder jede Benutzung mit einem Passwort sichert.
Multi-Hop Verbindungen #
Möchte man mit einem Befehl direkt in einem durch den Router in den heimischen Arbeitsplatz gelangen, kann man einen Befehl wie diesen benutzen:
ssh -A -t meinzuhause.dyndns.org ssh -A arbeitsplatz.local
Das kann man in der config-Datei auch vereinfachen. Dabei gibt es drei Methoden, die alle das gleiche Ergebnis bringen, die die Sache mit aktueller ssh-Version einfacher machen:
Host arbeitsplatz ProxyCommand ssh -q dmz-eingang.dyndns.org nc -q0 arbeitsplatz.localnet 22
Unter Benutzung der -W Option und der Variablen %h und %p (diese könnte man übrigens auch oben einsetzen, allerdings muss man aufpassen, wie man das handelt, wenn der Name, den man lokal benutzt, nicht identisch ist mit dem, den man vom Eingangsrechner aus nutzen muss (um z.B. eine Domain anzugeben oder wiel man ein Alias verwendet). Das sollte aber bestimmt lösbar sein, wenn man die manpage zu ssh_config studiert.
Host arbeitsplatz.localnet ProxyCommand ssh dmz-eingang.dyndns.org -W %h:%p
ab OpenSSH 7.3 geht dann die eleganteste Lösung:
Host arbeitsplatz ProxyJump dmz-eingang.dyndns.org
So ist es dann möglich, nur "arbeitsplatz" als host antzugeben. Insbesondere kann man das dann auch in anderen Befehlen benutzen, die ssh benutzen. Also z.B. bei sowas wie dem scp-Befehl oder auch in einer URL, die man in der graphischen Oberfläche in einen Datei-Explorer eingibt.
Siehe auch hier: http://sshmenu.sourceforge.net/articles/transparent-mulithop.html