Updates to four pages reflecting the combined → vanilla mgmt+signal+relay+coturn cutover and the IONOS-3478-firewall-exception discovery: * infrastructure/mesh.md — rewrites the ICE/STUN section to cover the new TURN endpoint, the IONOS upstream TCP-3478 filtering (load-bearing, undocumented before today), and the verification probe. New changelog entry covering the migration outcome + Device Code Stage gap. * infrastructure/vps-hardening.md — "At a glance" lists the new 6-service docker stack + host coturn. Firewall section notes the new `iifname ens6 tcp dport 3478 accept` rule plus the IONOS upstream exception. New changelog entry. * containers/124-authentik.md — replaces the "Netbird IdP integration — DEFERRED" section with the LANDED state: Provider details (Public client type — Confidential breaks PKCE on the dashboard SPA), the first-time owner-promotion sqlite recipe, the missing Device Code Stage gap + workaround (setup-keys), and a note that the old 2026-04-22 pre-work Provider/App is now obsolete and safe to delete. Updated changelog (Phase 6 landed). * operations/agent-enrollment.md — new "Getting onto Netbird" subsection explaining the setup-key path (currently the only working flow until Device Code Stage lands) and why direct OIDC from the public internet fails (auth.hubris.network is mesh-only-reachable). Prerequisites table row updated to point at the new section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.6 KiB
VPS hardening — 82.165.190.79 / 100.122.165.149
IONOS VPS that runs the Netbird control plane and the public ingress traefik. Hardened 2026-04-23 from its stock-Plesk state.
At a glance
- Hostname:
inspiring-ramanujan.82-165-190-79.plesk.page - OS: Debian 13
- Mesh: netbird
100.122.165.149(peer of the lab mesh; routes192.168.8.0/24via hubris). - Public:
82.165.190.79(ens6). - Public DNS: IONOS wildcard
*.hubris.network → 82.165.190.79. - Docker stack at
/opt/docker-compose.yml:traefik(TLS/ACME) +dashboard+mgmt+signal+relay+proxy— netbird-mgmt 0.71.3 vanilla deploy since 2026-05-21 (see mesh.md changelog). - Host services (outside docker):
coturn(TURN-TCP on :3478, long-term creds at/root/turn-pass.txt, used by mgmt'sTURNConfig).
SSH
- Key-only (
PasswordAuthentication no,PermitRootLogin prohibit-password) via drop-in at/etc/ssh/sshd_config.d/10-hubris-hardening.conf. Original config backed up at/etc/ssh/sshd_config.bak.<ts>. - Mesh-only: public
:22is dropped by the nftables firewall. SSH reaches the VPS only overwt0.ListenAddressitself is still0.0.0.0— gating is firewall-layer. - Authorized root keys: PVE (
root@hubris), Mac Mini (d.toro.v@pm.me). Add a new device withssh-copy-id root@100.122.165.149from a mesh peer before disabling its access paths.
Firewall — nftables (inet hubris-fw)
Config at /etc/nftables.conf, service enabled.
- Public iface
ens6. Wireguard ifacewt0. - INPUT on
ens6allow-list: DHCP (67→68), rate-limited ICMP/ICMPv6, TCP 3478 (coturn TURN-TCP, added 2026-05-21). Everything else drops. wt0fully accepted in INPUT.loaccepted.- IONOS upstream firewall also gates inbound traffic before it reaches
ens6. Open ports today: TCP 80/443 (traefik), UDP 51820 (netbird-proxy), TCP 3478 (coturn, added 2026-05-21). UDP 3478 is dropped by IONOS upstream regardless of local nftables. See mesh.md ICE/STUN for the STUN/TURN port matrix. - FORWARD chain at priority
filter-10(runs before Docker's FORWARD) hosts the fail2ban ban enforcement — see below. - Set
banned4(typedipv4_addr, flagtimeout) holds fail2ban's drops. - Coexists with Docker's
ip nat/ip filtertables (iptables-nft compat). Do NOTflush rulesetin this config — it'll wipe Docker's state too.
fail2ban
- Jail
traefik-4xxtails/var/log/traefik/access.log(bind-mounted from container). Filter at/etc/fail2ban/filter.d/traefik-4xx.confmatches 401/403/404/429 fromblog-public@fileorartifacto-public@filerouters only — netbird-grpc traffic isn't considered. - Tunables:
findtime=600, maxretry=30, bantime=3600. - Action at
/etc/fail2ban/action.d/nft-hubris.confadds/removes elements frominet hubris-fw banned4with per-element timeout.
CRITICAL invariant — wireguard / fail2ban
Bans must never affect wt0 or wireguard UDP. The FORWARD chain explicitly accepts the following before the ban check:
udp 51820(wireguard)udp 3478(STUN)ct state established,related
The INPUT ban rule is scoped to iifname "ens6".
Violating this takes the mesh down for every home device (they share one public IP) and the only recovery is IONOS console → nft flush set inet hubris-fw banned4.
Traefik access log
- Written to
/var/log/traefik/access.logon the host via a bind mount added to/opt/docker-compose.yml(traefik volumes include/var/log/traefik:/logs) plus--accesslog.filepath=/logs/access.log. - CLF format. Real client IP arrives correctly because docker userland-proxy is off — see public ingress.
Plesk / mail / FTP / Dr.Web
Stopped and disabled (not uninstalled). All of:
dovecot, dovecot.socket, postfix, postfix@-, pc-remote, xinetd, plesk-task-manager, plesk-web-socket, sw-cp-server, sw-engine, plesk-repaird, plesk-repaird.socket, drwebd.
psa.service is masked (was a one-shot boot bootstrap). /etc/cron.d/plesk-backup-manager-task renamed to .disabled.
Reverse: systemctl unmask psa; systemctl enable --now <svc>.
Auto-patching
unattended-upgradesenabled (stock).- Drop-in at
/etc/apt/apt.conf.d/52hubris-reboot.confsets auto-reboot at 04:00 UTC when/var/run/reboot-requiredis set. - Runs inside the stock
apt-daily-upgrade.timer.
Recovery paths
Ordered by preference:
- SSH via mesh — primary. Any mesh peer with an authorized key.
- IONOS web console (my.ionos.com → VPS → Console) — uses the system password, not SSH keys. Bypasses any firewall misconfig.
- IONOS rescue mode — boot rescue, mount rootfs, edit
/etc/nftables.confor/etc/ssh/sshd_config.d/10-hubris-hardening.confto a known-good state, reboot.
Related
- Public ingress (VPS traefik)
- Mesh migration — VPS as a mesh peer
- SSH access
Changelog
2026-05-21 — netbird stack migrated combined → vanilla; coturn added
Replaced the netbirdio/netbird-server combined image with the canonical mgmt + signal + relay + dashboard containers (0.71.3). Added host-side coturn for external TURN, with nftables rule iifname "ens6" tcp dport 3478 accept and an IONOS upstream firewall exception. Authentik on LXC 124 now provides OIDC for the netbird dashboard. Full context in mesh.md changelog.
2026-04-28 — wiki entry created
Initial documentation.
2026-04-23 — hardened
nftables firewall, mesh-only SSH, fail2ban traefik jail, Plesk disabled, auto-reboot 04:00 UTC, wireguard/fail2ban invariant established.