Zentrale Schlüsselverwaltung für ssh

von Markus Berger am Montag, 30. Oktober 2023

Einleitung

Wenn man mehr als einen Server und mehrere Nutzer hat, die evtl. auch noch nur eingeschränkt auch die verteilten Dienste zugreifen dürfen, ist die manuelle Schlüsselverwaltung aufwendig. Hier bietet sich eich zentraler Server mit allen Schlüsseln incl. deren Konfiguration z.B. command an.

Um diese Schlüssel nutzen zu können bietet der sshd die Möglichkeit den Nutzerschlüssel per Anwendung zu erhalten AuthorizedKeysCommand.

Server-Baum

Am einfachsten ist es wenn man einen Dienst hat auf den alle Server zugreifen können, z.B. die eigene Webseite. Damit die Konfiguration wie auch die Server und die Nutzer nicht enthüllt werden werden wir hier mit den Hashwerten und asynchron verschlüsselten Dateien arbeiten. Der Dateibaum auf dem Server ist im Klartext wie folgt:

keys/
├── user1
│   ├── host1
│   └── host2
├── user2
│   └── host2
└── user3
    ├── host1
    └── host3

nur das statt der Klarnamen die Hash-Werte verwendet werden.

Schlüsseldaten für den Server

Da die Dateien mit den öffentlichen Nutzerschlüsseln evtl. auch die Namen und andre Daten enthalten, die andere nicht angehen, ist es sinnvoll diese zu verschlüsseln. Hier biete sich age an. Zuerst wird ein neues Schlüsselpaar mit age-keygen -o /etc/ssh/key.txt && chown nobody /etc/ssh/key.txt erzeugt.

Mit dem so erzeugten Public-Key kann der Inhalt, z.B. der ursprünglichen Nutzer "authorized_keys"-Datei, mit:

#!/bin/sh

if [ $# -eq 1 ]; then
    grep public /etc/ssh/key.txt | awk -F': ' '{print $2}' > /tmp/pub_key
    UK=$1
    U=$(echo user1 | sha256sum | awk '{print $1}')
    H=$(echo hostname | sha256sum | awk '{print $1}')
    mkdir -p keys/$U
    cat $UK | age -a -R /tmp/pub_key > keys/$U/$H
else
    echo $0 user_keys_file
    exit 1
fi

für den zentral Server erzeugt werden.

Diese müssen dann noch in den passenden Serverordner kopiert oder synchronisiert werden.

Script zum holen der Schlüssel

Die Script wird mit Nutzername des sich anmeldenden von sshd aufgerufen, zusätzlich fragen wir noch den Hostnamen ab. In der sshd_config ist folgendes einzutragen:

AuthorizedKeysCommand /usr/local/bin/get_key %u
AuthorizedKeysCommandUser nobody

und der Dienst ist nach der Änderung neu zu starten.

Das ausführbare Script selbst ist recht einfach:

#!/bin/sh

H=$(hostname | sha256sum | awk '{print $1}')
U=$(echo $1 | sha256sum | awk '{print $1}')
logger "get central key for: $1"
curl -sf https://my_website.host/keys/$U/$H | age -d -i /etc/ssh/key.txt || echo "$U/$H"

So kann man es auch in der Shell aufrufen und testen.

Zusammenfassung

Mit dem hier gezeigten lassen sich die Berechtigungen für verschiedene Nutzer und Server zentral und sicher Verwalten und es werden keine weiteren Informationen preisgegeben, denn nur der Besitzer des privaten Schlüssels ist in der Lage die Schlüsselinformationen der Nutzer zu lesen.

Alle Scripte sind auch in 1 zu finden.