Skip to main content
RunBook Academy

← All labs in Proxmox VE

Lab · foundation · ~45 min

Enable two-factor authentication for a PVE user

A · Physical hardwareB · Nested virtualisationC · Simulation

Objectives

  • Enable TOTP for a PVE user account
  • Configure a backup recovery key
  • Verify login with 2FA
  • Audit the configured 2FA methods

Prerequisites

  • A PVE cluster with at least one non-root user
  • A smartphone or laptop with a TOTP app (Google Authenticator, Bitwarden, 1Password)
  • Time sync (chrony) working on the PVE host

Two-factor authentication lab

This lab turns on TOTP-based 2FA for a non-root user and verifies that login works end-to-end.

Steps

1. Confirm NTP is working

chronyc tracking | grep -E 'Last offset|Stratum'
# Expected: small offset, stratum 1-3

If NTP is not running:

apt install -y chrony
systemctl enable --now chrony

2. Create the user (if not already present)

pveum useradd alice@pve --comment "Lab user"
pveum passwd alice@pve
pveum aclmod / --roles PVEAdmin --user alice@pve

3. Enrol TOTP for the user

As root, run:

pveum tfa add alice@pve --type totp --description "Alice's phone"

This returns:

  • A TOTP secret URI
  • An initial recovery key list (use only once)

Open the URI in the user’s TOTP app:

# Either scan the QR with the phone, or paste the secret manually

4. Set the user’s password to require 2FA at next login

pveum user modify alice@pve --enable 1

5. Log in via the GUI

  1. Open https://pve-host:8006
  2. Username: alice@pve
  3. Password: alice’s password
  4. Realm: PAM
  5. Click “Login”
  6. Enter the 6-digit TOTP from the app

6. Log in via the CLI (SSH)

ssh alice@pve-host
# Password prompt → password
# TOTP prompt → 6-digit code

7. Configure recovery keys

# Generate recovery keys
pveum tfa add alice@pve --type recovery --description "Backup keys"

# Store them in a password manager
# Print and store in a safe as backup

8. Audit 2FA

pveum tfa list alice@pve
# Expected: list of TOTP and recovery entries with their IDs

9. Test recovery

# Log out; log back in using "Recovery code" instead of TOTP
# Expected: one of the recovery codes works

10. Test lost-device scenario

# Substitute the entry id from `pveum tfa list alice@pve`:
TOTP_ID=totp-0

# Simulate losing the TOTP device
# SSH into PVE as root
pveum tfa delete alice@pve --id "$TOTP_ID"
# Add a new TOTP for a new device
pveum tfa add alice@pve --type totp

Verification

  • alice can log in via GUI and CLI with password + TOTP
  • Recovery keys work as a fallback
  • 2FA configuration survives across reboots
  • pveum tfa list shows all enrolled factors

Cleanup

pveum tfa delete alice@pve
pveum userdel alice@pve

Notes

  • Always generate multiple recovery keys. TOTP without a backup is a single point of failure.
  • For service accounts (no human), use a long random password and store it in Vaultwarden. 2FA is for human accounts.
  • Consider WebAuthn / hardware keys (YubiKey) for high-privilege accounts; the same pveum tfa add flow works with --type u2f.

Deliverables

  • · A user with TOTP enrolled
  • · A documented recovery key stored securely
  • · Successful login from the GUI and the CLI

Verification status

Executed end to end
not yet run on hardware

The commands and configuration here have been reviewed against the verified software versions, but nobody has run this lab start to finish on a system meeting its prerequisites. Treat the Expected Outcome as the intended result rather than an observed one, and keep the Cleanup section to hand.