Alle Beiträge von adlerweb

Qt5: LoadLibrary-Fehler mit RDP unter Windows (ATI, OpenGL, Nextcloud)

Das Qt-Framework wird von vielen Projekten genutzt um grafische Oberflächen auf allen Betriebssystemen einheitlich entwickeln zu können. Bekannte Softwarepakete, welche Qt nutzen, sind unter Anderem: Nextcloud-Client, Owncloud-Client, FileZilla, Quassel, Mumble, MiniTube, Bitcoin-Qt, Scribus, LuminanceHDR, Audacious, Clementine, LMMS, VLC, AviDemux-qt, Shotcut, OpenShot, LibreCAD, FreeCAD, OpenSCAD, QOwnNotes, Calibre, KeePassX, KeePassXC, Wireshark und BlueStacks.

Eigentlich eine praktische Sache, jedoch mit einem Haken: Mit Qt5 versuchte man viele grafische Operationen per Hardwarebeschleunigung zu erledigen. Dies sorgt für schnellere Programme und weniger Systemlast. Für die Ansteuerung der Grafikkarte nutzt man hierbei OpenGL, welches auf allen gängigen Betriebssystemen verfügbar ist. Leider tritt man sich hierbei auch einige Probleme ein, so ist z.B. Windows dafür bekannt qualitativ zweifelhafte Treiber zu verteilen, welche stark auf Gaming optimiert sind, aber bei anderen Operationen gerne ins Straucheln kommen.

Ein recht verbreitetes Problem tritt dann auf, wenn eine AMD-Grafikkarte wie z.B. Radeon oder im System steckt, man jedoch auf den Windows-Rechner per Remote Desktop (RDP) zugreift. Windows lädt – auch wenn RDP genutzt wird – die Grafikkartentreiber. Ein Fehler in den ATI-Treibern, welcher bereits seit Ende der 2010er-Jahre bekannt ist, führt jedoch dazu, dass in RDP-Sitzungen Grafikoperationen nicht in Software ausgeführt oder von der Grafikkarte berechnet und zurückgegeben werden, sondern sie versuchen diese Trotzdem komplett in der GPU zu verarbeiten und brechen die Anfrage letztendlich ab. In vielen Anwendungen äußert sich das in fehlenden Grafikelementen oder Fehlermeldungen. So lässt sich z.B. der Nextcloud-Client gar nicht starten und Quittiert den Versuch die GUI per RDP zu öffnen mit einem fatalen Fehler. Es ist somit nicht möglich die Software per RDP zu starten.

Fehlermeldung NextCloud-Client: “LoadLibrary failed with error 87: The parameter is incorrect.”

Glücklicherweise kann man sich hierbei einer Eigenheit von “Shared Libraries” zu nutze machen, welche peeter123 auf GitHub vorschlägt: Jede App bevorzugt seine eigene Version, nur wenn sie selbst nichts mitliefert wird auf jene des Systems zurückgegriffen. Im Falle des OpenGL-Bugs kann man also einfach statt der Microsoft/ATI-Version eine weniger kaputte nutzen. Hierzu eignet sich z.B. die Variante des Mesa-Projektes, welche die OpenGL-Operationen nicht direkt an die Grafikkarte sendet. Um diese nun einzubinden lädt man auf der Releases-Seite die letzte Release-Version für mingw herunter (mesa3d-xx.yy.zz-release-mingw.7z), öffnet diese (z.B. mit 7Zip) und kopiert aus dem Ordner x64 (für 64-Bit-Systeme) die Datei “opengl32.dll” in den Ordner des betroffenen Programms, also z.B. C:\Program Files\Nextcloud. Hierdurch greift die Änderung nur für diese eine App und beeinflusst nicht alle installieren Programme. Fortan sollten die Operationen der Software ohne GPU-Treiber laufen und die Applikation somit auch per RDP lauffähig sein.

Durch diese Änderung verliert man zur potentiell etwas Geschwindigkeit in der betroffenen App, dies sollte bei aktuellen Systemen aber nicht groß auffallen – insbesondere, wenn man diese ohnehin nicht häufig aktiv nutzt. Immerhin ist die Software so auch remote nutzbar. Mit fortschreitender Migration auf Qt6 sollte sich das Problem mit der Zeit auch ganz von selbst erledigen: Dies nutzt statt OpenGL die jeweiligen Funktionen des Betriebssystems, welche auch auf Windows nicht ganz so kaputt sind.

Raspian: AbhängigkeitsFehler bei Upgrade von Buster zu Bullseye (unreleased)

Normalerweise ist ein Upgrade von Debian zu einer neueren Version keine große Sache: System in aktuellen Release aktualisieren (apt dist-upgrade), Sources anpassen, full-upgrade, fertig. Leider scheint Raspian hier wieder eine Extrawurst zu benötigen. Nach Ändern der Sources von Buster (Debian 10) zu Bullseye (Debian 11) gab es beim full-upgrade einen Abhängigkeitsfehler:

Calculating upgrade... Error!
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 libc6-dev : Breaks: libgcc-8-dev (< 8.4.0-2~) but 8.3.0-6+rpi1 is to be installed
E: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages.

Manuell festgenagelte Pakete gab es meinerseits nicht, entsprechend hätte ich erwartet, dass die Abhängigkeiten automatisch aufgelöst werden können. Abhilfe schaffte letztendlich das Update von GCC vor dem full-upgrade mittels apt install gcc-8-base per Hand zu installieren. Hierdurch wurden die beteiligten Pakete vorab aktualisiert und das Abhängigkeitsproblem somit aufgelöst.

Vorsicht: Bullseye für Raspian ist auch 2 Monate nach dem Release von Debian 11 noch nicht offiziell freigegeben. Viele Systemteile, die Raspian gegenüber einem “echten” Debian ändert, sind noch nicht lauffähig. So startet nach dem Update beispielsweise dhcpcd nicht mehr. Schaltet man die Raspian-Anpassungen ab (z.B. in dem man Systemd, Networkmanager o.Ä. nutzt) ist das System jedoch prinzipiell lauffähig.

Windows-Update – Fehler 0x800f0831 beheben

Hinweis: Die Screenshots sind von einem älteren System, die Meldungen, Pfade und Vorgehensweisen sollten sich jedoch auch auf aktuelle Versionen übertragen lassen.

Und wieder das übliche Bild: Auf einem Windows-System sind nicht alle Updates installiert. Keine gute Idee, insbesondere bei Systemen, die an einem Netzwerk betrieben werden. Also schnell in die Einstellungen und Updates installieren – in der Theorie. Leider passiert es nach meiner Beobachtung immer wieder, dass Updates quer sitzen und sich nicht installieren lassen. Auch im aktuellen Fall sah man bereits: “Failed” war im letzten Installationsversuch zu erkennen.

8 offene Windows-Updates, letzter Installationsversuch fehlgeschlagen

Auch ein manueller Versuch über “Install updates” brachte kein Erfolg. Der Assistent schien fehlerfrei zu laufen, nach dem im Anschluss angeforderten Reboot war jedoch das Bild wieder identisch: Die Updates standen erneut als offen drin. Also erster Blick: Welche waren überhaupt betroffen. In den Details fanden sich neben den meist wenig aussagekräftigen Bezeichnungen auch die KB-Nummern, welche bei Microsoft die zugehörigen Dokumentationen beschreiben.

Liste der offenen Updates mit KB-Nummern

Hier kam dann der Microsoft Catalog unter https://www.catalog.update.microsoft.com/ ins Spiel: Über diese Webseite lassen sich per KB-Nummer einzelne Updates suchen und per Hand herunterladen. Hierbei etwas aufpassen: Oft sind die Updates für verschiedene Betriebssystemversionen und CPU-Architekturen mit der selben KB-Nummer eingestellt, beim Download lohnt es sich also doppelt hin zu schauen.

Microsoft Update Katalog-Webseite mit einzelnen Updates

Die zum Download angebotenen MSU-Dateien sollten sich direkt per Doppelklick öffnen lassen und einen Setup-Assistenten zeigen. Leider brachte auch die händische Installation keine Besserung – am Ende des Assistenten vermeldete das Ergebnis ein wenig aussagekräftiges “The following updates were not installed“. Auch die Ereignisanzeige des Betriebssystems verriet nicht mehr als eben jene wenig hilfreiche Statusmeldung.

An dieser Stelle wird oft eine Reparatur mit DISM.exe /Online /Cleanup-image /Restorehealth bzw. Sfc /scannow oder gar eine Neuinstallation empfohlen. Ist jedoch klar, dass das System keine weiteren Probleme hat, ist eine gezielte Reparatur jedoch oft weniger Zeitintensiv als eine vollständige Neuinstallation, insbesondere wenn die betroffenen Systeme nicht über ein Konfigruationsmanagement/Orchestration zur automatischen Installation verfügen.

Glücklicherweise erstellt Windows Update an diversen Stellen erweiterte Protokolle, welche die Fehlersuche erleichtern. Bei Installationsfehlern sind die CBS-Logs meist die hilfreichste Anlaufstelle. Die Korrekte Datei findet sich unter %systemroot%\Logs\CBS\CBS.log. Eine Suche nach ” Error ” (mit ein paar Leerzeichen dahinter) sollte die relevante Stelle schnell sichtbar machen. In diesem Fall handelte es sich um eine Inkonsistenz im Updatespeicher, die zugehörige KB-Nummer ist in solchen Fällen in der Fehlermeldung erkennbar. Wer diese vergleicht wird feststellen, dass es sich hierbei nicht um eins der zur Installation vorgemerkten Updates handelte. Stattdessen betraf es ein älteres Update, welches für die aktuelle Installation benötigt wurde. Das genannte, ältere Update war laut System installiert, fehlte in Realität jedoch. Ein solcher Zustand ist oft zu finden, wenn bei einem vorherigen Update der Rechner abstürzte.

Ausschnitt CBS-Log. Vorausgesetzte KB-Nummer in der Fehlermeldung erkennbar

Also zurück zum Catalog, dort kann man das defekte Update manuell herunterladen und nochmals installieren. Ist dies Erfolgreich sind Updatespeicher und Realität an dieser Stelle wieder auf einem konsistenten Stand und die Installation der neueren Updates kann fehlerfrei erfolgen. Möglicherweise muss der Vorgang für mehrere ältere Updates wiederholt werden. Hier kann es helfen in der Updatehistorie zu prüfen, welche Updates mit dem Betroffenen zeitgleich installiert wurden und diese – sofern nicht ersetzt – präventiv ebenfalls neu zu installieren. Am Ende sollten sich alle Updates installieren und das System so auf einen aktuellen Stand bringen lassen.

Windows 10: Fehlende Audioausgabe nach April 2020-Updates (Realtek)

Nach installation der April 2020 Updates für Windows 10 19.09 kam es auf einigen von mir betriebenen Systemen zum Verschwinden der Audio-Treiber. Somit war eine Ton Ein- und Ausgabe nicht mehr möglich. In Zeiten von dauerhaften Videoschalten eher ungünstig. Selbes wurde von anderen Nutzern berichtet. Allen gemein: Es handelt sich um PCs und Laptops mit Realtek-Sound auf Basis von Intel HD Audio.

Treiber-Updates zeigen keine Änderung, das Booten eines vernünftigenanderen Betriebssystems bingt funktionierenden Ton mit sich. Interessant dabei: Die Audio-Devices tauchen nicht einmal mehr im Gerätemanager auf. In den ausgeblendeten Geräten wird das Gerät noch angezeigt, jedoch mit der Info “Dieses Hardwaregerät ist zurzeit nicht an den Computer angeschlossen. (Code 45)”.

Sucht man etwas weiter findet man unter “Systemgeräte” einen Eintrag für “Intel(R) Smart Sound Technologie-OED”, welcher als “nicht gestartet” (Code 10) markiert ist.

Auch an diesem kann man sich lange erfolglos abarbeiten. Ursache ist der vermeintlich fehlerfreie eintrag drüber: “Intel(R) Smart Sound Technologie-Audiocontroller”. Hier klickt man in den Details auf Treiber ? Treiber aktualisieren. Im Assistenten wählt mach “Auf dem Computer nach Treibersoftware suchen” und dort “Aus einer Liste verfügbarer Treiber auf meinem Computer auswählen”.

Nun erhält man eine Liste aktueller und älterer Treiber. Statt der Smart-Sound-Technologie (SST) wählt man “High Definition Audio-Controller” und installiert diesen. Im Anschluss erkennt Windows alle Geräte am Audio-bus neu und die Sound-Ausgabe sollte wieder wie gewohnt funktionieren.

Stromverbrauch von Switchen

In letzter Zeit hatte ich an diversen Stellen kurzfristig Netze umbauen müssen und daher diverse Switche in die Hand bekommen. Da ich bei meinem letzten Video doch etwas überrascht war, dass einige Switche einen sehr hohen Stromverbrauch zeigten hatte ich die Gelegenheit genutzt und bei verschiedensten Modellen im Fast-Leerlauf den Verbrauch gemessen und in eine Tabelle gepackt.

https://github.com/adlerweb/SwitchPower/

PostgreSQL-Update im Docker-Stil

Docker. Eigentlich ja ganz praktisch, wenn man “mal schnell” ein Softwarepaket trotz überschaubarer Wartbarkeit mit überschaubarem Aufwand ausrollen möchte, ab und an aber auch ein zuverlässiger Quell für Facepalm-Momente. So auch Heute: Nach dem Update einer mit docker-compose zusammengesetzten Anwendung ging nichts mehr. Der Maintainer hatte dort von postgres:10 auf postgres:11 aktualisiert. Kleines Update sollte man meinen, die PostgreSQL-Images für Docker sind jedoch technisch nicht in der Lage Daten älterer Installationen zu migrieren. Folglich zeigte sich im Log vor dem Absturz folgende Meldung:

postgres_1 | FATAL: database files are incompatible with server
postgres_1 | DETAIL: The data directory was initialized by PostgreSQL version 10, which is not compatible with this version 11.6.

Was auf “normalen” Servern mit pg_upgrade schnell geregelt und bei einigen Distributionen gar automatisiert ist, wird mit Docker ein paar Nummern komplizierter. Der Offizielle Weg: Backup machen, neu aufsetzen, importieren. Eigentlich wollte ich durch Docker Arbeit sparen, nicht mir weitere aufhalsen.

Glück im Unglück: Tianon Gravi hat auf GitHub und Docker Hub ein passendes System bereitgestellt, mit welchem man die Daten schnell zwischen verschiedenen PostgreSQL-Versionen migrieren kann.

Im Folgenden gehe ich davon aus, dass ein Named Volume “postgres-data” existiert und alle darauf zugreifenden Container gestoppt sind.

Achtung, Fallstrick: Nutzt man docker-compose, so ändern sich die Volume-Namen. Ein Named Volume “postgres-data” der Applikation “foobar” heißt in Wahrheit “foobar_postgres-data“. Im Zweifel nochmal mit “docker volume ls” prüfen.

  1. Fangen wir mit dem üblichen an: Backups. Bei Bind-Mounts kopiert man einfach den Quellordner passend zurecht, bei Named Volumes kann man diese üblicherweise unter /var/lib/docker/volumes/ finden oder mit docker-clone-volume duplizieren. Ich hatte postgres-data hierzu auf postgres-data-src und postgres-data-bck dupliziert.
  2. Weiter geht es mit dem Umwandeln der Datenbank. Hierzu nimmt man das Image mit den passenden Versionsnummern für Quell- und Zielversion.
    docker run --rm -v postgres-data-src:/var/lib/postgresql/10/data -v postgres-data-dst:/var/lib/postgresql/11/data tianon/postgres-upgrade:10-to-11
    Hiermit wird ein neues, mit PostgreSQL 11 kompatibles, Volume erzeugt, welches alle bisherigen Daten enthalten sollte.
  3. Leider gibt es in der aktuellen Version einen bekannten Bug, welche die Zugriffe in pg_hba.conf abweichend von den Dateien der offiziellen Images konfiguriert. Dies führt mit vielen Images zu Zugriffsfehlern. Um die Datei per hand zu editieren startet man entweder einen passenden Container oder greift über das Dateisystem des Hosts auf diese zu. In meinem Fall nutzte ich letztere Methode über die Datei /var/lib/docker/volumes/postgres-data-dst/_data/pg_hba.conf. An das Ende dieser wird folgende Zeile angefügt:
    host all all all md5
  4. Am Ende ändert man entweder den Volume-Eintrag seiner docker-compose.yml oder kopiert das neue Image passend zurück. In meinem Fall klang letzteres sinnvoller. Einen Befehl zum Umbenennen von Volumes ist Docker bis Heute nicht bekannt, daher bleibt hier nur das ursprüngliche Volume mit docker volume rm postgres-data zu löschen und postgres-data-dst – wie zuvor – mit docker-clone-volume oder im Dateisystem zum korrekten Volume-Namen zu klonen.

Warum man das nicht automatisiert erschließt sich mir nicht so ganz. Vermutlich beschränkt sich der Benutzerkreis hauptsächlich auf Entwickler, die ohnehin immer von 0 starten, und Enterprise-Häuser, die gemäß Fire-and-forget Systeme ohne Update bis zur Explosion betreiben.

Yubikey: Nicht ganz unkaputtbar

tl;dr: YubiKeys nicht am Schlüsselbund festmachen

Wenn es um Security-Tokens geht, hat YubiCo mit seinem YubiKey klar die Nase vorn. Nicht zuletzt, da diese so ziemlich die ersten Geräte waren, welche die gängigsten Sicherheitsmechanismen in einem Gerät vereinen konnten. Vor allem U2F, TOTP (aka Google Authenticator) und PGP sind bei mir fast dauerhaft im Einsatz. Mit dieser Kombination kann ich 2-Faktor-Anmeldung auf Webseiten nutzen, E-Mails signieren und entschlüsseln, mich auf SSH-Servern anmelden und Zugriff auf lokale Dateien und Programme absichern. Auch Zertifikate, aka X.509, sind eine praktische Sache, können sie doch für Logins in Windows-Netzen, S/MIME oder das signieren von Dokumenten unter Windows genutzt werden. Zwar lassen sich all diese Mechanismen auch ohne Dongle nutzen, dieser bringt jedoch zwei wichtige Sicherheitsverbesserungen mit sich: Der Zugriff ist nur möglich, wenn das Gerät eingesteckt ist, sodass eine “versehentliche” Nutzung erschwert wird. Zudem sind die privaten Schlüssel auf einem – vorzugsweise sicheren – Microcontroller gespeichert und können das Gerät nicht mehr verlassen.

Ich selbst bin Ende 2016 auf den YubiKey NEO * umgestiegen. Dieser kann per USB oder NFC genutzt werden. Letzteres ist z.B. für Logins oder Mailverkehr am Handy interessant. Etwas bedenken hatte ich, da USB-Sticks bei mir selten lange überleben und ein YK nicht gerade günstig ist. Das Werbesersprechen “unkaputtbar”, die robust aussehende Form und Empfehlungen aus dem Bekanntenkreis überzeugten jedoch am Ende. Seit dem ist er Stammgast an meinem Schlüsselbund, somit ständiger Begleiter und wird entsprechend viel genutzt.

YubiKey NEO an Schlüsselbund
YubiKey Neo an Schlüsselband

Schnellvorlauf November letzten Jahres, also 2 Jahre nach dem Kauf. Einiges hatte sich getan, aber der YK verrichtete noch anstandslos seine Dienste. Also fast. Von einem Tag auf den Anderen war NFC nicht mehr nutzbar und ich somit auf die Nutzung am PC beschränkt. Kein Beinbruch, Handy-Logins nutze ich eher selten, allerdings auch kein Pluspunkt für mein Vertrauen in die Haltbarkeit. Ich vermutete einen Softwarefehler, alternativ eine Einwirkung durch statische Aufladung. Beides Dinge, die nicht passieren sollten. Auch sonst zeigten sich Schwächen: Aus Sicherheitsgründen ist es nicht möglich die Firmware der Geräte zu aktualisieren. Hierdurch war ich bei PGP auf Keys mit maximal 2048 Bit limitiert. Noch OK, aber auch nicht toll. Einzige Möglichkeit auch in den Genuss neuerer Verfahren zu kommen wäre ein neueres Modell, diese hatten zum damaligen Zeitpunkt jedoch kein NFC und nutzten für PGP nun statt einer Open-Source-Lösung eine Eigenentwicklung des Herstellers, welcher sich nicht einsehen ließ.

Meh. Roughly 2 years after I bought my @yubico #Yubikey Neo it already failed. USB luckily still OK, but NFC completely dead. Really hoped these things would be more durable :<

adlerweb|BitBastelei@adlerweb, 2018-11-21

Da die neueren Modelle für mich keine Option waren wandte ich mich via Twitter an den Hersteller. Unter “unkaputtbar” verstehe ich etwas Anderes, als 2 Jahre und somit knapp über den regulären Gewährleistungen. Meine Intention: Ich wollte wissen was da schief gelaufen ist, ob es eventuell durch einen Reset o.Ä. behoben werden kann, wie man das verhindern kann und ob bei zukünftigen Modellen dieses Problem umgangen werden kann. Man verwies mich auf das Ticketsystem, antwortete dort jedoch nur mit Textblöcken. Nach meiner Info, dass ich die Diskusion in dem Fall für Sinnlos hielt bot man mir den Austausch gegen einen neuen Neo an. Da auf Grund der alternden PGP-Unterstützung und der unbekannten Fehlerursache das Modell eher auf meiner Abschussliste war lehnte ich dankend ab und nutzte mein Modell per USB weiter.

10 Monate später sprach mich ein Mitglied des lokalen Hackerspace auf den YubiKey an. Ein Arbeitskollege hätte da einen unschönen Ausfall mit seinem Key gehabt. Das ABS-Gehäuse wäre durch den Schlüsselring durchgescheuert und das Gerät hätte den Dienst versagt. Könnte das mit meinem Problem zu tun haben? Sure enough: Auch bei mir ist das Plastik im Bereich des Schlüsselrings schon sehr abgenutzt. Dass das ein technisches Problem verursachen könnte hatte ich gar nicht auf dem Schirm.

Abgenutzter Bereich am Schlüsselring-Loch eines YubiKey NEO

Zudem: ABS? Durchscheuern? Ich hatte vermutet, dass unter der Plastik-Packung noch ein Metallring eingearbeitet wäre, welche das ganze etwas verstärkt. Aber jetzt, wo ich das höre – hm, ja, da reflektiert ja etwas. Ein Blick unter dem Mikroskop verrät recht schnell, was mein NFC getötet hat: die Antenne ist um das Schlüsselring-Loch gelegt und inzwischen durchgescheuert. WTF.

Beschädigte NFC-Antenne an einem YubiKey NEO

Erinnert Ihr euch dran, dass ich ABS sagte? ABS kennt man ja auch von 3D-Druckern, hier ist es üblich mit Aceton das Plastik nach dem Druck anzulösen und zu glätten. Mit entsprechenden Konzentrationen kann man das Plastik aber auch einfach wegschmelzen. Exakt dies hat HexView mit einem YubiKey Neo gemacht, sodass sich das Innenleben in voller Pracht bewundern lässt. Glücklicherweise sieht es so aus, als ob hier wirklich nur die Antennen vorbeilaufen und ein Ausfall eher nicht wahrscheinlich ist. Trotzdem würde ich jedem mit YubiKey NEO raten, an dieser Stelle mit Aceton das Plastik anzulösen und mit mehr ABS oder gar einem Metallring zu verstärken um Ausfälle durch Abnutzung zu vermeiden.

Ich selbst bin etwa an selber Stelle wie vorher: Ich werde den NEO wohl weiter nutzen. Zwar hat man inzwischen den YubiKey 5 NFC * herausgebracht, welcher wieder NFC kann, auch längere Keys für PGP unterstützt und das bei mir ursächliche Schlüsselring-Loch verstärkt hat, allerdings sind mir sowohl die fehlenden Quellen als auch die unschöne Reaktion des Supports doch eher sauer aufgestoßen. Hätte man mir bei meiner Nachfrage geantwortet, dass es vermutlich ein bekanntes Problem wäre und man das in der nächsten Produktversion angehen würde – ich hätte sie vermutlich direkt nach dem Release hier liegen gehabt. Leider mangelt es aber auch an Konkurrenz. Viele Keys wie z.B. Thetis oder Googles TitanKey nutzen ausschließlich U2F. Toll für’s Web, aber meine Hauptanwendung ist eher PGP. TOTP sucht man bei allen vergeblich, ließe sich mit etwas Gebastel aber halbwegs brauchbar in Software nachbilden – freie Standards haben so ihre Vorteile. Etwas besser sieht es bei NitroKey aus, hier ist GPG, TOTP und X.509 verfügbar. Leider ist U2F nur als separates Gerät erhältlich und TOTP mit 15 Einträgen etwas knapp (YubiKey Neo 28, YubiKey 5: 32). Da es sich um einen freien Algorithmus handelt könnte man aber, zumindest bei der TOTP-Limitierung, mit etwas Software nachhelfen. Ein Auge habe ich zudem noch auf Somu. Dieses Crowdfunding-Projekt dreht sich primär um einen U2F und FIDO2-Stick, als Stretch-Goal hat man jedoch GPG und SSH auf dem Plan. Alles soll am Ende Open Source sein, was sich auch eher positiv anhört. Ob sie am Ende liefern können, was sie versprechen, werde ich dann ja sehen.

In eine vorherigen Variante des Artikels wurde angegeben, dass NitroKey kein TOTP könne. Dies ist nicht korrekt, sowohl Nitrokey Pro 2 und Nitrokey Storage 2 können jeweils 15 TOTP-Einträge speichern.

Nginx: allow mit dynamic DNS

Wenn man Webseiten mit Backend betreibt ist es oft eine gute Idee die Verwaltungsbereiche nur von bestimmten IPs oder Netzen zuzulassen. Unter nginx gibt es hierzu den allow-Befehl, mit welchem man IPs und Netze angeben kann. Ich verwende dies z.B. häufig um nur interne IP-Bereiche oder per VPN angebundene Clients zuzulassen. Für ein aktuelles Projekt sollte jedoch auf ein VPN verzichtet werden. Theoretisch kein Problem – externe IP rein und fertig, aber leider ist es auch 2019 noch in Deutschland für viele Anschlussarten üblich bei Trennung und erneutem Verbinden eine andere IP-Adresse zuzuweisen. Für eingehende Verbindungen lässt sich dies mittels dynamischen DNS-Einträgen schnell in den Griff bekommen, jedoch ist das für das hiesige Konstrukt keine Option, da nginx mit solchen Einträgen nicht sinnvoll umgehen kann. Im Netz finden sich einige Helper-Scripte, welche den DNS regelmäßig Prüfen, die Konfiguration anpassen und den Webserver passend umkonfigurieren. Leider sind diese oft eher alt und nur auf das schon seit Jahrzehnten veraltete IPv4 ausgelegt. Als Abhilfe habe ich meine Anforderungen in ein kleines Python-Script gegossen. Für IPv6 wird von der aufgefundenen IP auf ein /48er Netz geschlossen und dieses freigegeben, sollte euer Provider nur ein /56er oder gar /64er rausrücken muss dass ggf. angepasst werden.

Vorbedingung ist, dass nginx die neue Konfiguration findet. Um es einfach zu halten stehen die dynamischen Einträge in einer separaten Textdatei, welche an passender Stelle per include eingebunden wird. Statische Einträge können, sofern vorhanden, an der üblichen Stelle bleiben.

[…]
location /admin {
        allow 192.168.0.0/24;
        include /etc/nginx/dyndns.conf;
        deny all;
        […]

Das eigentliche Script nutzt nach meinem Wissen keine externen Module und sollte somit auf jedem System mit Python 3 laufen. Es werden alle IPv4- und IPv6-Adressen abgerufen. Der angegebene Port (80) ist irrelevant, da nur die IPs genutzt werden. Die Konfiguration wird mittels MD5 auf Änderungen geprüft, liegt eine solche vor wird per Systemd eine reload ausgelöst. Ich habe die Datei mit in den nginx-Konfigurationsordner als /etc/nginx/dyndns.py gepackt – nicht schön, aber passte besser in die bereits vorhandene Struktur und Verwaltung.

#!/usr/bin/python3
import socket
import subprocess
import hashlib
import ipaddress


def md5(fname):
    hash_md5 = hashlib.md5()
    with open(fname, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()



before = md5("/etc/nginx/dyndns.conf")
cfg = open("/etc/nginx/dyndns.conf", "w")
addrs = socket.getaddrinfo("DEIN.DYNAMISCHER.DNS", 80, type=socket.SOCK_STREAM)
for addr in addrs:
    out = ""
    ip = ipaddress.ip_address(addr[4][0])
    if ip.version == 6:
        ip = ipaddress.ip_network(str(addr[4][0]) + "/48", False)
        out = (str(ip.network_address) + "/" + str(ip.prefixlen))
    else:
        out = addr[4][0]
    cfg.write("allow\t\t" + out + ";\t#Dynamic DNS\n")

cfg.close()

after = md5("/etc/nginx/dyndns.conf")

if before != after:
    #DNS has changed
    #print("RELOAD")
    subprocess.call('/usr/bin/systemctl reload nginx', shell=True)

Das Script muss regelmäßig gestartet werden um Änderungen zu prüfen. Wenn der zugehörige DNS-Dienst auf dem selben System läuft kann man möglicherweise auf Hooks zurückgreifen, andernfalls muss es zeitbasiert über Cron oder Timer laufen. Für letzteres mit einem Intervall von 5 Minuten legt man die Datei /etc/systemd/system/nginx-dyndns.timer an und füllt sie wie folgt:

[Unit]
Description=Nginx DNS updater

[Timer]
OnBootSec=0min
OnUnitInactiveSec=5m

[Install]
WantedBy=timers.target

Dazu benötigt man noch einen passenden Service, welcher unter /etc/systemd/system/nginx-dyndns.service definiert wird:

[Unit]
Description=Nginx DNS updater

[Service]
Type=oneshot
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
ExecStart=/usr/bin/python3 /etc/nginx/dyndns.py

Last but not least wird der Timer eingeschaltet:

systemctl enable --now nginx-dyndns.timer

Sound Blaster Roar 2 öffnen

Sound Blaster Roar 2, Schwarz, Vorderseite

Der Sound Blaster Roar 2 von Creative ist ein tragbarer Lautsprecher mit Bluetooth (aptX), USB, Kartenleser, NFC, Akku, Powerbankfunktion und allem anderen technischen Schnickschnack, den man eventuell brauchen könnte.

Sound Blaster Roar 2, Schwarz, Anschlüsse und erweitertes Bedienfeld mit defekter Strombuchse

Ein solcher ist beim hiesigen Reparaturcafe aufgeschlagen. Durch einen Sturz waren Stecker des 15V/1.xA-Netzteils und Buchse im Gerät beschädigt – wohl etwas zu viel Bass. Bei einem aktuellen Preis von 125€ (Werbung: Produkt auf Amazon*) ist ein Austausch lohnenswert, jedoch hat das Öffnen etwas Kreativität abverlangt. Also mal schnell zusammengefasst, wie man an das Innere gelangt.

Wichtig: Da ein Akku verbaut ist sollte man beim Arbeiten besonders vorsichtig sein – ein kurzgeschlossener Li-Ion ist nichts, was man auf dem Basteltisch haben möchte.

Sound Blaster Roar 2, Abgenommene Frontplatte und Lautsprecherabdeckung. Positionen der Schrauben aus dem Gedächtnis markiert

Im ersten Schritt nimmt man die silberne Abdeckung über den Tasten ab. Auch wenn sie sich wehrt: sie ist nur geklebt. Darunter finden sich, neben einigen Tastern und dem Gesteckten LED/NFC-Modul, drei Schrauben um auch das darunterliegende Drahtgitter zu entfernen. zum Vorschein kommen drei Lautsprecher, die Äußeren sind mit etwas Schaumstoff abgedeckt. Alle Bauteile sind mit selbstklebenden Schaumstoffstreifen als Dichtung versehen um den innen entstehenden Luftdruck auf die seitlichen “Bassboxen” zu leiten. Durch etwas Suchen lassen sich unter den seitlichen Dichtungen die Schrauben zum letztendlichen Öffnen des Gehäuses lokalisieren. Vorsicht: Hier sind zum Teil unterschiedliche Typen verbaut, also Besser die Quelle der Schrauben markieren.

Sound Blaster Roar 2, Hauptplatine

Im Inneren findet sich eine Hauptplatine, welche nahezu alle Funktionen abdeckt. Der Akku, bestehend aus zwei 18650-Zellen, ist an der Vorderseite verklebt. Die vielen Kabel zwischen PCB und Perepherie scheinen alle gesteckt. Glücklicherweise sind sie lang genug, um auch ohne vollständiges Zerlegen Zugang zu den Komponenten und Schrauben zu erhalten.

Etwas ungewöhnlich ist der Bereich um die Anschlüsse herum: Dort findet sich eine weitere Plastikabdeckung, welche sowohl innen als auch außen verschraubt ist. Zusammen mit einer weitere Schaumstofftichtung sogt diese dafür, dass auch hier kein Druck aus dem Gehäuse entweicht.

Sound Blaster Roar 2, Defekte Strombuchse

Ist auch dieses Hindernis verschwunden erhält man Schlussendlich Zugang zu den Anschlüssen. In diesem Fall wurde die Buchse zur Stromversorgung so nach oben gehebelt, dass im hinteren Bereich eine Metallverbindung abgerissen war. Da die Buchse sonst keine Schäden zeigte und das Layout keine großen Hoffnungen auf eine einfache Ersatzteilbeschaffung machte wurde die schadhafte Stelle einfach zurück gebogen und verlötet.

Da leider kein passender Stecker für das Netzteil zur Hand war konnte ich keinen Abschließenden Test durchführen. Der verwendete Stecker scheint etwas ungewöhnlicher zu sein, die meisten mit diesem Außendurchmesser haben einen kleineren Stift in der Mitte. Ich vermute, dass es durch die Reparatur zu einer Verschlechterung der Audioqualität kommen könnte, da die Dichtungen an einigen Stellen geöffnet wurden. Im Zweifel sollte etwas neuer Schaumstoff oder auch Silikon an den betroffenen Stellen Abhilfe schaffen.

OSTicket: Ticketerstellung über Python

OSTicket ist ein freies Ticketsystem, also System zur Sammlung und Dokumentation von Aufgaben. Ab und an kann es praktisch sein solche Aufgaben auch per Software zu generieren, z.B. für wiederkehrende Aufgaben oder wenn Systeme Störungen automatisiert erkennen. Da die Doku bisher eher dünn ist anbei ein kleines Python-Script, welches über die API Tickets erstellen kann. Hierzu muss erst im Admin-Bereich ein passender API-Zugang angelegt werden. Zu beachten ist, dass ein solcher API-Zugang auf eine IP limitiert ist.

import requests
import json

headers = {'X-API-Key': '12345ENTERHERE12345'}
subject = "12345"

ostdata = {
    "alert": True,
    "autorespond": False,
    "source": "API",
    "name": "GenervterUser",
    "email": "genervter@us.er",
    "phone": "",
    "subject": str(subject),
    "ip": "::1",
    "message": "data:text/plain,Ich bin ein Ticket",
}

json_data = json.dumps(ostdata)

r =
requests.post("https://helpdesk.meinefirma.local/api/tickets.json", data=json_data, verify = '/usr/local/share/ca-certificates/meineca.crt', headers=headers)
print(r)

Hinweise:

  • Der verify-Parameter ist nur nötig, wenn man HTTPS mit einer im System unbekannten CA nutzt
  • Die Telefonnummer wird bei source=API wohl nicht angezeigt
  • Der Name wird bei erster Nutzung mit der E-Mail-Adresse verknüpft, wenn man weitere Tickets mit der selben E-Mail anlegt scheinen diese alle den zuerst genutzten Namen anzuzeigen

Weitere Doku