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 1 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 1.
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.