SSH-Konfiguration: Match-Blöcke und Agent-Genehmigungen
Prüfe SSH-Konfigurationsblöcke mit Match, damit Agent-Genehmigungen zu echtem Host, Benutzer, Schlüssel, ProxyJump-Route und kanonisiertem Ziel passen.

Eine SSH-Genehmigung ist nur dann aussagekräftig, wenn die genehmigte Verbindung der Verbindung entspricht, die SSH tatsächlich herstellt. Das klingt selbstverständlich, bis ein Agent ssh prod ausführt, ein Host-Alias einen anderen HostName auswählt, ein Match-Block den Remote-Benutzer ändert und ProxyJump die Sitzung über einen Bastion-Host leitet, den niemand in der Anfrage erwähnt hat.
Die meisten Fehler in SSH-Konfigurationen lassen sich überstehen, wenn jemand ein Terminal beobachtet. Die Person sieht eine unerwartete Host-Key-Abfrage, bemerkt root@... oder weiß noch, dass prod im Büronetz eine andere Bedeutung hat. Ein autonomer Agent bringt dieses Misstrauen nicht mit. Er verwendet den vorgegebenen Alias und folgt der Konfiguration genau.
Deshalb verdienen SSH-Konfigurationsblöcke mit Match eine Sicherheitsprüfung, bevor ein Agent SSH-Zugriff erhält. Es geht nicht darum, Aliase, Bastion-Hosts oder bedingte Konfiguration zu verbieten. Die angeforderte Aktion, die effektive SSH-Konfiguration und die von einem Menschen genehmigte Verbindung sollen dasselbe beschreiben.
Ein Host-Alias ist eine Eingabe, keine Identität
ssh app-prod sagt nicht, wohin SSH verbindet, welches Konto es verwendet, welchen Schlüssel es anbietet oder ob der Datenverkehr zuerst über eine andere Maschine läuft. Der Befehl gibt OpenSSH lediglich an, mit welchem Konfigurationsargument es beginnen soll.
Diese Unterscheidung wird leicht übersehen, weil Aliase die Arbeit auf der Befehlszeile angenehmer machen. Ein kurzer Name wie app-prod lässt sich leichter eingeben als ein vollständiger Hostname mit bestimmtem Benutzer und einem nicht standardmäßigen Port. Auch einem Agenten lässt er sich leichter übergeben. Der Alias ist jedoch nur ein Griff. Seine Bedeutung ergibt sich aus allen passenden Einstellungen in den Konfigurationsdateien, die SSH liest.
OpenSSH liest zuerst Optionen auf der Befehlszeile, danach die Konfiguration des Benutzers in ~/.ssh/config und anschließend die systemweite Konfiguration. Bei den meisten Optionen mit nur einem Wert wird der erste von SSH gefundene Wert verwendet. Das OpenSSH-Handbuch ssh_config(5) macht die praktische Konsequenz klar: Spezifische Angaben gehören nach oben, allgemeine Standards weiter nach unten. Ein weit gefasster Host *-Block am Anfang kann eine spätere, sorgfältigere bedingte Regel unbemerkt außer Kraft setzen.
Beginne mit einem Inventar, in dem jeder Alias, den ein Agent verwenden darf, so beschrieben wird, dass ein Prüfer ihn kontrollieren kann:
| Alias | Aufgelöstes Ziel | Remote-Benutzer | Route | Zweck der Identität |
|---|---|---|---|---|
staging-api | api-01.staging.example.net | deploy | direkt | Staging-Deployment-Identität |
prod-api | api-01.prod.example.net | deploy | prod-bastion | Produktions-Deployment-Identität |
prod-breakfix | api-01.prod.example.net | ops | prod-bastion | Nur für Störungen vorgesehene Identität |
Schreibe in die Zielspalte nicht production. Trage das tatsächliche Ziel ein, das SSH verwendet. Schreibe nicht default user, sondern deploy, ubuntu, ec2-user oder das Konto, das der Server tatsächlich erhält. Wenn die Route einen Jump-Host enthält, benenne ihn. Verhält sich der Alias in verschiedenen Netzwerken unterschiedlich, braucht er eine eigene Zeile, denn dann handelt es sich um eine andere effektive Verbindung.
Die wichtige Unterscheidung lautet: Ein Alias bezeichnet einen Konfigurationseintrag, ein Ziel bezeichnet den Remote-Endpunkt. Wer beides vermischt, genehmigt leicht das Falsche. Ein Prüfer kann einer Sitzung zu staging-api zustimmen und trotzdem beim tatsächlichen Endpunkt irren, weil der Alias veraltetes oder bedingtes Verhalten enthält.
Aliase sollten außerdem einen betrieblichen Zweck beschreiben und ihn nicht verbergen. prod-readonly, prod-deploy und prod-breakfix lenken die Aufmerksamkeit an die richtige Stelle. Ein einzelner Alias namens prod, der Benutzer, Schlüssel und Routen über bedingte Blöcke auswählt, spart ein paar Tastenanschläge und schafft ein dauerhaftes Prüfproblem.
Match-Blöcke sind ausführbare Verbindungslogik
Ein Match-Block ist kein Etikett für eine Hostgruppe. Er ist ein bedingter Abschnitt in ssh_config, der bestimmt, welche Direktiven gelten. Die Bedingungen können den angeforderten Host, den ursprünglichen Host, den Remote-Benutzer, den lokalen Benutzer, den Kanonisierungsstatus, das lokale Netzwerk, einen angeforderten Befehl und einen exec-Befehl umfassen, den SSH über die lokale Shell ausführt.
Diese Möglichkeiten sind nützlich. Sie bedeuten aber auch, dass eine Konfiguration Verhalten enthalten kann, das unsichtbar bleibt, wenn man nur den unmittelbar benachbarten Host-Alias betrachtet.
Betrachte diese Konfiguration:
Host prod-api
HostName api-01.prod.example.net
User deploy
ProxyJump prod-bastion
Match originalhost prod-api user root
IdentityFile ~/.ssh/breakfix_ed25519
IdentitiesOnly yes
Wer nur den Block Host prod-api liest, sieht eine Deployment-Verbindung als deploy. Führt ein Aufrufer ssh -l root prod-api aus, kann die Bedingung Match originalhost prod-api user root greifen. Ob die Einstellung für die Identität wirksam wird, hängt außerdem davon ab, wo frühere Identitätseinstellungen gefunden wurden und ob die Option mehrere Werte unterstützt. Der entscheidende Punkt ist einfacher: Die Verbindung hat sich wegen des Benutzerarguments auf der Befehlszeile geändert, nicht weil der Alias geändert wurde.
Vermeide bei Agenten Match user-Regeln, die eine privilegiertere Identität oder Route gewähren. Die Regel wirkt übersichtlich, weil sie Verhalten nach Kontonamen gruppiert. Ein aufrufendes Tool kann sie jedoch leicht mit -l, user@host oder einem generierten Befehl verändern. Setze den vorgesehenen User stattdessen direkt in einen Alias mit eindeutigem Zweck.
Eine sicherere Variante macht jede Absicht ausdrücklich:
Host prod-deploy
HostName api-01.prod.example.net
User deploy
ProxyJump prod-bastion
IdentityFile ~/.ssh/prod_deploy_ed25519
IdentitiesOnly yes
Host prod-breakfix
HostName api-01.prod.example.net
User ops
ProxyJump prod-bastion
IdentityFile ~/.ssh/prod_breakfix_ed25519
IdentitiesOnly yes
Das macht privilegierten Zugriff nicht harmlos. Es macht die angeforderte Verbindung lesbar. Ein Agent braucht eine eigene Genehmigung, um prod-breakfix aufzurufen. Er kann nicht allein durch das Ändern eines Benutzernamens in dieses Verhalten geraten.
Match exec verdient in einer Konfiguration für Agenten noch weniger Vertrauen. SSH führt den lokalen Shell-Befehl aus, während es die Konfiguration auswertet. Teams nutzen dies für die Erkennung des Netzwerks, Inventarabfragen oder die Auswahl von Zugangsdaten. Damit wird ein Verbindungsversuch zu einem lokalen Codepfad mit Abhängigkeiten von der Umgebung. Wenn du diese Flexibilität für menschliche Arbeit brauchst, halte solche Aliase aus der Menge heraus, die ein Agent aufrufen darf. Eine Verbindungsprüfung sollte nicht das Rückwärtslesen eines beliebigen Shell-Befehls erfordern.
Der erste passende Wert kann deine Ausnahme verhindern
Der hartnäckigste Fehler in einer SSH-Konfiguration ist keine ungültige Anweisung. Es ist eine gültige Anweisung, die hinter einer allgemeineren Regel steht, die den Wert bereits gesetzt hat.
Angenommen, ein Entwickler schreibt Folgendes, um für die Produktion einen Bastion-Host zu erzwingen:
Host *
User deploy
ProxyJump dev-bastion
Host prod-*
ProxyJump prod-bastion
Die Erwartung ist verständlich: prod-* sieht spezifischer aus und sollte daher gewinnen. OpenSSH sortiert Blöcke jedoch nicht nach ihrer Spezifität. Es verarbeitet sie in Dateireihenfolge, und bei vielen Direktiven gewinnt der zuerst gefundene Wert. prod-api behält dev-bastion, weil der frühere Host * den Wert für ProxyJump bereits geliefert hat.
Setze spezifische Blöcke nach oben:
Host prod-*
ProxyJump prod-bastion
Host *
User deploy
ServerAliveInterval 30
Das ist nicht bloß Stil. Eine Route über den falschen Bastion-Host kann die Sitzung auf den falschen Netzwerkpfad setzen. Ein allgemeiner Standard wie User deploy kann dazu führen, dass sich ein Produktions-Alias als Konto anmeldet, das auf diesem Host nichts zu suchen hat. Ein allgemeines IdentityFile kann unerwartete Zugangsdaten vor dem vorgesehenen Schlüssel anbieten.
Übertrage die Regel zum ersten Wert nicht blind auf alle Direktiven. Manche Optionen akzeptieren absichtlich mehrere Werte. IdentityFile ist ein häufiges Beispiel. Mehrere konfigurierte Identitäten können in die Menge aufgenommen werden, die SSH prüft. Daraus entsteht ein anderes Problem: Ein enger Alias kann zwar die richtige Identität nennen, aber durch frühere Konfiguration oder den lokalen SSH-Agenten weitere Identitäten verfügbar lassen.
Für automatisierte Verbindungen sollte die Identitätsauswahl ausdrücklich und langweilig sein:
Host prod-deploy
HostName api-01.prod.example.net
User deploy
IdentityFile ~/.ssh/prod_deploy_ed25519
IdentitiesOnly yes
ProxyJump prod-bastion
IdentitiesOnly yes weist OpenSSH an, nur Identitäten aus der SSH-Konfiguration oder von der Befehlszeile zu verwenden, statt frei jede über einen Agenten verfügbare Identität auszuprobieren. Eine schlampige Konfiguration wird dadurch nicht repariert. Ein fremder, lokal geladener Schlüssel wird jedoch nicht mehr versehentlich zu einem möglichen Kandidaten.
Die Empfehlung, alle Standards in Host * zu setzen und nur bei Bedarf zu überschreiben, ist für harmlose Einstellungen wie Keepalive-Intervalle vertretbar. Für Benutzer, Routen, Identitätsdateien, Ports, ProxyCommand und Host-Umschreibungen ist sie schlechte Praxis. Standards, die Berechtigungen beeinflussen, sollten sparsam sein. Ein wenig Wiederholung ist günstiger, als erklären zu müssen, warum ein Agent den richtigen Rechner über den falschen Weg erreicht hat.
ProxyJump erzeugt eine weitere Verbindung, die geprüft werden muss
ProxyJump ergänzt eine Zielverbindung nicht einfach um eine Eigenschaft. SSH verbindet sich zuerst mit dem Jump-Host und stellt anschließend von dort einen TCP-Weiterleitungspfad zum Ziel her. Mehrere Proxys können angegeben und nacheinander durchlaufen werden. Das OpenSSH-Handbuch weist außerdem darauf hin, dass die Konfiguration des Zielhosts im Allgemeinen nicht für Jump-Hosts gilt.
Gerade dieses Detail führt häufig zu fehlerhaften Prüfungen. Eine Konfiguration kann prod-api präzise beschreiben und prod-bastion völlig unklar lassen.
Host prod-api
HostName 10.40.8.17
User deploy
ProxyJump prod-bastion
Host prod-bastion
HostName bastion.prod.example.net
User jump
IdentityFile ~/.ssh/bastion_ed25519
IdentitiesOnly yes
Hier gibt es zwei Authentifizierungsentscheidungen und zwei Host-Identitäten:
- SSH authentifiziert den lokalen Client bei
bastion.prod.example.netalsjump. - Der Bastion-Host leitet einen TCP-Datenstrom an
10.40.8.17weiter. - SSH authentifiziert sich über diesen Datenstrom beim Ziel als
deploy.
Der Jump-Host kann einen anderen Schlüssel, Benutzer, Port und Host-Key-Eintrag haben. Er kann auch durch einen Wildcard-Alias oder einen bedingten Block ausgewählt werden, den niemand prüft, weil der Agent nur prod-api angefordert hat.
Prüfe jeden Hop mit ssh -G, nicht nur den endgültigen Alias:
ssh -G prod-api | egrep '^(hostname|user|port|proxyjump|identityfile|identitiesonly) '
ssh -G prod-bastion | egrep '^(hostname|user|port|identityfile|identitiesonly) '
Die Ausgabe enthält eine Option pro Zeile. Eine plausible Prüfung könnte so aussehen:
hostname api-01.prod.example.net
user deploy
port 22
proxyjump prod-bastion
identityfile ~/.ssh/prod_deploy_ed25519
identitiesonly yes
Prüfe den Bastion-Host anschließend separat. Verwendet prod-api eine durch Kommas getrennte Kette wie edge-bastion,prod-bastion, führe den Befehl für beide Aliase aus. Eine Kette ist keine undurchsichtige Route, sondern mehrere getrennte SSH-Client-Konfigurationen.
Vermeide eine allgemeine Jump-Route in Host * oder einem weiten Muster wie Host *.internal. Solche Regeln erfassen leicht temporäre Hosts, Staging-Umgebungen und Aliase, die Monate später hinzugefügt werden. Definiere die Jump-Route in den Aliasen, die sie benötigen. Wenn viele Produktions-Aliase sie brauchen, verwende ein enges Muster, das ausschließlich für Produktions-Aliase reserviert ist.
Prüfe außerdem auf ProxyCommand. OpenSSH behandelt ProxyJump und ProxyCommand als konkurrierende Optionen: Die zuerst angegebene verhindert, dass spätere Instanzen der jeweils anderen Option greifen. Eine Konfiguration, die scheinbar einen Bastion-Host verwendet, kann stattdessen einen früheren Proxy-Befehl ausführen. Beide Einstellungen sollten markiert werden, denn beide verändern, wo die Netzwerkverbindung entsteht und wie sie das Ziel erreicht.
Die Benutzerauswahl verändert die genehmigte Berechtigung
Das Remote-Konto gehört zur angeforderten Aktion. [email protected] und [email protected] können denselben Server erreichen, haben aber möglicherweise unterschiedliche Berechtigungen, Shell-Profile, erzwungene Befehle, sudo-Rechte und Audit-Spuren.
SSH kann den Remote-Benutzer aus mehreren Quellen beziehen: aus user@host im Befehl, aus ssh -l user host, aus einer User-Direktive oder, falls nichts anderes vorhanden ist, aus dem lokalen Benutzernamen. Eine Konfigurationsprüfung, die nur fragt «Welcher Host?», ist unvollständig.
Verwende Aliase mit festem Benutzer, wenn ein Agent eine klar definierte Aufgabe hat:
Host inventory-read
HostName inventory.prod.example.net
User inventory_ro
IdentityFile ~/.ssh/inventory_ro_ed25519
IdentitiesOnly yes
Host inventory-deploy
HostName inventory.prod.example.net
User deploy
IdentityFile ~/.ssh/inventory_deploy_ed25519
IdentitiesOnly yes
Gib einem Agenten keinen allgemeinen Hostnamen und verlasse dich darauf, dass eine Abfrage oder ein Wrapper das richtige Konto beibehält. Ein Befehlsgenerator kann genauso leicht [email protected] wie [email protected] erzeugen. Die Konfiguration sollte den autorisierten Weg zum einfachsten machen und privilegierte Wege klar sichtbar abgrenzen.
Teste die alternativen Formen, die ein Tool erzeugen kann:
ssh -G inventory-read | grep '^user '
ssh -G -l ops inventory-read | grep '^user '
ssh -G ops@inventory-read | grep '^user '
Ergibt der zweite oder dritte Befehl ein Konto, das ein Agent nicht verwenden sollte, ist die Konfiguration nicht geprüft. Repariere die aufrufende Schnittstelle oder isoliere den Alias. Ein Match user-Block kann bei einer dieser Varianten ebenfalls greifen, weshalb er ausdrücklich getestet und nicht nur oberflächlich gelesen werden sollte.
Reserviere root-Zugriff für einen separat benannten Notfall-Alias und halte ihn außerhalb der normalen Agent-Berechtigungen. User root hinter einer Match-Bedingung zu verstecken, ist schlechter, als es offen zu schreiben. Die Bedingung wird im Ernstfall zu einer Suche, und ein Aufrufer kann sie manchmal durch Ändern eines Parameters auf der Befehlszeile erfüllen.
IdentityFile steuert mehr als den Schlüsselpfad
IdentityFile sieht wie eine Einstellung zur Dateiauswahl aus. In der Praxis entscheidet sie, welche Zugangsdaten SSH präsentieren darf. Dadurch wird bestimmt, welche Autorisierungsregeln der Server auf der Gegenseite auswertet.
Ein typischer Fehler sieht so aus:
Host *
IdentityFile ~/.ssh/id_ed25519
Host prod-*
IdentityFile ~/.ssh/prod_ed25519
Der Betreiber glaubt, die Produktion verwende prod_ed25519. SSH kann jedoch beide Identitätsdateien in seiner Kandidatenliste haben, weil IdentityFile mehrere Einträge unterstützt. Befinden sich weitere Schlüssel im SSH-Agenten und fehlt IdentitiesOnly, kann SSH auch diese anbieten. Manche Server lehnen wiederholte Angebote früh ab, andere akzeptieren eine unbeabsichtigte Identität mit passenden Zugriffsrechten. Beides beschreibt die Absicht nicht sauber.
Ein Alias für Agenten sollte einen einzigen Zweck für Zugangsdaten nennen und die Angebote begrenzen:
Host reports-export
HostName reports.prod.example.net
User exporter
IdentityFile ~/.ssh/reports_export_ed25519
IdentitiesOnly yes
Prüfe anschließend die effektive Konfiguration, statt der einzelnen Anweisung zu vertrauen:
ssh -G reports-export | grep '^identityfile '
ssh -G reports-export | grep '^identitiesonly '
Mehr als eine Zeile mit identityfile ist nicht automatisch falsch. Zertifikatsbasierte Konfigurationen und geplante Schlüsselrotation können mehrere Einträge rechtfertigen. Jede aufgeführte Identität sollte jedoch zur selben Berechtigungsgrenze gehören. Kann ein Alias einen persönlichen Administratorschlüssel, einen alten Deployment-Schlüssel und einen Produktionsschlüssel für Automatisierung anbieten, fehlt ihm eine klare Autorisierung.
Löse dieses Problem nicht, indem du private Schlüssel in Dateien, Umgebungsvariablen, Abfragen oder generierte Skripte eines Agenten legst. Damit wird eine Konfigurationsunklarheit lediglich in die Offenlegung von Zugangsdaten verwandelt. Sallyport bewahrt SSH-Schlüssel in seinem verschlüsselten Tresor auf und führt SSH-Aktionen über seinen Helper aus. Eine unklare SSH-Konfiguration kann Sallyport jedoch nicht sinnvoll machen. Alias, Route, Benutzer und Zweck der Identität müssen klar sein, bevor ein Betreiber den Agentenlauf genehmigt.
Dasselbe gilt für Schlüsselnamen. Ein Pfad wie ~/.ssh/id_ed25519 sagt nichts über den vorgesehenen Zweck aus. prod_deploy_ed25519 ist besser, aber die Konfiguration muss zusätzlich erklären, für welche Hostgruppe, welchen Benutzer und welche Route der Schlüssel verwendet wird. Dateinamen unterstützen die Prüfung, ersetzen sie aber nicht.
Kanonisierung kann dazu führen, dass ein Alias zweimal greift
Die Kanonisierung von Hostnamen gehört zu den unsichtbarsten Möglichkeiten, mit denen SSH eine Konfiguration verändert. Wenn CanonicalizeHostname yes aktiviert ist, kann OpenSSH einen unqualifizierten Namen um konfigurierte Domain-Endungen ergänzen, ihn auflösen und die Konfiguration anschließend mit dem neuen Zielnamen erneut verarbeiten. Match canonical greift bei diesem späteren Durchlauf. Match final fordert eine abschließende Analyse an und greift während dieses Durchlaufs; bei aktivierter Kanonisierung treffen kanonische und abschließende Bedingungen gemeinsam zu.
In großen internen Netzwerken kann dieses Verhalten nützlich sein. Es kann einen kurzen Alias aber auch in eine bedingte Konfigurationsfalle verwandeln.
CanonicalizeHostname yes
CanonicalDomains corp.example.net
Host build
User ci
Match canonical host *.prod.example.net
ProxyJump prod-bastion
Ein Aufrufer gibt ssh build ein. Im ersten Durchlauf sieht SSH build. Löst die Kanonisierung diesen Namen als build.prod.example.net auf, liest SSH die Konfiguration erneut ein und der Block Match canonical host *.prod.example.net kann eine Produktionsroute setzen. Die Verbindung änderte sich nicht, weil der Aufrufer einen anderen Alias verwendet hat. Sie änderte sich, weil DNS und ein zweiter Analyse-Durchlauf den Host änderten, den spätere Regeln sehen.
Das OpenSSH-Handbuch unterscheidet zwei Bedingungen, die oft gleich behandelt werden:
Match originalhostprüft das Host-Token, wie es der Aufrufer eingegeben hat.Match hostprüft das Ziel nach der Ersetzung durchHostNameoder nach der Kanonisierung.
Verwende originalhost, wenn Verhalten an einen bewusst benannten Alias gebunden sein muss. Verwende host, wenn das Verhalten vom tatsächlich aufgelösten Ziel abhängen soll. Für Privilegänderungen sollte keine der beiden Bedingungen unbedacht verwendet werden.
Die Kanonisierung hat bei Bastion-Hosts eine weitere wichtige Besonderheit. CanonicalizeHostname yes gilt normalerweise nicht für Verbindungen mit ProxyCommand oder ProxyJump; CanonicalizeHostname always erweitert sie auf weitergeleitete Verbindungen. Daher können zwei strukturell ähnliche Aliase allein aufgrund eines Jump-Hosts unterschiedlichen Umschreibungsregeln folgen.
Für Agent-Berechtigungen ist die einfachste Regel meist die beste: Deaktiviere die Kanonisierung für Aliase, die ein Agent verwenden darf, und setze explizite vollständig qualifizierte HostName-Werte. Wenn deine Umgebung Kanonisierung braucht, teste jeden erlaubten Alias genau in dem Netzwerk, in dem der Agent läuft. Gehe nicht davon aus, dass ein kurzer Hostname im Heimnetz, im Unternehmensnetz, im VPN und im Büro-WLAN gleich aufgelöst wird.
Match localnetwork wirft dasselbe Problem auf. OpenSSH weist darauf hin, dass die lokale Netzwerkadresse für sicherheitsrelevante Konfiguration nicht vertrauenswürdig ist, besonders in DHCP-konfigurierten Netzwerken. Für Komforteinstellungen ist sie in Ordnung. Verwende sie nicht, um zu entscheiden, ob ein Agent eine privilegiertere Identität erhält, einen Bastion-Host überspringt oder die Produktion erreicht.
Rendere die Verbindung, bevor du sie genehmigst
ssh -G ist der schnellste Weg, eine SSH-Konfiguration aus Prosa in etwas Testbares zu verwandeln. Der Befehl gibt die Konfiguration aus, die SSH nach der Verarbeitung von Host- und Match-Regeln verwenden wird, und beendet sich anschließend, ohne eine Verbindung zu öffnen.
Führe ihn mit genau dem Alias und den Argumenten aus, die der Agent verwenden wird. Teste nicht nur eine von Hand bereinigte Version des Befehls.
ssh -G prod-deploy | egrep '^(hostname|user|port|proxyjump|proxycommand|identityfile|identitiesonly|canonicalizehostname) '
Für eine gründliche Prüfung solltest du die vollständige Ausgabe als Testdatei in dem Repository speichern, dem die Automatisierung gehört. Verwende eine bewusst benannte Konfigurationsdatei, damit der Test nicht stillschweigend die persönlichen Einstellungen eines Entwicklers übernimmt:
ssh -F ./agent-ssh-config -G prod-deploy > ./testdata/prod-deploy.effective
Prüfe die Testdatei, wenn sich die Konfiguration ändert. Ein sinnvoller Diff erkennt eine veränderte hostname-, user-, proxyjump- oder Identitätsliste, bevor sie einen Genehmigungsprozess erreicht. Ein lauter Diff der vollständigen Konfiguration ist immer noch besser, als einem Block zu vertrauen, den jemand in einen Pull Request kopiert hat.
Verwende ssh -vvv erst, wenn ssh -G die erwarteten Werte zeigt. Ausführliche Verbindungsprotokolle helfen zu bestätigen, welche Hostschlüssel und Authentifizierungsmethoden SSH tatsächlich ausprobiert. Sie vermischen jedoch Konfigurationsentscheidungen mit Netzwerkgeräuschen. -G beantwortet zuerst die Frage «Was sagt diese Konfiguration?». Genau das musst du vor der Fehlersuche bei der Erreichbarkeit klären.
Teste Varianten bewusst:
ssh -F ./agent-ssh-config -G prod-deploy
ssh -F ./agent-ssh-config -G -l ops prod-deploy
ssh -F ./agent-ssh-config -G ops@prod-deploy
ssh -F ./agent-ssh-config -G prod-deploy.prod.example.net
Die Ergebnisse sollten innerhalb der erwarteten Berechtigungsgrenze bleiben oder fehlschlagen. Ändert eine Benutzerüberschreibung das Konto, überspringt die vollständig qualifizierte Form den Bastion-Host oder erhält ein kurzer Name nach der Kanonisierung eine andere Identität, hast du einen Konfigurationspfad gefunden, den du schließen solltest.
Prüfe auch eingebundene Dateien. Include kann dafür sorgen, dass die sichtbare ~/.ssh/config nur der Eingang zu einem Verzeichnis voller automatisch erzeugter, unternehmensweiter oder projektspezifischer Regeln ist. Prüfe die effektive Ausgabe mit demselben lokalen Benutzer und demselben Konfigurationspfad, die der Agent verwenden wird. Ein Test aus deiner eigenen Shell, während der Agent unter einem anderen Konto läuft, vermittelt eine falsche Sicherheit.
Halte die SSH-Konfiguration für Agenten klein und zweckgebunden
Die beste SSH-Konfiguration für einen autonomen Programmieragenten ist normalerweise nicht deine persönliche SSH-Konfiguration mit einigen zusätzlichen Kommentaren. Persönliche Konfigurationen sammeln Abkürzungen, Ausnahmen für einzelne Clients, alte Host-Aliase, Verhalten für lokale Netzwerke, weitergeleitete Agenten und Identitäten, die irgendwann praktisch waren. Ein Agent braucht einen engen Katalog von Verbindungen.
Erstelle eine eigene Konfigurationsdatei, die nur genehmigte Aliase und die erforderlichen Jump-Hosts enthält. Weise den Agenten oder seinen Ausführungs-Wrapper mit -F auf diese Datei. Jeder Alias sollte genau eine Aufgabe, einen expliziten HostName, einen User, eine Route und einen Zweck für die Identität haben. Halte bedingte Logik heraus, sofern du nicht zeigen kannst, warum ein statischer Alias die Aufgabe nicht erfüllen kann.
Ein kompaktes Beispiel:
Host prod-bastion
HostName bastion.prod.example.net
User jump
IdentityFile ~/.ssh/prod_bastion_ed25519
IdentitiesOnly yes
Host prod-deploy
HostName api-01.prod.example.net
User deploy
ProxyJump prod-bastion
IdentityFile ~/.ssh/prod_deploy_ed25519
IdentitiesOnly yes
Host staging-deploy
HostName api-01.staging.example.net
User deploy
IdentityFile ~/.ssh/staging_deploy_ed25519
IdentitiesOnly yes
Diese Konfiguration wiederholt sich. Das ist gut. Die Datei erklärt einem Prüfer, was jede Verbindung bedeutet, ohne dass er Wildcard-Reihenfolge und bedingten Zustand gedanklich ausführen muss.
Verwechsle eine eigene Konfigurationsdatei nicht mit einer Richtlinien-Engine. Sie kann nicht beweisen, dass ein Befehl nach dem Öffnen der Sitzung sicher ist. Sie kann die Transportverbindung jedoch konkret und prüfbar machen: dieser Alias, dieser Endpunkt, dieser Benutzer, diese Route, diese Identität. Das ist eine sinnvolle Grenze.
Sallyports Genehmigung pro Sitzung und seine Aktivitätsaufzeichnungen geben Betreibern einen menschlichen Kontrollpunkt und eine Spur für Agent-Aktionen. Die SSH-Konfiguration liefert jedoch weiterhin die Fakten hinter der Aktion. Wenn prod-deploy in mehrere Netzwerkpfade oder Konten wechseln kann, hat die Konfiguration die Zuverlässigkeit der Genehmigung bereits geschwächt.
Bevor du einem Agenten die Verwendung eines SSH-Alias erlaubst, rendere ihn, prüfe jeden Jump-Host und teste die Varianten auf der Befehlszeile, die der Agent erzeugen kann. Wenn dich die effektive Verbindung auch nur einmal überrascht, gehe davon aus, dass sie jemanden im ungünstigsten Moment überraschen wird. Überarbeite den Alias, bis er wie eine Genehmigung klingt, die ein Mensch tatsächlich erteilen kann.
FAQ
Was bewirkt Match in einer SSH-Konfigurationsdatei?
Mit Match beginnt ein bedingter Abschnitt von ssh_config. Die darunterstehenden Einstellungen gelten nur, wenn die Bedingungen erfüllt sind. Geprüft werden können der eingegebene Hostname, der umgeschriebene Hostname, der Remote-Benutzer, der lokale Benutzer oder das Ergebnis eines Befehls. Behandle Match als Code, der eine Verbindung verändert, nicht als Kommentar, der eine Absicht beschreibt.
Wie sehe ich die effektive SSH-Konfiguration für einen Host?
Verwende ssh -G alias, um die aufgelösten Einstellungen für den gewünschten Alias auszugeben. Prüfe anschließend mindestens hostname, user, port, proxyjump, identityfile, identitiesonly und canonicalizehostname. Führe denselben Befehl mit -l user aus, wenn ein Agent oder Skript den Remote-Benutzer ausdrücklich auswählen kann.
Kann ein späterer Match-Block einen früheren Host-Block überschreiben?
In der Regel nicht. Für viele Einstellungen mit nur einem Wert verwendet OpenSSH den ersten gefundenen Wert. Ein früher, weit gefasster Block kann daher verhindern, dass ein späterer Match-Block User, ProxyJump oder Hostname ändert. Setze enge Ausnahmen vor allgemeine Standardwerte und prüfe das Ergebnis mit ssh -G.
Ist ein SSH-Host-Alias dasselbe wie der Zielhost?
Ein Host-Alias ist das an SSH übergebene Token, während HostName die Adresse angibt, zu der SSH tatsächlich verbindet. Ein harmlos wirkender Alias kann zu einer Produktionsadresse oder einem anderen Port führen oder über einen Bastion-Host geleitet werden. Bei Genehmigungen und Audits zählt das aufgelöste Ziel, nicht nur der Aliastext.
Verändert ProxyJump, wie SSH einen Server erreicht?
Mit ProxyJump verbindet sich SSH mit einem oder mehreren Jump-Hosts und leitet den Datenverkehr anschließend zum Ziel weiter. Die Einstellungen des Zielhosts gelten im Allgemeinen nicht für den Jump-Host, daher muss jeder Hop einzeln geprüft werden. Ein Jump-Host kann sowohl den Einsatz von Zugangsdaten als auch den Netzwerkpfad der Sitzung verändern.
Warum bietet SSH den falschen Schlüssel an?
IdentityFile bestimmt eine private Schlüsseldatei oder eine Referenz auf eine öffentliche Identität, die SSH anbieten kann. Mehrere Identitätsdateien können sich ansammeln. Ohne IdentitiesOnly yes bietet SSH möglicherweise zusätzlich Identitäten aus einem Agenten an. Für automatisierte Abläufe sollte jede Vertrauensgrenze eine bewusst festgelegte Identität erhalten, statt von den lokal geladenen Schlüsseln abzuhängen.
Kann CanonicalizeHostname das Verhalten von Match ändern?
Ja. CanonicalizeHostname yes kann einen kurzen Namen anhand konfigurierter Domains umschreiben und SSH anschließend die Konfiguration erneut einlesen lassen. always erweitert dieses Verhalten auf weitergeleitete Verbindungen. Dadurch können Host- oder Match-Regeln greifen, die auf den ursprünglichen Alias nicht zutrafen. Teste kurze und vollständige Hostnamen daher getrennt.
Was ist der Unterschied zwischen Match host und Match originalhost?
Match originalhost prüft den Namen, der auf der Befehlszeile übergeben wurde. Match host prüft das Ziel nach der Ersetzung durch HostName oder nach der Kanonisierung. Verwende originalhost, wenn eine Regel vom eingegebenen Alias abhängen soll, und host, wenn sie vom aufgelösten Ziel abhängen muss.
Ist es sicher, einen KI-Agenten meine bestehende SSH-Konfiguration verwenden zu lassen?
Nein. Ein SSH-Agent kann eine Konfigurationsdatei verwenden, deren Bedeutung vom lokalen Netzwerk, vom Benutzer auf der Befehlszeile, von kanonischen DNS-Namen, eingebundenen Dateien und früheren Einstellungen abhängt. Prüfe die gerenderte Konfiguration vor einer autonomen Ausführung und halte die Aliase so stabil, dass ein Mensch das beabsichtigte Ziel erkennen kann.
Wie prüfe ich eine SSH-Konfiguration, bevor ich sie einem Agenten übergebe?
Beginne für jeden Alias, den der Agent aufrufen darf, mit ssh -G und vergleiche die Ausgabe mit einem dokumentierten Verbindungsinventar. Entferne Wildcard-Standards, die privilegierte Benutzer oder Proxy-Routen auswählen, trenne Produktions-Aliase und setze Benutzer sowie Identitäten ausdrücklich. Wenn du eine effektive Verbindung nicht innerhalb einer Minute erklären kannst, übergib den Alias nicht an einen Agenten.