SSH key Management mit AuthorizedKeysCommand

Um ein zentralisiertes Echtzeit-Schlüsselmanagement für SSH zu realisieren, kann man entweder anfangen, Public Keys mit management Tools durch die Gegend zu schieben. Immer wenn ein neuer Benutzer Zugriff auf einen Host bekommen soll, würde ein Script den entsprechenden Public Key auf den jeweiligen Host kopieren. Würde man den Zugang wieder entziehen wollen, löschte man das File wieder. Diese Methode hätte, trotz der einfachen Umsetzung, offensichtliche Nachteile: Bei einer großen Anzahl von Hosts, müsste man ganz schön viele Schlüssel durch die Gegend schubsen und hätte anschließend wenig Wissen darüber, welche Schlüssel tatsächlich zum Einsatz kamen.

Zum Glück hat OpenSSH vor einiger Zeit einen interessanten Befehl nachgerüstet:

AuthorizedKeysCommand
Specifies a program to be used to look up the user’s public keys. […] Arguments to AuthorizedKeysCommand accept the tokens described in the TOKENS section. If no arguments are specified then the username of the target user is used.
The program should produce on standard output zero or more lines of authorized_keys output. If a key supplied by AuthorizedKeysCommand does not successfully authenticate and authorize the user then public key authentication continues using the usual AuthorizedKeysFile files.

Für jeden Authentifizierungsversuch wird ein Script ausgeführt, welches anhand des übergebenen Benutzernamens einen öffentlichen Schlüssel auf die Standardausgabe schreibt — oder eben nicht.

Ein Beispiel: /etc/ssh/get_remote_key.sh

#!/bin/sh
curl -s https://example.com/keys/$1 2>&1

Die Ausführbarkeit des Scripts muss nun ausschließlich auf root beschränkt werden:

chown root:root /etc/ssh/get_remote_key.sh
chmod 0700 /etc/ssh/get_remote_key.sh

Zuletzt noch das Feature in der SSH-Konfiguration aktivieren:

[...]
PubkeyAuthentication    yes
AuthorizedKeysCommand   /etc/sshd/get_remote_key.sh

Damit User nach dem erfolgreichen login, nicht zusätzliche Keys in ihrem user account hinterlassen und das Script umgehen, sollte noch folgende Option geändert werden:

AuthorizedKeysFile      /etc/ssh/authorized_keys

Und damit man den Root-Zugriff nicht verliert, sollte dort noch der public key des root users abgelegt werden.

Natürlich lassen sich, außer der Auflösung des Schlüssels, noch viele weitere Kriterien und Mechanismen realisieren. Auch kann das Script noch zusätzliche Metadaten des Hosts, wie IP, Hostnamen, etc., übergeben. Mit einer entsprechend potenten Gegenstelle, wie einer Web-Applikation, lässt sich ein recht mächtiges, zentralisiertes Zugangsmanagement realisieren.