A Step-by-step Guide For Securing π SSH Server
Almost every server π₯ out there has SSH. Security issues π in your SSH server is a problem π€¦ββοΈ as it can let anyone get access to the server. This article is a step-by-step π guide on securing SSH server by implementing better π οΈ configuration, π public/private key authentication and π― fail2ban.

To modify the behaviour of an SSH server we need to edit the sshd_config
file. On a typical Linux server the path to this config file is at: /etc/ssh/sshd_config
.
Configuring SSH Server
As the first step to securing an SSH server, we'll modify some SSH server settings to harden security and performance. For each step, I've made a video showing you exactly what to do. Checkout the below video for more information π

1. Changing the listening port
SSH server by default π’ listens at port 22, so scripts and botnets on the internet keep trying π¨ to login through SSH using the default port. By changing the port to any random number between 10,000 π 60,000 only specialized attacks π¨βπ on the server will be possible. A good place to generate a random number is random.org.
Replace the red colored line(s) with the green one(s) π
- #Port 22
+ Port 21318
2. Switch to Protocol 2
The newer SSH Protocol 2 supports public/private key algorithms better than RSA, along with lot of security holes π³ being fixed. So in this day and age one shouldn't be π ββοΈ using the older protocol. To use Protocol version 2, add the below line to the configuration file π I can simply start typing here π€·ββοΈ
+ Protocol 2
3. Specify ListenAddress
Often times, servers have multiple networks adapters and IP addresses. By restricting πͺ SSH to only the desired network adapter we reduce the risk π· of getting unwanted login requests thus making SSH more secure. Β π To restrict SSH to a particular network adapter π.
- #ListenAddress 0.0.0.0
+ ListenAddress 19.13.32.44
4. Enable verbose logging
Verbose π§ logs are quite helpful for both the π¨βπ» system administrator and fail2ban
. By enabling verbose logging we get a better idea π€ of what exactly is happening with the SSH server.
- #LogLevel INFO
+ LogLevel VERBOSE
5. Restrict logins through SSH
On a typical π§ Linux environment, there will be more than two users in most cases. Telling SSH exactly which user is allowed to login is π always better! As users like nobody
, www-data
, backup
are exploited to get into the server.
+ AllowUsers pratham
6. Prevent root login
In UNIX based operating systems, root
is an account which has complete control on the machine. If an attacker gets access to the root
account pretty much anything & everything is possible. NEVER β οΈ LOGIN AS root
TO YOUR SERVER! For tasks that require elevated permissions, use sudo
, su
or doas
. To disable login access to the root
account, set PermitRootLogin
to no
, like so π
- #PermitRootLogin prohibit-password
+ PermitRootLogin no
7. Ensure StrictModes
is on
Although StrictModes
is on
by default, some Linux distributions may π€·ββοΈ override it. When StrictModes
is turned on, the SSH server will only start if file permissions are β
properly setup. This prevents us from π€¦ββοΈ accidentally making permissions of config files and SSH keys too open and letting the attacker modify those. To ensure it is turned on, add StrictModes on
key to your configuration file or simply uncomment if already exists π
- #StrictModes on
+ StrictModes on
8. Reduce maximum retries
No matter how much prepared we are, there will always be script kiddies π out there. To tackle those and prevent brute forcing we must drop the connection if the user fails to authenticate a set number of times. As you will read π in the next stages we'll implement fail2ban
which is a more β robust solution for repeated login attempts.
- #MaxAuthTries 6
+ MaxAuthTries 3
9. Reject empty passwords
Although we will completely π disable password authentication later in this article, disabling empty passwords will make the π΅οΈββοΈ attacker hard to exploit those system accounts with no password. This setting is often applied as a π¦Ί safety measure, just in case of a vulnerable account.
- #PermitEmptyPasswords no
+ PermitEmptyPasswords no
10. Disable X11Forwarding
Most production servers don't have a πΌ graphical user interface on them. X11Forwarding
allows us to run graphical applications on the server and have the interface forwarded to us. An attacker could π€ leverage this to exploit SSH, so when not using it's best to turn off.
- X11Forwarding yes
+ X11Forwarding no
11. Drop connections when inactive
It is really β fatal if SSH connections are left unclosed. Rogue SSH connections can be used by an attacker to gain access to the server. Also, in a situation where the system administrator opens a connection and physically πΆββοΈ leaves the computer, we don't want anyone to give arbitrary commands to our servers. To make the server disconnect automatically after π 2 minutes of inactivity, set ClientAliveInterval
to 120 seconds π
- #ClientAliveInterval 0
+ ClientAliveInterval 120
12. Disable SSH tunneling
Port forwarding β© using SSH is referred to as "SSH Tunneling". An attacker can use it to hijack a port on the server to forward all it's packets to attacker's computer which can be quite harmful especially if it is 80 or 443 (these are HTTP and HTTPS ports used to serve websites). When not using, it's π best to disable this.
- #PermitTunnel no
+ PermitTunnel no
Generating Secure SSH Keys
Now that we have a good base π¨βπ to work with, the next step is to generate strong and secure SSH keys. Personally for ease of use I don't use a password along with SSH keys, but for added security you can optionally set a password which is safely β encrypted before transmitting.
The video is under production. Link will be updated as soon the video is released.
1. Checking OpenSSH version
The newer the OpenSSH version, the better and newer key algorithms it π€© supports. Click here to get a list of which algorithm is supported by what version of OpenSSH. Along with checking the version of OpenSSH installed on your workstation computer, it is required that the server also has the same version or newer. Run the below π command to check your installed version of OpenSSH
ssh -V # OpenSSH_8.3p1, OpenSSL 1.1.1g 21 Apr 2020
2. Generating SSH Keys
DSA π¨ is no longer considered safe these days, RSA β οΈ is only safe with 4096 and above bit-length, ECDSA's π security depends on your hardware. This leaves us with ED25519 π which is supported by platforms like GitHub, GitLab and BitBucket and is the most recommended algorithm today.
Run the below command to generate an ED25519 key π
ssh-keygen -o -a 200 -t ed25519 -f ~/.ssh/ssh_key -C "$(whoami)@$(hostname)"
This β should create two files named ssh_key
(which is your private key) and ssh_key.pub
which is the public key in your current directory.
3. Installing SSH Keys
Now that we have both the public and private keys on our workstation. We need to append the contents of public key into ~/.ssh/authorized_keys
file on the server inorder to start using the generated SSH keys. This is as simple as running another command π
ssh-copy-id -p 21318 -i ~/.ssh/ssh_key.pub pratham@13.81.80.37
In the above command β replace pratham@13.81.80.37
with your username
@ip address
and the port number accordingly.
4. Disable Password Login
Completely π« disabling password authentication will reduce the risk of getting brute forced. As without the exact private key that matches the public π key we installed on the server, authentication won't be successful.
- #PasswordAuthentication yes
+ PasswordAuthentication no
Configuring fail2ban
fail2ban
is a software that can read π° log files and add rules to the firewall. In this article we'll use fail2ban
to block repeated SSH authentication requests.
The video is under production. Link will be updated as soon the video is released.
1. Installing fail2ban
sudo apt install fail2ban
Run the β above command to install fail2ban
on a Debian/Ubuntu server. A jail is the configuration of fail2ban
for a service, and a filter is a file that tells fail2ban
exactly what lines to look for in the log files. On a typical installation of fail2ban
a jail.conf
template is already given, we just need to copy that as jail.local
in the directory where fail2ban
in installed. To do that run π the below command
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
2. Configuring fail2ban
for SSH
As we now have the default fail2ban
config in place, it's time to configure fail2ban
for SSH. To get started open /etc/fail2ban/jail.local
in your favorite text editor and find the below snippet of 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
And append the below property to enable the ssh
jail π
enabled = true
This will enable the SSH jail for fail2ban
. But we still have one more thing to do. By default fail2ban
's SSH filter won't look for key based authentication failures. As we have disabled password authentication we won't get passwords requests, but we'll get private key authentication failures. Modification of the SSH filter is required in this case.
To do that, open /etc/fail2ban/filter.d/sshd.conf
in your preffered text editor. In this file find the property named cmnfailre
. This property lists all patterns to look for in SSH's log file. Append the below pattern to this list to make fail2ban
block on private key authentication failure.
^%(__prefix_line)sConnection closed by authenticating user .+ port \d+ \[preauth\]$
Conclusion
We have finished configuring SSH, generating SSH keys and installing fail2ban
and finally configuring fail2ban
to automatically block repeated attackers. As a final step, let's restart both SSH and fail2ban
services π
sudo systemctl restart sshd fail2ban