If your Webmin control panel is reachable on port 10000 with only a username and password standing between an attacker and full root access, you have a single point of failure. Enabling Webmin two-factor authentication adds a time-based one-time password (TOTP) requirement so that a stolen password alone is never enough to log in. This guide covers the complete setup — including the Authen::OATH module install, per-user QR code enrolment, lockout recovery, and pairing 2FA with Fail2Ban for defence-in-depth.
Why Webmin's Default Login Is a Single Point of Failure
Webmin listens on a non-standard port (10000) but that port is trivially discoverable by any internet scanner. Credential-stuffing bots continuously target it with leaked username/password pairs from data breaches. Once an attacker logs in they have:
- Root shell access via the Webmin terminal module
- Full file-system read/write via the File Manager
- The ability to install backdoors, exfiltrate data, or pivot to hosted websites
- Control over firewall rules, cron jobs, and user accounts
Two-factor authentication makes credential theft effectively useless: even with the correct password, the attacker cannot generate the 6-digit TOTP code that rotates every 30 seconds. Combine that with IP allow-listing or server hardening services and the attack surface shrinks dramatically.
Prerequisites: What You Need Before Enabling Webmin 2FA
Before you start, confirm the following:
- Webmin version 1.870 or later — TOTP support was added in 1.870. Run
webmin --versionor check Webmin Configuration → Upgrade Webmin. - Root or sudo access — you need shell access to install the Perl module and for emergency recovery.
- A TOTP app installed on your phone: Google Authenticator (Android/iOS), Authy (Android/iOS/desktop), or any RFC 6238-compliant app.
- An alternative login path — confirm you can SSH into the server as root before enabling 2FA. If you lose your authenticator you will need SSH or console access to recover.
- CPAN or system package manager — needed to install
Authen::OATHif it is not already present.
💡 None of these worked? Skip the guesswork.
Get Expert Help →Step 1 — Install the Required Perl TOTP Module via Webmin
Run this command over SSH:
perl -e "use Authen::OATH; print 'OK
'"
If you see OK, skip ahead to Step 2. If you see Can't locate Authen/OATH.pm, continue below.
On Debian/Ubuntu:
apt-get install -y libauthen-oath-perl
On RHEL/AlmaLinux/Rocky Linux 8+:
dnf install -y perl-Authen-OATH
On CentOS 7:
yum install -y cpan
cpan Authen::OATH
When you navigate to Webmin Configuration → Two-Factor Authentication, Webmin detects the missing module and shows an Install Now button. Clicking it runs a CPAN install in the background. This is convenient but can fail if the server has no direct internet access or if CPAN configuration is missing — in those cases, use the package-manager method above.
Common error: if the CPAN install fails with Warning: No success on command..., it usually means make or gcc is missing. Fix with:
# Debian/Ubuntu
apt-get install -y build-essential
# RHEL/AlmaLinux
dnf groupinstall -y "Development Tools"
Then re-run the CPAN install or install the distro package.
Log in to Webmin → go to Webmin Configuration → click Two-Factor Authentication.
From the Two-factor authentication type drop-down, choose Google Authenticator. This selects the standard TOTP algorithm (RFC 6238) — the same one used by Authy, Microsoft Authenticator, and any other TOTP app.
Click Save. This enables TOTP at the system level but does not yet force it on any user — each Webmin user must enrol separately (Step 3).
What the config file looks like
Webmin stores this setting in /etc/webmin/miniserv.conf. After saving you should see:
twofactor_provider=totp
Individual user 2FA secrets are stored in /etc/webmin/[username].pw2 after enrolment.
Navigate to Webmin Users → click the username you want to enrol → scroll to the Two-Factor Authentication section → click Enrol For Two-Factor Authentication.
Webmin displays a QR code containing the TOTP secret. Open your authenticator app:
- Google Authenticator: tap the
+icon → Scan a QR code - Authy: tap Add Account → Scan QR code
Point your camera at the QR code on screen. The app will add a new entry labelled with your server's hostname.
Below the QR code, Webmin shows the raw secret (a Base32 string). Copy this and store it in a password manager or a printed emergency sheet. This secret lets you re-add the account to a new phone if your original device is lost — without it, recovery requires root SSH access (see Step 4).
Click Save on the user page. The next time this user logs in, Webmin will prompt for both password and TOTP code.
Enrolling multiple users
Repeat the above for every Webmin user account. If you have reseller or sub-admin accounts, each one must be enrolled separately — there is no bulk enrolment option in the Webmin UI.
ssh root@your-server-ip
rm /etc/webmin/root.pw2
(Replace root with the username that is locked out.)
systemctl restart webmin
The user can now log in with password only. Re-enrol 2FA immediately afterwards.
If SSH is also unavailable (e.g., you changed the SSH port and forgot), use your hosting provider's out-of-band console (KVM, VNC, or IPMI) to access a root shell and follow the same steps.
# Debian/Ubuntu
apt-get install -y fail2ban
# RHEL/AlmaLinux
dnf install -y fail2ban
Fail2Ban ships with a built-in Webmin filter at /etc/fail2ban/filter.d/webmin-auth.conf. Create a jail that uses it:
cat > /etc/fail2ban/jail.d/webmin.conf <<'EOF'
[webmin-auth]
enabled = true
filter = webmin-auth
logpath = /var/webmin/miniserv.log
maxretry = 5
bantime = 3600
findtime = 600
port = 10000
action = iptables-multiport[name=webmin, port="10000", protocol=tcp]
EOF
systemctl restart fail2ban
fail2ban-client status webmin-auth
You should see the jail as active with 0 currently banned IPs. After the first brute-force attempt, check again — the attacker's IP will appear in the Banned IP list.
Why this matters with 2FA: even though 2FA prevents actual logins from stolen passwords, each failed attempt still hits your server and generates log noise. Fail2Ban cuts off the attack at the network level after 5 failures, reducing server load and keeping logs clean.
FAQs
Conclusion
Enabling Webmin two-factor authentication takes under 10 minutes but eliminates the most common attack vector against server control panels — stolen credentials. The critical extras that most guides skip: install Authen::OATH before trying to enable TOTP (or Webmin silently fails), save the raw TOTP secret key for offline recovery, and know that rm /etc/webmin/root.pw2 + Webmin restart is your emergency escape hatch if you lose your phone. Pair 2FA with the Fail2Ban jail above and you have a layered defence that stops both credential stuffing and brute-force scanning in their tracks. If you want a full security audit of your Webmin setup or help hardening your server stack, explore our server hardening services.
