VPS (cloud droplet)¶
The VPS is the public-facing edge of the estate. Since the backup leg was retired on 2026-08-11 it no longer stores or receives any backup data — its jobs are purely network-facing.
Roles at a glance¶
| Role | What it does | Where it lives |
|---|---|---|
| NPM reverse proxy | Terminates web traffic on 80/443, passes Minecraft UDP straight through | Docker, /home/elliott/npm/ |
| RustDesk relay | Self-hosted remote-desktop rendezvous/relay (hbbs + hbbr) | Docker, /opt/rustdesk/ |
| WireGuard hub | wg0 10.10.0.1/24, carries the Minecraft game traffic home |
/etc/wireguard/ (root) — see WireGuard |
| Tailscale node | Member of the tailnet (100.75.121.110) | tailscaled |
Pending operator actions (audit 2026-08-12)
- Reboot — uptime is past 355 days; a reboot is pending to pick up kernel updates.
- Tailscale accept-routes — the VPS has not yet run
sudo tailscale set --accept-routes, so it cannot reach the LAN (192.168.1.0/24) via the ops subnet router. See Tailscale. - RustDesk ports — exposure review done 2026-08-12: 21115–21119 verified closed to the public (tailnet-only). See below and Remote desktop.
Nginx Proxy Manager¶
Runs as a single Docker container (jc21/nginx-proxy-manager:latest) defined
in /home/elliott/npm/docker-compose.yml, with config in ./data and
certificates in ./letsencrypt.
Published ports:
| Port | Proto | Purpose |
|---|---|---|
| 80 | TCP | HTTP (redirects / ACME) |
| 443 | TCP | HTTPS |
| 19132 | UDP | Minecraft — Creative |
| 19134 | UDP | Minecraft — Survival |
| 19136 | UDP | Minecraft — Survival World (classic) |
The admin panel port (81) is deliberately not published — it is commented out in the compose file. To use the panel, temporarily publish it (or tunnel to it) and close it again afterwards.
The Minecraft UDP ports are stream passthroughs: NPM forwards them over the WireGuard tunnel to the Minecraft VM at 10.10.0.2. See WireGuard and the Minecraft runbook.
TODO: export the proxy-host rules to this page
The actual proxy-host and stream rules (which hostname maps to which
backend, which streams forward where) live only inside NPM's SQLite
database (/home/elliott/npm/data/). They are not documented anywhere
else. Next time the panel is opened — or via a sudo sqlite3 read of the
database — copy the rule list into a table here. Until then this page
only knows the ports, not the rules.
RustDesk relay¶
Self-hosted OSS remote desktop (hbbs + hbbr) in Docker under /opt/rustdesk/,
set up by /home/elliott/rustdesk-setup/rustdesk-setup.sh (idempotent, root).
VPN-only via Tailscale — full detail, client onboarding and the security
model live on the dedicated Remote desktop (RustDesk) page.
RustDesk uses ports 21115–21119, all tailnet-only.
Port review closed — 2026-08-12
External scan confirmed 21115–21119 are closed to the public and open
only over the tailnet. The containers use network_mode: host (not -p
publishing), so Docker adds no rules that bypass UFW — the audit's "Docker
may be publishing around UFW" worry does not apply here. See
Remote desktop.
SSH and firewall¶
Hardening applied by /home/elliott/vps-harden.sh (run with sudo):
- SSH on port 2222, key-only. No password auth.
- fail2ban: default jail bans for 1h after 5 failures in 10m; the sshd jail is stricter — 3 failures on port 2222 → 24h ban.
- UFW: default deny incoming, allow outgoing. Allowed in:
| Port | Proto | Comment |
|---|---|---|
| 2222 | TCP | SSH |
| 80 | TCP | NPM HTTP |
| 443 | TCP | NPM HTTPS |
| 51820 | UDP | WireGuard |
| 19132 | UDP | Minecraft Creative |
| 19134 | UDP | Minecraft Survival |
19136 is in Docker but not in the UFW script
The compose file publishes 19136/udp (Survival World classic) but the harden script's UFW rules stop at 19134. Docker typically bypasses UFW for published ports, so it probably works anyway — but the script and reality have drifted. Worth reconciling next time the harden script runs.
Operational notes¶
- No passwordless sudo — by design. Interactive commands needing root will prompt; automation should not assume root on this box.
- Backup leg fully retired (2026-08-11). No rsync push from the LAN, no retention timers, old tarballs deleted. If you find backup remnants here, they are safe to remove. Offsite copies are handled elsewhere — see offsite backups.
- If the VPS is unreachable, see oh no: unreachable.