sudo über SSH nutzen, ohne das Passwort preiszugeben

Verwenden Sie ssh -t user@server 'sudo command' und tippen Sie das Passwort an der Abfrage: SSH verschlüsselt es wie alles andere in der Sitzung. Verraten wird das Passwort, wenn Sie es in einen Befehl schreiben, denn ssh server 'echo pass | sudo -S command' zeigt es in der Prozessliste beider Rechner und kann in der Shell-History landen. Für Automatisierung nehmen Sie eine NOPASSWD-Regel für genau einen Befehl.

Sie möchten das sudo-Passwort nicht auf jedem Server tippen? Wardterm kann die Abfrage für Sie beantworten. Zeigen

Aktualisiert am . Ausgeführt mit sudo 1.9.16 und OpenSSH 10.0 unter Debian 13 in einem Wegwerf-Container, von einem OpenSSH-10.3-Client unter macOS.

Wird das sudo-Passwort im Klartext gesendet?

Nicht über das Netz. Alles in einer SSH-Sitzung ist verschlüsselt, auch was Sie an einer sudo-Abfrage tippen. Das Passwort wird auf dem Server entschlüsselt, wie es sein muss, damit sudo es prüfen kann, ein kompromittierter Server kann es also abgreifen. Das ist ein Grund, dieses Passwort nirgendwo sonst wiederzuverwenden.

Der normale Weg: ssh -t

sudo braucht ein Terminal, um nach einem Passwort zu fragen, und ein Befehl aus der Ferne bekommt standardmäßig keines:

$ ssh user@server 'sudo whoami'
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required

Die Fehlermeldung schlägt -S vor, und hier gehen die Leute in die falsche Richtung. Die einfache Lösung ist -t, das ein Terminal anfordert:

ssh -t user@server 'sudo whoami'

Sie bekommen die normale Abfrage, nichts wird angezeigt und nichts landet in einer Befehlszeile.

Was bei sudo -S verraten wird

Dieses Muster sollten Sie vermeiden:

ssh user@server 'echo mypassword | sudo -S systemctl restart myapp'

Das Passwort ist jetzt Teil eines Befehls und taucht deshalb an drei Stellen auf:

  • In der Prozessliste auf dem Server. Während der Befehl lief, sah ein anderes unprivilegiertes Konto auf dem Testserver mit einfachem ps dies: user bash -c echo mypassword | sudo -S -p "" sleep 3.
  • In der Prozessliste auf Ihrem Rechner. Der ganze Text ist ein Argument von ssh, daher zeigt ps ihn auch dort.
  • In Ihrer lokalen Shell-History, wenn Sie ihn getippt haben, und in jedem Skript oder CI-Log, das ihn enthält.

Wenn Sie sudo wirklich aus einem Skript füttern müssen

Lesen Sie das Passwort ohne Anzeige ein und senden Sie es über die Standardeingabe, damit es nie zum Argument wird:

read -rs SUDO_PW
printf '%s\n' "$SUDO_PW" | ssh user@server 'sudo -S -p "" whoami'
unset SUDO_PW

printf ist ein Shell-Builtin und startet deshalb keinen Prozess, den ps zeigen kann. Im selben Test sah das andere Konto nur sudo -S -p sleep 3. -p "" entfernt die Abfrage aus der Ausgabe. sudo verwendet hier die Standardeingabe für das Passwort, der Befehl auf dem Server sollte also keine eigene Eingabe brauchen.

Für Automatisierung: NOPASSWD für genau einen Befehl

Ein Skript sollte gar kein Passwort halten. Erlauben Sie nur, was es braucht:

# /tmp/deploy.sudoers
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp, /usr/bin/journalctl -u myapp -n 100 --no-pager

Prüfen Sie die Datei vor der Installation, denn eine kaputte sudoers-Datei kann Sie von sudo aussperren:

sudo visudo -cf /tmp/deploy.sudoers
sudo install -m 0440 -o root -g root /tmp/deploy.sudoers /etc/sudoers.d/deploy
sudo visudo -c

Verwenden Sie sie dann mit -n, damit eine Abweichung sofort scheitert und nicht hängt, während sie auf ein Passwort wartet:

$ ssh deploy@server 'sudo -n /usr/bin/systemctl restart myapp'
$ ssh deploy@server 'sudo -n /usr/bin/systemctl stop myapp'
sudo: a password is required

Was ein Konto ausführen darf, zeigt sudo -l. Vier Fallen:

  • Ein Befehl ohne Argumente in der Regel erlaubt beliebige Argumente. Mit nur /usr/bin/id in der Regel liefen in unserem Test sowohl sudo -n /usr/bin/id als auch sudo -n /usr/bin/id -u. Schreiben Sie die Argumente hin, die Sie meinen.
  • Dateinamen mit einem Punkt werden ignoriert. /etc/sudoers.d/deploy.conf hatte in unserem Test keine Wirkung, dieselbe Datei mit dem Namen deploy funktionierte.
  • Manche Befehle können eine Shell starten. Editoren, Pager, find -exec und tar können andere Programme als root ausführen, sodass die Erlaubnis für einen davon einer Erlaubnis für alles gleichkommen kann. Deshalb hat die Regel oben --no-pager: Ohne es kann journalctl einen Pager öffnen.
  • Platzhalter passen auch auf Leerzeichen. Das sudoers-Handbuch warnt, dass Platzhalter in Argumenten auf jedes Zeichen passen, auch auf Leerraum, sie können also mehr Argumente treffen, als Sie geplant haben.

Wie lange sudo sich an Sie erinnert

Standardmäßig fragt sudo 5 Minuten lang nicht erneut, und die Aufzeichnung gilt getrennt für jedes Terminal. Im Test führte eine ssh -t-Sitzung ein zweites sudo -n whoami ohne Abfrage aus. Um das vorzeitig zu beenden, führen Sie sudo -k aus. Damit für ein Konto jedes Mal gefragt wird, fügen Sie dies mit visudo hinzu:

Defaults:deploy timestamp_timeout=0

Eine offen gelassene Root-Shell ist der Ort der meisten Fehlgriffe. Siehe Fehler auf Produktionsservern vermeiden.

sudo -A und askpass

Mit -A führt sudo das in SUDO_ASKPASS genannte Programm aus und liest das Passwort aus dessen Ausgabe:

SUDO_ASKPASS=$HOME/bin/askpass sudo -A whoami

Das hält das Passwort aus der Prozessliste heraus, aber der Helfer muss es irgendwoher bekommen. Auf einem Server ohne grafische Sitzung bedeutet das meist eine Datei, wie in unserem Test, das Geheimnis liegt dann auf der Platte. Eine enge NOPASSWD-Regel ist normalerweise die bessere Antwort.

Ansible

Verwenden Sie --ask-become-pass (-K), um abgefragt zu werden, oder halten Sie ansible_become_password in einer mit Ansible Vault verschlüsselten Datei. Übergeben Sie es nicht mit -e auf der Befehlszeile, denn das legt es wie jedes andere Argument in die Prozessliste und Ihre History.

Eine NOPASSWD-Regel für einige Befehle funktioniert mit Ansible nicht. Laut Dokumentation lässt sich die Rechteerweiterung nicht auf bestimmte Befehle beschränken, weil Module aus einer temporären Datei laufen, deren Name sich jedes Mal ändert. Sie empfiehlt, ein getrenntes Konto ohne diese Einschränkung zu verwenden.

Fragen

Wird das sudo-Passwort über SSH im Klartext gesendet?

Nein. Alles in einer SSH-Sitzung ist verschlüsselt, auch was Sie an der sudo-Abfrage tippen. Entschlüsselt wird es auf dem Server, der es prüfen muss.

Warum meldet ssh, dass ein Terminal zum Lesen des Passworts nötig ist?

Ein entfernter Befehl bekommt standardmäßig kein Terminal, sudo braucht aber eins für die Passwortabfrage. Ergänzen Sie -t, etwa ssh -t user@server 'sudo command'.

Ist NOPASSWD für Skripte sicher?

Sicherer als ein gespeichertes Passwort, wenn die Regel genau einen Befehl mit seinen Argumenten nennt. Meiden Sie Editoren, Pager und andere Programme, die eine Shell starten können.

Quellen

Mehr zu Server absichern

Alle Anleitungen