Harden SSH in OpenSSH

HydraHydraBeginner
Practice Now

Introduction

In this lab, you will learn essential techniques to enhance SSH security in OpenSSH through key authentication and configuration hardening. You'll practice replacing password authentication with secure key pairs, disabling root login, and modifying default ports to mitigate brute-force attacks.

The hands-on exercises will guide you through generating cryptographic keys, configuring proper file permissions, and testing your secure SSH setup. You'll also learn key commands for managing SSH services and verifying your security configurations.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL wireshark(("Wireshark")) -.-> wireshark/WiresharkGroup(["Wireshark"]) nmap(("Nmap")) -.-> nmap/NmapGroup(["Nmap"]) hydra(("Hydra")) -.-> hydra/HydraGroup(["Hydra"]) nmap/NmapGroup -.-> nmap/installation("Installation and Setup") nmap/NmapGroup -.-> nmap/basic_syntax("Basic Command Syntax") nmap/NmapGroup -.-> nmap/common_ports("Common Ports Scanning") nmap/NmapGroup -.-> nmap/port_scanning("Port Scanning Methods") nmap/NmapGroup -.-> nmap/target_specification("Target Specification") nmap/NmapGroup -.-> nmap/service_detection("Service Detection") nmap/NmapGroup -.-> nmap/firewall_evasion("Firewall Evasion Techniques") wireshark/WiresharkGroup -.-> wireshark/installation("Installation and Setup") hydra/HydraGroup -.-> hydra/installation("Installation and Setup") subgraph Lab Skills nmap/installation -.-> lab-549940{{"Harden SSH in OpenSSH"}} nmap/basic_syntax -.-> lab-549940{{"Harden SSH in OpenSSH"}} nmap/common_ports -.-> lab-549940{{"Harden SSH in OpenSSH"}} nmap/port_scanning -.-> lab-549940{{"Harden SSH in OpenSSH"}} nmap/target_specification -.-> lab-549940{{"Harden SSH in OpenSSH"}} nmap/service_detection -.-> lab-549940{{"Harden SSH in OpenSSH"}} nmap/firewall_evasion -.-> lab-549940{{"Harden SSH in OpenSSH"}} wireshark/installation -.-> lab-549940{{"Harden SSH in OpenSSH"}} hydra/installation -.-> lab-549940{{"Harden SSH in OpenSSH"}} end

Install OpenSSH

In this step, you will install the OpenSSH server package on your LabEx VM. OpenSSH (Open Secure Shell) is a free and open-source implementation of the SSH protocol that provides secure encrypted communications between two untrusted hosts over an insecure network. It's the standard tool for remote server administration and secure file transfers.

Before we begin, it's important to understand that SSH works in a client-server model. The server (which we're installing now) listens for incoming connections, while clients (like the terminal on your local machine) connect to it. All communication is encrypted, protecting your credentials and data.

Since LabEx VM uses Docker containers where systemctl is unavailable (Docker containers typically run single processes rather than full operating systems), we'll use the service command to manage the SSH daemon. This is a simpler alternative to systemctl that works well in containerized environments.

Follow these steps to install OpenSSH:

  1. First, update your package list to ensure you get the latest version. This fetches the most recent package information from Ubuntu's repositories:

    sudo apt update
  2. Install the OpenSSH server package. The -y flag automatically confirms any prompts during installation:

    sudo apt install -y openssh-server
  3. After installation, check if the SSH service is running. The status command shows whether the service is active and listening for connections:

    service ssh status

    You should see output indicating the service is active (running). If it's not running, we'll start it in the next step.

  4. If the service isn't running (which would show "inactive" in the status output), start it manually:

    service ssh start
  5. Verify SSH is listening on the default port (22). The netstat command shows network connections and listening ports, while grep filters for SSH-related entries:

    sudo netstat -tulnp | grep sshd

    You should see output similar to this, showing SSH is listening on all network interfaces (0.0.0.0) on port 22:

    tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -

Set Up Key Authentication

In this step, you will configure SSH key-based authentication, which provides stronger security than traditional password authentication. Unlike passwords that can be guessed or brute-forced, key authentication uses a pair of cryptographic keys - one private (kept secret) and one public (shared with servers).

When you connect to an SSH server, it uses mathematical algorithms to verify you possess the private key that matches the public key it has on file. This method is both more secure and more convenient once set up.

Let's create and configure these keys step by step:

  1. First, we'll generate a new SSH key pair. This command creates two files in your ~/.ssh directory:

    ssh-keygen -t rsa -b 4096 -f ~/.ssh/labex_key -N ""
    • -t rsa specifies the type of key (RSA algorithm)
    • -b 4096 makes a strong 4096-bit key
    • -f sets the filename for your key pair
    • -N "" means no passphrase (for lab simplicity)

    You'll now have:

    • Private key: ~/.ssh/labex_key (never share this!)
    • Public key: ~/.ssh/labex_key.pub (this gets shared with servers)
  2. Proper file permissions are crucial for SSH security. These commands ensure only you can access your keys:

    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/labex_key
    chmod 644 ~/.ssh/labex_key.pub
  3. Now we'll authorize your key by adding the public key to the special authorized_keys file that SSH checks:

    cat ~/.ssh/labex_key.pub >> ~/.ssh/authorized_keys
    chmod 600 ~/.ssh/authorized_keys
  4. Next, we'll configure the SSH server itself. Edit the main configuration file:

    sudo nano /etc/ssh/sshd_config

    Find and modify these important settings:

    PubkeyAuthentication yes
    PasswordAuthentication no

    This tells SSH to:

    • Allow key authentication (enabled by default but good to confirm)
    • Disable password logins (forcing key-based access only)
  5. After changing configuration, always restart the SSH service:

    service ssh restart
  6. Finally, let's verify everything works. Try connecting to your own machine (localhost) using your new key:

    ssh -i ~/.ssh/labex_key localhost

    The -i flag specifies which private key to use. If successful, you'll login immediately without any password prompt - this confirms key authentication is working correctly.

Disable Root Login

In this step, we'll disable direct root login through SSH. This is important because the root account has full system privileges, making it a prime target for hackers. By disabling root login, we force attackers to guess both a username and password, making brute-force attacks much harder.

When you need root privileges after this change, you'll first log in with a regular user account, then use sudo for administrative tasks. This creates an extra security layer since attackers would need to compromise two accounts.

Let's modify the SSH configuration:

  1. First, open the main SSH configuration file with a text editor. We'll use nano here, but you can use any editor you're comfortable with:

    sudo nano /etc/ssh/sshd_config
  2. Look for the line that says PermitRootLogin (usually around line 32). If you can't find it, you'll need to add it. Change or add this line to:

    PermitRootLogin no
  3. While we're editing this file, let's set some additional security parameters that work well with this change:

    StrictModes yes
    MaxAuthTries 3
    LoginGraceTime 60
    • StrictModes checks file permissions for security
    • MaxAuthTries limits failed login attempts
    • LoginGraceTime sets how long a login can take
  4. Save your changes in nano by pressing:

    • Ctrl+O to write out
    • Enter to confirm
    • Ctrl+X to exit
  5. For the changes to take effect, restart the SSH service:

    service ssh restart
  6. Let's test that our changes worked by trying to SSH as root (this should fail):

    ssh root@localhost

    You should see an error like "Permission denied (publickey)", which means our security measure is working correctly. From now on, you'll need to use a regular user account to log in.

Change Default Port

In this step, we'll modify the default SSH port from 22 to a custom port (2222 in our example). This is an important security measure because many automated bots and attackers scan for SSH servers on the standard port 22. By changing to a non-standard port, we make our server less visible to these automated scans.

Before making any changes, let's first check the current SSH port configuration. This helps us understand the existing setup:

sudo grep -i port /etc/ssh/sshd_config

You'll typically see #Port 22 in the output. The # symbol means this line is commented out, so SSH is currently using the default port 22.

Now we'll edit the SSH configuration file. We'll use the nano text editor, which is user-friendly for beginners:

sudo nano /etc/ssh/sshd_config

Inside the file, look for the line containing #Port 22. We need to make two changes here:

  1. Remove the # to uncomment the line (this activates the setting)
  2. Change the port number from 22 to 2222

The modified line should look like this:

Port 2222

After making this change, save the file in nano by pressing:

  1. Ctrl+O (to write the file)
  2. Enter (to confirm the filename)
  3. Ctrl+X (to exit the editor)

For the changes to take effect, we need to restart the SSH service:

service ssh restart

Let's verify that SSH is now listening on our new port (2222) instead of the default port:

sudo netstat -tulnp | grep ssh

The output should show SSH listening on port 2222. If you still see port 22, double-check your configuration file changes.

Finally, test the new configuration by connecting to SSH using the custom port. Notice we need to specify the port with -p flag now:

ssh -p 2222 -i ~/.ssh/labex_key localhost

After successfully connecting, you can exit the SSH session by pressing Ctrl+D. Remember that from now on, you'll always need to specify this custom port when connecting to your SSH server.

Test Hardened Setup

In this final step, we'll verify all the security hardening measures you've implemented. Testing is crucial to ensure your SSH server is properly configured and secure. We'll examine both server-side settings and client-side connection attempts.

Let's begin by checking the current SSH configuration on your server. This confirms the changes you made earlier are active:

  1. First, verify all current SSH settings:

    sudo sshd -T | grep -E 'port|permitrootlogin|passwordauthentication|pubkeyauthentication'

    The sshd -T command displays the actual runtime configuration. We're filtering for key security parameters. You should see:

    port 2222
    permitrootlogin no
    passwordauthentication no
    pubkeyauthentication yes

    This output confirms SSH is running on port 2222, root login is disabled, password authentication is off, and public key authentication is enabled.

Now let's test connections from a client perspective:

  1. Test successful connection with key authentication:

    ssh -p 2222 -i ~/.ssh/labex_key localhost "echo 'Key auth successful'"

    This attempts to connect using your private key (-i flag specifies the key file). The command executes a simple echo on the server if successful. You should see:

    Key auth successful
  2. Test failed root login attempt:

    ssh -p 2222 root@localhost 2>&1 | grep -i "permission denied"

    This tries to log in as root, which should fail because we disabled root login. The command filters for the expected error message.

  3. Test failed password authentication attempt:

    ssh -p 2222 -o PreferredAuthentications=password -o PubkeyAuthentication=no localhost 2>&1 | grep -i "permission denied"

    Here we force password authentication (disabled in our config) to verify it's properly blocked. The options explicitly disable key authentication.

Finally, let's check the server's network status:

  1. Check active SSH connections:

    sudo netstat -tulnp | grep 2222

    This shows all listening ports, filtered for our custom SSH port (2222). You should see sshd listed as listening on this port.

  2. Verify SSH service status:

    service ssh status

    Confirms the SSH service is running properly. The output should indicate the service is active.

Summary

In this lab, you have learned to enhance SSH security in OpenSSH through practical configurations. The exercises covered installing OpenSSH server, verifying its status, and implementing key-based authentication with proper permission settings.

You also explored critical security hardening techniques including disabling root login and changing the default SSH port. These measures effectively reduce vulnerability to brute-force attacks and automated scanning while maintaining system functionality.