IT-Blog von Sebastian van de Meer

Kategorie: Kernel-Error-Blog (Seite 6 von 45)

Persönlicher Tech-Blog von Sebastian van de Meer — Beiträge zu IT-Security, Netzwerken, FreeBSD, Linux, Elektronik und Maker-Projekten.

DNS over TLS mit BIND, Stunnel und Android 9: Eigener DoT-Server

Die Zeit ging weiter, die Entwicklung bei BIND und DNS ebenfalls. Daher gibt es nun einen neuen Beitrag, der das aktuelle Setup mit BIND 9.20 auf FreeBSD 15 beschreibt – inklusive sauberer Trennung von authoritative DNS (Port 53) und öffentlichem Resolver (DoT/DoH) sowie reproduzierbaren CLI-Tests für IPv4 und IPv6. Bitte dort weiterlesen.

Über die Techniken DoT (DNS over TLS) habe ich bereits im Zusammenhang mit Bind 9.16 geschrieben. Ebenfalls DoH (DNS over HTTPS) gibt es einen kleinen Beitrag.

Bilder der Bind 9 TLS Konfiguration

Zu diesem Zeitpunkt bracht BIND 9 die Unterstützung für DoH und DoT noch nicht selbst mit. Daher waren zu diesem Zeitpunkt noch Umwege über stunnel oder nginx zusammen mit doh-proxy nötig.

Zum Glück kommt die letzte stable Version 9.18.0 (26. Januar 2022) mit dem nötigen Support.

named now supports securing DNS traffic using Transport Layer Security (TLS). TLS is used by both DNS over TLS (DoT) and DNS over HTTPS (DoH).

Warum möchte man noch gleich DoH oder DoT benutzen? Ganz einfach… Über diese Techniken werden DNS Abfragen verschlüsselt übertragen. Dieses ist ein weiterer Schutz davor manipulierte Antworten zu bekommen und selbstverständlich, damit die eigenen DNS Abfragen erst überhaupt nicht mitgelesen werden. Denn wenn von einem Gerät im Netzwerk die DNS Abfrage zu z.B.: www.tagesschau.de kommt, könnte man davon bereits Dinge ableiten.

Wie die meisten Bind Konfigurationen ist dieses ebenfalls straightforward. Ab Version 9.18 bringt Bind alles Nötige mit. Da wir nun TLS mit dem Bind sprechen möchten, benötigen wir natürlich ein gültiges Zertifikat, wie z.B. beim nginx für seine Webseite.

Ebenfalls sollte man ein paar frische Diffie-Hellmann Parameter generieren:

openssl dhparam -out dhparam.pem 4096

Die eigentliche bind Konfiguration kann in der named.conf.options geschehen:

options {
        [...]
        listen-on port 853 tls local-tls { 37.120.183.220; };
        listen-on-v6 port 853 tls local-tls { 2a03:4000:38:20e::853; };
        listen-on port 443 tls local-tls http default { 37.120.183.220;  };
        listen-on-v6 port 443 tls local-tls http default { 2a03:4000:38:20e::853; };
        [...]
        allow-recursion-on { 127.0.0.0/8; ::1/128; 2a03:4000:38:20e::853; 37.120.183.220; };
        [...]
};

Da der bind auf weiteren Ports lauschen soll erweitert man diese für IPv4 und IPv6. Der Default Port für DoH ist dabei 443 und der default Port für DoT ist 853, beides TCP.

listen-on sowie listen-on-v6 sind wohl selbsterklärend.
port ist der TCP Port und erklärt sich ebenfalls.
tls sagt dem Bind das wir tls sprechen möchten.
local-tls verweißt auf den gleichnamigen tls Block über welchen man seine TLS Konfiguration vornimmt.
http ist für DoH.
default gibt den eigentlichen endpoint für die DoH Abfragen an, im default ist es /dns-query

Da der Server unsere DNS Abfragen erledigen soll, müssen wir ihm dieses noch per allow-recursion-on auf den jeweiligen Adressen erlauben.

Als nächstes wird die eigentliche TLS Terminierung konfiguriert (das lässt sich ebenfalls auslagern, wenn gewünscht). Dafür wird der folgende Block, außerhalb der Options Blocks, ergänzt:

tls local-tls {
    cert-file "/usr/local/etc/ssl/wild.kernel-error.de/2022/ecp/chain.crt";
    key-file "/usr/local/etc/ssl/wild.kernel-error.de/2022/ecp/http.key";
    dhparam-file "/usr/local/etc/ssl/dhparam.pem";
    protocols { TLSv1.2; TLSv1.3; };
    ciphers "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256";
    prefer-server-ciphers yes;
    session-tickets no;
};

local-tls ist dabei der name des Blocks. Auf diesen verweisen wir oben.
cert-file ist der Pfad zum Zertifikat. Ich habe dort nicht nur das Zertifikat, sondern die gesamte Chain, also mit Intermediate und Root.
key-file ist der Pfad zum Key des Zertifikates.
dhparam-file ist der Pfad zu den Diffie-Hellman Parametern.
protocols definiert die zu verwendenden TLS Protokolle. In diesem Beispiel TLS1.2 sowie TLS1.3.
ciphers definiert die zu verwendenden cipher. Es soll ja „sicher“ bleiben.
prefer-server-ciphers übermittelt dem Client die Information, in welcher Reihenfolge protokoll/cipher Kombinationen probiert werden sollen um einen Match zu finden. Erst das vermeintlich sicherste und dann immer „schlechter“.
session-tickets regelt ob eine Wiederaufnahme von TLS Sessions erlaubt ist oder nicht. Da ich forward secrecy nutzen möchte, ist es deaktiviert.

Damit ist die Konfiguration schon abgeschlossen (Firewall ggf. nicht vergessen!). Also testen….

Ein einfaches Tool dafür ist dog, oder natürlich dig aus den bind-tools aber Version 9.18. Für bind gibt es dann die Optionen +https oder auch +tls

dig +https @dns.kernel-error.de www.kernel-error.de A
dig +tls @dns.kernel-error.de www.kernel-error.de A

Der gleiche Test mit dog, sieht wie folgt aus:

dog www.kernel-error.de --tls "@dns.kernel-error.de"
A www.kernel-error.de. 6h00m00s   148.251.40.23
dog www.kernel-error.de --https "@https://dns.kernel-error.de/dns-query"
A www.kernel-error.de. 6h00m00s   148.251.40.23

Das war es auch schon! Viele Spaß mit einem „besseren“ DNS und wenn es noch Fragen gibt, einfach fragen.

Arduino und die jammernde Pflanze: Technik trifft Humor

Auf irgendeinem CCC Event bin ich über eine lustige Projektidee einer jammernden Pflanze gestoßen. Die hat mir und auch meiner größeren Tochter so gut gefallen, dass wir sie zusammen nachbauen wollten.

Geöffnetes Gehäuse mit der gesamten Technik für das Arduino-Projekt: Die jammernde Pflanze

Die Idee

Ein kleines Gerät misst den Feuchtigkeitsgehalt der Blumenerde. Ist der Wert zu trocken, spielt ein MP3-Player eine Audiodatei ab. Ein Bewegungsmelder sorgt dafür, dass die Pflanze sich nur beschwert, wenn auch jemand da ist. Ist die Erde trocken und es wird eine Bewegung erkannt, jammert die Pflanze los.

Die Bauteile

Da es das erste Projekt dieser Art für meine Tochter ist, sollte es übersichtlich und einfach bleiben. Ein Arduino Nano (fast die gleichen Möglichkeiten wie der UNO, aber deutlich kleiner), ein DFPlayer-Modul als MP3-Player, ein HC-SR312 Bewegungsmelder und ein kapazitiver Feuchtigkeitssensor.

Aufbau und Entwicklung

Gestartet haben wir mit einem Breadboard, um die Verschaltung Modul für Modul zu setzen und die Ansteuerung mit dem Arduino anhand der Beispiele zu testen. Beim DFPlayer haben wir per TTS Texte in MP3s umgewandelt und auf der SD-Karte im Ordner mp3 gespeichert. Diese werden zufällig abgespielt, wenn die Erde zu trocken ist und eine Bewegung erkannt wurde.

Als die Verschaltung zusammen mit dem Code funktionierte, haben wir mit KiCad eine Platine designt und fertigen lassen. So hat man weniger Kabelsalat und alles ist platzsparend aufgehoben.

Elektrischer Schaltplan für die jammernde Pflanze

Das Gehäuse haben wir in FreeCAD designt und mit dem 3D-Drucker gedruckt. Die Teile sind mit einem Tropfen Sekundenkleber fixiert.

FreeCAD-Design des Gehäuses für die jammernde Pflanze

Im Einsatz

Das Teil steckt in der Blume und meldet sich zuverlässig, wenn es Zeit zum Gießen ist. Da es von den MP3s auf dem Player abhängt, was die Pflanze „sagt“, sind lustige Reaktionen garantiert. Die Pflanze kann dich im Vorbeigehen voll jammern, um Wasser betteln oder anfangen zu schimpfen.

Meine Tochter wird nach dem Projekt nicht alles alleine wiederholen können, aber die einzelnen Schritte sind klar. Wie so ein Gerät entsteht, was nötig ist. Schnell findet man Verbesserungsmöglichkeiten: Den Feuchtigkeitssensor von der Elektronik trennen, mit einem NodeMCU ESP8266 WLAN-Statusdaten senden, oder mit Li-Ion-Akkus und einem BMS vom Stromnetz unabhängig werden.

Quellcode

Für den DFPlayer wird die DFRobotDFPlayerMini Library benötigt (lokal unter ~/Arduino/libraries ablegen).

#include <Arduino.h>
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>

/* --- Pins ---------------------------------------------------- */
const uint8_t PIN_DF_RX   = 10;
const uint8_t PIN_DF_TX   = 11;
const uint8_t PIN_PIR     = 7;
const uint8_t PIN_SENSOR = A0;

/* --- Parameter ----------------------------------------------- */
const int schwellwert = 380;
const unsigned long PLAY_COOLDOWN_MS = 15000;
const uint8_t TRACK_JAMMERN = 1;

/* --- Objekte ------------------------------------------------- */
SoftwareSerial dfSerial(PIN_DF_RX, PIN_DF_TX);
DFRobotDFPlayerMini dfPlayer;

/* --- Laufzeitstatus ------------------------------------------ */
unsigned long lastPlay = 0;

/* ------------------------------------------------------------- */

void setup() {
  pinMode(PIN_PIR, INPUT);

  Serial.begin(115200);
  dfSerial.begin(9600);

  Serial.println(F("Initializing DFPlayer ..."));

  if (!dfPlayer.begin(dfSerial)) {
    Serial.println(F("DFPlayer init failed"));
    while (true);
  }

  dfPlayer.volume(20);
  dfPlayer.outputDevice(DFPLAYER_DEVICE_SD);
  dfPlayer.EQ(DFPLAYER_EQ_NORMAL);
  dfPlayer.setTimeOut(500);

  Serial.println(F("DFPlayer Mini online"));
}

/* ------------------------------------------------------------- */

void loop() {
  /* DFPlayer Events immer zuerst abholen */
  if (dfPlayer.available()) {
    handleDFPlayerEvent(dfPlayer.readType(), dfPlayer.read());
  }

  int messwert = analogRead(PIN_SENSOR);
  bool bewegung = digitalRead(PIN_PIR) == HIGH;
  bool trocken = messwert > schwellwert;

  unsigned long now = millis();

  if (trocken && bewegung) {
    if (now - lastPlay >= PLAY_COOLDOWN_MS) {
      Serial.println(F("Bewegung + Erde trocken -> spiele Sound"));
      dfPlayer.play(TRACK_JAMMERN);
      lastPlay = now;
    }
  } else {
    logStatus(trocken, bewegung, messwert);
  }

  delay(100);  // leichte Entlastung – kein Logik-Delay
}

/* ------------------------------------------------------------- */

void logStatus(bool trocken, bool bewegung, int messwert) {
  if (!bewegung && trocken) {
    Serial.print(F("Keine Bewegung, Erde trocken: "));
  } else if (bewegung && !trocken) {
    Serial.print(F("Bewegung, Erde ok: "));
  } else if (!bewegung && !trocken) {
    Serial.print(F("Keine Bewegung, Erde ok: "));
  }
  Serial.println(messwert);
}

/* ------------------------------------------------------------- */

void handleDFPlayerEvent(uint8_t type, int value) {
  if (type == DFPlayerPlayFinished) {
    Serial.print(F("Track "));
    Serial.print(value);
    Serial.println(F(" beendet"));
  }
}

Downloads

3D-Druck: STL Gehäuse | STL Deckel
Platine: Gerber-Dateien

Einkaufsliste

Optional: Breadboard mit Kabeln, Multimeter, Lötkolben

Fragen? Einfach melden.

Datenschutz geht zur Schule

Datenschutz ist oft ein sehr langweilige und oft schwer verständliches Thema. Ein Bekannter (danke dir) hat mir den folgenden Link zukommen lassen:

https://www.datenschutz-leicht-erklaert.de/#videos

Die Link verweist einer Initiative vom Berufsverband der Datenschutzbeauftragten Deutschlands (BvD) e.V. mit dem Namen Datenschutz geht zur Schule. Die Zielgruppe sind dabei Schüler:rinnen um ihnen das Thema Datenschutz näher zu bringen. Dazu gibt es kurze, Themen bezogene Videos, welche wirklich gut verständlich sind.

Vielleicht ebenfalls etwas für euch?

Fragen? Einfach melden.

Dead-Link-Checker für die Konsole: Effektive Tools im Überblick

Tote Links auf einer Webseite zu suchen, kann aufwendig sein. Es gibt viele Angebote im Internet, diese sind aber meist auf eine gewisse Anzahl Seiten beschränkt und ab dann kostenpflichtig.

Ich mag Tools, die einen Job gut können und dieses möglichst einfach erledigen. Daher habe ich für diesen Fall den LinkChecker für die CLI.

404 ERROR mit totem gehäkelten Link von Selder.

Das Tool ist schnell per pip installiert:

pip3 install linkchecker

Die Bedienung ist nicht viel komplizierter:

linkchecker https://www.kernel-error.de

Ohne weitere Angaben läuft das Tool mit 10 threads los, dieses lässt sich über die Option -t erweitern:

linkchecker -t 200 https://www.kernel-error.de

Nun läuft das Tool über die komplette Webseite und prüft alle Links, ist einer kaputt, meldet das Tool dieses. Dabei bekommt man direkt die Informationen, was verlinkt wurde, was der eigentliche Link ist und auf welcher seiner Seiten sich dieses befindet. So lässt sich ohne große Mühe und Arbeit nach toten Links suchen und diese im Anschluss beheben.

URL        `www.kernel-error.de'
Parent URL https://www.kernel-error.de/en/lala/seite, line 746, col 17
Real URL   https://www.kernel-error.de/en/lala/zeugen
Check time 67.089 seconds
Result     Error: 404 Not Found

Viel Spaß!

Link zur Dead Link Bild Quelle: https://www.deviantart.com/amiamalilium/art/It-looks-like-you-found-a-dead-link-365756737

Fragen? Einfach melden.

Kodi auf dem Raspberry Pi 4: Ruckelfreie Wiedergabe einrichten

Der Raspberry Pi 4 , egal ob mit 4GB oder 8GB RAM, ist in der Kombination mit Kodi eine wunderbare Erweiterung am Fernseher. Leider sorgte die letzte Version Kodi v19.3 (Matrix) bei mir für ein paar Problemchen. So stockte oder ruckelte die Wiedergabe von Videos oder die Wiedergabe lief für einige Minuten gut, dann wurde gebuffert, nur damit sich dieses Spielchen alle paar Minuten wiederholte. Egal ob im WLAN oder direkt am LAN.

Folgende Änderungen haben bei mir für eine Lösung der Probleme gesorgt:

  1. Erstellen einer XML Datei, welche die default Einstellungen des Cachings überschreibt.

    Speicherort und Dateiname ist: /storage/.kodi/userdata/advancedsettings.xml
<?xml version="1.0" encoding="utf-8"?>
<advancedsettings>
        <cache>
                <memorysize>524288000</memorysize>
                <buffermode>1</buffermode>
                <readfactor>6</readfactor>
        </cache>
</advancedsettings>

Achtung… Bei XML Dateien, spielt das richtige „Einrücken“ schon mal eine Rolle.

2. Erweitern des Arbeitsspeichers für die GPU, sowie das Erzwingen des „Turbo“ Modus.
Dafür einfach die Datei /flash/config.txt um folgende Zeilen erweitern/einpassen:

# Default GPU memory split, 76MB are needed for H264 decoder
gpu_mem=256
force_turbo=1

Wer dieses gerne per SSH machen möchte, muss das Volume /flash einmal schreibfähig mounten:

mount -o remount,rw /flash

Die Option gpu_mem setzt recht einfach den, für die Grafikkarte, reservierten Arbeitsspeicher fest auf 256MB. Dieses macht selbst bei der 4GB Raspberry PI 4 Version kein Problem.

force_turbo deaktiviert das dynamische, lastabhängige takten der CPU, GPU und des Arbeitsspeichers, sowie der Spannungen. Alles läuft daher auf Maximum, aber ohne zu übertakten. Dieses hat weniger Auswirkungen auf die Probleme bei der Wiedergabe, sorgt aber für ein allgemein „flüssigeres“ Verhalten. Dafür steigt die Stromaufnahme und die Temperatur. Da wir hier über einen Raspberry sprechen, ist es wohl für die Meisten zu vernachlässigen.

3. Um Temperatur und Geräuschpegel im Zaum zu halten, empfiehlt sich ein gutes passiv gekühltes Gehäuse. Folgendes kann ich empfehlen: https://amzn.to/3qF61pe

Das mitgelieferte Netzteil hat ausreichend Power, man kommt noch an „alles“ ran, das Gehäuse ist sehr massiv und selbst bei großer Last/langem Betrieb, wird alles nur handwarm.


Update Februar 2026 — Kodi 21 (Omega) / LibreELEC 12.x

Seit Kodi 21 (Omega), das mit LibreELEC 12.x ausgeliefert wird, funktioniert die oben beschriebene Cache-Konfiguration über die advancedsettings.xml nicht mehr korrekt. Die <cache> Sektion wird zwar noch eingelesen und im Log angezeigt — die tatsächlich aktiven Werte kommen aber aus den GUI-Settings (guisettings.xml). Im Kodi-Log erkennt man das an dieser Zeile:

New Cache GUI Settings (replacement of cache in advancedsettings.xml) are:
    Buffer Mode: 4
    Memory Size: 20 MB
    Read Factor: 4.00 x

Das bedeutet: Trotz konfigurierter 500 MB in der advancedsettings.xml läuft Kodi mit nur 20 MB Puffer — dem Default. Nicht gerade ideal.

Die neue Methode

Die Cache-Werte müssen jetzt direkt in /storage/.kodi/userdata/guisettings.xml gesetzt werden. Dafür Kodi stoppen, Datei bearbeiten, Kodi starten:

systemctl stop kodi
sleep 3

In der guisettings.xml diese drei Zeilen suchen und anpassen. Wichtig: Das default="true" muss entfernt werden, damit Kodi die Werte als benutzerdefiniert erkennt.

Vorher:

<setting id="filecache.buffermode" default="true">4</setting>
<setting id="filecache.memorysize" default="true">20</setting>
<setting id="filecache.readfactor" default="true">400</setting>

Nachher (Beispiel für 8 GB RAM):

<setting id="filecache.buffermode">1</setting>
<setting id="filecache.memorysize">500</setting>
<setting id="filecache.readfactor">600</setting>

Dann Kodi wieder starten:

systemctl start kodi

Was die Werte bedeuten

buffermode = 1

Legt fest, welche Quellen gepuffert werden:

WertBedeutung
0Nur Internet-Streams (HTTP, FTP…)
1Alles (Internet + LAN + lokal) ← empfohlen
2Nur „echte“ Internet-Streams
3Kein Puffer
4Alle Netzwerk-Quellen (Default in Kodi 21)

Wir setzen 1 statt 4, damit NFS-Quellen garantiert gepuffert werden — egal wie Kodi die Quelle intern klassifiziert.

memorysize = 500 (bzw. 250)

Die Größe des Puffers in MB. Das ist der Speicher, den Kodi im RAM reserviert, um Film-Daten vorauszulesen.

Praktisches Beispiel: Ein typischer 4K-Film hat ~80 Mbit/s Bitrate (ca. 10 MB/s).

  • 20 MB (Default): Nur ~2 Sekunden Film im Puffer. Wenn das Netzwerk kurz schwankt, stockt die Wiedergabe sofort.
  • 500 MB: Ca. 50 Sekunden Film im Puffer. Selbst wenn NFS mehrere Sekunden hängt, läuft die Wiedergabe weiter.

Empfohlene Werte nach verfügbarem RAM:

  • 8 GB RAM: memorysize = 500
  • 4 GB RAM: memorysize = 250

readfactor = 600 (= 6×)

Der Wert wird intern durch 100 geteilt, also 600 = 6,0×. Kodi liest Daten mit der 6-fachen Geschwindigkeit der benötigten Bitrate voraus. Bei einem 80 Mbit/s Film liest Kodi also mit ~480 Mbit/s vom NFS, bis der Puffer voll ist. Danach drosselt es auf die tatsächlich benötigte Rate. Das sorgt dafür, dass der Puffer sich schnell füllt und möglichst voll bleibt.

Verifizierung

Nach dem Neustart im Kodi-Log prüfen, ob die neuen Werte aktiv sind:

grep "New Cache GUI Settings" -A4 /storage/.kodi/temp/kodi.log

Hinweis zum Raspberry Pi 5

Die config.txt Anpassungen (gpu_mem=256 und force_turbo=1) gelten weiterhin für den Raspberry Pi 4. Beim Raspberry Pi 5 sind diese nicht nötig — er nutzt eine andere GPU-Architektur (VideoCore VII) und gpu_mem hat dort keine Wirkung.

Jetzt mit HTTP/3 und QUIC: Schnelleres Surfen leicht gemacht

Von QUIC habt ihr sicher alle schon gehört, seit knapp Mitte 2021 ist dieser neue Standard fertig und in einem recht einfach zu merkendem RFC 9000 beschrieben.

Im Grunde geht es darum, HTTP-Verbindungen schneller zu machen und dabei sogar UDP zum Einsatz zu bringen. Nicht ganz korrekt ist es einfach eine Weiterentwicklung von SPDY.

Um zu testen, ob eine Webseite bereits HTTP/3 also QUIC unterstützt, kann ich euch http3check.net ans Herz legen. Diese gibt, wenn gewünscht, sogar noch ein paar Detailinformationen aus.

Wer sehen möchte, ob sein Browser QUIC „macht“, kann auch nginx.org nutzen. Steht oben „Congratulations! You’re connected over QUIC.“ Dann ist man ein Gewinner.

Die Konfiguration am Nginx ist wie immer sehr einfach und ein sehr gutes Beispiel findet sich direkt von nginx.

Mein Nginx spricht dieses nun ebenfalls, mal sehen ob es Probleme gibt.


Update März 2026: Drei Jahre HTTP/3 im Betrieb

Es sind jetzt gut drei Jahre vergangen und ich kann sagen: Es gab keine Probleme. Kein einziges. HTTP/3 läuft hier seit 2022 auf allen vHosts und ich habe nie einen Fehler gesehen, der auf QUIC zurückzuführen war. Auch in den Logfiles nichts Auffälliges.

Illustration zu HTTP/3 und QUIC: schneller Web-Transport über UDP mit moderner Verschlüsselung und Browser-Support

Was sich geändert hat: Damals war HTTP/3 in Nginx noch experimentell und brauchte einen separaten Build mit dem quiche-Patch oder BoringSSL. Seit Nginx 1.25.0 (Mai 2023) ist HTTP/3 offiziell im Mainline-Branch enthalten und wird mit dem normalen --with-http_v3_module Build-Flag aktiviert. Kein Patch mehr, kein BoringSSL mehr, einfach OpenSSL 3.x und fertig. Mein aktueller Stack: Nginx 1.29.4 mit OpenSSL 3.5.4 auf FreeBSD 15.

Was bringt HTTP/3 in der Praxis?

Der größte Vorteil von QUIC gegenüber TCP ist die Verbindungsaufbauzeit. Bei TCP+TLS braucht ihr mindestens zwei Roundtrips, bevor Daten fließen (TCP Handshake + TLS Handshake). QUIC macht das in einem einzigen Roundtrip. Bei einem Wiederverbindungsversuch sogar in null Roundtrips (0-RTT).

Auf einer Glasfaserleitung mit 5 ms Latenz merkt ihr das kaum. Aber auf einem Smartphone im Zug mit 80 ms Latenz und gelegentlichem Paketverlust macht das einen spürbaren Unterschied. Dazu kommt, dass QUIC auf UDP basiert und damit das Head-of-Line-Blocking Problem von TCP löst: Ein verlorenes Paket blockiert nicht mehr alle Streams, sondern nur den einen betroffenen.

Konfiguration 2026

Die Konfiguration hat sich seit 2022 etwas verändert. Hier mein aktuelles Setup für den Blog-vHost:

server {
    listen [::]:443 ssl;
    listen [::]:443 quic;

    http2 on;

    server_name  www.kernel-error.de;

    # TLS (wird per include eingebunden)
    include tls-default.conf;
    ssl_certificate      /path/to/fullchain.pem;
    ssl_certificate_key  /path/to/privkey.pem;

    # ...
}

Wichtig sind zwei Dinge. Erstens: Der quic Listener läuft auf demselben Port 443 wie der SSL-Listener, nur eben über UDP statt TCP. Zweitens: Die Clients müssen wissen, dass HTTP/3 verfügbar ist. Das passiert über den Alt-Svc Header:

add_header Alt-Svc 'h3=":443"; ma=86400' always;

Dieser Header sagt dem Browser: „Ich spreche auch h3 auf Port 443, merk dir das für 24 Stunden.“ Beim nächsten Besuch nutzt der Browser dann direkt QUIC. Ohne diesen Header bleibt alles bei HTTP/2 über TCP.

Optional könnt ihr auch einen HTTPS-DNS-Record (SVCB) setzen, damit der Browser schon beim DNS-Lookup weiß, dass HTTP/3 verfügbar ist:

$ dig +short HTTPS www.kernel-error.de
1 . alpn="h3,h2" ipv4hint=148.251.30.200 ipv6hint=2a01:4f8:262:4716::443

Mit alpn="h3,h2" im HTTPS-Record kann der Browser die QUIC-Verbindung schon beim allerersten Besuch aufbauen, ohne erst auf den Alt-Svc Header warten zu müssen.

Firewall nicht vergessen

Ein Klassiker, der mich 2022 kurz stolpern ließ: QUIC braucht UDP Port 443. Wenn eure Firewall nur TCP 443 durchlässt, sehen die Clients den Alt-Svc Header, versuchen QUIC und laufen ins Timeout. Auf FreeBSD mit pf:

pass in quick on $ext_if proto udp to $jail_nginx port 443

Post-Quantum-Kryptografie inklusive

QUIC verwendet intern TLS 1.3 für die Verschlüsselung. Das heißt: Wenn ihr in eurer Nginx-TLS-Konfiguration X25519MLKEM768 als Key-Exchange-Gruppe konfiguriert habt, gilt das automatisch auch für QUIC-Verbindungen. Kein extra Aufwand. Euer HTTP/3 Traffic ist dann ebenfalls mit hybridem Post-Quantum-Schlüsselaustausch abgesichert.

Browser-Support

2022 war HTTP/3 noch ein Feature für Early Adopter. 2026 ist es Standard. Chrome, Firefox, Safari und Edge unterstützen QUIC seit Jahren. Laut den Logfiles dieses Blogs nutzen inzwischen gut 40% der Besucher HTTP/3. Tendenz steigend, weil immer mehr Mobilgeräte von dem schnelleren Verbindungsaufbau profitieren.

Wer es noch nicht aktiviert hat: Der Aufwand ist minimal, die Vorteile real und das Risiko gleich null. Drei Jahre Betrieb ohne ein einziges Problem sprechen für sich.

Siehe auch: HTTPS RR und SVCB Records — per DNS-Record signalisieren, dass HTTP/3 verfügbar ist. Damit können Clients direkt mit QUIC starten, ohne vorher TCP zu probieren.

Wechsel zur WordPress

Ich nutze Joomla seit 2006, als es aus Mambo hervorging. Die Datenbank und einige Plugins/Teils sind inzwischen also sehr alt und machen bei Versionssprüngen immer mehr Probleme. Den Wechsel vom CMS habe ich dennoch immer von mir weggeschoben, denn es macht viel Arbeit und für eine solch kleine Spielerei lohnt der Aufwand kaum. Da ich es inzwischen eh nur noch für einfache Blogeinträge nutze… Nun ich werde wohl in der nächsten Zeit auf WordPress wechseln. Damit wird es ebenfalls einen neuen RSS Feed geben und sicher wird ebenfalls viel Content verschwinden.

Fragen? Einfach melden.

Lieber Thorben,

Lieber Thorben,

vielen Dank, dass du uns so lange ertragen hast. Du hast unsere Arbeit leichter und bunter gemacht. Ohne dich hätten wir sicher schon die Raufasertapete mehr als einmal von der Wand gefressen.
Vielen Dank für deine Unterstützung in technischer und menschlicher Weise! Wir werden dich NIE vergessen!

Liebe Grüße
Die zwei „Dicken“

FreeBSD: Unverschlüsseltes ZFS-Dataset nachträglich verschlüsseln

Bild der Bücher FreeBSD Mastery ZFS und FreeBSD Mastery Advanced ZFS

ZFS Encryption lässt sich nicht nachträglich auf ein bestehendes Dataset aktivieren. Die Daten müssen per zfs send | zfs receive in ein neues, verschlüsseltes Dataset geschrieben werden. Typischer Anwendungsfall: Jails, die in eigenen Datasets liegen und nach einem FreeBSD-Upgrade auf 13+ verschlüsselt werden sollen.

Wer die Grundlagen zu ZFS Encryption noch braucht (Dataset anlegen, Passphrase, Mount nach Reboot), findet sie im Beitrag Native ZFS Encryption einrichten.

Ausgangslage

Ein Pool zroot mit dem unverschlüsselten Dataset varta:

zfs list zroot/varta
NAME          USED  AVAIL     REFER  MOUNTPOINT
zroot/varta   100M  12.0G      100M  /zroot/varta

zfs get encryption zroot/varta
NAME         PROPERTY    VALUE   SOURCE
zroot/varta  encryption  off     default

Migration

Bei zfs send | zfs receive kann man kein Passphrase interaktiv eingeben, weil stdin durch die Pipe belegt ist. Deshalb legt man den Schlüssel temporär in einer Datei ab:

echo 'MeinGeheimesPassphrase' > /tmp/keyfile.txt
chmod 600 /tmp/keyfile.txt

Snapshot erstellen und in ein neues verschlüsseltes Dataset senden:

zfs snapshot zroot/varta@migration

zfs send zroot/varta@migration | \
  zfs receive -F \
  -o encryption=on \
  -o keyformat=passphrase \
  -o keylocation=file:///tmp/keyfile.txt \
  zroot/en-varta

Das neue Dataset zroot/en-varta enthält jetzt dieselben Daten, verschlüsselt mit AES-256-GCM:

zfs list zroot/varta zroot/en-varta
NAME             USED  AVAIL     REFER  MOUNTPOINT
zroot/en-varta   100M  11.8G      100M  /zroot/en-varta
zroot/varta      100M  11.8G      100M  /zroot/varta

Aufräumen

Die Keyfile-Referenz auf Passphrase-Abfrage umstellen und die temporäre Datei löschen:

zfs set keylocation=prompt zroot/en-varta

zfs get keylocation zroot/en-varta
NAME            PROPERTY     VALUE   SOURCE
zroot/en-varta  keylocation  prompt  local

rm /tmp/keyfile.txt

Dann das alte Dataset entfernen und das neue umbenennen:

zfs destroy -r zroot/varta
zfs rename zroot/en-varta zroot/varta

Fertig. Das Dataset liegt jetzt verschlüsselt am selben Mountpoint wie vorher:

zfs get encryption,keylocation,keyformat zroot/varta
NAME         PROPERTY     VALUE        SOURCE
zroot/varta  encryption   aes-256-gcm  -
zroot/varta  keylocation  prompt       local
zroot/varta  keyformat    passphrase   -

Hinweise

Bei Jails: Jail vorher stoppen, nach der Migration den Mountpoint anpassen falls nötig (zfs set mountpoint=...), dann neu starten. Bei großen Datasets dauert der zfs send | zfs receive entsprechend lange. Ein Test mit einem kleinen Dataset vorher schadet nicht.

Eine Übersicht über alle ZFS-Funktionen gibt es im ZFS-Überblick. Fragen? Einfach melden.

RIDEN RD6006: Reparatur der defekten Schottky-Diode S10C100D

Vor einigen Monaten habe ich ein neues Labornetzteil aus China gekauft. AliExpress Labornetzteil – RIDEN RD6006 DC POWER SUPPLY

Defekte S10C100D-02 Schottky Diode

Bisher arbeitet dieses Gerät vor sich hin und hat auch bereits einige kWh abgeleistet. Als Fazit… Das Netzteil tut seinen Job, die grüne Schraubklemme verwechselt man schnell mit PE, ist aber zum Laden von Akkus und am Oszilloskop kann man sehr gut einiges „switching noise“ erkennen. Wenn man sich dessen bewusst ist, gibt es kaum etwas, was man gegen dieses Netzteil sagen kann. Preis / Leistung ist einfach unschlagbar!

Selbst die Ladefunktion für Akkus funktioniert tadellos, wenn auch manuell. Das Netzteil erkennt nicht selbstständig den Akku, sondern man muss dem Netzteil sagen, was es tun muss.

In der Zwischenzeit habe ich es ebenfalls etwas „missbraucht“, um ein paar alte Blei gel Akkus wieder zu beleben. Dabei hat sich leider ein kleines Problemchen ergeben…. Mir ist eine Schottky-Diode geplatzt, genauer die S10C110D vom RIDEN RD6006. Diese ist auf dem Board mit D12 gekennzeichnet. Wenn man in die >>Specs<< dieser Diode schaut, sieht es so aus, als wenn sie eine Art Verpolungsschutz beim Akkulader ist. Nun ist mir nicht bewusst aufgefallen, dass ich hier etwas verpolt habe. Die kaputte Diode (vor allem mit den Leistungsdaten) sagen dazu etwas anders.

Nun wollte ich schnell Ersatz bestellen, leider konnte ich nichts Passendes finden. Klar ich hätte hier und da etwas kombinieren können, nur wollte ich dieses nicht.

Hangzhou Ruideng Technology Co., Ltd. bietet zur Kontaktaufnahme WeChat (15868147353) an. Wie ich lernen durfte, ist es nicht ganz trivial, als nicht Festlandchinese WeChat zu nutzen. Ich meine inzwischen zusätzliche Kontaktmöglichkeiten gefunden zu haben. Durch die Unterstützung eines Bekannten (DANKE JOST), lief es irgendwann und ich konnte das Unternehmen RD Tech in China darüber erreichen.

Der Support dabei war extrem gut. Schnell, super freundlich, sehr hilfsbereit und kompetent.

Zusammen mit dem Support konnten wir das komplette Labornetzteil durch testen und sicherstellen, dass wirklich nur diese eine Diode def. ist. Absoluter Service von RD Tech, eigentlich wollte ich nur nach dem Ersatzteil fragen. Dieses habe ich am Ende ebenfalls bekommen, sogar direkt 5 Stück davon und noch zwei Sicherungen als Reserve (da hat wohl jemand den Verdacht, ich könnte noch mehr kaputt machen). Zahlen musste ich nur 3€ für den Versand.

Der Versand von China zu mir hat natürlich ein paar Tage gedauert, heute ich alles angekommen.

Inzwischen verbaut und das Netzteil ist wieder voll funktionsfähig!

Ich möchte hier noch einmal ganz besonders den Support von RD Tech hervorheben. Englisch war überhaupt kein Problem (was mir vorher etwas Sorgen bereitete), es hat sich wirklich jemand knapp 2 Stunden Zeit genommen um mir bei meinem Problem zu helfen und derjenige war wirklich daran interessiert, mein Problem zu lösen. Alles für 0€. Ich habe kostenlos viel mehr Ersatzteile bekommen, als ich eigentlich haben wollte. Ich musste, wie schon erwähnt, nur den Versand bezahlen. Wenn ich dann also noch mal etwas Werbung machen darf: YouTube link

Siehe auch: RD6006 Zusammenbau und erster Eindruck

Fragen? Einfach melden.

« Ältere Beiträge Neuere Beiträge »

© 2026 -=Kernel-Error=-RSS

Theme von Anders NorénHoch ↑