# Security Hardening Stage 1 (see `00-overview.md`) — applies to any Proxmox host, independent of cluster plans. Proxmox has no `sudo` out of the box — everything defaults to root. That's the install default, not the recommended end state. Two layers to harden separately. ## Checklist / script mapping Run `scripts/bootstrap.sh` for everything except the admin user (needs a username decision) and 2FA enrollment (must be done interactively via the web UI — there's no safe way to script TOTP secret generation over SSH). Then run `scripts/audit.sh` to verify. Order matters (matches `bootstrap.sh`): | # | Item | Script | Manual step required? | |---|------|--------|------------------------| | 1 | Remove enterprise repos, switch to no-subscription | `switch-to-no-subscription-repo.sh` | no | | 2 | SSH: key-only root login + fail2ban | `harden-ssh.sh` | no (requires an `authorized_keys` already in place — script warns if missing) | | 3 | Unattended security upgrades, no auto-reboot | `setup-unattended-upgrades.sh` | no | | 4 | PVE firewall, default-deny, mgmt-only SSH/8006 | `deploy-firewall.sh` | needs `MGMT_CIDR` set | | 5 | Disable subscription nag (cosmetic) | `disable-subscription-nag.sh` | no | | 6 | Named PVE admin user, Administrator role | `create-admin-user.sh ` | yes — pick the username, change the generated password on first login | | 7 | 2FA/TOTP on that user and `root@pam` | — | yes — web UI only: Datacenter → Permissions → Two Factor, or user menu → TFA | | 8 | Verify everything above | `audit.sh` | no | ## Linux/SSH layer - `PermitRootLogin prohibit-password` in `sshd_config` — root can only log in via SSH key, never password. Kills most brute-force attempts. - fail2ban jail for SSH on top of that. - Restrict SSH to the management VLAN/trusted IPs via the Proxmox firewall (see `03-networking.md`) rather than exposing broadly. - A separate Linux sudo user isn't strictly required for day-to-day PVE admin (the PVE permission system below governs that), but worth adding if multiple people SSH into the box directly, for accountability. ## PVE/web layer (the one that actually matters day-to-day) - Keep `root@pam` for emergencies only. - Create a named user (e.g. `wayne@pve`) with the Administrator role for routine cluster management — `create-admin-user.sh` does this, or Datacenter → Permissions → Users manually. - Enable 2FA (TOTP or hardware key) on both that account and `root@pam`: Datacenter → Permissions → Realms/Users. - For API integrations (monitoring, automation, Terraform, etc.), issue scoped API tokens with least-privilege roles (e.g. `PVEAuditor` or a custom role) — never hand out root credentials. ## Firewall Default-deny at datacenter/node level, whitelist only what's needed (see `03-networking.md` for the specifics). Template in `config/pve-firewall/cluster.fw.example`, applied by `scripts/deploy-firewall.sh`. ## Repos and updates Fresh installs point at the enterprise repo, which fails on `apt update` without a subscription. `scripts/switch-to-no-subscription-repo.sh` removes the enterprise sources entirely (renamed `.disabled`, not just commented out) and switches to the no-subscription repo — handles both the legacy `.list` format and the deb822 `.sources` format current installers write. Keep the host patched — hypervisor CVEs are high-value targets; `scripts/setup-unattended-upgrades.sh` automates security patches (deliberately no auto-reboot on a hypervisor — check `/var/run/reboot-required` and reboot during a planned window). The web UI's "No valid subscription" popup and dashboard indicator are cosmetic upsell, not a security control, but with no subscription they'll nag on every login — `scripts/disable-subscription-nag.sh` patches `proxmox-widget-toolkit`'s JS to suppress them, and installs an apt `Post-Invoke` hook that reapplies the patch automatically after every `apt`/`dpkg` run, since a `proxmox-widget-toolkit` package upgrade overwrites the patched file. ## Misc - Management interface on a network you trust, not the same broadcast domain as guest VM traffic. - If the web UI is ever needed outside the LAN, put it behind a VPN — don't port-forward 8006 directly. ## Further reading / not yet automated here - CIS Benchmark for Proxmox VE - Community PVE hardening guides (kernel parameters, audit logging, storage encryption)