Mijn Blog // Digitaal archief

Gedachten, projecten en technische notities

Oorspronkelijk was mijn blog-setup gepland als een puur IPv6-project via WireGuard, omdat het geheel op een homeserver draait (gratis IPv6-adressen kun je overigens krijgen bij route64.org). Om de bereikbaarheid te vergroten, heb ik nu een externe IPv4-proxy toegevoegd (met dank aan @Larvitz).

Daarbij ontstonden echter direct SSL-problemen: Omdat oorspronkelijk zowel het A- als het AAAA-record via de proxy liepen, mislukte de Let's Encrypt-validatie op mijn server.

De oplossing: De „IPv6-hack“

De oplossing was om het AAAA-record expliciet rechtstreeks naar het WireGuard-IP van mijn server te laten verwijzen, in plaats van dit ook via de proxy te leiden.

  • Domein: blog.burningboard.org
  • A-record (Proxy): 194.28.98.217
  • AAAA-record (Server): 2a11:6c7:f05:a8::2 (WireGuard)

Door dit directe AAAA-record naar mijn WireGuard-IP bereikt Let’s Encrypt mijn server nog steeds rechtstreeks via IPv6 (omdat het AAAA-record standaard prioriteit krijgt) en wordt het SSL-certificaat uitgegeven. Het IPv4-verkeer wordt door de proxy versleuteld naar mij doorgegeven.

De uiteindelijke configuratie

Om de communicatie soepel te laten verlopen, moesten we de Caddy-servers aanpassen:

1. Op mijn server (NixOS, blog.nix)

Om ervoor te zorgen dat de echte IP-adressen van bezoekers correct aankomen en niet worden overschreven door het IP van de proxy, moet deze als vertrouwd worden gemarkeerd:

services.caddy.globalConfig = ''
  servers {
      trusted_proxies static 2a06:9801:1c:1000::10
  }
'';

2. Op de externe proxy (Caddy)

Om ervoor te zorgen dat de proxy mijn server correct via HTTPS benadert, moet deze de hostnaam (SNI) meesturen:

reverse_proxy [https://[2a11:6c7:f05:a8::2]:443](https://[2a11:6c7:f05:a8::2]:443) {
    header_up Host {host}
    transport http {
        tls_server_name blog.burningboard.org
    }
}

De blog is nu bereikbaar via IPv4 en IPv6, veilig versleuteld en mijn thuis-IP blijft toch privé! 🚀

Het belangrijkste eerst: de vertrouwde Markdown-bestanden blijven de basis – ik ben simpelweg een groot fan van deze ongecompliceerde oplossing. Maar onder de motorkap is er veel veranderd:

Ik heb flink aan de setup gesleuteld:

📂 MD-bestanden: De blogstructuur blijft simpel op Markdown-basis.

🌍 Globaler dan ooit: Mijn blog ondersteunt nu vertalingen in 43 talen. Ja, inclusief Klingon! 🖖 (Qapla'!)

Het plan was een volautomatische real-time vertaling op basis van de taalherkenning van de browser. Spoiler: het werkte maar gedeeltelijk. Je merkt: AI is indrukwekkend, maar nog niet helemaal "daar" waar we het graag zouden willen hebben.

De oplossing: ik vertaal nu simpelweg elk bericht vooraf in alle vastgestelde talen, wat ook aanzienlijk beter is voor de zoekmachines (SEO) is. Mocht de automatische herkenning een keer niet werken, dan kun je via het wereldbol-icoontje handmatig je voorkeurstaal instellen, die vervolgens heel eenvoudig via een cookie wordt opgeslagen.

De vertalingen worden nu uitgevoerd met Gemini 3 Flash, wat verbazingwekkend goede resultaten oplevert. Je moet de AI echter wel goed in de gaten houden: in de eerste bulk-ronde werden per ongeluk ook de tags meevertaald, wat natuurlijk niet de bedoeling was.

De code is nog steeds beschikbaar (stuur me bij interesse gewoon een bericht) 👍 Houd er wel rekening mee dat het systeem nu een eigen Gemini API Key 🔑 nodig heeft.

Ik heb onlangs mijn blog overgezet van WriteFreely naar een eigen ontwikkeling: MD-Blog (de MD staat natuurlijk voor Markdown). De aanleiding was een mislukte update van het oude systeem – uiteindelijk was dit echter de perfecte stimulans om alles radicaal te vereenvoudigen en de volledige controle over het design te krijgen.

De kern bestaat uit eenvoudige Markdown-bestanden in de data/-map, die tijdens runtime worden omgezet in modern HTML. Het resultaat is razendsnel, werkt zonder database en ziet er dankzij een eigen design-systeem (inclusief Dark Mode) nu precies zo uit als ik me had voorgesteld. Zelfs een moderne Mastodon-deelknop is nu direct inbegrepen.

Mocht je interesse hebben in de code of de slanke setup, neem dan gerust contact met me op via Mastodon!

Eigenlijk is het idee achter #Winboat uitstekend, maar de uitvoering lijkt momenteel nog wat onstabiel te zijn. Sinds de installatie aan het begin van het jaar draaide het systeem weliswaar, maar vandaag weigerde de software volledig dienst.

De image meldde plotseling onvoldoende werkgeheugen (RAM). Ik heb nog geprobeerd het probleem handmatig op te lossen, maar dat heeft het systeem helaas definitief onbruikbaar gemaakt. In plaats van meer tijd te steken in het opsporen van de fout, ben ik direct overgestapt op de Dockurr Windows-image – deze vormt sowieso de technische basis van Winboat.

Foutmelding

1. Voorbereiding

Omdat ik Podman gebruik, heb ik eerst de benodigde mappen op mijn host-systeem aangemaakt. Zo blijft de data-integriteit gewaarborgd als de container opnieuw moet worden aangemaakt:

mkdir -p $HOME/Windows/System
mkdir -p $HOME/Windows/Shared

2. Het startcommando

Belangrijke opmerking: Vervang in de variabelen -e USERNAME en -e PASSWORD de tijdelijke aanduidingen door je persoonlijke inloggegevens.

podman run -d \
  --name windows \
  -p 8006:8006 \
  --device=/dev/kvm \
  --cap-add NET_ADMIN \
  -e RAM_SIZE="8G" \
  -e USERNAME="Carsten" \
  -e PASSWORD="1234" \
  -e LANGUAGE="German" \
  -v $HOME/Windows/System:/storage:Z \
  -v $HOME/Windows/Shared:/shared:Z \
  --stop-timeout 120 \
  dockurr/windows

Zodra de container actief is, kun je de Windows-instantie direct via je browser openen:

http://127.0.0.1:8006

Draaiende container

3. Samenvatting

Het bovenstaande commando hoefde ik slechts één keer uit te voeren. In het dagelijks gebruik kan de Windows-omgeving nu heel comfortabel via deze snelkoppelingen worden aangestuurd:

  • Starten: podman start windows
  • Stoppen: podman stop windows (of direct binnen Windows afsluiten)
  • Status controleren: podman ps -a

Verdere links:

Ik heb een eigen blog geïnstalleerd — vooral om #NixOS beter te leren kennen. Verrassend genoeg ging dat allemaal vrij ongecompliceerd.

WriteFreely past daar erg goed bij: minimalistisch, snel opgezet en zonder veel ballast. Perfect om gewoon aan de slag te gaan en gaandeweg wat bij te leren. De configuratie is prettig overzichtelijk. Een paar opties instellen, map voorbereiden, reverse proxy ervoor — klaar.

Zo ziet mijn huidige NixOS-configuratie hiervoor eruit:

{ config, pkgs, ... }:

{
  services.writefreely = {
    enable = true;
    host = "blog.burningboard.org"; 
    settings = {
      server = {
        port = 8080;
        min_log_level = "debug";
      };
      app = {
        host = "https://blog.burningboard.org";
        single_user = true;
        landing = "/read";
        wf_modesty = true;
        federation = true;
        public_stats = true;
        theme = "write";
      };
    };
    stateDir = "/opt/writefreely";
  };

  # Fix voor de ActivityPub-sleutelgeneratie: federatie vereist openssl
  systemd.services.writefreely.path = [ pkgs.openssl ];

  # Automatisch aanmaken van de datamap met de juiste rechten
  systemd.tmpfiles.rules = [
    "d /opt/writefreely 0700 writefreely writefreely -"
  ];

  services.caddy.virtualHosts."blog.burningboard.org".extraConfig = ''
    reverse_proxy 127.0.0.1:8080 {
      header_up Host {host}
      header_up X-Real-IP {remote_host}
      header_up X-Forwarded-For {remote_host}
      header_up X-Forwarded-Proto {scheme}
    }
  '';
}

Dat was het in essentie. NixOS maakt het echt eenvoudig om dit soort diensten netjes te configureren en reproduceerbaar te houden.