Two-factor authentication (2FA) requires not just a password but also a one-time code from an app (TOTP). Even if your password leaks, the account stays protected.
Enabling 2FA in cPanel
Step 1: Open the settings
Log in to cPanel → the "Security" section → "Two-Factor Authentication".
Step 2: Install an app
On your smartphone, install one of:
- Google Authenticator (iOS/Android)
- Authy (syncs across devices)
- Microsoft Authenticator
Step 3: Scan the QR code
In cPanel, click "Set Up Two-Factor Authentication" — a QR code will appear. Open your authenticator app → "+" → "Scan QR Code".
Step 4: Confirm
Enter the 6-digit code from the app into the "Security Code" field and click "Configure Two-Factor Authentication". After this, every cPanel login will prompt for a code.
Logging in to cPanel with 2FA
- Enter your username and password as usual
- Open your authenticator app
- Enter the 6-digit code (refreshes every 30 seconds)
Recovering access
If you lose your phone:
- Use the secret key to restore access in another app
- Contact ZevsHost support with proof of account ownership
2FA for SSH (optional)
# Install Google Authenticator PAM
sudo apt install -y libpam-google-authenticator
# Configure it for the current user
google-authenticator
# Enable in /etc/pam.d/sshd:
auth required pam_google_authenticator.so
# In /etc/ssh/sshd_config:
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Common TOTP code problems explained
Most complaints about a code "not being accepted" come down to a handful of mechanical causes.
Permission denied (publickey,keyboard-interactive).— this is how SSH reports that every configured login method, including TOTP, failed. The message itself does not say which factor was the problem — password, key, or code — that is visible only in the server log.Do you want authentication tokens to be time-based (y/n)— this is the exact question thegoogle-authenticatorutility asks during first-time setup. Answery: answeringnswitches to a counter instead of time, and most apps like Google Authenticator and Authy work in time-based mode and sync poorly with HOTP.- The code was copied correctly but the server still rejects it — this almost always means the clocks are out of sync. TOTP is based on the current time, and the module only tolerates a small amount of drift.
- Re-entering an already-used 30-second code is rejected even though it technically "hasn't expired" yet — this is not a bug, it's built-in replay protection inside the authentication module itself.
- The code consistently runs "behind" or "ahead" by one step — the shared secret was entered correctly, the problem is only the phone's or server's clock, not the key itself.
Comparing TOTP apps
| App | Sync across devices | Backup | Notable trait |
|---|---|---|---|
| Google Authenticator | None (manual QR transfer only) | Manual export only | Simple and minimal |
| Authy | Yes, across multiple devices | Cloud backup, protected by a PIN | Multi-device convenience widens the attack surface if the Authy account leaks |
| Microsoft Authenticator | Partial, tied to a Microsoft account | Through Microsoft's cloud | Push confirmation for Microsoft services |
| FIDO2/U2F hardware key | None | Physical device, needs a spare key | Not phishable like a code, but this is not TOTP |
When 2FA in this form is not enough
- A shared account used by several people at once — TOTP on one phone blocks everyone else if the owner is unavailable, and handing the shared secret to the whole team reduces the value of the second factor to almost nothing.
- Automated scripts and cron jobs calling the cPanel API — TOTP expects interactive input and does not fit into automation; APIs need their own API tokens, not a password-plus-code pair.
- A user with no smartphone and no way to install a TOTP app on a computer — a backup recovery channel becomes necessary, otherwise support cannot instantly confirm identity if access is lost.
- Expecting 2FA to protect an already-open session from being hijacked — the second factor is only checked at login; it does nothing retroactively to a stolen session cookie or an open SSH connection.
Verifying that login without the second factor is impossible
# Confirm the module is wired into PAM
grep google_authenticator /etc/pam.d/sshd
# Check the effective sshd configuration, not just the file
sudo sshd -T | grep -i authenticationmethods
# Test login in a separate terminal window without closing the current session
ssh user@server-ip
Open the new connection in a separate window on purpose: if the login fails, the old session stays alive and you can roll back the settings without losing access to the server. For cPanel, cross-check the list of users with two-factor authentication enabled in WHM — it shows who actually has 2FA active, not just who set it up at some point.