ssh Zugang via Keycloak absichern

von Markus Berger am Montag, 27. Dezember 2021

Einleitung

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

Keycloak

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.

Server Setup

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.

Client Setup

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.

Betrieb