RSS Amplifier

Blog

Larvitz Blog

FreeBSD, Linux, all things cleanly engineered

blog.hofstede.itRSS feed ↗75 posts

Latest posts

Crawlfest: Building a Terminal Roguelike in Rust

For a few months now I have been building a terminal roguelike in Rust in the spirit of ADOM and NetHack. This article is about the technical groundwork: why ratatui and legion instead of a game engine, how the four map generators work (rooms, cellular-automata caverns, hand-drawn prefabs, and a hybrid of the last two), how field of view and A* pathfinding hook into my own map type through two…

Chezmoi and Git: Dotfiles Without Pretending Every Machine Is the Same

A Git repository is a good place for configuration files, but it does not know where they belong, which permissions they need, or why a work laptop and a home server should differ. Chezmoi adds that missing layer. This is how I use both tools to manage fish, Git, Neovim, GnuPG, OpenSSH and Atuin, including the recovery command for the inevitable day I edit a live file directly.

Three Test Jails on a 512 MB Free-Tier VPS

A bug report against my jailexec connection plugin needed a real FreeBSD jail to reproduce. An idle free-tier VPS with 512 MB of RAM turned out to be plenty: pkgbase provides a 33 MB base userland, persistent jails need no idle processes, and three Python-equipped test targets added only 1.1 GB of disk use. This is the build, including the two sharp edges that cost me twenty minutes.

Sane Development Environments for Ansible Automation Code

Ansible content deserves something better than a laptop full of loosely related pip packages. My preferred setup puts the editor on RHEL , the Red Hat-packaged Ansible toolchain in a versioned Dev Container, and Podman underneath both development and Execution Environment workflows. The result is reproducible without pretending that upstream community bits and supported downstream product content…

Rice Deserves Better Than a Kochbeutel

Rice is not the anonymous white ballast next to the actual food. Jasmine, basmati, brown rice, parboiled rice, and the great Italian risotto varieties all behave differently, and the way you cook them matters just as much. A short argument against the Kochbeutel, followed by the rice-cooker method that has served me best.

Running Your Own AS: An IXP over VXLAN, IPv4 on the Overlay, and a Config Spring Clean

Part 5 of the AS201379 journey: joining EVIX , an internet exchange that hands out VXLAN tunnels instead of switch ports, carrying a routed IPv4 /29 across the IPv6 overlay with PF policy routing, the dual- FIB routing that makes a VPS work as both a normal host and a routed AS site, moving the downstream MikroTik onto WireGuard, and a long-overdue cleanup of four routers worth of accumulated…

Building My Own TV Station: ErsatzTV in a FreeBSD Jail, With Intel Hardware Transcoding

Being ill for a week taught me that a large Jellyfin library is not entertainment, it is homework. ErsatzTV turns a media library back into linear television with real channels and schedules, but it only ships for Linux, Windows, and macOS. It is a . NET application driving ffmpeg, so I built it in a FreeBSD Bastille jail instead. One missing conditional was all that stood between FreeBSD and…

Android Development on Fedora 44 Without Installing an Android Development Stack

I wanted to build a native Android companion for Kollect without filling Fedora 44 with a JDK , Gradle, Android SDKs, build tools, emulator images, and assorted mobile-development debris. My complete Android toolchain now lives in an Ubuntu 24.04 Distrobox instead. It builds the APK , talks to my phone over wireless ADB , runs the Android emulator, and even lets Kollect enrich links for free with…

My Home Assistant Setup: bhyve, FreeBSD Jails, Zigbee, Homematic, and Matter over Thread

My Home Assistant OS installation runs as a bhyve VM on a FreeBSD home server, while Zigbee2MQTT and Mosquitto live in a VNET jail with direct access to a ConBee II USB adapter. Homematic comes through a CCU3 , and three recent IKEA Matter-over-Thread devices use the Nanoleaf Shapes controller I already owned as their border router.

Kollect: The Native KDE Link Collector I Built for Myself

Kollect is a small native Plasma 6 application I wrote to get interesting links out of browser tabs and into a durable collection. It uses Kirigami and C++ on the desktop, plain TOML files by default, optional multi-user server storage, OpenRouter-powered metadata, KWallet for secrets, and a proper Fedora RPM . The source is not public, but the design is worth documenting.

Hosting DokuWiki on FreeBSD with Bastille, nginx, and Caddy

A small, database-free DokuWiki deployment in a FreeBSD 15.1 Bastille jail, with nginx and PHP - FPM inside the jail and Caddy handling TLS and access policy at the edge.

chana_masala.sh: A Recipe as a Shell Script

Some years ago a chana masala arrived in a HelloFresh box and never left the household again. It has since been refactored, hardened, and put under version control. Here is the current release: a chickpea curry for hungry IT people, documented the only way I know how - as a bash script with a proper runbook attached.

A Caching FreeBSD Mirror for DN42: nginx proxy_store, pf, and a Dual-Homed VM

Patching FreeBSD machines inside the DN42 overlay network without giving them clearnet access - a dual-homed VM that lazily caches pkg.freebsd.org, update.freebsd.org, and release tarballs from ftp.freebsd.org with nginx proxy_store, follows CDN redirects server-side, and serves everything over IPv6 into the mesh. Now also available as a public DN42 service at bsdmirror.chofstede.dn42.

Upgrading FreeBSD 15.0-RELEASE to 15.1-RELEASE: The Official Paths

FreeBSD 15.1- RELEASE is here, and the official upgrade instructions depend on whether your system uses distribution sets or packaged base. This guide walks through both supported paths, covers the boot-loader update, and explains the configuration merging process - all based on the official 15.1 upgrading documentation.

FreeBSD Foundationals: The Boot Process - From the Loader to Boot Environments

The third in the FreeBSD Foundationals series. This one covers how FreeBSD actually boots: the stages from power-on to login, BIOS vs UEFI , the loader and loader.conf, the difference between read-only tunables and runtime sysctls, the modern way to load kernel modules with kld_list, managing it all safely with sysrc, a practical security-hardening baseline, and - the headline act - boot…

Monitoring a FreeBSD Mastodon Instance with Prometheus, Grafana, and Loki

How I watch burningboard.net, my multi-jail FreeBSD Mastodon instance, from a separate observer host. A pull-based Prometheus stack reaching exporters across my own AS201379 backbone (locked down at the perimeter firewall, not by binding to unroutable addresses), Loki and Promtail for nginx logs, a textfile collector that fills the gaps FreeBSD exporters leave ( ZFS , S3, pkg audit, Mastodon API…

Leaving the Apple Ecosystem: One Fairphone Instead of Two iPhones

For years I carried two iPhones, a personal iPhone 12 and a work iPhone SE , and neither ever felt at home in my Linux and BSD centric life. I finally collapsed both into a single Fairphone Gen6 running Android with separate personal and work profiles. Here is why I picked the Fairphone, how Android slots into a desktop Linux workflow far better than iOS ever did, which apps I kept, which I…

IPv6 Foundations: The Internet Protocol You Should Already Be Using

A laid-back tour through the basics of IPv6: how the addresses are built, how to shorten them without losing your mind, how they map onto the IPv4 you already know, and how hosts configure themselves with SLAAC . Plus a short sidebar on NDP and why blocking ICMP on an IPv6 network is a self-inflicted wound. The premise throughout: IPv6 is the current internet protocol, IPv4 is a relic we are still…

A Monoblock AC Is Only as Good as Its Window Seal

I moved into a top-floor 1970s apartment in one of the warmest corners of Germany, work from home, and needed the office to stay below thinking is hard now . A single-hose portable AC is a thermodynamically compromised machine, but most of what makes it bad happens at the window. Here is the personal story, a short detour into why these units leak, and the cheap XPS panel I cut to fix the part…

The AI Stack I Actually Run in 2026: A Laptop iGPU and Four Rented Frontiers

The most interesting thing about AI in 2026 is not which frontier model wins this month s benchmark. It is that the frontier became a commodity you rent through near-interchangeable clients, while the part with actual craft in it moved onto the integrated Radeon 780M in my laptop. Here is the tiered stack I actually run, with the local layer in detail because that is the unusual part, and the…

bcachefs on RHEL 10.2: The Kernel That Said No

A few months ago I bullied RHEL onto a ZFS root and it worked. This time I tried to get bcachefs running on RHEL 10, lost a whole evening to compile errors, and the kernel won. Here is the autopsy, plus what bcachefs actually is and why an out-of-tree filesystem and a conservative enterprise kernel are a terrible couple.

Two Sites, One Cluster: My Hetzner Proxmox VE Setup - A low-cost two-node cluster with VXLAN, ZFS replication and an external quorum vote

How I run a single quorate Proxmox VE cluster across two cheap Hetzner dedicated servers in two different datacentres, glued together with Hetzner vSwitches, a VXLAN overlay, an external QDevice for quorum, and one OPNsense firewall per node.

Tag-Driven Deployments: How MastoSum Ships Itself with Forgejo Actions and Rootless Podman

A walk through the MastoSum deployment pipeline: a version tag triggers Forgejo Actions, builds and signs a UBI -based image, then hands deployment to a rootless systemd/Podman host via a path unit and explicit cosign verification.

mdo on FreeBSD 15: Base-System Privilege Delegation with mac_do

FreeBSD 15 ships mdo(1) and the mac_do(4) policy module in the base system. It replaces sudo and doas for most of my hosts, needs no ports, and configures with a single sysctl. This article walks through enabling it, the rule syntax, a few real examples, and a short detour into the security sysctls I run on every box.

Fedora Hummingbird: Distroless, Container-Native Linux and a Slim mastogreet

Fedora Hummingbird brings the distroless container model to a full, image-based rolling operating system, and it ships a catalog of hardened language images alongside it. I rebuild the mastogreet bot s Containerfile on top of registry.access.redhat.com/hi/python to see what changes, what shrinks, and where the commercial Red Hat Hardened Images downstream fits in.

Red Hat Offline Knowledge Portal: All the Docs, Air-Gapped, On Your Laptop

The entire Red Hat documentation site and the full Knowledgebase fit into a single OCI container that updates weekly, runs locally with a web UI and Solr search, and is included in every RHEL subscription that bundles Satellite. I have it on my laptop. I use it daily. Almost nobody I talk to knows it exists. This post is my small contribution to fixing that.

A Field Manual for Three Years on Deutsche Bahn

After years of regular business travel by Deutsche Bahn, here is the small library of habits, app picks, routing folklore, and survival gear that actually helps. Not a complaint piece. A handbook for everyone who has resigned themselves to the system and would like the next trip to suck a little less.

FreeBSD Resource Monitoring, Accounting, and Troubleshooting

A practical tour of FreeBSD s built-in tools for watching CPU , memory, disk I/O, and network activity, finding the process or jail that is eating your server, and applying per-jail accounting and limits with kern.racct and rctl.

Distrobox: Different Distributions in a Box, Powered by Podman

A real RHEL container on a Fedora laptop, an Arch box for the AUR , an Ubuntu box for that one vendor tool that ships .deb files only, all of them with your home directory mounted, your shell history shared, and GUI apps that integrate into your desktop as if they were native. Distrobox uses Podman to make that boring instead of clever, and it pairs especially well with Atomic distributions where…

Reproducible Ansible with Execution Environments

A control node with a hand-curated venv works. Until it doesn t. A colleague has different collection versions, CI installs a slightly newer Python library, and a playbook that ran yesterday now fails. Execution Environments turn the control node into a versioned container image. ansible-builder produces it, ansible-navigator runs against it, and the same artifact ships from your laptop into AAP /…

Ansible-Native Quadlets: Deploying a Mastodon Greeter Bot with containers.podman

Hand-writing Quadlet files works for one host. For a fleet, the containers.podman collection s native Quadlet generation lets you describe containers as Ansible state, including secrets, registry logins, and templated configuration. A small Mastodon welcome bot makes a concrete example.

Joining DN42: A MikroTik Border, Three WireGuard Peerings, and a FreeBSD Jail in the Hobbyist Internet

Building a DN42 node from scratch - registering AS4242422539 and fdce:73f7:a2dc::/48 in the registry, configuring a MikroTik border router with three WireGuard peerings and BGP filters, running a FreeBSD bastille jail as authoritative DNS for chofstede.dn42, and reaching the rest of the hobbyist mesh in two hops.

Running Your Own AS: Direct Hetzner Peering, a Fourth Edge, and Bringing the Home LAN into the Fabric

Part 4 of the AS201379 journey: adding a fourth FreeBSD edge router at iFog with FogIXP peering, establishing direct BGP sessions with Hetzner, bringing the home network into the AS via an iBGP-speaking MikroTik, and a little traffic engineering to steer Deutsche Telekom traffic over Vultr.

Automating FreeBSD Jails with cdist - Zero Dependencies Inside the Jail

cdist is refreshingly minimal - the target only needs POSIX sh, and the control machine speaks ssh. But cdist expects one ssh endpoint per host, and FreeBSD jails are not normally their own ssh targets. Two small Python wrappers plug cdist into jexec on the host, so configuration state flows into every jail without running a single daemon, agent, or Python interpreter inside the jail itself.

Replacing Lenovo’s WWAN Unlock Blob with a 100-Line Bash Script

My ThinkPad T14s shipped with an Intel XMM7560 LTE modem that would not register on the network until Lenovo s proprietary FCC -unlock helper ran. I replaced it with a roughly 100-line bash script from a ModemManager merge request, and along the way learned that the unlock is just a small challenge-response handshake that is easy to explain in plain shell.

Podman on FreeBSD: OCI Containers Without systemd

Podman runs on FreeBSD too - but without systemd, the workflow is different. This follow-up to my Linux Podman deep dive covers how to run both native FreeBSD and Linux OCI containers on FreeBSD, how container lifecycle management works without Quadlets, and how Podman complements Jails rather than replacing them.

Podman in Production: Quadlets, Secrets, Auto-Updates, and Docker Compatibility

An opinionated production-ops guide to Podman on Linux servers - why I prefer it over Docker, how Quadlets replace Compose files, and practical patterns from real deployments including secrets management, auto-updates, and Docker compatibility.

Speeding Up Forgejo CI with a Custom OCI Image

How I cut my blog s CI / CD build time in half by baking dependencies into a custom container image and hosting it in Forgejo s built-in OCI registry.

Keycloak 26 on Podman with Quadlets: Identity Management the systemd Way

Deploying Keycloak 26 as an identity provider using Podman Quadlets with network segmentation, secret management, and systemd integration.

My Multi-Stage Backup Strategy: ZFS, Proxmox, and Paranoia

Backups are the thing everyone knows they should do and nobody does well enough. Here s my multi-stage strategy for keeping about a dozen servers safe: ZFS snapshots with sanoid, off-site replication with syncoid to rsync.net, Proxmox Backup Server with an S3 backend for VMs, and a creative Podman trick for backing up RHEL hosts that don t have proxmox-backup-client. Plus a dead man s switch,…

Shell Tricks That Actually Make Life Easier (And Save Your Sanity)

Watch someone backspace 40 characters instead of pressing CTRL +W, and you ll understand why this list exists. A collection of shell tricks-grouped by what works everywhere and what s Bash/Zsh-specific-that save keystrokes and time.

Dual-FIB Policy Routing on FreeBSD: Two Upstreams, One Server, Zero Confusion

How to run a FreeBSD server with two completely independent internet uplinks - a physical provider and a BGP tunnel - using dual- FIB routing tables, PF s rtable and reply-to directives, and a single bridge that carries NAT d, routed, and pure public jail traffic simultaneously.

Running Your Own AS: Joining an IXP with a Third Edge Router

Connecting AS201379 to LocIX Düsseldorf via a dedicated edge router - adding direct exchange point peering to the existing multi-homed BGP setup, completing a three-router FreeBSD infrastructure with transit, native peering, and IXP connectivity.

Why I Prefer CentOS Stream Over Old CentOS

Old CentOS rebuilt RHEL faithfully, but its downstream position meant it could only follow, never contribute back. CentOS Stream changes that. Sitting upstream of RHEL and downstream of Fedora, it combines enterprise-grade stability with a genuine feedback loop into RHEL development. After years of running it in production, I m convinced it s the better model.

Linux Firewalls: How to Actually Secure a Cloud Server (iptables, nftables, firewalld, ufw)

A practical guide to the four major Linux firewall technologies - iptables, nftables, firewalld, and ufw. Covers real-world cloud server hardening with concrete examples, from locking down SSH to building zone-based configurations. Includes an honest comparison and an entirely unbiased opinion about which firewall is actually best.

FreeBSD Foundationals: ZFS - The Last Filesystem You’ll Ever Need

The second in the FreeBSD Foundationals series. This one covers ZFS from philosophy to practice: why it exists, how pools and datasets work, what checksumming and self-healing actually do, how to tune recordsize, compression, and atime, how encryption works with key management, how snapshots and the hidden .zfs directory give you time travel, and how ZFS send/recv turns backup and migration into a…

FreeBSD Foundationals: Jails - From Chroot on Steroids to Full Virtual Networks

The first in a series on FreeBSD fundamentals. This one covers Jails from the ground up: why they exist, how classic Jails differ from VNET Jails, what epair interfaces actually are, how bridges tie it all together, and what devfs rules do for your isolation story. Practical configurations included.

Neovim Crash Course for Sysadmins: The 20% That Solve 80% of the Pain

Not another hjkl tutorial. This is the stuff you still get wrong after years of using Vim - efficient navigation, copy/paste that actually works, YAML -specific workflows, and the motions that turn config file editing from a chore into a joy.

Running Your Own AS: Going Multi-Homed with iBGP and three Transits

Expanding a single BGP router into a two-PoP distributed network: adding a Vultr edge router with native BGP peering, three upstream GRE providers and iBGP to tie it together - plus the stateless PF rules that make transit routing actually work.

HTTP/3 on FreeBSD: Getting QUIC Working with nginx in a Bastille Jail

What looked like a simple nginx config change turned into a tour through SSL library incompatibilities, pf firewall rules for a new protocol, and a multi-worker affinity problem that only shows up under real traffic. A complete guide to getting HTTP /3 working with nginx 1.28 on FreeBSD 15.0 inside a Bastille jail.