RSSAmplifier

Blog

/dev/io

Yak shaving, documented.

blog.iodev.orgRSS feed ↗42 posts

Latest posts

DMARC reports are the only outside view of your mail

Self-hosting mail means taking over deliverability from a provider. Stalwart reports on its own work; only receivers can tell you whether your DKIM actually aligns.

Kernel 6.18.38 inflates diskstats latency by the uptime

Disk latency on my hypervisor looked like it had been climbing for three weeks: ratenodediskwritetimesecondstotal5m / ratenodediskwritescompletedtotal5m gave seconds per write on an NVMe mirror, while

Attic Has No Metrics Endpoint: Monitoring It via SQLite

Attic exposes no /metrics and logs nothing by default. The numbers are in its SQLite database: 2.45x savings, and what GC will actually reap.

Open Source Firefox Extensions: Most Don't Publish Code

Of 71,433 Firefox extensions carrying an open source license on AMO, only 18,734 link a public repository. I built ffext to rank them by what you can check.

iPhone notifications in Home Assistant with ANCS

An ESP32 bonds with my iPhone over Bluetooth and republishes its notifications to Home Assistant, so apps with no integration become sensor state and history.

archive.is stopped loading: EDNS Client Subnet

archive.is resolved instantly but returned an IP that dropped port 443. The cause was ECS-stripping upstreams plus a one hour minimum cache TTL.

Relaying outbound mail: DKIM, client IPs, and visibility

If you run your own mail server but send through a provider, the relay changes the message and the picture you get of it. Here is what to sign, how to keep client addresses, and where your delivery data ends.

Running mail at home without sending mail from home

I moved mailbox storage and inbound mail to Stalwart at home, while leaving outbound reputation and transactional delivery to a provider.

Recovering an old Acronis TIB archive on Linux

I reverse engineered a 22 GiB Acronis True Image backup chain and wrote a read-only Go extractor for its complete snapshots.

Reverse-engineering the iOmeter Bridge's Bluetooth onboarding

Working out the iOmeter Bridge's BLE onboarding protocol - GATT, HDLC framing, gRPC-over-Bluetooth - to do what the app won't: join a hidden Wi-Fi network. Plus a first look at pointing it at my own MQTT broker instead of the vendor cloud.

Inside the SwitchBot AI Art Frame

Reverse-engineering a Tuya-OEM e-ink frame: the BLE protocol, a public S3 bucket, a hardcoded AES key for cloud creds, and why the firmware blob is a dead end.

Matter over Thread across VLANs

Flashing a SONOFF dongle as a Thread radio, running the border router in Home Assistant, and routing the Thread mesh to a separate client VLAN from a NixOS router.

Lelit Mara X touchscreen with ESPHome

Tapping the Lelit Mara X read-only diagnostic UART and putting boiler and HX temperatures on a 3.5-inch panel with ESPHome and LVGL 9.

Building Kinesis Advantage 360 Pro Firmware with Nix

Using zmk-nix to build ZMK firmware for the Kinesis Advantage 360 Pro with a reproducible Nix flake, no Docker or GitHub Actions needed.

A Year of Hetzner Auction Data: Where Did All the Servers Go?

A year of Hetzner auction data: weekly volume down 43% since February, EPYC and Ryzen 9 inventory cratering, restocks shifting to budget CPUs.

Running a RIPE Atlas Probe on NixOS with Starla

Starla is a Rust reimplementation of the RIPE Atlas software probe with a NixOS module and Prometheus metrics. Here's why I run it and what setup looks like.

Why do agents always speak text?

A thought about binary I/O between LLM agents and the tools they call.

Receiving OpenRouter OTLP traces in Grafana Tempo

OpenRouter can broadcast OTLP traces for every LLM request. I set up Grafana Tempo to receive them and built a dashboard for model usage, costs, and latency.

AliExpress orders fulfilled by Amazon

Ordered something on AliExpress and it arrived in an Amazon package. Turns out some AliExpress merchants use Amazon fulfillment they stock inventory in Amazon warehouses and ship from there. Explains

Push metrics from Cloudflare Workers to Prometheus via OTLP

Cloudflare Workers are stateless and can't be scraped. Here's how I built a lightweight OTLP client to push counters and histograms to Prometheus.

Cloudflare for SaaS: your old provider can silently keep your domain

My apex domain kept redirecting to the old host after migration, despite correct DNS and certs. A stale Cloudflare for SaaS custom hostname was to blame.

Caddy ACME DNS-01 fails with split-horizon DNS

If you run a local DNS resolver with custom entries splithorizon DNS, Caddy's DNS01 ACME challenges can fail silently. Caddy queries your local resolver to verify the acmechallenge TXT record, but you

DNS-over-QUIC (DoQ) upstream support in Blocky

I implemented DoQ upstream support in Blocky and cut cold encrypted-DNS latency from 20ms to 4ms. Now merged upstream in Blocky 0.30.0.

Adding machinectl support to microvm.nix

Making microvm.nix VMs show up in machinectl and reachable over SSH-via-VSOCK, using the RegisterMachineEx machined API added in systemd 259.

curl: certificate rejected (28) on Cloudflare sites

curl fails with 'certificate rejected (28)' on Cloudflare-hosted sites after NSS 3.111 distrusted the AAA Certificate Services root.

qBittorrent throughput tuning on NixOS over WireGuard

Tuning qBittorrent throughput inside a WireGuard VPN namespace on NixOS: BBR congestion control, TCP buffer sizing, disk I/O threads, and systemd priorities.

BBR and larger TCP buffers for WireGuard tunnels

Default CUBIC congestion control undershoots throughput on WireGuard tunnels. Switching to BBR and increasing TCP buffer sizes made a noticeable difference for torrent racing: BBR needs fq as the qdis

iBGP over WireGuard for DN42 routing

iBGP over a WireGuard tunnel to propagate DN42 routes from a VPS to the home network, replacing fragile static routes. Why Tailscale won't do it.

Monitoring the *arr Stack on NixOS

Setting up Prometheus and Loki monitoring for Radarr, Sonarr, and Prowlarr with Exportarr metrics and log-based alerting on NixOS.

Bypassing Telekom's Cloudflare Congestion with Tailscale

Routing Cloudflare traffic through a VPS with Tailscale to work around Telekom's peering bottleneck. Connection times dropped from 11s to under 400ms.

Netzbremse: Telekom throttles peering with Cloudflare

Deutsche Telekom refuses to peer properly with Cloudflare, degrading a fifth of the internet for German fiber customers. A rant about monopoly rent-seeking.

Live homelab stats on a Cloudflare Workers blog

Wiring a Cloudflare Workers blog to a homelab Prometheus behind a dynamic IP, using SigV4-signed requests and edge caching to show live uptime and stats.

CAKE SQM traffic shaping on NixOS

Setting up CAKE SQM on NixOS to fix bufferbloat on a 1 Gbit fiber PPPoE line, including IFB ingress shaping and overhead compensation for a low-latency A rating.

WireGuard failover on NixOS with Prometheus

Automatic failover across multiple WireGuard VPN endpoints on NixOS, using systemd services and Prometheus packet-loss metrics to switch to the healthiest server.

Booting into Rescue Mode with a Locked Root Account

If your root account is locked common on NixOS, systemd's rescue mode normally refuses to start. Add systemd.setenv=SYSTEMDSULOGINFORCE=1 to the kernel command line and it will drop you into a shell r

Auto-updating ESPHome Devices with Home Assistant

Automating ESPHome firmware updates across multiple devices using Home Assistant automations.

Telekom Glasfaser with Zyxel SFP ONT

Replacing Deutsche Telekom's fiber modem with a Zyxel PMG3000-D20B SFP module to plug fiber directly into the switch.

My Favorite Firefox Extensions

A curated list of Firefox extensions for privacy, usability, and development that I use daily.

Cloning a live OPNsense ZFS disk to another disk

Clone a running OPNsense ZFS install to a second disk with no downtime, using gpart to copy the partition table and zpool attach to mirror and resilver.

GRUB2 boot loop protection by limiting slot retries

A GRUB2 config that caps boot attempts per A/B slot to prevent infinite boot loops on remote or embedded systems, with RAUC integration for updates.

Great Hugo Reference Template

Hugo's documentation can be tricky to parse, so I look for good examples. While figuring out how to integrate a CSS/JS framework with Hugo, I found hugothemebootstraphttps://github.com/razonyang/hugot

Caddy Security: one OAuth app for multiple vhosts

Authenticate multiple virtual hosts with a single OAuth app in Caddy Security, using the redirect_url parameter to work around callback URL matching.