{"id":2698,"date":"2024-09-29T03:55:58","date_gmt":"2024-09-29T02:55:58","guid":{"rendered":"https:\/\/bornoe.org\/blog\/?p=2698"},"modified":"2024-09-29T03:56:00","modified_gmt":"2024-09-29T02:56:00","slug":"fortify-your-ssh-connections-with-two-factor-authentication","status":"publish","type":"post","link":"https:\/\/bornoe.org\/blog\/2024\/09\/fortify-your-ssh-connections-with-two-factor-authentication\/","title":{"rendered":"Fortify Your SSH Connections with Two-Factor Authentication"},"content":{"rendered":"\n<p>One way to strengthen your SSH setup is by enabling Two-Factor Authentication (2FA), which adds an additional layer of security. While the setup process involves a few steps, the additional security layer is well worth the effort. Whether you\u2019re managing a personal project server or a critical production environment, adding 2FA to SSH ensures that your system remains secure even in the face of password compromises.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is Two-Factor Authentication (2FA)?<\/h2>\n\n\n\n<p>Two-Factor Authentication (2FA) is a security mechanism that requires two forms of identification before granting access. The first form is usually something you know, like a password, and the second is something you have, such as a physical device or an app-generated code. The idea behind 2FA is that even if an attacker manages to steal your password, they would still need the second factor to gain access.<\/p>\n\n\n\n<p>When applied to SSH, 2FA ensures that your server is protected not just by a password but also by a time-sensitive, one-time code that can only be generated by an authentication app or device in your possession.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why Enable 2FA for SSH?<\/h2>\n\n\n\n<ul start=\"1\" class=\"wp-block-list\">\n<li><strong>Enhanced Security<\/strong>: Adding a second layer of authentication dramatically reduces the risk of unauthorized access. Even if an attacker compromises your SSH password, they won\u2019t be able to log in without your second factor.<\/li>\n\n\n\n<li><strong>Protection Against Brute Force Attacks<\/strong>: Attackers can often try multiple password combinations in brute force attacks. 2FA adds a near-impenetrable barrier because they would also need access to your 2FA device.<\/li>\n\n\n\n<li><strong>Mitigating Phishing Attacks<\/strong>: Phishing attacks can trick users into giving up their credentials. Even if a password is phished, the attacker still can&#8217;t access your server without the second factor.<\/li>\n\n\n\n<li><strong>Compliance Requirements<\/strong>: Many organizations are required to implement multi-factor authentication (MFA) to comply with security standards and regulations. Enabling 2FA for SSH helps meet these requirements.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">How does 2FA for SSH Works?<\/h2>\n\n\n\n<p>With 2FA enabled on SSH, the login process is as follows:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Step 1<\/strong>: The user enters their username and password as usual.<\/li>\n\n\n\n<li><strong>Step 2<\/strong>: After the correct password is entered, the user is prompted to enter a one-time code generated by a 2FA app like Google Authenticator or a hardware device such as a YubiKey.<\/li>\n\n\n\n<li><strong>Step 3<\/strong>: If both the password and the code are correct, the user is granted access.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Setting Up 2FA for SSH on a Linux Server<\/h2>\n\n\n\n<p>Let\u2019s walk through the steps to enable 2FA on your SSH server using Google Authenticator, a popular 2FA app. This setup assumes you&#8217;re using a Linux server with SSH access.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerequisites<\/h3>\n\n\n\n<p>You:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Have SSH access to the server with sudo privileges.<\/li>\n\n\n\n<li>Can install packages on the server.<\/li>\n\n\n\n<li>Have a smartphone with a 2FA app like Google Authenticator or <a href=\"https:\/\/authy.com\/\">Authy<\/a>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Install Google Authenticator<\/h3>\n\n\n\n<p>First, you\u2019ll need to install the libpam-google-authenticator package, which is required for integrating Google Authenticator with SSH. On Debian-based distributions (like Ubuntu), run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>sudo apt-get update<\/code><br><br><code>sudo apt-get install libpam-google-authenticator<\/code><\/pre>\n\n\n\n<p>On Red Hat-based distributions (like CentOS or Fedora), you can install it with:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>sudo yum install google-authenticator<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Configure Google Authenticator for Your User<\/h3>\n\n\n\n<p>Now, configure Google Authenticator for the user you\u2019ll be logging in with. Log in to the server via SSH and run the following command:<\/p>\n\n\n\n<p>google-authenticator<\/p>\n\n\n\n<p>You\u2019ll be asked a series of questions and provided with a QR code and a secret key. You can scan the QR code using your smartphone app (e.g., Google Authenticator or Authy), or manually enter the secret key if scanning isn\u2019t possible.<\/p>\n\n\n\n<p>Here\u2019s what you\u2019ll need to configure:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Time-based tokens (TOTP)<\/strong>: Choose yes. This ensures that codes expire after a set time.<\/li>\n\n\n\n<li><strong>Disallow multiple uses of the same token<\/strong>: Answer yes to prevent replay attacks.<\/li>\n\n\n\n<li><strong>Rate limiting<\/strong>: This limits the number of attempts a user can make, further securing the system.<\/li>\n\n\n\n<li><strong>Emergency scratch codes<\/strong>: These are one-time-use codes you can save in case you lose your phone. Make sure to store these securely.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Configure SSH to Use 2FA<\/h3>\n\n\n\n<p>Next, we need to modify SSH\u2019s Pluggable Authentication Module (PAM) and SSH configuration files to enable 2FA.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Edit PAM <\/strong>Configuration:<\/h4>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\"><\/ol>\n\n\n\n<p>Open the \/etc\/pam.d\/sshd file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/pam.d\/sshd<\/pre>\n\n\n\n<p>Add the following line at the end of the file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">auth required pam_google_authenticator.so<\/pre>\n\n\n\n<p>This line tells PAM to use Google Authenticator for SSH logins.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Edit SSH Configuration:<\/h4>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\"><\/ol>\n\n\n\n<p>Open the \/etc\/ssh\/sshd_config file:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo nano \/etc\/ssh\/sshd_config<\/pre>\n\n\n\n<p>Look for the following lines and modify them as necessary.<\/p>\n\n\n\n<p>Ensure that ChallengeResponseAuthentication is set to yes:<\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\"><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">ChallengeResponseAuthentication yes<\/pre>\n\n\n\n<p>Ensure that UsePAM is enabled:<\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\"><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">UsePAM yes<\/pre>\n\n\n\n<p>If <em>PasswordAuthentication<\/em> is enabled, users will still need to enter their password before entering the one-time code. If you have already set up SSH key-based authentication, you can choose to combine key-based authentication with 2FA.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Restart SSH Service:<\/strong><\/h4>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\"><\/ol>\n\n\n\n<p>After making the changes, restart the SSH service to apply them:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo systemctl restart sshd<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Test the 2FA Setup<\/h3>\n\n\n\n<p>Now that everything is configured, open a new terminal window and try to SSH into your server. After entering your username and password, you should be prompted to enter the one-time code generated by your 2FA app.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ssh your_user@your_server_ip<\/pre>\n\n\n\n<p>You\u2019ll be asked for your password, followed by the verification code from your Google Authenticator app:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Verification code:<\/pre>\n\n\n\n<p>If everything is set up correctly, you\u2019ll gain access to the server only after successfully entering both your password and the 2FA code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<p>If you encounter issues during setup, here are a few troubleshooting tips.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Check Time Synchronization<\/h3>\n\n\n\n<p>2FA codes rely on time synchronization between your server and your phone. Ensure that the server&#8217;s time is accurate by installing and enabling the NTP service.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sudo apt-get install ntp<br><br>sudo systemctl enable ntp<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Test Configuration Locally<\/h3>\n\n\n\n<p>You can disable 2FA temporarily by commenting out the relevant lines in your SSH and PAM configurations if you get locked out.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Check Logs<\/h3>\n\n\n\n<p>Check SSH logs at \/var\/log\/auth.log or \/var\/log\/secure (depending on your distribution) for error messages that may help diagnose the problem.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One way to strengthen your SSH setup is by enabling Two-Factor Authentication (2FA), which adds an additional layer of security. While the setup process involves a few steps, the additional security layer is well worth the effort. Whether you\u2019re managing a personal project server or a critical production environment, adding 2FA to SSH ensures that [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[36,33,17],"tags":[],"class_list":["post-2698","post","type-post","status-publish","format-standard","hentry","category-cybersecurity","category-gnu-linux","category-linux"],"_links":{"self":[{"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/posts\/2698","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/comments?post=2698"}],"version-history":[{"count":1,"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/posts\/2698\/revisions"}],"predecessor-version":[{"id":2699,"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/posts\/2698\/revisions\/2699"}],"wp:attachment":[{"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/media?parent=2698"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/categories?post=2698"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bornoe.org\/blog\/wp-json\/wp\/v2\/tags?post=2698"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}