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.
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:
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 updateInstall the OpenSSH server package. The
-yflag automatically confirms any prompts during installation:sudo apt install -y openssh-serverAfter installation, check if the SSH service is running. The
statuscommand shows whether the service is active and listening for connections:service ssh statusYou should see output indicating the service is active (running). If it's not running, we'll start it in the next step.
If the service isn't running (which would show "inactive" in the status output), start it manually:
service ssh startVerify SSH is listening on the default port (22). The
netstatcommand shows network connections and listening ports, whilegrepfilters for SSH-related entries:sudo netstat -tulnp | grep sshdYou 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:
First, we'll generate a new SSH key pair. This command creates two files in your
~/.sshdirectory:ssh-keygen -t rsa -b 4096 -f ~/.ssh/labex_key -N ""-t rsaspecifies the type of key (RSA algorithm)-b 4096makes a strong 4096-bit key-fsets 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)
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.pubNow we'll authorize your key by adding the public key to the special
authorized_keysfile that SSH checks:cat ~/.ssh/labex_key.pub >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keysNext, we'll configure the SSH server itself. Edit the main configuration file:
sudo nano /etc/ssh/sshd_configFind and modify these important settings:
PubkeyAuthentication yes PasswordAuthentication noThis tells SSH to:
- Allow key authentication (enabled by default but good to confirm)
- Disable password logins (forcing key-based access only)
After changing configuration, always restart the SSH service:
service ssh restartFinally, let's verify everything works. Try connecting to your own machine (localhost) using your new key:
ssh -i ~/.ssh/labex_key localhostThe
-iflag 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:
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_configLook 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 noWhile we're editing this file, let's set some additional security parameters that work well with this change:
StrictModes yes MaxAuthTries 3 LoginGraceTime 60StrictModeschecks file permissions for securityMaxAuthTrieslimits failed login attemptsLoginGraceTimesets how long a login can take
Save your changes in nano by pressing:
- Ctrl+O to write out
- Enter to confirm
- Ctrl+X to exit
For the changes to take effect, restart the SSH service:
service ssh restartLet's test that our changes worked by trying to SSH as root (this should fail):
ssh root@localhostYou 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:
- Remove the
#to uncomment the line (this activates the setting) - 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:
- Ctrl+O (to write the file)
- Enter (to confirm the filename)
- 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:
First, verify all current SSH settings:
sudo sshd -T | grep -E 'port|permitrootlogin|passwordauthentication|pubkeyauthentication'The
sshd -Tcommand displays the actual runtime configuration. We're filtering for key security parameters. You should see:port 2222 permitrootlogin no passwordauthentication no pubkeyauthentication yesThis 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:
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 (
-iflag specifies the key file). The command executes a simple echo on the server if successful. You should see:Key auth successfulTest 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.
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:
Check active SSH connections:
sudo netstat -tulnp | grep 2222This shows all listening ports, filtered for our custom SSH port (2222). You should see
sshdlisted as listening on this port.Verify SSH service status:
service ssh statusConfirms 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.


