PHP2Shell: patching a custom Nextcloud Docker image (and the :latest trap)

After patching my WordPress stack for PHP2Shell (CVE-2026-109618 and CVE-2026-109619), the next one on the list was Nextcloud. It deserved more care: it holds my files, and it runs on the official nextcloud:apache image, which means Apache with mod_php, the setup where the confirmed exploit fires before any application code runs.

Read more

PHP2Shell: patching my Dockerized WordPress in five minutes

On 21 October 2026 the PHP project shipped an emergency release for two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, nicknamed PHP2Shell. Both are rated CVSS v4.0 9.2 and allow remote code execution without logging in. Details had leaked a day before the planned disclosure, so the patch window was short. This is a quick write-up of how I patched the WordPress stack that runs this blog.

Read more

A hardened Hetzner Cloud server with Docker in one cloud-init file (2026 edition)

When I spin up a new Hetzner Cloud VM, I paste a cloud-init file into the “Cloud config” box and let the server set itself up. Hetzner’s community tutorial has a nice baseline: a sudo user, SSH moved to port 2222, root and password logins disabled, fail2ban and ufw. What it doesn’t have is Docker. This post is the version I actually use, plus a few things I corrected after checking it against current documentation.

Read more

Isolating a guest VLAN on OPNsense with a Ruckus AP: no sneaking through to the main network

My Ruckus access point broadcasts a dedicated guest SSID and tags that traffic with a separate VLAN before handing it to OPNsense. The AP side is easy – Ruckus does the tagging reliably. The router side is where things go wrong if the firewall rules are in the wrong order or a step gets skipped. Here is the full setup I use to make sure a guest really cannot reach anything on the internal network.

Read more

Deploying LXC containers at scale on Proxmox: cloud-init alternatives

Every time I spin up a new LXC on Proxmox, I ask myself the same question: why can’t I just hand it a cloud-init file like I do with VMs? The short answer is that cloud-init is a VM-only feature in Proxmox. LXC containers don’t support it natively. But there are several approaches that get you to the same place — or better.

This post covers the options, the trade-offs, and what I actually use for a fleet of Ubuntu + Docker + Docker Compose + Dockge containers.

Read more

Country-based geoblocking in NPMplus: allow only Germany and Switzerland (or block a single country)

I run several self-hosted apps behind NPMplus (the ZoeyVid fork of Nginx Proxy Manager). They are reachable over my domain without any open ports other than the reverse proxy, but “reachable from the whole internet” is more exposure than most of them need. None of mine have to be accessible from outside the DACH region, so one cheap extra layer is country-level geoblocking: anything from outside the countries I care about simply gets dropped.

NPMplus has GeoIP2 built in, and the important part is that you can apply it per proxy host (or even per location), not just globally. So one host can be locked to Germany and Switzerland while the rest stay open. Here are the two recipes I use.

Read more

Split-Horizon DNS with Technitium and OPNsense: Resolving Internal Hosts Locally (plus Let’s Encrypt via DNS-01)

My home network uses Technitium DNS as the primary DNS server and OPNsense as the router. I own a public domain (in this post I’ll use domain.com as a placeholder), and I wanted truenascale.domain.com to point to my TrueNAS SCALE box on the LAN instead of being resolved somewhere on the internet. On top of that, I wanted a proper TLS certificate for it without exposing the NAS to the outside world.

Read more

Homelab logs and metrics with Grafana Alloy: journald to Loki, metrics to Prometheus

My homelab has grown to a good dozen Linux hosts: Proxmox nodes, Docker VMs, a few VPSs. For a while every host had something different collecting logs and metrics: an old OpenTelemetry Collector here, a Docker Loki logging driver there, nothing at all somewhere else. Now every host runs Grafana Alloy with almost the same config:

  • Logs: journald → Loki
  • Host metrics: built-in node exporter → Prometheus
  • Container metrics (Docker hosts only): built-in cAdvisor → Prometheus

Everything is pushed. Prometheus doesn’t need a scrape job per host and the hosts don’t need any open ports. And no, you don’t need Mimir for that: Prometheus can receive remote writes itself.

Read more

UPS shutdown with NUT over SNMP – Part 2: TrueNAS SCALE

This is the second half of a two-host setup on one shared UPS (APC Smart-UPS SMT1500RMI2U with an AP9630 network card). Part 1 explains the design and the Proxmox side. In short:

  • Every host polls the UPS card directly over SNMP and shuts itself down. No NUT master that everyone depends on.
  • Proxmox goes down at 50%, TrueNAS at 40%. The VMs that write to the NAS are stopped before the NAS itself shuts down.
  • A read-only SNMP community means no host can cut power to the shared UPS.

Tested on TrueNAS SCALE 24.10 (Electric Eel), NUT 2.8.0. Everything here is done in the web UI, no shell editing needed.

Read more