FedoraRHEL Based

How To Set Up SSH Two-Factor Authentication on Fedora 41

Set Up SSH to Use 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:

  1. Create a backup access method by keeping an existing SSH session active while making changes
  2. Verify you have console access (physical or virtual) in case SSH becomes inaccessible
  3. Update your system with the latest security patches:
sudo dnf update -y
  1. 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:

  1. 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.
  2. The system will display a QR code in your terminal along with your secret key, verification code, and emergency scratch codes. Keep these safe.

Set Up SSH to Use Two-Factor Authentication on Fedora 41

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:

  1. “Do you want me to update your ~/.google_authenticator file?” Answer y to save your settings.
  2. “Do you want to disallow multiple uses of the same authentication token?” Answer y for best security. This prevents replay attacks.
  3. “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.
  4. “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 continue
  • requisite: Must succeed, and failure immediately returns control to the application
  • sufficient: If succeeds, no further modules are processed
  • optional: 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:

  1. Keep an existing SSH session open while testing to maintain access if something goes wrong
  2. Test from a different terminal or machine to verify the authentication flow
  3. Have your console access ready (physical or virtual) as a fallback
  4. 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:

  1. Your normal authentication (password or SSH key)
  2. A prompt for your verification code: Verification code:
  3. Enter the 6-digit code from your authenticator app
  4. 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:

  1. Check that you’re prompted for a verification code when logging in
  2. Confirm that incorrect verification codes are rejected
  3. Test login with both your primary credentials and verification code
  4. If using key-based authentication, verify it still works with 2FA
  5. 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:

  1. 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
  2. Expired TOTP codes: Codes typically expire after 30 seconds. Generate a fresh code in your app.
  3. 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:

  1. SSH daemon not running: Check the service status:
    sudo systemctl status sshd
  2. Configuration syntax errors: Verify your sshd_config syntax:
    sudo sshd -t
  3. 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:

  1. App synchronization issues: Resynchronize your app with the server time.
  2. Device time drift: Many authenticator apps have a time correction feature in settings.
  3. 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:

  1. Use emergency scratch codes if you have them available.
  2. 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.

  3. Restart SSH and log in:
    sudo systemctl restart sshd
  4. 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:

  1. 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
  2. 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
  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:

  1. Regularly update your system:
    sudo dnf update -y
  2. Audit SSH access logs periodically:
    sudo journalctl -u sshd | grep "authentication failure"
  3. Rotate emergency scratch codes every 3-6 months:
    mv ~/.google_authenticator ~/.google_authenticator.old
    google-authenticator
  4. 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.

VPS Manage Service Offer
If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal!

r00t

r00t is an experienced Linux enthusiast and technical writer with a passion for open-source software. With years of hands-on experience in various Linux distributions, r00t has developed a deep understanding of the Linux ecosystem and its powerful tools. He holds certifications in SCE and has contributed to several open-source projects. r00t is dedicated to sharing her knowledge and expertise through well-researched and informative articles, helping others navigate the world of Linux with confidence.
Back to top button