Ein funktionierendes Beispiel
Include ~/.ssh/config.d/*
Host web
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
Host *.example.com
User admin
Host *
ServerAliveInterval 60
User user
Jetzt bedeutet ssh web dasselbe wie ssh -p 2222 -i ~/.ssh/id_ed25519_work deploy@203.0.113.10, und es sendet außerdem alle 60 Sekunden ein Keepalive. Dieselben Namen funktionieren für scp, sftp und rsync.
Die Datei ist ~/.ssh/config. Sie darf für andere nicht beschreibbar sein, sonst bricht ssh mit Bad owner or permissions ab. Führen Sie chmod 600 ~/.ssh/config aus. Systemweite Einstellungen werden danach aus /etc/ssh/ssh_config gelesen.
Bei Dutzenden Hosts ist die Datei nur ein Teil der Lösung. Lesen Sie, wie Sie viele SSH-Server verwalten, damit Namen, Gruppen und Schlüssel übersichtlich bleiben.
Der erste Wert gewinnt
Diese Regel überrascht die Leute. Jeder passende Host-Block wird angewendet, nicht nur der erste. Für jede Option behält ssh den ersten gelesenen Wert und ignoriert spätere. Im Beispiel:
ssh webbekommtUser deploy, weil sein Block vorHost *steht.ssh db.example.combekommtUser admin.ssh otherbekommtUser user, und alle drei bekommenServerAliveInterval 60.
Setzen Sie also spezifische Hosts nach oben und Standardwerte ans Ende. Verschieben Sie Host * nach oben, gewinnt dessen User überall. Optionen auf der Kommandozeile haben Vorrang vor allem, ssh -l other web, ssh other@web und ssh -p 3000 web überschreiben also die Datei.
Eine Ausnahme sollten Sie kennen. IdentityFile addiert sich: Ein Wert in Host web-* und ein weiterer in Host * werden beide der Reihe nach probiert. Fügen Sie IdentitiesOnly yes hinzu, wenn Sie Schlüssel aus dem Agent vermeiden wollen, und lassen Sie IdentityFile aus Host * heraus, wenn Sie einen Schlüssel pro Host wollen.
Host-Muster
| Muster | Passt auf |
|---|---|
Host web db | Einen der beiden Namen. |
Host *.example.com | Jeden Namen, der auf .example.com endet. |
Host web-? | web- und ein Zeichen. |
Host web-* !web-old | Alle web--Namen außer web-old. Eine Negation allein passt auf nichts: Sie schließt nur aus einem positiven Treffer aus. |
Das Muster wird mit dem verglichen, was Sie tippen, nicht mit der Adresse, zu der es aufgelöst wird. %h steht für diesen Namen, was Kurznamen möglich macht:
Host web-*
HostName %h.example.com
ssh web-1 verbindet sich jetzt mit web-1.example.com.
Include
Include ~/.ssh/config.d/*
Das liest andere Dateien, als wären sie an dieser Stelle eingefügt, sodass Sie eine Datei pro Projekt führen können. Relative Pfade beginnen bei ~/.ssh. Es braucht OpenSSH 7.3 oder neuer.
Setzen Sie es an den Anfang der Datei. Ein Host-Block geht bis zum nächsten, und ein danach stehendes Include gehört zu diesem Block. Wir haben das getestet: Mit einem Include unter einem Block Host a bewirkten die Einstellungen der eingebundenen Datei für keinen anderen Host etwas. Sie können das absichtlich nutzen, um eine Datei nur für manche Hosts einzubinden.
Match
Match ist eine mächtigere Form von Host, mit Bedingungen:
Match host "*.internal" user deploy
Port 2200
Match exec "test -f /tmp/at-office"
ProxyJump bastion
Der erste gilt nur, wenn beide Bedingungen zutreffen. Der zweite führt einen Shell-Befehl aus und gilt, wenn er mit 0 endet, womit Sie Einstellungen nach Netz oder Ort ändern. Beachten Sie, dass dieser Befehl jedes Mal läuft, wenn die Konfiguration gelesen wird, auch mit ssh -G.
Die nützlichen Bedingungen sind host, originalhost, user, localuser, exec, tagged, final und all. host prüft den Namen, nachdem HostName angewendet wurde, und originalhost prüft, was Sie getippt haben. final lässt ssh die Konfiguration ein zweites Mal lesen, sodass ein Block das Ergebnis des ersten Durchlaufs sehen kann:
Host *.corp
HostName %h.example.com
Match final host *.example.com
User admin
Ab OpenSSH 9.4 können Sie Hosts auch mit Tags versehen und sie mit Match tagged oder ssh -P auswählen:
Host web
Tag prod
Match tagged prod
User deploy
Für ProxyJump gibt es eine eigene Seite: ProxyJump und Jump-Hosts in SSH verwenden.
Das Ergebnis mit ssh -G sehen
ssh -G web
Das gibt jede Einstellung aus, die ssh für diesen Host nutzen würde, mit allen Dateien und Regeln angewendet, und endet ohne Verbindung. Es ist der schnellste Weg, die Frage „Warum nimmt es diesen Benutzer?“ zu beantworten:
ssh -G web | grep -E '^(hostname|user|port|identityfile) '
Um herauszufinden, ob Ihre Konfiguration die Ursache eines Problems ist, ignorieren Sie sie für einen Befehl. -F none überspringt sowohl die Benutzerdatei als auch die Systemdatei:
ssh -F none user@203.0.113.10
Für die Verbindung selbst gibt ssh -v web aus, welche Konfigurationszeilen angewendet wurden.
Häufige Fehler
- Ein
Host *ganz oben, das alles darunter überschreibt. - Eine globale Option am Ende der Datei. Optionen außerhalb eines Blocks müssen vor dem ersten
Hoststehen. Am Ende gehören sie zum letzten Block. - Ein Tippfehler in einer Option. ssh bricht mit
Bad configuration optionab und verbindet sich mit nichts, bei jedem Host. Für eine Option, die nur manche Versionen kennen, setzen SieIgnoreUnknownund den Optionsnamen darüber. - Geheimnisse in der Datei. Sie enthält Pfade zu Schlüsseln, keine Schlüssel, und hat keine Passwort-Option. So sollte es bleiben.
Fragen
Wo liegt die SSH-Konfigurationsdatei?
Unter Linux und macOS ist es ~/.ssh/config im Home-Verzeichnis, unter Windows C:\Users\Name\.ssh\config. Die Datei existiert erst, wenn Sie sie anlegen. Systemweite Einstellungen in /etc/ssh/ssh_config werden danach gelesen.
Warum ignoriert ssh eine Einstellung in meiner Config?
Ein anderer passender Block hat dieselbe Option vorher gesetzt, und der erste Wert gilt. Führen Sie ssh -G mit dem Hostnamen aus, um den Wert zu sehen, den ssh verwendet, und stellen Sie spezifische Hosts über Host *.
Gilt die SSH-Konfigurationsdatei auch für scp, sftp und rsync?
Ja. Sie verbinden sich über ssh, daher gelten die Hostnamen und Optionen aus ~/.ssh/config auch für sie, zum Beispiel scp datei.txt web:/tmp/.
Quellen
- ssh_config(5), OpenBSD manual
- ssh(1), OpenBSD manual
- OpenSSH 7.3 release notes, Include
- OpenSSH 9.4 release notes, tags