Real work on my own gear, written up honestly — including what broke. Each card links to its full write-up.
Projects
The projects behind the posts — networking, security, game modding, and tooling.
Homelab SIEM — Loki + Promtail
Firewall and server logs centralised into Loki and searched with LogQL in Grafana — through a journal dead end, an RFC 3164/5424 mismatch, and an rsyslog translator in the middle.
Claudian — Claude inside Obsidian
An agentic Claude Code sidebar embedded in my study vault — runbook frontmatter, semantic callouts and cross-links applied vault-wide, with every code fence preserved byte-for-byte.
Alerting — the lab pages my phone
Alertmanager + ntfy on top of the existing Prometheus stack — a packaging conflict dodged with Docker, a silent YAML trap caught by querying state, and a firewall that correctly said no.
pfSense containment lab
A pfSense VM firewalling the Debian VM where my Claude agents run — allow internet-out, block every private range. Plus a full-outage debug.
Home network hardening
Baseline hardening and guest segmentation on an ISP-issued Arcadyan HWG2025 — WPA3, WPS off, two isolated zones, and the ISP-DNS workaround.
Virtual VLAN segmentation
Three firewall-isolated zones — Trusted, IoT, Guest — built entirely in VMs with no managed switch, and proven by one client changing a tag.
WireGuard through a nested firewall
Raw WireGuard on pfSense, reached from my phone on mobile data through the lab's containment layer — plus a four-layer silent-failure debug.
Self-hosted Vaultwarden vault
A password vault with a genuinely trusted wildcard cert via DNS-01 and zero inbound ports — reached over WireGuard, invisible to the internet.
Identity provider — Authentik SSO
A self-hosted IdP with MFA enforced centrally, wired into Grafana over OIDC — so an app that has never heard of MFA suddenly requires a second factor and grants admin by group.
The firewall joins the IdP
pfSense authenticating against Authentik over LDAP — MFA and group-based admin on a device with no browser — plus proving the RADIUS path was a genuine upstream bug, not my config.
Hardening the Debian lab VM
An honest security audit of my own automation VM and the fixes — auto-updates, an nftables default-deny, Tailscale-only SSH, systemd sandboxing.
MCP hub over Tailscale
A custom MCP server on the lab VM a roaming laptop's Claude Code pushes notes to over a Tailscale mesh — no inbound ports, a narrow tool surface.
Prometheus + Grafana stack
The dashboard layer under the glance — Prometheus scraping the VM and pfSense, Grafana drawing live graphs, all on one localhost-bound VM.
LaMetric TIME on an isolated net
Live home-lab stats on a LaMetric display, bridged over MQTT through a cloud broker so the publisher and display never touch the LAN directly.
LaMetric — WAN throughput over SNMP
A follow-up polling pfSense over SNMP for real WAN in/out rates and adding them to the display — reading the gateway without breaking isolation.
BiggerBang — SPT mod port
An abandoned Single Player Tarkov trader mod, ported from the 3.x TypeScript API to a compiled C#/.NET DLL for SPT 4.0 — five bugs fixed.
FoxWeaponSound — port via Fable 5
A 2022 JavaScript weapon-sound mod rebuilt as a .NET 9 DLL for SPT 4.0.13, driven end-to-end through Claude Fable 5 — surfacing five long-shipped bugs.
Spec Grabber — system info tool
A native desktop GUI (Python, customtkinter, psutil) that collects system info into a styled HTML report — hardened, packaged for Linux and Windows.
Mini projects on the laptop
A running log of smaller Claude Code sessions on a Debian laptop — env setup, OneDrive sync, and an Obsidian vault tidy-up wired to the Claude API.
This blog
Hugo + PaperMod with a Claude Code publishing pipeline — raw notes in, finished post out, filed, committed and deployed by one command.
Moving to Cloudflare Pages
Migrated off GitHub Pages to Cloudflare Pages for real HTTP security headers — a hash-locked CSP, HSTS, and the rest a meta-tag CSP can't deliver.
My own domain — billsblog.dev
Registered a custom .dev domain (an HTTPS-forced TLD) and moved the site onto it with the whole hardened header set intact — plus the privacy trade-offs.