Proxmox VE Hardening Guide
Exposing a hypervisor directly to the internet is a major security risk. This guide walks you through securing Proxmox VE using a defense-in-depth strategy: OS-level hardening, a dedicated firewall, a WireGuard VPN, and strict access controls.
Critical Warning
- Risk of Lockout: Changing SSH ports and firewall rules can easily lock you out of your server.
- Recovery: Ensure you have IPMI/iDRAC/KVM console access or a physical monitor and keyboard attached before applying these changes.
- Testing: Always test new configurations in a separate terminal window before closing your current session.
1. Correct Repositories & Updates
By default, Proxmox tries to use the Enterprise repository, which fails for non-subscribers. To ensure you actually receive security patches, you must switch to the “No-Subscription” repository.
Edit your sources list:
# Disable Enterprise Repo (prevents 401 errors)
sudo sed -i "s/^deb/#deb/" /etc/apt/sources.list.d/pve-enterprise.list
# Add No-Subscription Repo
echo "deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription" | sudo tee /etc/apt/sources.list.d/pve-no-subscription.list
Update the System:
sudo apt update && sudo apt full-upgrade -y
sudo apt autoremove -y
2. Create a Non-Root Admin User
Never use root for remote SSH access. Create a dedicated user with sudo privileges.
sudo adduser adminuser
sudo usermod -aG sudo adminuser
Generate strong keys on your local machine:
We recommend Ed25519 keys for better security and performance.
ssh-keygen -t ed25519 -C "proxmox-admin"
ssh-copy-id -i ~/.ssh/id_ed25519.pub adminuser@your.server.ip
Test the login explicitly:
ssh adminuser@your.server.ip
3. Harden SSH Configuration
We will move SSH to a high, random port and disable password authentication entirely.
1. Pick a port (e.g., 54321): Ensure the port is not in use:
sudo ss -tuln | grep 54321
2. Edit /etc/ssh/sshd_config:
Port 54321
AddressFamily inet # Listen on IPv4 only (optional, simplifies rules)
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers adminuser
MaxAuthTries 3
3. Reload and Validate:
sudo sshd -t # specific check for config syntax errors
sudo systemctl reload ssh
Do not verify functionality yet—keep your current terminal open and open a NEW terminal to test the connection on port 54321.
4. Setup WireGuard VPN
We will treat the VPN as the only door into the management interface.
Install WireGuard:
sudo apt install wireguard -y
Generate Server Keys:
umask 077
wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub
Configure Server (/etc/wireguard/wg0.conf):
[Interface]
Address = 10.10.10.1/24
ListenPort = 51820
PrivateKey = <Contents of /etc/wireguard/server.key>
# Enable IP forwarding logic here if needed for VM access
[Peer]
# Your Client (Laptop/Phone)
PublicKey = <Client Public Key>
AllowedIPs = 10.10.10.2/32
Enable IP Forwarding:
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Start the Interface:
sudo systemctl enable --now wg-quick@wg0
5. Configure UFW (The Firewall)
Note: Proxmox has a built-in firewall, but UFW is often easier for single-node hardening. If you are running a Proxmox Cluster, be very careful with UFW as it can block Corosync (UDP 5404/5405).
Install and Set Defaults:
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
Step 1: Allow SSH (Temporary Public Access): Crucial step to prevent immediate lockout.
sudo ufw allow 54321/tcp comment 'Temp SSH Public'
Step 2: Allow WireGuard:
sudo ufw allow 51820/udp comment 'WireGuard VPN'
Step 3: Enable the Firewall:
sudo ufw enable
Step 4: Restrict Admin Access to VPN-Only: Once you have confirmed you can connect to the VPN (10.10.10.1), lock everything else down.
# Allow SSH and GUI *only* from inside the VPN
sudo ufw allow from 10.10.10.0/24 to any port 22 proto tcp
sudo ufw allow from 10.10.10.0/24 to any port 54321 proto tcp
sudo ufw allow from 10.10.10.0/24 to any port 8006 proto tcp
# Remove the public SSH rule created in Step 1
sudo ufw delete allow 54321/tcp
6. Configure Fail2Ban (Brute Force Protection)
Proxmox does not come with Fail2Ban configured for the Web GUI by default. Let’s fix that.
Install:
sudo apt install fail2ban -y
Create Jail Config (/etc/fail2ban/jail.d/proxmox.conf):
[proxmox]
enabled = true
port = https,http,8006
filter = proxmox
logpath = /var/log/daemon.log
maxretry = 3
findtime = 2d
bantime = 1h
Create Filter Config (/etc/fail2ban/filter.d/proxmox.conf):
[Definition]
failregex = pvedaemon\[.*authentication failure; rhost=<HOST> user=.* msg=.*
ignoreregex =
Restart Fail2Ban:
sudo systemctl restart fail2ban
sudo fail2ban-client status proxmox
7. Enable Two-Factor Authentication (2FA)
Even with a VPN, you should enable 2FA in case your workstation is compromised.
- Log into Proxmox Web UI (via VPN IP
https://10.10.10.1:8006). - Go to Datacenter > Permissions > Two-Factor.
- Add TOTP for your user.
- Scan the QR code with an app like Google Authenticator or Raivo OTP.
- Important: In the user login realm settings, require TFA.
Safety Checklist
Before walking away from the server, verify the following:
- Updates:
apt updateruns without 401 Unauthorized errors. - SSH: Root login is disabled; password login is disabled.
- SSH: You can login via port 54321.
- VPN: You can handshake with WireGuard.
- Firewall: Port 8006 (GUI) and SSH are TIMEOUT when accessed from the public internet (not the VPN).
- Backups: You have backed up your SSH keys and WireGuard config off-site.