
SSH keys are strong authentication, but a stolen or leaked private key still grants full access to your server. Two-factor authentication (2FA) adds a time-based one-time password (TOTP) as a second factor — even with the key file, an attacker cannot log in without the rotating 6-digit code from an authenticator app.
This means your private key can be compromised — copied from a laptop, found in a backup, or leaked in a credential dump — and your server remains protected. The attacker would additionally need real-time access to your authenticator app (Google Authenticator, Authy, or 1Password) to generate the correct TOTP code. This article covers setting up TOTP 2FA using libpam-google-authenticator on Ubuntu 24.04.
Install the PAM module and run the setup wizard for each user who will use 2FA. Run the wizard as the target user — not as root — so the ~/.google_authenticator file is created in that user's home directory:
The wizard generates a ~/.google_authenticator file containing the TOTP secret and configuration. Protect it immediately: chmod 400 ~/.google_authenticator. This file is the seed for all future TOTP codes — anyone who reads it can generate valid codes.
PAM (Pluggable Authentication Modules) controls what authentication steps SSH applies. Edit the SSH PAM config to require the TOTP code as part of the login flow:
Also comment out @include common-auth if you want to disable PAM's standard password fallback — otherwise PAM may still ask for a password AND the TOTP code, which is redundant when using SSH key authentication. The goal is: SSH key + TOTP, with no password prompt at all.
The SSH daemon must be told to require both public key authentication and keyboard-interactive (which is how PAM delivers the TOTP prompt). Open /etc/ssh/sshd_config and set the following:
The AuthenticationMethods publickey,keyboard-interactive directive enforces both factors in sequence. A connection that passes only the key check but fails the TOTP step is rejected. Always run sudo sshd -t to validate your config file before reloading — a syntax error in sshd_config can prevent the service from starting.
Open a new terminal session — do not close your existing one yet. Connect to the server. You should see a two-step prompt flow:
Do not close your existing session until the new session confirms the full 2FA flow works end-to-end. The scratch codes generated during setup bypass TOTP entirely — they are your only recovery path if you lose your phone. Treat them like a root password: store them in a password manager, not in a note on the server itself.
CloudStick's server management doesn't require you to have 2FA configured on SSH — it manages servers via its own secure agent connection. The CloudStick agent communicates over an outbound channel from your server to the CloudStick backend, so the dashboard never needs to connect through your user's SSH keys.
However, for servers you connect to directly via SSH — for maintenance, debugging, or deployments — 2FA adds meaningful protection, especially on shared developer accounts where multiple people may hold copies of the same key. CloudStick's built-in browser terminal connects over its agent channel, not via your user's SSH keys, so 2FA on SSH doesn't affect CloudStick dashboard access in any way.
We use cookies to improve your experience
CloudStick uses cookies to personalise content, analyse traffic and keep you signed in. Cookie Policy · Terms of Service