How To Set Up SSH Two-Factor Authentication on Fedora 41
In this tutorial, we will show you how to set up SSH to use two-factor authentication on Fedora 41. Securing your SSH connections is crucial in today’s increasingly hostile digital landscape. While SSH already provides strong encryption, adding two-factor authentication (2FA) significantly enhances your server’s security posture. This additional layer of protection ensures that even if your password or SSH key is compromised, attackers still cannot access your Fedora 41 system without the second authentication factor. This comprehensive guide walks you through implementing 2FA for SSH on Fedora 41, creating a robust security solution that protects your servers from unauthorized access.
By following this tutorial, system administrators and security-conscious users will learn how to secure their SSH connections with time-based one-time passwords (TOTP). This method is widely recognized as an industry best practice for critical systems, particularly those exposed to the internet.
Understanding SSH Security and Two-Factor Authentication
SSH (Secure Shell) has been the standard protocol for remote server administration for decades. Its encryption capabilities provide substantial protection, but traditional authentication methods have inherent limitations.
What is SSH and its security limitations
SSH typically relies on either password authentication or key-based authentication. Password-based access is vulnerable to brute force attacks and credential theft. Meanwhile, key-based authentication, though stronger, can still be compromised if an attacker gains access to your private key file and it lacks passphrase protection.
The fundamental weakness in both methods is their single-factor nature. Once a credential is compromised, security is immediately breached. This single point of failure represents an unacceptable risk for critical systems.
Two-factor authentication explained
Two-factor authentication addresses this vulnerability by requiring users to provide two different types of evidence to verify their identity. This typically follows the principle of “something you know” (password or key) plus “something you have” (a physical device generating time-based codes).
For SSH connections, this usually means combining your regular authentication method with a time-based one-time password (TOTP) generated by a smartphone app. These codes typically expire after 30 seconds and are mathematically impossible to predict without access to the secret key stored on your physical device.
Benefits of implementing 2FA for SSH
Implementing 2FA for SSH connections provides several critical security advantages:
- Protection against credential theft, as stolen passwords or keys become useless without the second factor
- Defense against brute force attacks, since attackers cannot generate valid TOTPs
- Compliance with security best practices and regulatory requirements
- Early detection of unauthorized access attempts when unexpected 2FA prompts occur
- Time-limited authentication codes that prevent replay attacks
Prerequisites and Preparation
Before implementing two-factor authentication for SSH on your Fedora 41 system, ensure you meet the following requirements and take important preparatory steps.
System requirements
- A Fedora 41 system with all packages updated to the latest versions
- SSH server (OpenSSH) installed and operational
- Administrative access with sudo privileges
- A working SSH connection that you’ve tested and verified
Required mobile components
You’ll need a smartphone with an authenticator application installed. Several options are available:
- Google Authenticator (Android and iOS)
- Authy (Android and iOS)
- Microsoft Authenticator (Android and iOS)
- FreeOTP (open-source for Android and iOS)
Download and install your preferred authenticator app from your device’s app store before proceeding.
Before you begin
Taking precautionary measures is essential. Follow these steps before making any changes:
- Create a backup access method by keeping an existing SSH session active while making changes
- Verify you have console access (physical or virtual) in case SSH becomes inaccessible
- Update your system with the latest security patches:
sudo dnf update -y
- Back up any existing SSH configuration files:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
sudo cp -r /etc/pam.d /etc/pam.d.backup
These precautions will prevent a lockout scenario, which can occur if configuration errors prevent all SSH access methods.
Installing the Google Authenticator PAM Module
To enable two-factor authentication for SSH, you’ll need to install and configure the Google Authenticator PAM module on your Fedora 41 system.
Understanding PAM (Pluggable Authentication Module)
PAM provides a flexible framework that allows applications to authenticate users through various methods. Rather than each application implementing its own authentication mechanism, PAM centralizes this functionality, making it easier to enhance security across multiple services.
When SSH attempts to authenticate a user, it consults PAM, which then processes a stack of authentication modules defined in configuration files. We’ll be adding the Google Authenticator module to this stack to enable 2FA.
Installation steps
The Google Authenticator PAM module is available in Fedora’s default repositories. Install it with the following command:
sudo dnf install google-authenticator -y
This package provides the necessary PAM module and the command-line utility for generating TOTP secrets. After installation, verify that all components were correctly installed:
rpm -qa | grep google-authenticator
The command should return the package name and version, confirming successful installation. The package includes:
- The
google-authenticator
binary for generating TOTP secrets - The PAM module library file
- Documentation and examples
The installation process automatically resolves dependencies, including required cryptographic libraries and PAM development files. Now that the software is installed, we can proceed to configuring it for your user account.
Configuring Google Authenticator for Your User Account
With the Google Authenticator PAM module installed, you need to configure it for your user account. This process generates the secret key for producing time-based one-time passwords.
Initial setup process
Run the google-authenticator command as your regular user (not as root or with sudo):
google-authenticator
The command will prompt you with several configuration questions. Let’s examine each:
- The first prompt asks whether to use time-based authentication tokens. Answer
y
(yes) as time-based tokens are more secure than counter-based ones. - The system will display a QR code in your terminal along with your secret key, verification code, and emergency scratch codes. Keep these safe.
QR code setup and mobile app integration
Open your authenticator app on your smartphone and add a new account. Most apps offer a “scan QR code” option. Point your phone’s camera at the QR code displayed in your terminal. The app will automatically add your Fedora account and begin generating TOTPs.
Alternatively, if you can’t scan the QR code, you can manually enter the secret key displayed in the terminal. This creates the same result but requires more careful typing.
Verify that your app is generating codes that match the verification code shown in your terminal. The codes should change every 30 seconds.
Configuration options explained
The setup process continues with several important security questions:
- “Do you want me to update your ~/.google_authenticator file?” Answer
y
to save your settings. - “Do you want to disallow multiple uses of the same authentication token?” Answer
y
for best security. This prevents replay attacks. - “By default, a new token is generated every 30 seconds. Do you want to do so every 90 seconds?” For most users, answer
n
to keep the 30-second window, which provides better security. - “Do you want to enable rate-limiting?” Answer
y
to prevent brute force attacks. This limits authentication attempts to 3 per 30 seconds.
Backup codes
During setup, the system generates five emergency scratch codes. These one-time use codes provide backup access if you lose your phone or the authenticator app. Store these codes securely:
- Write them down and store them in a physical safe
- Store them in an encrypted password manager
- Never keep them in plain text on any computer
Each scratch code can be used only once, and they bypass the need for your authenticator app in emergency situations. After using a scratch code, you should regenerate your 2FA setup to maintain security.
Modifying PAM Configuration for SSH
Once you’ve set up the Google Authenticator for your user account, you need to configure PAM to use it for SSH authentication. This involves modifying PAM’s SSH configuration file.
Understanding the PAM configuration structure
PAM uses a modular approach with configuration files stored in the /etc/pam.d/
directory. Each service has its own configuration file defining which authentication modules to use and in what order. The file we need to modify is /etc/pam.d/sshd
.
PAM modules use control flags to determine how their success or failure affects the overall authentication process:
required
: Must succeed for authentication to continuerequisite
: Must succeed, and failure immediately returns control to the applicationsufficient
: If succeeds, no further modules are processedoptional
: Success or failure doesn’t impact authentication unless it’s the only module
Editing the PAM configuration file
Open the SSH PAM configuration file with a text editor:
sudo nano /etc/pam.d/sshd
Add the following line at the bottom of the file:
auth required pam_google_authenticator.so
This configuration makes the Google Authenticator a required component of SSH authentication. Users must provide a valid TOTP code to be authenticated.
If you want to make 2FA optional (not recommended for production systems), you can use:
auth sufficient pam_google_authenticator.so
For even stronger security, you can configure PAM to require both password and 2FA by modifying the file to include:
auth required pam_google_authenticator.so
auth required pam_unix.so no_warn try_first_pass
Setting nullok option (optional 2FA)
If you need to gradually roll out 2FA to users while allowing those without it to still log in, you can add the nullok
option:
auth required pam_google_authenticator.so nullok
This configuration makes 2FA required only for users who have set it up. Users without a .google_authenticator
file can still log in with just their regular authentication method. This option is useful during a transition period but should be removed once all users have configured 2FA.
Proper file permissions and ownership
After modifying PAM configuration files, always check their permissions:
sudo ls -la /etc/pam.d/sshd
The file should be owned by root and have permissions that prevent ordinary users from modifying it (typically 644). If needed, correct the permissions:
sudo chmod 644 /etc/pam.d/sshd
sudo chown root:root /etc/pam.d/sshd
Improper permissions could allow users to modify authentication requirements, creating a security vulnerability.
Configuring the SSH Server
With PAM configured, you now need to adjust the SSH server settings to enable challenge-response authentication and specify your authentication methods.
Modifying sshd_config file
Open the SSH daemon configuration file:
sudo nano /etc/ssh/sshd_config
Find and modify the following parameters (or add them if they don’t exist):
# Enable challenge-response authentication (required for 2FA)
ChallengeResponseAuthentication yes
# Disable password authentication if using key-based auth
PasswordAuthentication no
# Enable keyboard-interactive authentication
KbdInteractiveAuthentication yes
# PAM authentication enabled
UsePAM yes
These settings enable the necessary authentication methods for 2FA to work. The ChallengeResponseAuthentication
directive is particularly important as it allows the SSH server to prompt for the TOTP code.
Authentication methods configuration
For maximum security, configure SSH to require both key-based authentication and the verification code by adding:
# Require both public key and keyboard-interactive (for 2FA)
AuthenticationMethods publickey,keyboard-interactive
This configuration ensures that users must authenticate with both their SSH key and a valid TOTP code. The comma between methods indicates that both are required sequentially.
If you want to allow either key-based authentication with 2FA or password authentication with 2FA, use:
AuthenticationMethods publickey,keyboard-interactive password,keyboard-interactive
Here, the space between authentication method groups indicates “OR” logic, while commas indicate “AND” logic.
SSH service management
After making these changes, verify your configuration syntax:
sudo sshd -t
If no errors are reported, restart the SSH service to apply the changes:
sudo systemctl restart sshd
Check the status to ensure the service restarted successfully:
sudo systemctl status sshd
If there are any issues, check the system logs for detailed error messages:
sudo journalctl -u sshd -f
Testing Your Two-Factor Authentication Setup
After configuring both PAM and SSH, you should thoroughly test your 2FA setup to ensure it’s working correctly and doesn’t lock you out of your system.
Best practices for secure testing
Follow these best practices when testing your 2FA configuration:
- Keep an existing SSH session open while testing to maintain access if something goes wrong
- Test from a different terminal or machine to verify the authentication flow
- Have your console access ready (physical or virtual) as a fallback
- Prepare to revert changes if needed using your configuration backups
The new SSH login process
With 2FA enabled, the SSH login process changes significantly. Connect to your server using your normal SSH command:
ssh username@your-server-ip
You’ll now experience a login flow that includes:
- Your normal authentication (password or SSH key)
- A prompt for your verification code:
Verification code:
- Enter the 6-digit code from your authenticator app
- If correct, you’ll be granted access to the system
The new process adds minimal friction while significantly enhancing security. The verification code prompt appears after your initial authentication succeeds.
Verification of successful implementation
To verify your 2FA implementation is working properly:
- Check that you’re prompted for a verification code when logging in
- Confirm that incorrect verification codes are rejected
- Test login with both your primary credentials and verification code
- If using key-based authentication, verify it still works with 2FA
- Try logging in from different clients (desktop, mobile SSH apps) to ensure compatibility
If any tests fail, review your configuration files for errors or omissions before proceeding.
Troubleshooting Common Issues
Even with careful configuration, you might encounter issues with your 2FA setup. Here are common problems and their solutions.
Authentication failures
If you’re unable to authenticate even with the correct verification code, check these potential issues:
- Time synchronization problems: TOTP codes are time-based, so server and phone time must be synchronized. Check both devices:
date
If your server time is incorrect, configure NTP:
sudo dnf install chrony sudo systemctl enable --now chronyd
- Expired TOTP codes: Codes typically expire after 30 seconds. Generate a fresh code in your app.
- PAM configuration errors: Check your PAM configuration:
cat /etc/pam.d/sshd | grep authenticator
Ensure the line was added correctly and in the appropriate location.
SSH connection issues
If SSH connections are refused or fail before reaching the verification code prompt:
- SSH daemon not running: Check the service status:
sudo systemctl status sshd
- Configuration syntax errors: Verify your sshd_config syntax:
sudo sshd -t
- Firewall blocking SSH: Check firewall rules:
sudo firewall-cmd --list-all
Ensure port 22 (or your custom SSH port) is open.
Mobile app problems
Issues with your authenticator app can prevent successful login:
- App synchronization issues: Resynchronize your app with the server time.
- Device time drift: Many authenticator apps have a time correction feature in settings.
- Incorrect secret key: If the app was set up incorrectly, you may need to regenerate your secret:
mv ~/.google_authenticator ~/.google_authenticator.old google-authenticator
This requires console access or an active SSH session.
Emergency access methods
If you’re locked out despite all troubleshooting:
- Use emergency scratch codes if you have them available.
- Access the server via console (physical or virtual) and disable 2FA temporarily:
sudo nano /etc/pam.d/sshd
Comment out the Google Authenticator line with a # character.
- Restart SSH and log in:
sudo systemctl restart sshd
- Fix your configuration and re-enable 2FA.
Advanced 2FA Configurations
Once you have basic 2FA working, you can implement more sophisticated configurations to balance security and convenience.
User-specific 2FA policies
You can enforce 2FA only for specific users or groups by modifying your PAM configuration:
sudo nano /etc/pam.d/sshd
To require 2FA only for specific users:
auth [success=1 default=ignore] pam_succeed_if.so user notingroup 2fa-exempt
auth required pam_google_authenticator.so
Create the exempt group and add users:
sudo groupadd 2fa-exempt
sudo usermod -a -G 2fa-exempt username
Users in the 2fa-exempt group will bypass 2FA requirements.
IP-based 2FA requirements
You can configure SSH to require 2FA only for connections from untrusted networks:
auth [success=1 default=ignore] pam_succeed_if.so innetgroup trusted_networks
auth required pam_google_authenticator.so
Define trusted networks in /etc/netgroup
:
trusted_networks (localhost,) (192.168.1.0/24,)
Connections from trusted networks will skip 2FA, while external connections require it.
Combining with SSH keys for enhanced security
For the highest security, enforce both SSH key authentication and 2FA. Edit /etc/ssh/sshd_config
:
# Disable password authentication entirely
PasswordAuthentication no
# Require both public key and 2FA
AuthenticationMethods publickey,keyboard-interactive
This configuration requires users to have both something they possess (SSH key) and something they know (verification code), creating a true multi-factor authentication system.
Additional Security Enhancements
While 2FA significantly improves SSH security, consider these additional measures for comprehensive protection.
SSH hardening beyond 2FA
Enhance your SSH security with these additional configurations in /etc/ssh/sshd_config
:
# Disable root login
PermitRootLogin no
# Limit user access to specific groups
AllowGroups ssh-users admins
# Restrict SSH to specific IP addresses
ListenAddress 192.168.1.10
# Change default port (provides obscurity, not security)
Port 2222
# Limit authentication attempts
MaxAuthTries 3
These settings create defense-in-depth by restricting who can attempt to authenticate in the first place.
System-level security improvements
Protect your SSH service with these system-level enhancements:
- Configure firewall rules to limit SSH access:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept' sudo firewall-cmd --permanent --remove-service=ssh sudo firewall-cmd --reload
- Implement Fail2ban to block brute force attempts:
sudo dnf install fail2ban sudo systemctl enable --now fail2ban
Create a custom SSH jail configuration:
sudo nano /etc/fail2ban/jail.d/sshd.local
Add:
[sshd] enabled = true bantime = 3600 maxretry = 3
- Enable log monitoring to detect unusual activity:
sudo dnf install logwatch sudo logwatch --output mail --mailto your-email@example.com --detail high
Regular maintenance practices
Establish these routines to maintain your SSH security:
- Regularly update your system:
sudo dnf update -y
- Audit SSH access logs periodically:
sudo journalctl -u sshd | grep "authentication failure"
- Rotate emergency scratch codes every 3-6 months:
mv ~/.google_authenticator ~/.google_authenticator.old google-authenticator
- Test your 2FA setup after system updates that affect SSH or PAM.
Congratulations! You have successfully set up SSH two-factor authentication. Thanks for using this tutorial to setting up SSH two-factor authentication on Fedora 41 system. For additional or useful information, we recommend you check the official Fedora website.