Upgrading self-hosted Pangolin Enterprise Edition from 1.21 to 1.25.3 (and patching Node2Shell)

Pangolin is the tunneled reverse proxy in front of most of my self-hosted services. It runs as a small Docker Compose stack of Pangolin, Gerbil (WireGuard) and Traefik on a VPS. Mine was still on the Enterprise Edition image ee-1.21.0. When Node2Shell (CVE-2026-111497) was published for Node.js, it was time to catch up four minor versions. This post covers the path I took, the versions that belong together, and how I verified the result.

Read more

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

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

Ubuntu 24.04 Server Quick Start: Sudo User, SSH Hardening, fail2ban, Docker and Dockge

Every time I spin up a new Ubuntu server I go through the same handful of steps before anything else touches it. This post is that checklist, written down so I (and hopefully you) don’t have to piece it together again. It assumes a fresh Ubuntu 24.04 LTS install where your SSH public key is already in place for the initial login.

Throughout the post I use youruser as the new account name and 2222 as the new SSH port. Replace both with your own values.

Golden rule: keep your current SSH session open the whole time and test every change from a second terminal. That way a typo never locks you out.

Read more