Introduction

You just finished installing Proxmox VE. The web interface loads, you can see your node in the summary panel, and maybe you've already spun up a test VM. It feels done. It isn't quite.

A default Proxmox VE install is set up to work, not to be locked down. Root can log in over SSH with a password, the firewall is off, there's no two-factor authentication, and the web GUI is happy to sit on the open internet on port 8006 if you let it. None of that is a bug — Proxmox assumes you'll harden things to match your own environment. Most people just never get around to it.

This is the checklist I'd hand a friend who just installed Proxmox VE for the first time and asked "okay, now what?" It's written for a single homelab node or a small office server, not a 40-node enterprise cluster with a compliance team. If that's you, this is still the right starting point — you'll just add more on top later.

What You Will Learn

  • Why the default Proxmox VE setup isn't safe to expose to the internet as-is
  • The first ten things worth doing after a fresh install, in a sensible order
  • The exact commands and GUI clicks for each step
  • Which defaults quietly cause the most support-forum posts
  • How to tell if you've locked yourself out — and how to avoid it in the first place

What Is This Feature?

"Hardening" just means changing the defaults that assume trust into defaults that assume nothing. Proxmox VE ships as a Debian-based hypervisor with a web GUI on port 8006 and SSH on port 22, both reachable with the root password you set during install. There's no firewall running, no two-factor login, and the built-in certificate is self-signed, which is why your browser complains the first time you open the dashboard.

None of that is a flaw. A hypervisor install script can't guess whether you're putting this on an isolated homelab VLAN or a box with a public IP. It gives you a working system and leaves the security posture to you.

A few terms will come up below, so let's get them out of the way. SSH (Secure Shell) is how you get a remote terminal on the Proxmox host — think of it as the command-line equivalent of the web GUI. 2FA (two-factor authentication) means logging in needs your password plus a rotating six-digit code from an app like Google Authenticator, so a stolen password alone isn't enough. ACME is the protocol Let's Encrypt uses to issue free, trusted SSL certificates automatically, instead of you paying for one or living with the ugly "not secure" warning forever.

Why Would You Use It?

Because the failure mode isn't hypothetical. Search "proxmox 8006 shodan" sometime and you'll see thousands of exposed Proxmox login pages, plenty still on default settings. If someone brute-forces root's password on one of those, they don't just get a shell — they get every VM and container on that host, including whatever data lives on the disks.

Even on a private homelab network, hardening still earns its keep. Kids, roommates, IoT devices, a compromised laptop on the same LAN — any of them could reach port 8006 if nothing stops them. And a few of these steps aren't really about attackers at all. Enabling notifications means you find out about a failed backup job before you need that backup, not after.

I'll be honest: not every item here matters equally. A two-node homelab tucked behind a router with no port forwarding has a very different risk profile than a box colocated at a datacenter. Read through all ten, then decide which ones actually apply to you.

Prerequisites

Before you start, make sure you have:

  • A working Proxmox VE 9.x install (8.x works too — I'll flag anywhere the steps differ)
  • Root access to the web GUI at https://your-node-ip:8006
  • SSH access to the host, either via the GUI's Shell button or a terminal on your workstation
  • An SSH key pair on your workstation (run ssh-keygen -t ed25519 if you don't have one yet)
  • About 45 minutes, and ideally a way to reach the host physically or via IPMI/iDRAC/iLO in case a step goes wrong

That last point matters more than it sounds. A couple of these changes — SSH and firewall rules especially — can lock you out if you get the order wrong. Keep a GUI console session open in a separate tab while you work through the SSH and firewall sections, just in case.

Step-by-Step Tutorial

1. Update the system first

Do this before anything else, so you're hardening a current install rather than one with a month of unpatched packages sitting on it.

apt update
apt full-upgrade

Reboot afterward if a new kernel was installed — the GUI will show a small icon next to the node name reminding you a reboot is pending.

2. Sort out the repository situation

Fresh installs point at the pve-enterprise repository by default, which needs a paid subscription key to actually pull updates. Without one, apt update throws a 401 error on that repo. This isn't a security problem, just an annoyance — but it trips up almost everyone in their first week.

Go to Node → Updates → Repositories in the GUI. Disable the Enterprise repository if you don't have a subscription, and add the No-Subscription repository instead. It's fully functional and what most homelab and small-business installs run — you just don't get access to the Enterprise support channel.

3. Create a real admin user — stop living as root

Using root@pam for everything means one compromised password takes down the whole host with no accountability trail. Create a named account instead.

pveum user add jdoe@pve --password
pveum aclmod / -user jdoe@pve -role Administrator

Log out, log back in as jdoe@pve, and confirm you can see everything root could. From here on, use this account day to day and save root for emergencies.

4. Lock down SSH

Copy your public key to the host first, before you disable password login, or you'll shut yourself out:

ssh-copy-id root@your-node-ip

Test that key-based login works — open a fresh terminal and confirm ssh root@your-node-ip logs you in without a password prompt. Only then edit /etc/ssh/sshd_config and set:

PermitRootLogin prohibit-password
PasswordAuthentication no

Apply it with:

systemctl restart sshd

prohibit-password still allows root in with a key, which you'll occasionally need for recovery, but it kills password-guessing attacks stone dead.

5. Turn on the firewall — carefully

The Proxmox firewall lives at Datacenter → Firewall and again at Node → <yournode> → Firewall, and both switches need to be flipped on for rules to actually apply. Before enabling either, add an explicit rule allowing SSH (port 22) and the web GUI (port 8006) from your own network or IP range. The default policy on the input chain is DROP, and it does not make an exception for the connection you're currently using.

Enable the node-level firewall first, confirm you can still reach the box, then enable the datacenter-level one. If you do get locked out, the GUI console (or physical/IPMI access) lets you run pve-firewall stop to kill it immediately.

6. Add two-factor authentication

Under Datacenter → Permissions → Two Factor, add a TOTP (time-based one-time password) entry for your admin user. Scan the QR code with an authenticator app, and from then on, logging into the GUI needs your password plus that rotating code.

7. Replace the self-signed certificate

If your Proxmox host has a real domain name pointing at it, go to Node → Certificates and set up an ACME account with Let's Encrypt. Proxmox handles the renewal automatically after that. If you're on a private IP with no domain, skip this one — a self-signed cert on an internal network is a cosmetic annoyance, not a real risk, and you'll just click through the browser warning.

8. Set up notifications

Under Datacenter → Notifications, add an SMTP or Gotify target and make sure backup jobs, replication failures, and package updates are routed to it. A failed backup you never hear about isn't a backup at all — it's a false sense of security.

9. Schedule your first backup job

Under Datacenter → Backup, create a scheduled vzdump job targeting local storage at minimum, or ideally a separate disk, NFS share, or Proxmox Backup Server instance. Do this before you put anything important on the host, not after something breaks.

10. Keep the web GUI off the public internet

Don't port-forward 8006 on your router. If you need remote access, put a VPN (WireGuard is built into most routers and is simple to set up) or a tool like Tailscale in front of it, and connect to that instead of exposing the dashboard directly.

Commands Explained

CommandWhat it does
apt full-upgradeUpgrades all packages, including ones that need to remove or replace other packages — safer than plain upgrade on Proxmox because kernel and PVE package updates often need this.
pveum user add jdoe@pve --passwordCreates a new Proxmox-realm user named jdoe and prompts for a password. pveum is the Proxmox user management CLI.
pveum aclmod / -user jdoe@pve -role AdministratorGrants the Administrator role at the root path (/), meaning it applies to the whole node — the same as full root-equivalent access inside Proxmox's own permission system.
ssh-copy-id root@ipPushes your local public key into the remote user's ~/.ssh/authorized_keys file so future logins don't need a password.
systemctl restart sshdReloads the SSH daemon so config changes in sshd_config take effect without rebooting.
pve-firewall stopImmediately disables the Proxmox firewall — your emergency escape hatch if a rule locks you out.

Common Errors

"401: authentication key expired" when running apt update — you're still pointed at the Enterprise repository without a subscription key. Switch to No-Subscription as described in step 2.

Connection refused on SSH after restarting sshd — usually means your key wasn't actually copied before you set PasswordAuthentication no. Use the GUI console to fix sshd_config back and try again.

Locked out entirely after enabling the firewall — the input chain defaulted to DROP with no allow rule for your IP. Use the console (physical, IPMI, or the GUI's noVNC shell) and run pve-firewall stop, then add the missing rule before re-enabling.

2FA code "always invalid" — almost always a clock drift issue. TOTP codes are time-based, so if the host or your phone's clock is off by more than about 30 seconds, codes won't match. Check timedatectl on the host.

Troubleshooting

If something above breaks access entirely, don't panic — nothing here touches your VMs or containers directly, only the management layer. Get to the host via its physical console, IPMI/iDRAC/iLO, or your hosting provider's out-of-band access, log in as root locally (this still works even with SSH password auth disabled, since it's not a network login), and undo the last change you made.

For firewall lockouts specifically, pve-firewall stop is the fastest fix — it's a live command, no reboot needed. For SSH, editing sshd_config back to PasswordAuthentication yes and restarting sshd from the local console gets you back in over the network.

If notifications aren't arriving, test the target directly from Datacenter → Notifications — there's a "Send test notification" button that bypasses waiting for a real event to trigger.

Best Practices

  • Do this checklist in order. Update first, then repositories, then users — enabling the firewall before you've confirmed SSH access is the single most common way people lock themselves out.
  • Keep root's password long and unique even after switching to key-based SSH login. You'll still need it for the GUI and local console.
  • Don't disable the firewall to "fix" a lockout permanently — fix the rule, then turn it back on. A permanently disabled firewall defeats the entire point of this exercise.
  • Revisit this list after major version upgrades (8.x to 9.x, for example) — some settings, particularly repository files, changed format between versions.
  • Snapshot or back up your Proxmox host configuration (not just guest VMs) before making sweeping changes, so a bad firewall rule or SSH config is a five-minute fix, not a re-install.

Frequently Asked Questions

Do I really need all ten steps for a homelab with no internet exposure?

No. Updates, a non-root admin user, and backups matter everywhere. The firewall, 2FA, and Let's Encrypt steps matter most once the host is reachable from outside your own LAN.

Will disabling the Enterprise repository break anything?

No — the No-Subscription repository carries the same packages, just without access to Proxmox's paid support channel. Plenty of production homelabs run on it long-term.

Can I skip SSH key setup and just use a really long root password?

You can, but a leaked or brute-forced password is still just one string. A key pair can't be guessed, and disabling password auth removes an entire attack category rather than just making it slower.

What happens if I lock myself out of the firewall by mistake?

Nothing on your VMs is affected. Use the console (physical, IPMI, or GUI noVNC shell) and run pve-firewall stop to get management access back immediately.

Is the self-signed certificate warning actually a security problem?

Not on a private network you control. It just means your browser can't verify the cert against a public trusted authority. On a public-facing host, replace it with Let's Encrypt so you're not training yourself to click through security warnings.

Conclusion

None of these ten steps take more than a few minutes individually, and together they turn a wide-open default install into something you could reasonably leave running unattended. Start with updates and the admin user — those two alone remove most of the risk from a typical homelab setup. Add the firewall, 2FA, and VPN access once you're comfortable, especially if the host is ever going to be reachable from outside your own network.

Do it once, right after install, while the box is still empty and a mistake costs you nothing. Waiting until you've got a dozen VMs running makes every one of these changes more nerve-wracking than it needs to be.