MFA über SSH auf Arch/Manjaro

Heute habe ich meinen Jumpserver neu aufgesetzt. Das ist eine kleine VM auf meinem Homeserver der mit einem Bein in meinem internen Netzwerk, mit dem anderen Bein im Internet steht. Über den Jumpserver komme ich von außen auf alle Maschinen in meinem internen Netzwerk, und von meinem internen Netzwerk auf alle Maschinen im Internet, die ich betreue.
Das ganze ist kein Proxy, sondern eigentlich nur ein SSH-Jumphost… Bei dem ein Wireguard-VPN ins Rechenzentrum läuft. Ohne Wireguard, keine SSH Verbindung zu den Maschinen. (Und kein Zugang zum Firewall-UI… und zur Management-Konsole… und so ziemlich zu nichts administrativen…)

Wie dem auch sei. Mein alter Jumphost lief auf einem Debian dass ich seit Version 4 oder 5 immer nur wieder aktualisiert habe. In der letzten Zeit gab es da so ein paar Problemchen, weswegen ich den Jumpserver neu aufsetzen wollte. Diesmal aber mit einem Arch Linux als Unterbau.

Die Grundinstallation von Arch möchte ich hier nicht breit treten, denn dafür gibt es eine ganze Reihe von Anleitungen, inklusive der im Arch-Wiki. Einzig eine Netzwerkverbindung nach der Installation und das automatische Verbinden beim Systemstart hat mich ein bisschen beschäftigt.

Was mich mehr interessiert hat, war der Login via SSH. Ich wollte neben Fail2ban eine Multi-Faktor-Authentifizierung (MFA) haben. Was eine MFA ist, ist recht schnell erklärt. Es gibt mehrere Faktoren um einen Login zu ermöglichen:

  • Etwas das man weiß (Wissen)
  • Etwas das man ist (Idendität)
  • Etwas das man hat (Besitz)
  • (neue Definition) Standort

Man spricht von „Multi-Faktor“ sobald zwei oder mehr dieser Merkmale bei einem Login abgefragt und geprüft werden. Da ich den Standort wechsle, manchmal mit meinem Smartphone oder Laptop von unterwegs, manchmal von meinem Homerechner aus mich auf meinem Jumpserver einlogge ist der Ort als Verifikation unbrauchbar. Sollte man denken, aber der Ort wird später noch wichtig. Was ich wollte war „Wissen“ und „Besitz“ – also eine klassische „Zwei-Faktor-Authentifizierung“ (2FA). Also einen Usernamen und Passwort (Wissen) und einen Token (Besitz). Aber ich bin faul. EXTREM faul. Ich bin so faul dass ich keine Lust habe, jedesmal bei einem Login mein Smartphone herauszuholen und einen sechsstelligen TOTP-Key abzutippen. (TOTP = Timebased One Time Password). Darum habe ich einen Yubikey. Den will ich verwenden. (Anmerkung, Mein Yubikey ist auf „Yubikey-OTP“ konfiguriert)

Aber was wenn ich den mal vergesse oder verliere? Ok. Als backup will ich dann eben doch TOTP. Zum Glück ist das Linux. Da sollte das möglich sein.

Zuerst installiere ich mein ARCH base System. Das geht recht schnell und mein System läuft. Anschließend installiere ich noch einige System-tools wie den Midnight Commander und diverse Packprogramme. Auch die dnsutils, net-tools und natürlich yay dürfen nicht fehlen. Yay ist der Paketmanager für AUR (Arch User Repository). Anschließend installiere ich die Bibliotheken für den Yubikey und den TOTP-Mechanismus.

yay -Syyu
yay -S yubico-pam google-authenticator-libpam-git

Danach muss ich zuerst mein PAM (Pluggable Authentication Modules) und die SSH-Demon config ein bisschen tweaken. Am einfachsten ist hier die SSH-Config. Da ich hier ohnehin noch einige Feineinstellungen machen wollte fange ich hier an. Doch zuerst öffne ich eine kleine SSH-Sitzung welche ich aktiv lasse und minimiere. Sollte ich einen Fehler machen und mich nicht mehr einloggen können, ist das mein Backup. Für MFA benötige ich hier eigentlich nur die fett markierte Zeile. Der Rest ist allgemeines „Feintuning“:

Port 22
HostKey /etc/ssh/ssh_host_ed25519_key
PermitRootLogin no
MaxAuthTries 3
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication yes
PermitEmptyPasswords no
UsePAM yes
AllowAgentForwarding yes
AllowTcpForwarding yes
X11Forwarding no
TCPKeepAlive yes
ClientAliveInterval 300
ClientAliveCountMax 2
ChallengeResponseAuthentication yes
Banner /etc/ssh/bannet.txt
Subsystem sftp /usr/lib/ssh/sftp-server
AllowUsers arsimael

Nach einem „systemctl restart sshd“ sind die änderungen aktiv. Nun muss ich meine PAM Regeln bearbeiten. Da ich nur die SSH-Verbindungen absichern möchte, bearbeite ich hierzu die /etc/pam.d/sshd:

So sieht die Datei im Originalzustand aus.
Ich füge folgende Zeile am Ende hinzu:

auth [new_authtok_reqd=ok default=ignore] pam_yubico.so id=16 nullok

Nun speichere ich ab. Ich muss meinen Yubikey als erlaubt hinterlegen. Dazu erstelle ich einen Ordner in meinem home -Verzeichnis mit dem namen „.yubico“ und lege dort eine Datei „authorized_yubikeys“ an und vergebe die entsprechenden Rechte:

mkdir .yubico
chmod 700 .yubico
touch .yubico/authorized_yubikeys
chmod 600 .yubico/authorized_yubikeys

Ich öffne die authorized_yubikeys Datei und stecke meinen Yubikey an. Ich drücke in paar mal den Button und sehe mir die erzeugten Passwörter an. Die ersten zwölf Zeichen sind immer dieselben. So wie es in der Yubikey-Doku beschrieben ist, lösche ich alles danach und weise diese Zeichenfolge meinem Benutzer zu:

Nach dem speichern versuche ich einen Login auf dem Jumpserver, und voilá:

Ich stecke meinen Yubikey ein, drücke den Button und der Login ist komplett. – DAS funktioniert also schonmal.

Aber was wenn ich meinen Yubikey verliere? Oder wenn dieser gestohlen wird? Ich möchte ein backup, eine Alternative zum Yubikey. Hier kommt mir TOTP in den Sinn. Zeitbasierte Einmal-passwörter. Wie man sie bei beinahe jedem gut eingerichtetem Webservice nutzen kann. „Wenn andere das können, kann ich das auch.“

Ich mache mich auf die Suche, und die einfachste Methode scheint hier wohl der „google-authentikator“ zu sein. Obwohl diese Library von Google ist, nimmt sie (angeblich) keine Verbindung zu Google-Servern auf, sondern stellt lediglich die Funktionen zur verfügung, welche ich nutzen möchte. Das authentifizieren via Einmal-kennwörter.

Die Installation habe ich oben schon erledigt. Die Integration in pam stellt laut offizieller doku auch kein Problem dar. Ich passe meine /etc/pam.d/sshd Direktiven ein weiteres mal an:

Da ich ZUERST nach meinem Yubikey gefragt werden möchte, und nur im Falle dass ich den Yubikey nicht habe nach dem TOTP Passwort gefragt werden möchte, passe ich die Yubikey direktive an und sage „Wenn der Yubikey eingegeben wurde, frage nicht weiter sondern erlaube den login“ (success=done).

Danach muss ich meinen TOTP einrichten. Das geht recht angenehm mittels dem Commandline Tool „google-authenticator“ (einfach als user den man einrichten möchte Ausführen)

Anschließend teste ich die neue Konfiguration und es funktioniert.

Tweaks/Tricks – oder „Wo der Standort eine Rolle spielt“:

Ich habe jetzt eine MFA Authentifizierung auf meinem Jumpserver. Aber ich habe oben schon erwähnt: Ich bin faul. Ich habe keine Lust jedesmal meinen Yubikey heraus zu suchen wenn ich ZUHAUSE (also in meinem eigenen, sicheren und vertrauensvollen Netzwerk) bin.

Das muss sich auch orgendwie regeln lassen. Und das geth auch. Ich lege eine neue Datei an: /etc/ssh/ssh-pamrules.conf und definiere mein eigenes Heimnetz als „erlaubt“:

Der Hierarchie nach:

  • ERLAUBE ALLES VON 10.0.0.0/8
  • ERLAUBE ALLES LOCAL
  • VERBIETE ALLE

Ich erlaube demnach Verbindungen aus meinem Heimnetzwerk und von local – also von meinem Server auf sich selbst, und verbiete den Rest.

Diese Regeln müssen pam nun noch mitgeteilt werden. Dazu modifiziere ich meine /etc/pam.d/sshd wie folgt:

Wichtig idt die Reihenfolge. Der gesamte obere part sorgt dafür dass ich regulär nach meinem Passwort gefragt werde. Danach prüft er ob ich mich in meinem eigenen Netzwerk befinde (Standort). Trifft diese Regel zu, darf ich mich einloggen (success), stimmt das nicht, muss ich entweder meinen Yubikey, oder meinen TOTP verwenden.

Selbstverständlich sollte trotzdem bei ALLEN Servern im Netz fail2ban installiert sein.

MFA über SSH auf Arch/Manjaro Weiterlesen