Für den sicheren ssh Zugang zu einem Server im Internet ist die Authentifizierung via PublicKey angeraten. Jeder User kann die berechtigten Schlüssel erst einmal selbst verwalten, womit es jedoch für den Admin schwer zu kontrollieren ist, wer hier Zugang hat. Zwar kann man dies durch eine zentrale Schlüssel-Verwaltung umgehen, muss dies dann aber für jeden Host separat pflegen.
Das hier vorgestellte Verfahren nutzt zusätzlich zum Schlüssel eine externe Web-Applikation, um einen weitern Faktor zu erzeugen. Dies Web-Applikation authentifiziert nun ihrerseits den User über Keycloak. Damit steht eine zentrale Quelle für die Authentifizierung verschiedener Dienste zur Verfügung. Die Quellen für Server und Client stehen unter
zur Verfügung
Das grundlegende Setup will ich hier nicht weiter erläutern.
Für die Web-App benötigen wir einen neuen Client mit der Rücksprungadresse der Web-App z.B. `https://my.c1r1-server.de/cr/kc/callback/*` und den Credentials. Diese sind für die Serverkonfiguration nötig.
Der Server `r1.py` sollte über eine TLS geschützte Verbindung mit einem gültigen Domain-Namen eingerichtet werden. Hier bietet sich z. B. `nginx` als proxy an.
location /cr { proxy_pass http://127.0.0.1:5000; proxy_read_timeout 90; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; proxy_http_version 1.1; }
Der Server selbst kann als normaler User betrieben werden. Dafür werden die Dateien `r1.py`, `static\*`, `telmplates\*` und `keycloak.json` benötigt. Da die Software in Python geschrieben ist, werden die Module `Flask`, `gevent` und `keycloak` benötigt.
In die Datei `keycloak.json` wird der Keycloak-Server, die Rücksprung-Adresse der Web-App, die Credentials und der Token für die Client Authentifizierung eingetragen.
{ "realm": "apps", "auth-server-url": "https://a-keycloak-server.org/auth", "resource": "ssh-c1r1-auth", "verify-token-audience": true, "callback_uri": "https://my.c1r1-server.de/cr/kc/callback", "ptoken": "the-client-token", "credentials": { "secret": "aaaaaaaaaaaaaaaaaaaaaaaaaaa" }, "confidential-port": 0, "policy-enforcer": {} }
Danach kann der Server gestartet werden und stellt seinen Dienst unter dem angegebenen Port bzw. unter der SubUrl `/cr` des Servers zur Verfügung.
Der Client ist hier der ssh-Server, auf den man sich einloggen möchte.
Die Quellen gibt es wieder unter
. Nach dem Übersetzen des Clients `c1` wird dieser mit der Konfiguration in das passende Verzeichnis kopiert und die Konfiguration angepasst.
Hier muss der bei Server-Konfiguration verwendete Token und die Adresse der Web-App angegeben werden.
Nun wird die Datei `/etc/pam.d/sshd` um folgende Zeile erweitert:
auth sufficient pam_exec.so expose_authtok seteuid quiet stdout /etc/c1s1/c1
Für die User, die sich so anmelden sollen, wird kein Passwort vergeben und ihr public-key wird in die Datei `.ssh/authorized_keys` eingetragen. Zusätzlich wird die sshd Konfiguration um einen Mach-Block für den User erweitert.
ChallengeResponseAuthentication yes Match User username1 PasswordAuthentication yes AuthenticationMethods publickey,keyboard-interactive
Dem Server selbst wird die Challenge Response Authentifizierung erlaubt.