Securing SSH

SSH (Secure Shell) is a cryptographic network protocol used to securely access and manage remote systems over an unsecured network. It provides encrypted communication between a client and a server, ensuring data integrity and confidentiality. SSH is commonly used for logging into remote servers, executing commands, and transferring files securely. It replaces older, less secure protocols like Telnet and FTP. With features like public-key authentication, SSH ensures that only authorized users can connect, making it a vital tool for system administrators, developers, and anyone needing secure remote access.

We will make come configuration based changes to secure out our ssh service


Securing SSH using Fail2Ban

Fail2ban is a security tool that protects servers from brute-force attacks by monitoring log files and banning IP addresses that show suspicious activity, like repeated failed login attempts.

Instalation of Fail2Ban is simple , we can do this with :

$> sudo apt install fail2ban
$> sudo systemctl status fail2ban

Now we will configure the fail2ban , but we will not edit the .conf file directly we will copy it and create a local file to override the global settings and avoid messing up the fail2ban config.

By default the ssh is being protected by the fail2ban serivice we can check with the following command :

$> sudo fail2ban-client status
# The output should look like : 
Status
|- Number of jail:      1
`- Jail list:   sshd

Which means the ssh is indeed filtered by fail2ban by default, Now we will create local config file and configure ssh access using fail2ban

$> sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Now we will edit the settings under the local file

First we wil look into the sshd section for the default config, Look for the following config

[sshd]

# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
#mode   = normal
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
  • port = ssh: Specifies the port to monitor for SSH connections (default is port 22).

  • logpath = %(sshd_log)s: Points to the log file for SSH logs (usually /var/log/auth.log).

  • backend = %(sshd_backend)s: Specifies the log backend to use for reading logs.

  • The mode option (commented out here) can set different levels of protection (normal, ddos, extra, aggressive) to handle SSH brute-force attacks with varying intensities.

Now we will configure the following parameters findtime , bantime & maxretries . Search for the following lines :

# "bantime" is the number of seconds that a host is banned.
bantime  = 10m
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 10m
# "maxretry" is the number of failures before a host get banned.
maxretry = 2

We have set the value of maxretry to 2 which will block our IP address for 10 Minutes if 2 failed password attempts are found in the interval of 10 mins.

Restarting the service :

$> sudo systemctl restart fail2ban

Testing fail2ban :

Here we can see the fail2ban has sucessfully banned the ssh connection from the IP & blacklisted the connections.

$> fail2ban-client status sshd
# The output should look like : 
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     2
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 1
   |- Total banned:     1
   `- Banned IP list:   3.3.3.126

Ignoring Trusted IP Addresses :

We can ignore certain trusted IPs from getting banned by adding the following line in the config file

ignore ip = 3.3.3.0/24 ## To Ignore this network range

Incrementing Bantime for repetative offenders :

bantime.increment = true # Increment by : 1 2 4 8 16 32 64 128

This is how we can secure our servers using fail2ban. We can also secure other services like Apache2, php & many more using fail2ban which can also be managed my the same config file.


Disabling root login using SSH

Directly accessing the root account with the SSH might pose a significant risk so we should consider disabling the SSH access over the root account.

The config file of the ssh service is located on /etc/ssh/sshd_config so we will edit the file and disable the root login parameter

sudo nano /etc/ssh/sshd_config

Under the authentication section we have the parameter named PermitRootLogin so we will set the value to yes to disable the root login.

# Authentication 
PermitRootLogin no

Upon restarting the service the changes will be applied and root login is now disabled.

sudo systemctl restart ssh

Restricting password based authentication

Password based authentication is a feature which allows the users to get authentication with the plain text. Allowing plain text the ssh service might be vulnerable for weak credentials and brute force attacks so we will disable the password based authentication.

We will edit the config in the same config file of the ssh service and then under the authentication section we will find the below options

# Authentication
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no

Upon restarting the service the changes will be applied and we have sucessfully disabled the plain text authentication on the ssh server.

sudo systemctl restart ssh

Enabling Authorized Key Based Authentication

Authorized keys based authentication is the mechanism which only allows the certain public keys to authenticate with the server so it mitigates the threats of using password based authentication

We will edit the config in the same file and under the authentication section we will edit the following parameters

# Authentication
PubkeyAuthentication yes
PasswordAuthentication Yes

Now we will create the file authorized_keys file inside the .ssh/ directory and add the public keys of the systems on which access is required.

cd .ssh/
touch authorized_keys

After adding the keys we will save & exit the file and restart the ssh service to place the config in place

sudo systemctl restart ssh

Changing SSH port

Changing the default SSH port is very important steps to implement in the production environment to enusre the hackers and the scanners not easily identify and hack the servers using common ports

To change the ssh ports we will change the port config in the ssh config in the same file where above changes are done.

# General config 
port <port number other then 22>

restarting the services will confirm the changes.

sudo systemctl restart ssh

Securing SSH using ufw

ufw (Uncomplicated Firewall) is the default firewall on the system we can limit the access with ufw as follows :

  • Checking wheather the UFW is enabled

$> sudo ufw status
# Output :  ufw is active & rules will be displayed if active

If disabled we will have to enable it first so we will enable it with :

Ensure to add the ssh allow rule in case you are using ssh for accessing server , otherwise we might loose access over the server

$> sudo ufw allow ssh 
$> sudo ufw enable

If your ssh service is running & configure on the different port we can alow the following using :

$> sudo ufw allow <port>

To limit the SSH acces only through the particulat IP or network we can do this with :

## Access from a IP Address only
$> sudo ufw allow from 10.10.10.10 to any port 22
$> sudo ufw deny 22

### Access from a Network range 
sudo ufw allow from 10.10.10.10/24 to any port 22
sudo ufw deny 22

To learn more on UFW we will cover it in the upcoming sections ...

Last updated