Enable two-factor authentication with Google Authenticator on Linux
Google Authenticator adds a time-based one-time password (TOTP) to SSH and sudo access on RHEL, CentOS, Fedora and other Linux systems. The administrator confirms a rotating six-digit code from a phone, while PAM links the check to normal system authentication.
Australian teams may run servers in Sydney and Melbourne, plus branches in Perth, Brisbane and Adelaide. Hosts can use AEST, AEDT, ACST or AWST, while TOTP uses UTC, so network time accuracy matters more than the displayed timezone. The method supports Australian Signals Directorate MFA guidance and OAIC guidance on securing personal information.
| Method | Contribution | Benefit | Limitation |
|---|---|---|---|
| Password | Knowledge factor | Familiar to users | Reuse and phishing |
| SSH private key | Possession factor | Server stores no reusable secret | Stolen key can be used |
| Google Authenticator TOTP | Time-based second factor | Works without a mobile carrier network | Lost device or clock drift |
| SMS code | Possession factor via carrier | No authenticator app needed | SIM problems and outages |
Prepare the host without creating a lockout
Start with a test account and keep an existing SSH session open. Confirm access through the hosting provider’s serial console or the server’s management interface, because PAM errors can lock out all remote administrators.
Back up SSH and sudo configuration, then check the account and clock. Do not remove key-based access until the second factor has passed a real login test.
sudo cp --archive /etc/ssh/sshd_config "/etc/ssh/sshd_config.bak.$(date +%F)"
sudo cp --archive /etc/pam.d/sshd "/etc/pam.d/sshd.bak.$(date +%F)"
sudo cp --archive /etc/pam.d/sudo "/etc/pam.d/sudo.bak.$(date +%F)"
timedatectl status
Install packages and synchronise the clock
Install the PAM helper and time-sync package. On RHEL or CentOS Stream, enable EPEL first if policy permits; Fedora normally provides the packages directly.
# RHEL and CentOS Stream
sudo dnf install -y epel-release
sudo dnf install -y google-authenticator qrencode chrony
# Fedora
sudo dnf install -y google-authenticator qrencode chrony
TOTP codes change every 30-second interval and fail when clocks drift. Start chronyd and verify the result. When configuration grows, quick feedback matters: integrating Magik errors with Flycheck demonstrates how compiler diagnostics can appear directly in an editor. The same principle applies here—check the clock and configuration before a restart turns a small mistake into an outage.
sudo systemctl enable --now chronyd
timedatectl status
Enrol administrator accounts in the app
Run enrolment as each administrator, not root, so the secret remains account-specific. The -t option selects TOTP, -w 1 tolerates one adjacent interval, and -e 10 creates ten recovery codes.
google-authenticator -t -d -w 1 -e 10 -s -l "alice@au-linux"
Scan the QR code with the app, or type the shared secret manually where a terminal QR is impractical. Keep the phone’s automatic date-and-time setting enabled and test a generated code immediately. Keep recovery codes in an encrypted vault or a sealed offline record, never beside the phone.
Current packages normally store the secret in ~/.config/google-authenticator; older packages may use ~/.google_authenticator. Protect whichever file was created.
# Current packages
chmod 600 ~/.config/google-authenticator
# Older packages
# chmod 600 ~/.google_authenticator
Enforce PAM checks for SSH and sudo
Add the module as the first authentication entry in /etc/pam.d/sshd and /etc/pam.d/sudo, retaining the distribution’s password rules. The nullok setting permits a staged rollout: enrolled users must still supply TOTP. Remove it after every administrator has enrolled.
auth required pam_google_authenticator.so secret=${HOME}/.config/google-authenticator nullok
Replace the path for older packages. If the PAM implementation does not expand ${HOME}, use an absolute home path instead.
For SSH, require PAM keyboard-interactive authentication. RHEL 9 and Fedora use KbdInteractiveAuthentication; older CentOS releases use ChallengeResponseAuthentication. AuthenticationMethods prevents a plain password-only SSH session from bypassing the second factor.
UsePAM yes
PasswordAuthentication yes
KbdInteractiveAuthentication yes
AuthenticationMethods keyboard-interactive:pam
Validate before reloading sshd and test from a second terminal. The same staged approach in RHEL 9 virtual hosts protects web-server changes: check syntax, reload, then verify from another session. If the check fails, restore the backup and keep the original session open.
sudo sshd -t && sudo systemctl reload sshd
Test access and rehearse recovery
Test both SSH and sudo, including one deliberately invalid code, while watching the logs. A correct code should grant access; an incorrect or expired code should fail cleanly without disturbing the first session.
sudo journalctl -u sshd -f
sudo journalctl -t sudo -f
Rehearse account recovery before relying on the setup. Store emergency codes offline, keep another administrator or console route, and do not leave the phone as the only recovery method. For workloads in AWS Sydney or Melbourne regions, confirm that serial-console access exists and is restricted as break-glass access.
Maintain the authentication lifecycle
Treat the setup as a lifecycle. After OS, PAM or phone changes, retest enrolment, clock synchronisation, SSH, sudo and recovery. Check that the package remains available through enabled repositories. Australian organisations using local Red Hat reseller channels and RHEL subscriptions should include PAM compatibility in renewal checks.
Phones are lost, replaced and wiped. Register a replacement device, update the stored seed, invalidate the old entry and renew recovery codes. Audit which administrator accounts have enrolled, remove nullok, and avoid copying seeds into email, chat or shared documents.
The lasting lesson is to combine a tested backup route with a synchronised TOTP factor and rehearsed recovery. Remember that strong Linux two-factor authentication depends on the whole chain—enrolment, PAM, SSH policy, time and recovery—not just the QR code.