Anleitungen

Verschiedenste Anleitungen für Linux, Fediverse

Voice/Video-Calls mittels #WebRTC sind ja eine wunderbare Sache. Und oft funktioniert das ja “out-of-the-box”. Meine Kollegen erzählten mir, dass sie in der #Matrix-Config (/etc/matrix-synapse/homeserver.yaml) keinerlei stun/turn-Server konfiguriert haben und “keine Probleme bisher feststellten”.

Dann bat ich sie, mich anzurufen. Und es ging nicht. Ein anderes Mal ging es, dann wieder nicht. Also nix was man stabil oder verlässliche Verbindung nennen kann...

Da ich voraussichtlich die ehrenvolle Aufgabe bekommen werde, einen #POC für einen sehr großen Nutzerkreis bei mir in der Arbeit für einen Matrix-Server aufzubauen, hat mich das natürlich schwerst gewurmt, dass ich keine stabile und verlässliche Verbindung für Voice/Video-Calls auf meinem privaten Matrix-Server hinbekomme. Denn Voice/Video-Calls sind eine essentielle Anforderung für den POC bei mir in der Arbeit.

Ich hab mir dazu bei mehreren Matrix-Servern diverse Testaccounts zugelegt und alle verschiedenen Kombinationen (#Element, #Schildichat, #Nheko, #Android-App, Linux-App, auf den zwei Mobiltelefonen und am #Linux-Laptop, mit allen Accounts) durchgespielt.

Es zeigte sich immer wieder das selbe Phänomen. Von einem Client im Drei-Netz zu einem Client im A1-Netz blieb ein Voice/Video-Call immer bei “Verbindungsaufbau” hängen und brach dann ab.

Schließlich kam mir adminforge.de in die Quere. Die betreiben auch zwei STUN-Server. Mit der Erklärung, dass für die vollumfängliche Detektion welche NAT zum Einsatz kommen, zwei verschiedene #STUN-Server konfiguriert sein müssen. Ich hab das zwar schon gelesen... aber bislang nicht berücksichtigt.

STUN/TURN(S)

Ich betreibe einen eigenen coturn, der für #TURN auf Port 443 und für STUN auf Port 3478 lauscht. Ich dachte, das wird schon reichen, da es ja in vielen Fällen auch klappt.

Diesen STUN/TURN-Server verwende ich übrigens auch für meinen eigenen #PairDrop Server. Der ebenso relativ unzuverlässig die Verbindung zwischen besagten Clients in den A1- und Drei-Netzen herstellt. Mal finden sich die Clients, mal nicht...

Zurück zu adminforge.de die einen Matrix-Account für die Kontaktaufnahme auf nope.chat betreiben. Ich hab mir also nun auch auf nope.chat einen Testaccount registriert. Da ich einmal ganz billig davon ausgegangen bin, dass adminforge deswegen dort einen Account haben, da der Matrix-Server korrekt (mit stun oder gar auch turn) eingerichtet ist. Und siehe da, ein Voice/Video-Call ist damit von A1 zu Drei möglich.

Also habe ich weiter gespielt/analysiert. Hab bei meinem Matrix-Account alle stun/turn-Einträge entfernt und synapse neu gestartet.

Voila: Die Verbindung bleibt bei “connecting” hängen.

Hab in meinem Matrix-Server zwei stun-Server hinzugefügt: Ich kann erneut erfolgreich Voice/Video-Calls herstellen.

Außerdem hab ich meinem Pairdrop-Server nun einen zweiten stun-Server hinzugefügt, und damit krieg ich nun auch zuverlässig hin, dass Clients im A1- und Drei-Netz sich wechselseitig finden.

Fazit

Für eine zuverlässige Voice/Video-Verbindung zwischen Matrix-Clients in zwei vollkommen verschiedenen Netzen ist es notwendig, dass BEIDE beteiligten Matrix-Server zumindest STUN-Server konfiguriert haben. Besser noch STUN und TURN, damit auch zwischen Clients die beide hinter einem NAT sind auch Gespräche notwendig sind.

In der Datei /etc/matrix-synapse/homeserver.yaml sind dazu folgende Zeilen hinzuzufügen:

  turn_uris:
    - "stun:ein.stunserver.tld:443"
    - "stun:zweiter.stunserver.tld:443"
    - "turns:ein.turnserver.tld:443?transport=udp"
    - "turns:ein.turnserver.tld:443?transport=tcp"

Ich habe für den ersten stun-Server meinen eigenen und für den zweiten den von adminforge.de eingetragen. Und für den turn-Server ist ebenfalls die Domain meines coturn.

Links:

https://adminforge.de/service-beschreibung/#stun

Lange hat hat es dauern müssen, bis endlich die erste Alpha-Software für den Nitrokey 3 herausgekommen ist, die diesem kleinen Stick etwas mehr Leben einhaucht, als bloß webauthn.

Der Login auf #Gitea, #Forgejo und #Nextcloud sowie anderen Services mittels webauthn funktionierte ja von Anfang an.

Ich möchte mit diesem Artikel auf die Einrichtung und Handhabung der gpg-Funktionen eingehen, und wo man in die Stolperfallen tappen kann, und wie das Stückerl einzurichten ist.

Firmwareupdate

Damit gpg funktioniert muss man auf den Stick erst die Firmware erneuern. Da die Doku dazu ausreichend gut ist, verweise ich direkt auf die Seiten von Nitrokey für Linux und Nitrokey3. Bei der Firmware ist allerdings zu beachten, dass man beim Update zwischen zwei Varianten auswählen muss. Bei einer funktioniert gpg, bei der anderen nicht. Ich hab aber leider vergessen, welche der beiden gpg kann.

Notwendige Software auf dem Computer

Ansich ist bloß gnupg am Linux-Rechner notwendig. In manchen Anleitungen wird pcscd genannt. Der pcscd-Server dürfte aber buggy sein, oder das Zusammenspiel mit gpg klappt nicht ganz sauber. Jedenfalls ist hierzu ein älterer Bugreport auf Debian vorhanden, und der Fix mit Deinstallation von pcscd und dem Setzen einer UDEV-Rule hat bei mir auch bislang funktioniert.

Momentane Recherchen ergaben, dass das Problem mit pcscd wohl durch

pcsc_scan

während der Nitrokey eingesteckt ist, lösbar wird. Zuerst führt man einen scan durch und erhält bei eingestecktem Nitrokey folgendes Ergebnis (Ausschnitt)

$ pcsc_scan 
Using reader plug'n play mechanism
Scanning present readers...
0: Alcor Micro AU9540 00 00
1: SafeNet eToken 5100 [Main Interface] 01 00
2: Nitrokey Nitrokey 3 [CCID/ICCD Interface] 02 00

Der Nitrokey wird erkannt. Dann muss noch die Konfigurationsdatei für den scdaemon angelegt werden: Für den reader-port habe ich nach mehreren Versuchen herausgefunden, dass “Nitrokey” alleine auch genügt, damit das Werkel funktioniert. Ganz klar ist mir die Syntax hier noch nicht.

Laut Manpage man scdaemon ist der Defaultreiber für pcsc-driver libpcsclite.so. Auf meinem Debian aber ist dies nicht gesymlinked... es existiert bloß die Verlinkung auf /usr/lib/x86_64-linux-gnu/libpcsclite.so.1

Ich habe getestet und ln -s libpcsclite.so.1 /usr/lib/x86_64-linux-gnu/libpcsclite.so ausgeführt, und das Setup erneut getestet. Der Nitrokey wird nun zuverlässig mit gpg --card-status erkannt.

$ cat ~/.gnupg/scdaemon.conf

card-timeout 5
reader-port Nitrokey 

Mit systemctl restart --user gpg-agent den GPG-Agent neustarten.

Fix mit udev

Meine UDEV-Rule /etc/udev/rules.d/ccid.rules sieht so aus: ATTRS{idVendor}=="1d6b", ATTRS{idProduct}=="0002", MODE="664", GROUP="plugdev"

Initialisieren des Nitrokey 3

Einerseits kann man mit chromium oder chrome PIN, Admin-PIN und einen Reset-Code erzeugen. Dazu ruft man in der Adressleiste bloß chrome://settings/securityKeys auf und steckt den Key ein. Leider ist hier nur ein Reset und das Setzen einer PIN möglich.

Die deutlich bessere Wahl ist gpg. Dazu ruft man auf der Shell gpg auf, nachdem man den Nitrokey 3 eingesteckt hat gpg --edit-card Das zeigt einem dann die Informationen über den Stick.

mit help kann man eine Hilfe für die verfügbaren Befehle aufrufen. Ruft man einmalig admin auf, werden die admin-Befehle freigeschaltet. Erneut help zeigt dann ein längeres Menü.

PIN, admin-PIN, Rücksetz-Code

Nachdem die admin-Befehle freigeschaltet sind, geht es weiter mit passwd, ein Befehl, den man von der Linux-Shell auch kennt. Aber keine Sorge, hier wird passwd nur in und für gpg Smartcard-Handling aufgerufen.

!!! Achtung – Ohne vorherigem admin wird gleich der eigene Pin zurückgesetzt. Mit vorherigem admin kommen weitere Optionen!!!

Es wird folgendes Menü sichtbar:

gpg/card> admin
Admin-Befehle sind erlaubt

gpg/card> passwd
gpg: OpenPGP Karte Nr. D2670001234567040000B0432W5V0000 erkannt

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Ihre Auswahl? 

Das ist ziemlich eindeutig. Die Default-Passwörter sind: – PIN: 123456 – Admin PIN: 12345678 Diese werden zum Ändern abgefragt. Ich weiß leider nicht mehr genau wo, aber irgendwo bei meinen vielen Versuchen dieses Teil verstehen zu lernen, stand das mal in der Shell... zufällig hab ich es gesehen.

Man setzt einen PIN, einen Admin-PIN und einen Reset Code zum Zurücksetzen. Und idealerweise speichert man diese 3 Codes in seinem Passwortmanager. Ich verwende dazu pass bzw. passwordstore, den Standard Unix Passwordmanager

Sind nun PIN, Admin-PIN und ResetCode gesetzt, geht es weiter. Ich habe Meinen Namen mit name, meine Anrede mit salutation Logindaten mit login (ein Username... keine Ahnung wo der wirklich verwendet werden kann...) usw. gesetzt. Und schließlich das wichtigste:

Generieren eines GPG-Keys.

Mit generate wird dann ein GPG-Key erstellt. Wichtig bei gpg-Keys ist nur Name und Email, und kein Kommentar zu setzen, auch wenn es verlockend klingt. Das Kommentar gehört blöderweise auch zum Schlüssel.

Vorher aber habe ich noch mit key-attr festgelegt, dass ich ed25519-Keys und keine rsa-Keys möchte. Überall. Die sind kürzer, schneller erzeugt und viel sicherer als RSA-Keys. Und das ver/entschlüsseln sollte damit auch spürbar schneller klappen.

Ist der Key dann auch erzeugt, so muss der noch verteilt werden.

Public-Keys

Mit quit steigt man aus dem card-edit von gpg wieder aus und landet auf der Shell.

Den Public-Key des Nitrokey 3 bekommt man mit gpg --export --armor --output meine@email.adresse.tld <key> Für kann entweder der Fingerprint mit Leerzeichen in Hochkommas oder ohne Leerzeichen, oder nur der keygrip (sagt man da so?) verwendet werden, der mit 0x... beginnt, wenn man gpg --card-status aufruft. Der Main-Key ist jener, der unter General key info..: pub ed25519/0x... auftaucht. Hier nur den Teil ab 0x... verwenden. (Das sind die letzten 4 4-er-Paare des Fingerprints nur ohne Leerzeichen und mit 0x davor!!)

Der in das File exportierte Pubkey kann dann z.B. auf einen Server hochgeladen werden. Ich habe dazu auf meinem Git-Server, den ich mit Forgejo betreibe, ein eigenes Repo erstellt, wo ich verschiedene Pubkeys sammle. Das Handling über ein git-Repo geht von der Workstation aus easy und die Keys sind öffentlich abrufbar.

Apropos... Den in git publizierten Pubkey habe ich auf der “Raw-Adrese” (Also wo das File direkt abrufbar ist https://git.schuerz.at/jakob/public-keys/raw/branch/master/gpg/nk3c1.asc wiederum in den Nitrokey selbst eingetragen.

Dazu muss wieder gpg --edit-card und dann admin und danach url aufgerufen, und da dann dieser URL eingefügt werden.

Warum?

Ganz einfach. Open Keychain auf Android kann mittels NFC diesen Key importieren. Und um ihn zu überprüfen benötigt es einen Pubkey. Diesen kann man zuvor per File auf Smartphone übertragen, in Open Keychain importieren, dann mit der Funktion “Meine Schlüssel verwalten” im 3-Punkt Menü rechts oben und dann “SECURITY-TOKEN VERWENDEN” den Nitrokey einlesen (es wird zuerst der PIN abgefragt, und dann erst der Token verlangt!). Da sieht man, dass Open Keychain zuerst nach einem lokalen File sucht, dann im Web. Also gleich den Pubkey im Web veröffentlichen und schon geht es in einem Rutsch bei allen Smartphones, wo man diesen Key verwenden möchte.

Zurücksetzen

Falls irgendwas schief gehen sollte... Ich habe für euch getestet, dass mit gpg --edit-card oder gpg --card-edit und dann admin > factory-reset der Stick tatsächlich wieder in den Ausgangszustand zurückgesetzt werden kann. Dann sind auch wieder die Default-PINS gültig und die Keys gelöscht.

Passwordstore pass

Einen Fallstrick möchte ich hier mit pass unbedingt erwähnen.

Initialisiert man ein Verzeichnis mit mehreren Pubkeys/Identitäten, so ist die Reihenfolge wichtig. Ich habe z.B. zwei Nitrokeys (einer als Fallback) und derzeit noch einen Software-Key in Verwendung, bis ich mit den Nitrokeys besser umgehen kann.

Ist die Reihenfolge der Pubkeys beim Initialisieren pass init -p neuer/pfad softwarekey nitrokey1 nitrokey2 so wird in genau dieser Reihenfolge nur der ERSTE Key von Open Keychain abgefragt.

Öffnet man allerdings in einem anders initialisierten Unterordner zuerst den einen Nitrokey oder den anderen (wie in meinem Falle), dann checkt Open Keychain dass der schon verfügbar ist und nimmt diesen zum Öffnen des Passwortes her, auch wenn der Software-Key noch gar nicht aufgesperrt ist.

Zusammenfassung

Die Nitrokey 3 sind ja der Beschreibung nach wahre Wunderwerke/Alleskönner. Die NFC-Funktion ist allerdings so schwach, dass man mit Smartphone in der Hülle schon probleme bekommt, dass diese überhaupt lesbar sind. Die versprochenen Funktionen sind nach knapp 2 Jahren nach der Bestellung nach wie vor nicht vollständig nachgeliefert. Immerhin funktioniert jetzt schon gpg und damit eine wesentliche Funktion, damit ich meinen Passwort-Store nicht mehr mit leicht stehlbaren Software-Keys absichern muss. Das Handling wird etwas umständlicher mit Hardware-Token, aber Sicherheit und Komfort schließen einander aus, wie wir wissen.

Es war eine Challenge herauszufinden, wie der Nitrokey 3 am besten zu verwalten und bedienen ist. pkcs11 oder gar pkcs15 sind noch nicht wirklich die Burner, viele dort angebotenen Funktionen sind schlicht nicht implementiert und funktionieren nicht. Die Dokumentation seitens Nitrokey zum Stick sind auch noch mager. Immerhin funktionieren die Firmware-Updates wie beschrieben und recht easy.

Ob ich die Dinger nochmals kaufen würde... ich bin mir noch nicht ganz sicher. Es waren meine ersten Produkte von Nitrokey, und die eeeeewig lange Wartezeit war einerseits Corona und andererseits diversen Verzögerungen der Lieferketten (Chip-Mangel, das quergestellte Schiff im Suez-Kanal) und Personalmangel geschuldet... Der HSM-Stick war allerdings ratzfatz da und funktioniert sehr gut.

Meine Herausforderung ist, dass ich oftmals auf einem Server verbunden bin per ssh und Aufgaben zu erledigen habe. Auf diesen Servern gibts aber kein tmux.

Dann lasse ich gerne einmal das Log mitlaufen, um Fehler zu debuggen. Dazu muss aber ein Service neu gestartet werden. Damit das Log aber nicht unterbrochen wird, verbinde ich mich in einem zweiten Fenster auch mit dem Server und starte dort das Service neu...

Das muss schöner gehen

Wozu hat man nun tmux. Das ist schön konfigurierbar und bedienerfreundlich, und kann mein Terminal in mehrere Bereiche aufteilen.

Mit einem beherzten C-b " wird nun das Fenster geteilt. Ich muss dann nur noch erneut den ssh-Befehl ausführen und schon bin ich im zweiten Teil ebenfalls auf dem Server und kann tun, was ich für richtig halte.

Das muss NOCH schöner gehen

Das geht es auch. Mittels Keybinding kann ich die immer selbe Aufteilung eines Pane in tmux erzeugen. Dazu gehört in die Datei ~/.tmux.conf folgene Zeile bind D source-file ~/.tmux/sessions/dev.session Damit wird auf das große “D” gemapped, dass das File ~/.tmux/sessions/dev.session gesourced wird.

In das File ~/.tmux/sessions/dev.session kommt dann folgender Inhalt

selectp -t 1 # select the first (0) pane
splitw -h -p 50 # split it into two halves
selectp -t 2 # select the new, second (1) pane
splitw -v -p 50 # split it into two halves
selectp -t 1 # go back to the first pane
set-environment -u sshcon 

Dabei wird das Fenster zuerst in zwei vertikale Hälften und die rechte der vertikalen Hälfte noch in zwei horizontale Hälften geteilt. WICHTIG ist die letzte Zeile. Hier wird die Environment-Variable der tmux-Umgebung sshcon gelöscht. Als lokale Variable bleibt sie aber in der Shell vorhanden.

Aber wie kommt diese Variable ins Environment von tmux?

Ganz einfach. Mit einer Funktion die ich sssh nenne, damit sie einfach zu tippen ist, wenn man sich per ssh verbinden möchte. Diese funktion sssh muss in die Datei ~/.bashrc und wird mit jeder neuen Bash geladen.

sssh() {
     [ "${sshcon:-x}" == "x" ] || set -- "${sshcon}" 
     if [ -n "${TMUX}" ]; then
         tmux set-environment sshcon "$@"
     fi
     ssh "$@"
}

Die Funktion prüft, ob sie in einer tmux-Umgebung aufgerufen wird ($TMUX ist dann nicht leer), um die tmux umgebungsvariable sshcon mit den Aufrufparametern von sssh zu setzen. Zuerst aber prüft sie, ob sshcon überhaupt gesetzt ist. Und wenn ja, dann überschreibt sie die Aufrufparameter mit dem Inhalt von $sshcon.

Das kann man bei Belieben noch umdrehen. Nur wenn sssh keine Aufrufparamter hat, wird geprüft ob sshcon gesetzt ist, und dann verwendet. Ansonsten werden die originalen Aufrufparamter verwendet. Aber das kann man an die eigenen Bedürfnisse anpassen.