Solange es ein Schlüssel auf einer Maschine ist, verwaltet sich das von selbst. Interessant wird die Frage, sobald mehrere Personen, mehrere Geräte und Dienstkonten dazukommen und niemand mehr sicher sagen kann, wer eigentlich Zugang hat.
Ein vergessener Schlüssel ist ein dauerhaft offener Zugang ohne Ablaufdatum. Anders als ein Passwort läuft er nie ab, taucht in keiner Übersicht auf und überlebt jeden Personalwechsel, bis jemand aktiv hinsieht.
Die Grundregel: ein Schlüssel pro Gerät#
Nicht pro Person, sondern pro Gerät. Der Laptop hat einen, der Arbeitsrechner einen, das Telefon einen. Der Grund zeigt sich an dem Tag, an dem ein Gerät wegkommt: Dann entfernst du genau eine Zeile, statt alle Beteiligten zum Schlüsseltausch zu bewegen.
ssh-keygen -t ed25519 -C "mauri@laptop-2026"
ssh-keygen -t ed25519 -C "mauri@arbeitsrechner-2026"
Der Kommentar am Ende ist die einzige Dokumentation, die mit dem Schlüssel mitwandert. user@host ist wertlos; Name, Gerät und Jahr sind in zwei Jahren Gold wert.
Die Client-Konfiguration#
~/.ssh/config auf deinem Rechner spart Tipparbeit und verhindert ein Problem, das viele nicht kennen:
Host web01
HostName 203.0.113.10
User mauri
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host *
ServerAliveInterval 30
ServerAliveCountMax 3
HashKnownHosts yes
AddKeysToAgent yes
IdentitiesOnly yes ist die wichtige Zeile. Ohne sie bietet der Client dem Server der Reihe nach alle geladenen Schlüssel an. Bei MaxAuthTries 3 auf der Gegenseite ist die Verbindung abgelehnt, bevor der richtige Schlüssel an der Reihe war und der Fehler sieht aus wie „Schlüssel funktioniert nicht“.
Einschränkungen direkt am Schlüssel#
authorized_keys kann mehr als nur Schlüssel auflisten. Jede Zeile nimmt Optionen entgegen, die nur für diesen einen Schlüssel gelten:
restrict,command="/usr/local/bin/backup-pull" ssh-ed25519 AAAAC3Nz... backup@nas
restrict,from="10.99.0.0/24" ssh-ed25519 AAAAC3Nz... deploy@ci
restrict schaltet alle Weiterleitungen ab (Port, Agent, X11, TTY) und ist die richtige Grundhaltung für jeden Schlüssel, der genau eine Aufgabe hat. command= erzwingt einen festen Befehl, egal was der Client anfordert. from= bindet den Schlüssel an ein Quellnetz.
ssh -A reicht deinen Agenten auf den Zielserver durch. Wer dort root ist, kann darüber deine Schlüssel für weitere Verbindungen benutzen, solange die Sitzung offen ist. Auf Maschinen, die dir nicht allein gehören, ist ForwardAgent deshalb aus, für den Sprung auf eine dritte Maschine ist ProxyJump der sichere Weg.
Host intern-db
HostName 10.20.0.15
ProxyJump bastion
Mehr zum Aufbau eines solchen Zwischenwegs in Sprungserver: eine Tür statt zwanzig.
Unterschiedliche Regeln für unterschiedliche Konten#
Ein Deploy-Konto braucht andere Rechte als ein Mensch. Match erlaubt das, ohne einen zweiten SSH-Dienst zu betreiben:
# /etc/ssh/sshd_config.d/20-konten.conf — Match-Blöcke stehen immer am Ende
Match User deploy
ForceCommand /usr/local/bin/deploy-hook
PermitTTY no
AllowTcpForwarding no
X11Forwarding no
Alles nach einem Match gilt nur für diesen Fall, bis der nächste Match kommt. Eine allgemeine Einstellung, die versehentlich darunter rutscht, wirkt plötzlich nur noch für ein einziges Konto, ein Fehler, den sshd -T sichtbar macht, die Datei allein aber nicht.
Wer hat eigentlich Zugang?#
Die Frage, die man einmal im Quartal beantworten können sollte:
# Alle Konten mit hinterlegten Schlüsseln, samt Kommentar
sudo awk -F: '$3>=1000 || $1=="root" {print $1":"$6}' /etc/passwd | while IFS=: read -r u h; do
[ -f "$h/.ssh/authorized_keys" ] && \
awk -v u="$u" '!/^#/ && NF {print u" "$NF}' "$h/.ssh/authorized_keys"
done
Die Ausgabe ist die Liste, die man mit der Realität abgleicht. Alles, was man nicht zuordnen kann, kommt weg, im Zweifel zuerst, dann fragen.
Wenn ein Gerät wegkommt#
Der Ablauf sollte geübt und aufgeschrieben sein, nicht improvisiert:
# Auf jeder betroffenen Maschine, Kommentar als Suchmuster
sudo sed -i '/mauri@laptop-2026/d' /home/mauri/.ssh/authorized_keys
sudo sed -i '/mauri@laptop-2026/d' /root/.ssh/authorized_keys
# Bestehende Sitzungen dieses Schlüssels beenden
sudo ss -tp state established '( dport = :ssh or sport = :ssh )'
Der zweite Befehl wird gern vergessen: Ein Entzug in authorized_keys beendet keine laufende Verbindung. Wer wirklich aussperren will, beendet die Sitzung zusätzlich.
Bei mehr als einer Handvoll Maschinen lohnt es, authorized_keys aus einer Quelle zu verteilen, per Konfigurationsverwaltung oder über AuthorizedKeysCommand. Dann ist Entzug eine Änderung an einer Stelle statt einer Runde über alle Hosts.
Was das Zusammenspiel ergibt#
| Maßnahme | Wirkung |
|---|---|
| ein Schlüssel pro Gerät | Entzug betrifft ein Gerät, nicht alle |
| aussagekräftiger Kommentar | Zuordnung auch nach zwei Jahren |
restrict bei Dienstkonten | ein übernommenes Konto kann nichts weiterleiten |
IdentitiesOnly yes | keine Ablehnung durch zu viele Anbieteversuche |
ProxyJump statt -A | dein Agent bleibt auf deinem Rechner |
| quartalsweise Sichtung | keine Schlüssel ohne Besitzer |
Voraussetzung für alles: Der Passwort-Login ist aus. Falls noch nicht geschehen, steht das in Passwort-Login abschalten.
Geschrieben aus dem laufenden Betrieb: MRMedia betreibt eigene Hosts, Kundendienste und deren Härtung in der EU. Eine veraltete Anleitung ist hier ein Sicherheitsproblem, kein Schönheitsfehler. Korrekturen bitte über Discord.