Für den sicheren ssh Zugang zu einem Server im Internet ist die Authentifizierung via PublicKey empfehlenswert. Was aber, wenn man nicht nur selbst Zugang benötigt, sondern auch anderen diesen gewähren muss?

Mann könnte dafür auch mehrere Authentifizierungsmethoden in Reihe schalten mit "AuthenticationMethods publickey,keyboard-interactive" in der "/etc/ssh/sshd_config", was aber bedeutet, dass man das UserPassword teilen muss.

Lösung

Die publickey Authentifizierungsmethode bietet die Möglichkeit jedem Schlüssel weitere Optionen mitzugeben. Auch kann angegeben werden, welches Programm auszuführen ist. Hier kann z.B. ein Wrapper stehen, welcher zuerst nach erfolgreicher Prüfung eine Shell öffnet. Wenn dieses Programm nun zuerst ein z.B. zeitabhängigens Einmalpasswort prüft und dieser abhängig vom Schlüssel ist, muss kein Geheimnis mehr geteilt werden.

Client Setup

Auf der Client-Seite benötigen wir eine Anwendung, welche aus dem Server-Geheimnis einen zeitabhängiges Einmalpasswort berechnet. Unter einem Linux-System ist dies das Program "oathtool". Für aktuelle Mobilgeräte gibt es dafür Apps, die dies ermöglichen.

Um eine sichere Speicherung unter Linux zu ermöglichen, bietet sich das Programm "pass" an, was auf "gnupg" aufbaut. Ein

pass generate totp/servise/user

sichert das Geheimnis. Um das Einmalpasswort zu erhalten, reicht dann ein

watch -n 10 "oathtool --totp -b $(pass totp/service/user)"

aus.

Server Setup

Um das Geheimnis zu erzeugen, verwenden wir "google-authenticator" aus dem Paket "google-authenticator-libpam". Dieses speichert die Einstellungen in "$HOME\.google-authenticator". Weiterhin benötigen wir noch "oathtool" aus dem Paket "oath-toolkit" und ein Shell-Script.

Zuerst erzeugen wir das Geheimnis und verschieben dann die Datei z.B. nach "$HOME/.key1". Das Geheimnis, welches sich in die erste Zeile befindet, bzw. der erzeugte QR-Code oder die gesamte Ausgabe muss nun zu dem Client transferiert werden.

Dann muss das Script:

#!/bin/sh

SK=$1
if [ -x /bin/bash ]; then
    S=/bin/bash
else
    S=/bin/sh
fi
if [ -f $HOME/.$SK ]; then
    echo -n "key: "
    read key
    keyl=$(oathtool --totp -b $(head -1 $HOME/.$SK))
    if [ $key = $keyl ]; then
        exec $S -il
    else
        echo "auth failed"
        exit 1
    fi
else
    echo "secret not found"
    exit 2
fi

nach "/usr/local/bin/bashWc" kopiert und ausführbar gemacht werden.

Der Zugangsschlüssel welcher nun zusätzlich mit dem TOTP Passwort geschützt werden soll, wird durch bearbeiten der Datei "~/.ssh/authorized_keys" durch folgenden Eintrag am Anfang der Zeile ergänzt (bis zu ssh-rsa):

command="/usr/local/bin/bashWc key1" ssh-rsa AAA...

Nun wird bei jedem Anmelden mit diesem Schlüssel zusätzlich nach dem aktuell gültigen Einmalpasswort gefragt.

Verbesserungen

Das Script erlaubt im Moment nicht das per ssh übergebene Kommandos ausgeführt werden, was aber für diesen Zugang auch evtl. nicht nötig ist. Durch eine Scriptanpassung ist dies aber möglich.

Bemerkung

Gegen Vandalismus hilft dies natürlich nicht, denn nach erfolgreichen Login, kann der angemeldete natürlich auch Anpassungen vornehmen. Wenn dies ein Problem ist, sollte z.B. eine zentral gesteuerte Authentifizierung in Betracht gezogen werden.

Schlüsseldatei unter admin Kontrolle

Um ein manipulieren der ssh Authentifierungsdatei durch den User zu unterbinden, kann diese durch anpassen der Datei "/etc/ssh/sshd_config" aus dem User-Verzeichnis in ein zentrales Verzeichnis verlegt werden.

AuthorizedKeysFile /etc/ssh/authorized_keys/%u

damit steht für jeden User weiterhin eine eigene Datei zur Verfügung, welche nun aber z.B. root gehört. Hier sind die Rechte auf 644 zu setzen.

Mit diesen Setup kann die Datei aber auch weiterhin dem entsprehenden User gehören, womit er diese dann auch selbst abpassen kann.

totp-pam