ssh Zugang via totp absichern

von Markus Berger am Samstag, 27. Februar 2021

Einleitung

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. Auch die Vartiante mit dem totp-pam Modul erfordert dies.

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 insert topt/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.