Yubikey Archives - credativ®

In den bisherigen Artikeln zu Yubico OTP haben wir Benutzerkonten und YubiKeys über ein sogenanntes authfile aufeinander abgebildet (Mapping). Dies ist beim Einsatz auf wenigen Systemen oder bei nur wenigen YubiKeys sicherlich ausreichend, stellt sich bei größeren Installationen jedoch schnell als zu wartungsintensiv heraus.

Das Yubico OTP PAM-Modul bietet daher die Möglichkeit die Public ID eines YubiKey als Attribut eines Benutzerobjektes in einem bei großen Installationen vermutlich ohnehin vorhandenen LDAP-Verzeichnisserver abzulegen und zum Mapping heranzuziehen.

Dieser Artikel zeigt als kleiner Exkurs anhand von OpenLDAP, wie ein solches LDAP-gestütztes Mapping eingerichtet werden kann. Ob dabei die YubiCloud oder ein selbst gehosteter Validierungs-Service zum Einsatz kommt spielt keine Rolle: beide Setups können um eine LDAP-Anbindung erweitert werden.

Download

Die für die Einrichtung benötigten Schema-Dateien werden wider Erwarten nicht zusammen mit dem Yubico PAM-Modul ausgeliefert. Yubico selbst verweist dazu auf das von Michael Ludvig entwickelte und auf Github zur Verfügung gestellte Projekt yubikey-ldap, welches Schema-Dateien für verschiedene LDAP-Server enthält.

Neben den Schema-Dateien enthält das Projekt außerdem das namensgebende Python-Script yubikey-ldap, mit dem Benutzerobjekten eine YubiKey ID hinzugefügt oder wieder von diesen entfernt werden kann. Das Script erlaubt außerdem die Auflistung aller Benutzer, denen eine YubiKey ID zugewiesen wurde. Das Script ist noch in Python 2 geschrieben und benötigt das Modul ldap, welches unter Debian mit dem Paket python-ldap nachinstalliert werden kann.

Ob das Projekt mit git geklont oder als ZIP-Archiv heruntergeladen und entpackt wird spielt letztlich keine Rolle. Hauptsache, die Dateien des Projekts befinden sich letzten Endes auf dem Rechner:

$ git clone https://github.com/mludvig/yubikey-ldap.git 

$ wget https://github.com/mludvig/yubikey-ldap/archive/refs/heads/master.zip
$ unzip master.zip

Installation

Die Dateien, welche für die Schema-Installation bei OpenLDAP benötigt werden, befinden sich im Unterordner ldap-schema. Die eigentliche Installationsschritt unterscheidet sich darin, ob die OpenLDAP-Installation bereits OLC (auch bekannt als cn=config) unterstützt.

Wird bereits OLC eingesetzt muss lediglich per ldapadd die Datei yubikey.ldif dem Verzeichnis hinzugefügt werden:

$ ldapadd -W -x -D cn=admin,dc=example,dc=org -f yubikey.ldif
adding new entry "cn=yubikey,cn=schema,cn=config"

Natürlich muss dem Argument -D der RootDN der lokalen Installation übergeben werden. Mit der Meldung adding new entry… ist die Installation bereits abgeschlossen und im Verzeichnis /etc/ldap/slapd.d/cn=config/cn=schema/ sollte sich nun eine Datei mit der Endung yubikey.ldif befinden.

Wird stattdessen die veraltete slapd.conf-Methode eingesetzt, muss die Datei yubikey.schema in den Ordner /etc/ldap/schema/ kopiert und der Konfigurationsdatei slapd.conf die folgende Zeile hinzugefügt werden:

include  /etc/ldap/schema/yubikey.schema

Nach einem Neustart des OpenLDAP-Servers steht das Schema dann zur Verfügung.

Konfiguration

Die im Folgenden beschriebene Konfiguration geht von einer bereits erfolgreichen Einrichtung basierend auf den vorangegangen Artikeln zum Thema 2FA und Yubico OTP aus. Dabei spielt es keine Rolle, ob das Setup zur Verifikation die YubiCloud nutzt oder die benötigten Dienste selbst gehostet werden.

PAM

Bei der Konfiguration des PAM-Moduls zur Benutzung eines LDAP-Verzeichnisdienstes entfällt naturgemäß der Parameter authfile, da dieses durch die LDAP-Anbindung ersetzt wird. Stattdessen kommen nun mehrere LDAP-Spezifische Parameter hinzu, welche gemäß der bestehenden LDAP-Installation angepasst werden müssen. Die im folgenden Listing benutzten Backslashes (\) dienen wie üblich dazu, die Parameter auf mehrere Zeilen verteilen zu können. Sie stehen stets als letztes Zeichen auf einer Zeile und müssen entfernt werden, wenn alle Parameter in einer Zeile geschrieben werden.

auth sufficient pam_yubico.so id=xxxxx key=xxxxxxxxxxxxxxxx urllist=http://localhost/wsapi/2.0/verify \
    ldap_uri=ldap://localhost ldapdn=ou=people,dc=example,dc=org ldap_bind_as_user ldap_cacertfile=/etc/ssl/ca.crt \
    ldap_filter=uid=%u user_attr=uid yubi_attr=yubiKeyId
account required pam_permit.so

Der Parameter ldap_uri gibt die für den Verbindungsaufbau zum LDAP-Server verwendete URI an, ldap_certificate das bei der TLS-Aushandlung verwendete CA-Zertifikat. Bei der Suche nach Benutzerobjekten sucht das Modul unterhalb von dem in ldapdn angegebenen Knoten nach Objekten, welche das in user_attr angegebene Attribut besitzen und schaut dort in dem gegebenenfalls vorhandenen mit yubi_attr angegebenen Attribut nach der ID des YubiKey.

LDAP

Um einem LDAP-Benutzer nun eine YubiKey ID zuweisen zu können, wird schlicht die Liste der objectClass-Attribute des Benutzerobjekts um die Klasse yubiKeyUser erweitert und ein neues Attribut yubiKeyId hinzugefügt, welches als Wert die Public ID des YubiKey erhält.

dn: uid=user,ou=people,dc=example,dc=org
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: yubiKeyUser
objectClass: top
cn: user
sn: user
gidNumber: 4711
homeDirectory: /home/user
uid: user
uidNumber: 4711
loginShell: /bin/bash
userPassword: user
yubiKeyId: credtivccccc

Dies kann mit jedem beliebigen Tool erledigt werden, welches das Bearbeiten von LDAP-Objekten erlaubt: sei es low-level mit ldapmodify oder ldapvi, etwas bequemer mit dem oben erwähnten yubikey-ldap oder gar grafisch mit dem JXplorer und dem Apache Directory Studio.

Fazit

Mit der Erweiterung der Benutzerobjekte ist die Einrichtung der LDAP-Anbindung abgeschlossen. Clientseitig ändert sich weder aus Benutzer- noch aus Admin-Sicht etwas. Statt des authfile wird nun das LDAP-Verzeichnis zum Mapping herangezogen.

Unterstützung

Falls Sie Unterstützung bei der Konfiguration oder dem Einsatz von Zwei-Faktor-Authentisierung wünschen, steht Ihnen unser Open Source Support Center gerne zur Verfügung – falls gewünscht auch 24 Stunden am Tag, an 365 Tagen im Jahr.

Im vorangegangenen Artikel Zwei-Faktor-Authentisierung mit Yubico OTP haben wir gezeigt, wie schnell man mit Hilfe des PAM-Moduls pam_yubico bestehende Dienste um eine Zwei-Faktor-Authentisierung (2FA) mit Yubico OTP erweitern kann. Der dabei genutzte Validierungs-Service, die YubiCloud, wird von Yubico kostenlos zur Verfügung gestellt.

Die Tatsache, dass man sich dabei an einen externen Dienstleister bindet, gefällt jedoch nicht jedem: Datenschutzbedenken oder Zweifel an der Ausfallsicherheit des Cloud-Services führen zur Frage, ob der Betrieb der benötigten Dienste nicht auch auf eigenen Systemen möglich ist. Auch mag es Szenarien geben, bei welchem man nicht auf externe Dienste nicht zugreifen kann.

Die erfreuliche Antwort ist, dass es auch die Möglichkeit gibt, die Dienste entsprechend selber zu hosten!

Komponenten

Um Yubico OTPs auf einem eigenen System validieren zu können, werden zwei Komponenten benötigt: der YubiKey OTP Validation Server und das YubiKey Key Storage Module. Yubico stellt die benötigte Software sowohl im Quelltext, als auch als fertige Binärpakete in verschiedenen Linux-Distributionen zur Verfügung.

Es ist zu beachten, dass ein Großteil der online verfügbaren Dokumentation noch auf dem alten Key Storage Modul, YK-KSM, basiert. Das YK-KSM ist in PHP5 implementiert und als veraltet anzusehen, denn es benötigt Funktionen und Bibliotheken, welche in aktuellen PHP-Versionen nicht mehr enthalten bzw. verfügbar sind.

Validation Server – VAL

Der Validation Server implementiert die Yubico WSAPI zur Validierung von Yubico OTP, welche auch in der YubiCloud zum Einsatz kommt. Es handelt sich dabei um eine PHP-Anwendung, die für den Betrieb neben dem Apache Webserver ein RDBMS wie PostgreSQL® oder MySQL benötigt.

Das in den vergangenen Artikeln behandelte PAM-Modul pam_yubico kann durch Angabe einer URL so konfiguriert werden, dass es statt der YubiCloud einen anderen, in unserem Falle lokalen, Validation Server nutzt.

Sendet ein Client, zum Beispiel das PAM-Modul, über die WSAP ein Yubico OTP an den Validierungsdienst, sendet dieser das OTP an das Key Storage Module weiter, und enthält das OTP entschlüsselt von dort zurück. Anhand der Zählerstände und Zeitstempel, welche mit den letzten, in der Datenbank gespeicherten Werten verglichen werden, kann der VAL dann entscheiden, ob das OTP gültig ist oder nicht.

Key Storage Modul – KSM

Das Key Storage Module dient der sicheren Aufbewahrung der Shared Secrets der verwendeten YubiKeys. Der für die Verschlüsselung verwendete Schlüssel wird dafür entweder auf einem gut 650,– € teuren Hardware-Modul oder aber – wie in diesem Falle – preisgünstig in einer Textdatei gespeichert. Im Gegensatz zum VAL benötigt das KSM keine relationale Datenbank, sondern nutzt stattdessen das Dateisytem, standardmäßig den Ordner /var/cache/yubikey-ksm, und legt dort die Shared Secrets verschlüsselt in sogenannten AEAD-Dateien ab.

Das hier verwendete KSM ist in Python implementiert und läuft als eigenständiger Dienst, welcher standardmäßig auf Port 8002 TCP auf Verbindungen von localhost lauscht und dort ein simples REST-Interface anbietet.

Über dieses REST-Interface kann der Validation Server zu überprüfende OTP an das Key Storage Module senden, welches dann anhand der Public ID das entsprechende Shared Secret aus seinem Speicher ausliest, um damit das OTP zu entschlüsseln und dessen Inhalt an den VAL zurückzuliefern.

Installation

Erfreulicherweise existieren sowohl für den Validierungs-Server als auch für das Key Storage Modul fertige Pakete in den meisten Linux-Distributionen. Im Folgenden wird die Installation und Konfiguration der Dienste unter Debian GNU/Linux Buster beschrieben.

Key Storage Modul – KSM

Das KSM kann in Debian einfach mit dem Paket yhsm−yubikey−ksm installiert werden:

# apt-get install yhsm−yubikey−ksm

Bevor es an die Konfiguration des frisch installierten Dienstes geht, muss noch das sogenannte Keyfile, welches den für die Verschlüsselung des Key Storage verwendeten Schlüssel enthält, angelegt werden:

# mkdir -p /etc/yubico/yhsm
# touch /etc/yubico/yhsm/keys.json
# chown yhsm−ksmsrv /etc/yubico/yhsm/keys.json
# chmod 400 /etc/yubico/yhsm/keys.json

Das Keyfile kann nun mit einem beliebigen Editor geöffnet und mit einem Schlüssel gefüllt werden. Wie die Dateiendung andeutet handelt es ich bei dem Keyfile um eine JSON-Datei. Im folgenden Beispiel lautet der Schlüssel, welcher sich in “Slot” 1 befindet, 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f.

{
    "1": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}

Bei 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f handelt es sich um die hexadezimale Darstellung eines 32 Byte (also 256 Bit) langen Beispielschlüssels. Für den produktiven Einsatz sollte natürlich ein vernünftiger, aus Zufallsdaten erstellter Schlüssel benutzt werden. Hierfür kann das Programm openssl benutzt werden:

$ openssl rand -hex 32

Um das KSM zu konfigurieren, müssen in der Datei /etc/default/yhsm−yubikey−ksm nur wenige Parameter angepasst werden:

YHSM_KSM_ENABLE="true"
YHSM_KSM_DEVICE="/etc/yubico/yhsm/keys.json"
YHSM_KSM_KEYHANDLES="1"

Der Parameter YHSM_KSM_ENABLE="true" sorgt dafür, dass das KSM beim Systemstart automatisch gestartet wird. Dabei wird statt des standardmäßig konfigurierten Hardware-Devices das soeben erstellte Keyfile und daraus der Schlüssel mit der ID 1 verwendet.

Mit systemctl restart yhsm−yubikey−ksm wird das KSM zu guter Letzt mit der geänderten Konfiguration neu gestartet.

Validation Server – VAL

Wie bereits erwähnt handelt es sich beim Validation Server um eine in PHP geschriebene Webanwendung, deren Betrieb einen Webserver und ein RDBMS voraussetzt. Während die Paketabhängigkeiten einen Apache Webserver vorschreiben, hat man bei den Datenbanken die Wahl zwischen MySQL, MariaDB und PostgreSQL®. Gemäß der Abhängigkeitsreihenfolge des Pakets würde von apt hier MySQL installiert, um jedoch PostgreSQL® den Vorzug zu geben muss dieses explizit aufgeführt werden:

# apt-get install yubikey−val postgresql php−pgsql

Die in /etc/yubico/val/ befindliche Konfiguration des Validation Servers ist standardmäßig auf das lokal auf dem gleichen System laufende Key Storage Modul eingestellt, sodass keine weiteren Eingriffe notwendig sind.

Damit sich das PAM-Modul später bei Anfragen an den Validation Server authentifizieren kann, müssen noch Credentials in Form einer ID sowie eines Schlüssels erstellt werden:

# ykval−gen−clients
2,cOyFHRvltNYDjx74JE9jOBcdPhI=

Dieser Schritt entspricht der im vorausgegangenen Artikel beschriebenen Registrierung in der YubiCloud. Die Ausgabe des Kommandos besteht aus zwei Teilen: der ID, gefolgt von einem Komma und dem Schlüssel in Base64-Kodierung.

Soll der Validation Service von mehreren Maschinen aus genutzt werden, empfiehlt es sich für jede Maschine eigene Credentials zu erstellen. Um mehrere ID-Schlüssel-Paare erstellen zu lassen, wird ykval-gen-clients einfach mit der gewünschten Anzahl aufgerufen:

# ykval−gen−clients 5
3,6WP1q1ohy92G/BNLMNjpHpVeL1Q=
4,InVj6Nbqc9FQN1EgtbsedtuYT9I=
5,p/R/hHx6E3Kf3Qc+671O46laNec=
6,/FRX6YqioHSap+zoM+LkWp88TFU=
7,XxEp4zoHSi9zTDSngvxnGiD4V1A=

Um den Überblick nicht zu verlieren, sollte festgehalten werden, für welchen Rechner welche Credentials benutzt wurden. Alternativ erlaubt ykval-gen-clients mit dem Schalter --notes das Anlegen einer Notiz:

# ykval-gen-clients --notes=OpenVPN
8,rZKpqc5WcU4OB4Nv551+U3lj2tk=

Das Programm ykval-export-clients gibt alle in der Datenbank gespeicherten Credentials samt Notizen auf der Standardausgabe aus:

# ykval-export-clients
1,1,1619686861,ua//VH5rvFoxrFHGhLZBz/RO3m0=,,,
…
8,1,1619687606,pkodRX1F77Ck7bvS9MzpXE5IfxA=,,OpenVPN,

Hier ist zu erkennen, dass während der Installation des Pakets schon Credentials mit der ID 1 erstellt wurden. Selbstverständlich kann man, statt eine eigene ID anzulegen, auch diese aus der Datenbank auslesen und zur Einrichtung des PAM-Moduls benutzen.

PAM

Als letzte Änderung am System muss das PAM-Modul pam_yubico installiert und in die entsprechende Dienstkonfiguration eingetragen werden.

# apt-get install libpam−yubico

Wie auch schon in den vorherigen Artikeln soll auch hier wieder OpenVPN in den Genuss einer 2FA mit Yubico OTP kommen. Hierzu wird die Datei /etc/pam.d/openvpn angelegt bzw. angepasst:

auth sufficient pam_yubico.so id=2 key=cOyFHRvltNYDjx74JE9jOBcdPhI= urllist=http://localhost/wsapi/2.0/verify authfile=/etc/yubikey_mappings
account required pam_permit.so

Als Werte für id und key werden jeweils die Werte angegeben, welche beim obigen Aufruf von ykval-gen-clients bzw. ykval-export-clients ausgegeben wurden. Der Parameter urllist erhält die URL der WSAPI des Validierungsdienstes, der in diesem Fall auf dem gleichen Rechner läuft.

Wie auch beim Einsatz der YubiCloud muss auch diesmal wieder ein authfile angegeben werden – eine Datei, welche die Mappings von Benutzernamen auf Public IDs enthält. Diese wird später, nach der Erzeugung der Schlüssel, angelegt.

Die Konfiguration des OpenVPN-Dienstes erfolgt wie im Artikel Zwei-Faktor-Authentisierung für OpenSSH und OpenVPN beschrieben. Serverseitig muss dafür das mitgelieferte OpenVPN-PAM-Plugin in der Konfiguration geladen werden:

plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so openvpn

Clientseitig wird der bestehenden Konfiguration lediglich die Option auth-user-pass hinzugefügt, sodass der Benutzer beim Verbindungsaufbau nach Benutzernamen und Passwort (hier: OTP) gefragt wird.

Schlüsselverwaltung

Damit YubiKeys mit einem eigenen Validierungsdienst genutzt werden können, müssen diese mit einem neuen Schlüssel, dem Shared Secret, programmiert werden. Diese Schlüssel werden im KSM erstellt, aus diesem ausgelesen und dann auf den YubiKey geschrieben.

Da das werksseitig auf dem YubiKey programmierte Shared Secret nicht ausgelesen werden kann, ist dieses nicht für einen selbst gehosteten Validierungsdienst zu gebrauchen.

Erzeugung im KSM

Um eine Reihe von Schlüsseln im Key Storage Module zu erzeugen, wird der Befehl yhsm-generate-keys verwendet:

# yhsm-generate-keys -D /etc/yubico/yhsm/keys.json --key-handle 1 --start-public-id credtivccccc -c 10
output dir              : /var/cache/yubikey-ksm/aeads
keys to generate        : 10
key handles             : {1: '1'}
start public_id         : 13412510728192 (0xc32d7f00000)
YHSM device             : /etc/yubico/yhsm/keys.json

Generating 10 keys

Done

Der obige Befehl erstellt 10 (-c) Schlüssel, beginnend mit der ID credtivccccc (--start-public-id) und nutzt für die Verschlüsselung den Key mit der ID 1 (--key-handle), welcher in der Datei /etc/yubico/yhsm/keys.json (-D) gespeichert ist. Die Schlüssel werden wie oben beschrieben unter /var/cache/yubikey-ksm/aeads abgelegt.

Die Ausgabe gibt einen kurzen Überblick über die verwendeten Parameter, das schlichte Done zeigt die erfolgreiche Erstellung und Speicherung der Credentials an.

Vorsicht: wird der obige Befehl mehrfach aufgerufen, werden bereits existierende Schlüssel mit der gleichen ID ohne Rückfrage überschrieben!

Mit Hilfe des Befehls yhsm-decrypt-aead können die soeben erstellten Schlüssel nun aus dem KSM ausgelesen werden:

# yhsm-decrypt-aead --aes-key 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f --format yubikey-csv /var/cache/yubikey-ksm/aeads/
1,credtivccccf,47072c411963,1feff43b2d2b529c697d9db0849c9594,000000000000,,,,,,
2,credtivccccc,512a73c09e98,d6e07a6def46cee722be21b7c2f35aec,000000000000,,,,,,
3,credtivcccce,b491988426de,a72669341ab2a7d2acecec91c2fa0efb,000000000000,,,,,,
4,credtivcccci,fccc5e1dcfcf,b0b14a2454c6d2a54bd2351f09d19d6e,000000000000,,,,,,
5,credtivccccb,8a0b3916582f,a031f201920f6204a38b239836486bbf,000000000000,,,,,,
6,credtivccccj,b9dd85895291,e04d79d45ff80438c744f2a8deec4a15,000000000000,,,,,,
7,credtivccccg,a5213cab8e9c,f20acb5646de4282f21ef12b65c6a082,000000000000,,,,,,
8,credtivcccch,73e9c1fa06b9,4c9d121e432a2fbd14b4a5d96f3b9d8f,000000000000,,,,,,
9,credtivccccd,0695db026eb8,90779c79b363b7dbe54a9c3012e688e5,000000000000,,,,,,
10,credtivcccck,ddd42451acb3,f5803057ea519149041be830509b7b2a,000000000000,,,,,,

Als --aes-key wird hier der bei der Einrichtung des KSM erzeugte AES-Schlüssel angegeben; das Argument --format yubikey-csv sorgt dafür, dass die Credentials als Komma-separierte Werte statt im Rohformat ausgegeben werden. Als letztes Argument wird der Speicherort der AEAD im Dateisystem angegeben.

Programmieren des YubiKey

Eine Zeile in der obigen Ausgabe des Befehls yhsm-decrypt-aead enthält in mehreren, durch Kommata getrennten Feldern, die Credentials für einen YubiKey: neben der Seriennummer (Feld 1) sind das die Public ID (Feld 2), die Private ID (Feld 3) sowie der eigentliche AES-Schlüssel (Feld 4). Alle weiteren Felder finden in unserem Fall keine Anwendung.

Der Eintrag in Zeile 1 enthält also die Public ID credtivccccf mit der Private UID 47072c411963 und dem AES-Schlüssel 1feff43b2d2b529c697d9db0849c9594.

Diese Credentials können nun auf einen YubiKey geschrieben werden. Das Programm ykpersonalize ist ein mächtiges Kommandozeilentool zur Konfiguration von YubiKeys und befindet sich bei Debian im Paket yubikey-personalization.

Befindet sich in Slot 1 (-1) des Yubikey bereits eine Konfiguration, welche nicht überschrieben werden soll, kann mittels -2 stattdessen in Slot 2 geschrieben werden. Mit dem Aufruf ykpersonalize -x werden die Inhalte von Slot 1 und Slot 2 eines YubiKey getauscht.

Leider verwendet das Tool ykpersonalize andere Begriffe für die Bestandteile eines Credentials: so wird aus der Public ID der fixed part und aus der Private UID wird die uid. Folgender Aufruf schreibt die obigen Credentials in den Slot 1 eines eingesteckten YubiKeys.

$ ykpersonalize -1 -o fixed=credtivccccf -o uid=47072c411963 -a 1feff43b2d2b529c697d9db0849c9594
Firmware version 5.1.2 Touch level 1287 Program sequence 3

Configuration data to be written to key configuration 1:

fixed: m:credtivccccf
uid: 47072c411963
key: h:1feff43b2d2b529c697d9db0849c9594
acc_code: h:000000000000
ticket_flags: APPEND_CR
config_flags:
extended_flags:

Commit? (y/n) [n]:

Hierbei ist zu beachten, dass fixed part und uid als KV-Paar mittels -o übergeben werden, während der AES-Schlüssel direkt mittels -a übergeben wird.

Bei positiver Antwort auf die Abfrage Commit? wird die angezeigte Konfiguration auf den Yubikey geschrieben und dieser gibt von nun an bei Knopfdruck ein mit den neuen Credentials erstelltes Yubico OTP aus.

Möchte man mehrere YubiKeys programmieren, werden in weiteren Aufrufen von ykpersonalize einfach entsprechend das jeweils nächste der erzeugten Credentials benutzt. Alle verwendeten Befehle und Tools verwenden Dateien im CSV-Format oder benutzen stdin/stdout; wiederkehrende Abläufe lassen sich somit hervorragend durch ein Bash-Script oder ähnliches automatisieren.

Alternativ zu der hier beschriebenen Herangehensweise bietet das YubiKey Personalization Tool aus dem Paket yubikey-personalization-gui die Möglichkeit gleich mehrere YubiKeys hintereinander zu programmieren. Hierfür aktiviert man in der GUI unter Yubico OTP → Advanced die Option Program Multiple YubiKeys. Um die Credentials der so programmierten YubiKeys im KSM abzulegen, muss die nach der Programmierung zum Speichern angebotene Logdatei configuration_log_hmac.csv zunächst angepasst werden, bevor die darin enthaltenen Credentials mit dem Programm yhsm-import-keys in das KSM importiert werden können.

Laut Manpage erwartet yhsm-import-keys eine CSV-Datei mit folgendem Aufbau:

# ykksm 1
seqno, public id, private uid, AES key,,,,
…

Die Logdatei des YubiKey Personalization Tool enthält die Felder public id, private uid und AES key bereits in der richtigen Reihenfolge als Felder 4-6. Das folgende awk-Script log2ksm.awk extrahiert diese Felder aus der Datei, setzt ihre Zeilennummer als sequence number davor und gibt die Einträge nach dem obligatorischen Header # ykksm 1 Zeile für Zeile aus:

#!/usr/bin/awk -f

BEGIN {
    FS=","
    printf("# ykksm 1\n")
}

/^Yubico OTP/ {
    printf("%d,%s,%s,%s,,,,\n", NR, $4, $5, $6)
}

Der Aufruf, um die Datei configuration_log_hmac.csv umzuwandeln und das Ergebnis als yubikey_secrets.csv zu speichern lautet:

$ ./log2ksm.awk configuration_log_hmac.csv > yubikey_secrets.csv

Die erzeugte Datei kann dann auf den Rechner, auf der das KSM läuft, kopiert und deren Einträge mit folgendem Befehl in dieses importiert werden:

# yhsm-import-keys -D /etc/yubico/yhsm/keys.json --key-handle 1 < yubikey_secrets.csv
output dir              : /var/cache/yubikey-ksm/aeads
key handles             : {1: '1'}
YHSM device             : /etc/yubico/yhsm/keys.json


Done

Auch hier zeigt Done, dass die Credentials erfolgreich importiert wurden.

PAM

Damit PAM während der Authentisierung empfangene Public IDs auf Benutzerkonten abbilden (mappen) kann, muss noch das oben konfigurierte authfile unter /etc/yubikey_mappings angelegt werden. Dieses enthält pro Zeile einen Benutzernamen und dessen zugeteilte YubiKey IDs, getrennt durch Doppelpunkte. Soll der soeben erstellte YubiKey mit der Public ID credtivccccf vom Benutzer bob verwendet werden, muss das authfile folgende Zeile enthalten:

bob:credtivccccf

Mappings für weitere Benutzerkonten werden entsprechend in eigenen Zeilen konfiguriert.

Alternativ zum Einsatz eines authfile können die Mappings auch mithilfe eines LDAP-Verzeichnisdienstes vorgenommen werden. Dieser Variante wird sich ein separater Artikel widmen.

Demo

Wurden bis hierhin alle Schritte erfolgreich durchgeführt, fragt der OpenVPN-Client beim Verbindungsaufbau nach Benutzernamen und Passwort beziehungsweise dem OTP. Während der Benutzername nach wie vor von Hand eingegeben werden muss, reicht zur Eingabe des OTP ein Knopfdruck auf dem YubiKey, sodass die Verbindung hergestellt werden kann. Statt der einzelnen Zeichen des OTP werden auch hier diesmal lediglich Sterne angezeigt.

# openvpn client.conf
...
Enter Auth Username: bob
Enter Auth Password: ********************************************
...

Fazit

Die Installation und der Betrieb eines eigenen Validierungsdienstes und Key Storage Moduls ist recht komplex und mit einigem Aufwand verbunden. Die Interaktion der Komponenten untereinander ist schwer nachzuverfolgen (was die Fehlersuche erschwert), die verfügbaren Tools sind teils wenig intuitiv oder gar inkonsistent (was das Verständnis erschwert).

Wer den Aufwand jedoch nicht scheut und bereit ist sich tiefer mit der Thematik auseinanderzusetzen kann letztlich den vollen Komfort von Yubico OTP genießen und dabei trotzdem die Kontrolle über alle Komponenten behalten.

Unterstützung

Falls Sie Unterstützung bei der Konfiguration oder dem Einsatz von Zwei-Faktor-Authentisierung wünschen, steht Ihnen unser Open Source Support Center gerne zur Verfügung – falls gewünscht auch 24 Stunden am Tag, an 365 Tagen im Jahr.

Zeitbasierte Einmalpasswörter, sogenannte TOTP, finden mittlerweile eine weite Verbreitung. In früheren Artikeln haben wir bereits beschrieben, wie diese zur Absicherung von PAM-fähigen Diensten eingesetzt und bequem verteilt werden können.

Durch den Einsatz von Passwort-Managern oder Generator-Apps können jederzeit problemlos aktuelle TOTP erstellt werden. Diese werden dann per Copy & Paste oder von Hand beim Login eingegeben.

Die hierfür verwendeten Shared Secrets werden von der Anwendung in einem besonders abgesicherten Speicherbereich abgelegt, in dem diese vor dem Zugriff anderer Anwendungen geschützt sein sollen. Die meisten Anwendungen bieten ihren Benutzern jedoch die Möglichkeit den Speicherbereich auch im Nachhinein auszulesen – ein unbefugter Benutzer könnte so unbemerkt das Shared Secret erlangen.

Abhilfe versprechen USB-Sticks wie Nitrokeys oder Yubikeys als sicherer Ablageort für TOTP Secrets. Einmal auf dem Stick abgelegte Secrets können nicht mehr ausgelesen, sondern höchstens überschrieben werden. Einzig der in dem Stick befindliche Generator hat lesenden Zugriff auf den Speicherbereich, um ein TOTP erstellen zu können. Das erstellte TOTP wird von einer eigens hierfür vorgesehenen Anwendung über die USB-Schnittstelle angefordert und ausgelesen; per Copy & Paste können diese dann zur Authentisierung verwendet werden.

Yubikeys sind vielen vor allem dadurch bekannt, dass sie erzeugte Token auf Knopfdruck “wie von Geisterhand” in ein Formular eintragen können. Hierzu meldet sich der Yubikey beim Einstecken in einen USB-Port als Tastatur beim Rechner an. Wird der Knopf am Yubikey gedrückt, gibt dieser dann beispielsweise das angeforderte Token selbsttätig an der aktuellen Cursorposition ein.

Da ein Yubikey jedoch nicht über eine eingebaute Echtzeituhr verfügt, können TOTP, welche auf der aktuellen Uhrzeit basieren, nicht auf dem Stick selbst erzeugt und auf diese Art und Weise an das System übertragen werden. Die oben erwähnte Anwendung auf dem Rechner ist für die Erstellung von TOTP also unumgänglich.

Yubico OTP

Neben Speicherplätzen für TOTP-Secrets unterstützen Yubikeys jedoch auch das Verfahren “Yubico OTP”, eine offen dokumentierte Eigenentwicklung von Yubico, welche durch die Verwendung von Zeitstempeln und Zählern mit einem zeitbasierten Verfahren wie TOTP vergleichbar ist. Die Token können direkt auf dem Stick erzeugt und per Knopfdruck als Tastatureingabe an den Computer übertragen werden.

Im Gegensatz zu TOTP erfolgt die Überprüfung von Yubico OTP Token jedoch nicht direkt auf dem Rechner, an dem der Login stattfindet, sondern über einen Validation Service. Dieser Dienst wird von Yubico in seiner YubiCloud nach einmaliger Registrierung kostenfrei zur Verfügung gestellt, kann aber auch on premise selbst betrieben werden.

Auch bei Yubico OTP muss beiden Seiten ein Shared Secret bekannt sein. Der Validierungsdienst überprüft, ob die übermittelten Daten mit dem zur Seriennummer des Yubikey gehörigen Secret verschlüsselt wurden und diese Daten gültig sind.

Yubikeys sind bei der Auslieferung bereits mit einem der Yubico Cloud bekannten Shared Secret konfiguriert, sodass Admins, welche Yubicos cloudbasierte Validierung verwenden, lokal lediglich einem Benutzerkonto die Seriennummer des Yubikey zuweisen müssen.

Vorarbeiten

Wie für TOTP existiert auch für den Einsatz von Yubico OTP ein PAM-Modul, welches in den offiziellen Paketquellen vorhanden ist. Vor dem Einrichtung müssen jedoch noch einige Vorbereitungen getroffen werden.

Yubikey ID

Neue Yubikey sind werksseitig so programmiert, dass sie bei Tastendruck ein Yubico OTP ausgeben. Das hierfür verwendete Shared Secret ist Yubico bekannt, sodass Dienste wie YubiCloud die erzeugten OTP verifizieren können.

Ein Yubico OTP ist eine 44 Zeichen lange Zeichenkette, welche aus einem öffentlichen, 12 Zeichen langen Teil – der Yubikey ID, und einem verschlüsselten, 32 Zeichen langen Teil besteht. Der genaue Aufbau ist in der Entwicklerdokumentation beschrieben. Interessantes Detail: Durch die Verwendung von Modhex werden für Token nur Zeichen verwendet, welche auf den gängigsten Tastaturbelegungen (QWERTY, QWERTZ, AZERTY) an gleicher Stelle vorhanden sind, sodass die Eingabe unabhängig von der Belegung erfolgen kann.

Mittels der Yubikey ID kann der Yubikey später einem Benutzer zugeordnet werden. Werkseitig besteht diese ID aus der Zeichenkette cccccc sowie der Seriennummer des Yubikey in Modhex. Die Seriennummer des Yubikey befindet sich auf der Rückseite der Kontakte des USB-Anschlusses, kann aber auch einfach aus einem erzeugten Yubico OTP oder mithilfe der Yubikey Personalization GUI ab- bzw. ausgelesen werden.

Wurde die Konfiguration des Yubikey zwischenzeitlich verändert oder überschrieben, kann mit Hilfe der Yubikey Personalization GUI eine neue Konfiguration erzeugt und das Shared Secret an Yubico übermittelt werden.

Auf der Yubico Demo Website kann überprüft werden, ob eine Validierung der erzeugten OTP mittels der YubiCloud erfolgreich ist.

Registrierung

Um den Validierungs-Service YubiCloud für eigene Dienste nutzen zu können, ist eine vorherige Registrierung notwendig.

Unter https://upgrade.yubico.com/getapikey/ trägt man hierfür seine E-Mail-Adresse ein und bestätigt die Registrierung mit einem Yubikey OTP. Hierfür wird der Yubikey in einen USB-Port gesteckt, sodass dieser bei Knopfdruck das Feld Yubikey OTP ausfüllen kann.

Auf der folgenden Seite erhält man dann seine Client ID sowie den zugehörigen Secret key. Diese werden bei der Einrichtung des PAM-Moduls benötigt.

Einrichtung

Das Yubico PAM-Modul ist in den offiziellen Quellen der gängigen Distributionen enthalten und kann somit bequem aus diesen installiert werden. Unter Debian lautet der Paketname libpam-yubico.

Leider enthält das aktuelle Paket einen Bug, durch den PAM das Modul nicht finden kann. In der Logdatei /var/log/auth.log findet sich dann nach einer fehlgeschlagenen Authentisierung dann der folgende Eintrag:

PAM unable to dlopen(pam_yubico.so): /lib/x86_64-linux-gnu/security/pam_yubico.so: cannot open shared object file: No such file or directory

Obwohl PAM das Modul pam_yubico.so im Ordner /lib/x86_64-linux-gnu/security/ erwartet liegt es tatsächlich im Ordner /lib/security/. Das Problem kann durch das Anlegen eines symbolischen Links (Symlink) behoben werden:

# ln -s /lib/security/pam_yubico.so /lib/x86_64-linux-gnu/security/pam_yubico.so

PAM

Um das PAM-Modul zur Authentisierung nutzen zu können, müssen die Service-Definitionen der entsprechenden Dienste angepasst werden. Zur Vorgehensweise sei auf den früheren Artikel Zwei-Faktor-Authentisierung für OpenSSH und OpenVPN verwiesen.

Statt des Moduls pam_oath.so, muss in diesem Fall jedoch das Modul pam_yubico.so konfiguriert werden:

auth require pam_yubico.so id=00000 key=xxxxxxxxxxxxxxxxxxxxxxxxxxxx authfile=/etc/yubikey_mappings

Für die Parameter id und key werden hier die bei der Registrierung erhaltene Client ID respektive der Secret key eingetragen. Der Parameter authfile verweist auf eine noch zu erstellende Textdatei, welche Yubikey IDs auf Benutzerkonten abbildet.

Mapping

Um Yubikey IDs und Benutzerkonten aufeinander abbilden (mappen) zu können reicht in den meisten Fällen eine einfache Textdatei aus. Diese Datei enthält pro Zeile einen Benutzernamen und beliebig viele Yubikey IDs, getrennt durch Doppelpunkte.

Hat Alice den Yubikey mit der ID ccccccredtiv erhalten, lautet das entsprechende Mapping:

alice:ccccccredtiv

Diese Datei wird entsprechend der obigen Konfiguration des PAM-Moduls als /etc/yubikey_mappings gespeichert. Verbindet und authentifiziert sich ein Benutzer mit einem konfigurierten Dienst, validiert pam_yubico nicht nur das übermittelte OTP, sondern überprüft außerdem die Zugehörigkeit des Yubikeys zum entsprechenden Benutzernamen.

Ein solches Mapping kann bei einer größeren Anzahl von Benutzern auch bequem über ein LDAP-Verzeichnis erfolgen. Die entsprechenden Parameter finden sich in der Dokumentation, benötigte Schemata werden von Michael Ludvig zur Verfügung gestellt.

Betrieb eines eigenen Dienstes

Yubico bieten mit ihren vorprogrammierten Yubikeys und der YubiCloud eine schnelle und einfache Lösung bestehende Dienste um eine Zwei-Faktor-Authentisierung mit Yubico OTP zu erweitern. Wer jedoch nicht von einem externen Dienstleister abhängig sein oder vielleicht aus Datenschutz gründen seine Metadaten für sich behalten möchte, kann seinen eigenen Validierungs-Service betreiben.

Hierzu müssen zwei Dienste, ein Validation Server sowie ein Key Storage Module, eingerichtet werden.

Der Validation Server implementiert die Yubico API zur Validierung von Yubico OTP, welche auch in der YubiCloud zum Einsatz kommt. Das PAM-Modul pam_yubico kann durch Angabe einer URL so konfiguriert werden, dass es statt der YubiCloud einen anderen Validation Server nutzt.

Das Key Storage Module dient der sicheren Aufbewahrung der Shared Secrets der eingesetzten YubiKeys sowie der Entschlüsselung von OTP für eine Überprüfung durch den Validation Server.

Die Installation und Einrichtung dieser Dienste würden den Rahmen dieses grundlegenden Artikels deutlich sprengen. Dieser Thematik wird sich zeitnah ein gesonderter Artikel annehmen.

Unterstützung

Falls Sie Unterstützung bei der Konfiguration oder dem Einsatz von Zwei-Faktor-Authentisierung wünschen, steht Ihnen unser Open Source Support Center gerne zur Verfügung – falls gewünscht auch 24 Stunden am Tag, an 365 Tagen im Jahr.