# 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 :&#x20;

```bash
$> 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 :&#x20;

{% code overflow="wrap" %}
```bash
$> sudo fail2ban-client status
# The output should look like : 
Status
|- Number of jail:      1
`- Jail list:   sshd
```
{% endcode %}

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

{% code overflow="wrap" %}
```bash
$> sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
```
{% endcode %}

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

{% code overflow="wrap" %}
```
[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

```
{% endcode %}

* `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 :&#x20;

{% code overflow="wrap" %}
```bash
# "bantime" is the number of seconds that a host is banned.
bantime  = 10m
```
{% endcode %}

{% code overflow="wrap" %}
```bash
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 10m
```
{% endcode %}

{% code overflow="wrap" %}
```bash
# "maxretry" is the number of failures before a host get banned.
maxretry = 2
```
{% endcode %}

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 :&#x20;

```bash
$> sudo systemctl restart fail2ban
```

#### Testing fail2ban :&#x20;

<figure><img src="https://2332860236-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fq6mjlFfyDOi3mV0lemKE%2Fuploads%2F9RZVNKGJYEZG49MKI4bA%2Fimage.png?alt=media&#x26;token=019f1e32-3d11-472d-a03b-72dae1a76e97" alt=""><figcaption></figcaption></figure>

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

{% code overflow="wrap" %}
```bash
$> 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
```
{% endcode %}

#### Ignoring Trusted IP Addresses :&#x20;

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

{% code overflow="wrap" %}
```bash
ignore ip = 3.3.3.0/24 ## To Ignore this network range
```
{% endcode %}

#### Incrementing Bantime for repetative offenders :&#x20;

{% code overflow="wrap" %}
```bash
bantime.increment = true # Increment by : 1 2 4 8 16 32 64 128
```
{% endcode %}

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&#x20;

{% code overflow="wrap" %}
```bash
sudo nano /etc/ssh/sshd_config
```
{% endcode %}

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

{% code overflow="wrap" %}
```bash
# Authentication 
PermitRootLogin no
```
{% endcode %}

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

{% code overflow="wrap" %}
```bash
sudo systemctl restart ssh
```
{% endcode %}

***

## 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

{% code overflow="wrap" %}
```bash
# Authentication
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
```
{% endcode %}

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

```bash
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

```bash
# 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.

```bash
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

```bash
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.

```bash
# General config 
port <port number other then 22>
```

restarting the services will confirm the changes.

```bash
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 :&#x20;

* &#x20;Checking wheather the UFW is enabled&#x20;

```bash
$> 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 :&#x20;

{% hint style="info" %}
Ensure to add the ssh allow rule in case you are using ssh for accessing server , otherwise we might loose access over the server
{% endhint %}

```bash
$> sudo ufw allow ssh 
$> sudo ufw enable
```

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

```bash
$> sudo ufw allow <port>
```

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

{% code overflow="wrap" %}
```bash
## 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
```
{% endcode %}

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

