SSH stands for Secure Shell, one of the well-known service protocols used to execute an operation to the remote administration over the internet. It provides a very secure passage between the designated computers. Once the connection is established, SSH will then provide encrypted sessions for all public (unsecured) networks in a client-server architecture. It was developed for the replacement of insecure remote protocols like "Telnet, rlogin, and rsh". As we know the drawbacks of using these insecure protocols, if someone used a third party packet capturing tools like ‘tcpdump and Wireshark’ between the designated computers can reveal the password and exploit the systems easily.
SSH services are deployed and used by millions of Servers in Data Centers around the world. These days shell accounts are much less used, but the protocol remains the same standard for operating systems where there is no physical access. SSH is one of the essential tools preferred by many System and Network Administrators is used for remote server management, but still, few users do prefer to use GUI tool. SSH packages are available mostly on all RHEL, CentOS, and Fedora OS by default and for other distros maybe not, in that case, you need to install the packages manually.
Table of Contents show
SSH Access methods:
There are two common methods used to access the (remote or local) server using SSH.
(i) Username and Password: This is the basic method of accessing the server, once you are connected to the server with a username, the server will be asked to verify your identity by providing the password. If the credentials are correct, then you will be granted access; or else it will be denied.
(ii) Public or Private keys: This is a very secure method of accessing the server, it doesn't require a password to access the server, but it needs a private key. Once the user is connected to the server using the correct private key, the server starts to perform a check whether the given key is correct or not. If the key is correct, the user will be granted access; or else it will be denied.
Encryption Techniques:
SSH offers an outstanding feature in encryption to transfer the data's between the server and the client. The client is nothing but a local computer where the SSH client package which is used to connect to the remote server via secure shell protocol and the server will be located at the remote location.
In SSH we can use three different types of encryption:
(a) Symmetrical Encryption
(b) Asymmetrical Encryption
(c) Hashing
Symmetric encryption: It is also called a shared key or secret encryption key. It helps for both encryption and decryption of data by client and server. Obtaining the key by anyone (client or server) can decrypt the message. In Symmetrical there are a variety of ciphers that exist, like AES, CAST128, Blowfish, RC4, etc. But the most used ones are AES-128, AES-192, and AES-256. The drawback of using this key encryption is that it will involve all the parties to exchange the key to encrypt the information before they can decrypt the same.
Asymmetrical Encryption: Asymmetrical uses two separate (public and private) keys for encryption and decryption. The combination of these two keys forms as key pair named "public-private key". The public key can be freely available or openly shared with any party, but the private key will be kept secret. The combination between these two keys is a bit difficult in terms of encryption and decryption, which means if a piece of information is encrypted by using a public key it can be used by only the private key to decrypt and vice-versa. Asymmetric encryption is the most used form of communication over the internet. It uses RSA, DSA,PKCS,etc.
Hashing: Hashing uses another form of cryptography to secure connections. It is a one-way process and completely different from the above forms of encryption, meaning hashed data is never meant to be decrypted. For more details about encryption, click here.
In real-time, to set up, the SSH server is one of the common tasks for every system administrator to access the servers remotely (Cloud VPS or Traditional Server). It is very simple to install and enable, but to configure and secure the SSH server is a bit tough and must know how to do it properly otherwise it can be easily hacked.
This step-by-step guide will help you how to install and secure your SSH server on RHEL / Centos 7 for a better remote administration over the internet. You can use the same guide for all the versions of RHEL/CentOS/Fedora with a few minimal changes.
Prerequisites :
Operating System : CentOS Linux 7 or higher version's
package : openssh-server openssh-clients
User account : root user or user account with sudo privileges
Recommended to run all the administrative commands as with sudo privilege instead of root
Difficulties in setting up sudo users? Click here to find the steps.
My Lab Setup :
For the lab setup, I am using 2 centos machines. One for the server and the other one for the client.
SSH Server:
Operating System : CentOS Linux 7 (core)
Hostname : sshs01.linuxteck
IP Address : 192.168.1.100
SSH Client:
Operating System : CentOS Linux 7 (core)
Hostname : cli01.linuxteck
IP Address : 192.168.1.200
SSH client : An active ssh client like " Terminal for Linux/Mac and Putty for Windows"
Step1: Install and enable SSH Server
First, let's update the latest current version and then install the SSH server and client. OpenSSH package is the most popular one and mostly these packages are installed by default, if not use the following command to install.
$ sudo yum update -y
$ sudo yum install -y openssh-server
Note:
The OpenSSH package is a free version of SSH. This package contains an init script called SysV to manage the OpenSSH Server. Now start, enable, and check the status of the sshd daemon using the following command.
$ sudo systemctl start sshd
$ sudo systemctl enable sshd
$ sudo systemctl status sshd
Note:
If the status shows as "active (running)", then the installation of your SSH server went well without any issues also you use the 'netstat' command to verify the port number. As you can see in the output below, it is only listening on the default port 22.
$ sudo netstat -tulnp | grep ssh
The main configuration file of the SSH server in Centos is located at "/etc/ssh/sshd_config". For any customization on the SSH server, we need to modify this file correctly. If you install the server-client package on the same server, then you can find a similar named file "ssh_config" in the "/etc/ssh" path as well, but don't get confused about these two files. (sshd_config is for SSH server and ssh_config is for SSH Clients)
If you want to know more about ssh client commands, you can have a look at this article on 10 basic and most useful 'ssh' client commands in Linux
Note:
It is always recommended to make a copy of the original configuration file before making any changes to it. If there are any issues, you can simply revert the changes to the default one.
$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Step2: Enable SSH Protocol Version 2
By default, SSH protocols support versions 1 and 2 within a single daemon. As we know, version 1 has a lot of issues related to the security part and those have been updated in version2 especially the security and encryption, also it is not very compatible with version1. Hence, it is recommended to block the connections coming from version 1 clients. To make the changes, open your ssh config file and add the line "Protocol 2" as highlighted below :
$ sudo vi /etc/ssh/sshd_config
Protocol 2
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
Save and exit.
Note:
For every change/modification in the "sshd_config" file, we need to restart the service to implement these changes. This server currently only accepts connections from only version 2 clients. You can do the test using the following command:
$ sudo ssh -1 [email protected]
Output:
SSH protocol v.1 is no longer supported
Note:
The above message clearly shows that the SSH protocol version 1 no longer supports the above Server. The above command (-1) specifies protocol version1. Now if you want to access the server, you need to use one of the following commands.
$ sudo ssh -2 [email protected]
$ sudo ssh [email protected]
Step 3: Customize the default SSH port (22)
As mentioned above, by default ssh used Port 22 for communication. Hackers are really smart and intelligent if they come to know if your server is using it as default and it will be easy for them to attack. To avoid this, we can customize the SSH port number. I am going to use Port 1875. To make the changes, open your ssh config file and scroll through the file until you see the line that starts with "#Port 22". Uncomment/remove the (#) from the beginning of the line. Now replace the line with "Port 1875" as highlighted below :
$ sudo vi /etc/ssh/sshd_config
Port 1875
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
Save and exit.
Note:
After restarting the service, you can verify it through the client machine to access the default method of using port 22 and then test with port 1875.
$ sudo systemctl restart sshd
Output:
Job for sshd.service failed because the control process exited with error code. See "systemctl status sshd.service" and "journalctl -xe" for details.
WARNING:
SSH fails to restart after the port change in CentOS7. To make the ‘sshd’ to run after the port change we need to adjust the SELinux or disable it completely. I will disable it in our demo, but I highly recommend activating SELinux in production. To adjust SELinux, execute the following command:
$ sudo semanage port -a -t ssh_port_t -p tcp 1875
The above command will tell SELinux that the SSH service is now running on the new port 1875. Restart the sshd service and try to access it from the client using port 22 and port 1875.
$ sudo ssh [email protected]
Output:
ssh: connect to host 192.168.1.100 port 22: Connection refused
Note:
Here you can see that the ssh connection was completely rejected using port 22 and now try with our customized port 1875
$ sudo ssh -p 1875 [email protected]
Output:
ssh: connect to host 192.168.1.100 port 1875: No route to host
WARNING:
Again, the connection was refused. This time it shows as "No route to host". This is due to the firewall setup. You can either disable the firewall or permit port 1875 in the firewall for ssh. In our demo, we are going to add a new rule to permit the new port.
$ sudo firewall-cmd --permanent --add-port=1875/tcp
Note:
Once you have added a permanent rule to the firewall, make sure to restart the firewalld service to make those rules work in a permanent configuration.
$ sudo systemctl restart firewalld
If you want to know more about firewalld services, have a look at this article on 15 basic useful firewall-cmd commands in Linux.
You can now access your ssh server with port 1875.
$ sudo ssh -p 1875 [email protected]
[email protected]'s password: xxxxxxxx
Note:
Finally, the connection is accepted!
Step4: Disable root login (SSH)
Using root accounts in SSH is quite dangerous especially on the public network. Hence, it is advised to disable the root login to your server. Before deleting/deactivating the root account, make sure you have a normal user on your server who has enough privileges to use sudo or su. To deactivate the root login, open your ssh config file and scroll through the file until you see the line that starts with "#PermitRootLogin yes". Uncomment/remove the (#) from the beginning of the line. Now replace the line with "PermitRootLogin no" as highlighted below :
$ sudo vi /etc/ssh/sshd_config
PermitRootLogin no
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
Save and exit.
Note:
Restart the service. The root account has now been deactivated on the SSH Server.
Step 5: Use ssh keys (Public and Private)
In Linux, there are two common methods of accessing the SSH servers. The first one is using the password, and the second method is by using the SSH key (public & private). The second method is much more secure than the password method. We know that passwords can be cracked or brute-forced at any time by hackers, so it is recommended to use the SSH keys to access the server via remotely. Using the following command we can generate the ssh keys.
$ sudo ssh-keygen
Note:
While executing the above command, it will ask you to enter the path to save the key, or press enter to save the key to the default path or you can specify your path. Next, the system will ask you to "Enter passphrase (empty for no passphrase):", it is a choice only, either you enter the passphrase or leave it as blank, but it is highly recommended to enter the secure passphrase as it will give you an additional layer of security to prevent unauthorized access to your servers.
Now that you have your public and private key, the public key is named "id_rsa.pub" and the private key is named as id_rsa. Using these keys you can configure SSH. After ensuring your key-based authentication is working without any issues, go ahead and disable the password authentication mechanism. To do the same, open your ssh config file and scroll through the file until you see the line that starts with "Password Authentication yes". Now replace the line with "Password Authentication no" as highlighted below :
$ sudo vi /etc/ssh/sshd_config
# To disable tunneled clear text passwords, change to no here!
Password Authentication no
Save and exit.
Note:
Now restart the service and do the test. As a precaution, I advise, keep the current session on, and do the test in the new terminal. Once you have verified with your SSH service, then close all the sessions.
Step 6: Disable X11 Forwarding
The X11 Forwarding option is enabled in many Linux distros by default. It is a mechanism that permits remote users to execute GUI (graphical) applications from their SSH sessions. It can be misused if things go to the wrong hands as ssh clients can easily generate fake cookies and transmit over the remote SSH server after they establish the connection. To prevent such kind of security gaps, it is better to disable X11Forwarding. To do this, just open your ssh config file and scroll through the file until you see the line starts with "X11Forwarding yes". Now replace the line as "X11Forwarding no" as highlighted below :
$ sudo vi /etc/ssh/sshd_config
#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding no
#X11DisplayOffset 10
Save and exit.
Note:
Now, restart the service and do the testing accordingly.
Step 7: Disable Empty Passwords
Linux system permits users to create with an empty password. It is highly recommended not to use an empty password on SSH servers as it creates some security issues like brute force attacks. Therefore, we are advised to disable the user with an "Empty Password" in SSH. To apply this, open your ssh config file and scroll through the file until you see the line that starts with "#PermitEmptyPasswords no". Uncomment/remove the (#) from the beginning of the line and keep the line as "PermitEmptyPasswords no" as highlighted below :
$ sudo vi /etc/ssh/sshd_config
# To disable tunneled clear text passwords, change to no here!
PermitEmptyPasswords no
Save and restart the service.
Step 8: Set Max Authentication Attempts
It is good practice and recommended to protect our server against brute force attacks. If someone tries to access your server with incorrect passwords, more than a few attempts will be disconnected automatically. To enable this feature, open your ssh config file and scroll through the file until you see the line that starts with "#MaxAuthTries 6". Uncomment/remove the (#) from the beginning of the line and keep the line as "#MaxAuthTries 3" as highlighted below :
$ sudo vi /etc/ssh/sshd_config
MaxAuthTries 3
Save and exit.
Note:
Now restart the service. If you test using the wrong password more than 3 times you will receive a message like the following:
Received disconnect from 192.168.1.100 port 1875:3: Too many authentication failures
Disconnected from 192.168.1.100 port 1875
Step 9: Allow only Specific IP Address
By default, there is no restriction to accessing the SSH server from anywhere with any IP address. As part of the security concern, it is good practice and recommended to permit only a specific IP address. For example: If you have a corporate/business network with a static public IP address, then permit only those and deny the rest of the IP address. This can be done by adding the following entries into "/etc/hosts.allow" file.
$ sudo vi /etc/hosts.allow
sshd : 192.168.1.200 : ALLOW
sshd : 192.168.1.201 : ALLOW
sshd : ALL : DENY
Save and exit.
Note:
The above configuration will permit only two IP's "200 and 201" and deny all other IP addresses access to our SSH server.
Step 10: Set Idle Timeout
By default, there is no idle timeout set on Linux servers or clients, it is good practice to set up idle timeout sessions on the server itself, it will prevent unauthorized access to the system. For e.g., if a user walks away from his desk and doesn't lock the screen and is busy with something else, in the meantime someone can access the user's ssh session. To reduce this kind of risk, it is better to enable timeout value. The recommended setting is 300 seconds (5 minutes), you can set this based on your policy. Also set the ClientAliveCountMax is 0. Open your ssh config file and scroll through the file until you see the line that starts with "#ClientAliveInterval 0". Uncomment/remove the (#) from the beginning of the line and keep the line as "ClientAliveInterval 300" and set "ClientAliveCountMax is 0" as highlighted below:
$ sudo vi /etc/ssh/sshd_config
ClientAliveInterval 300
ClientAliveCountMax is 0
Save and exit.
Note:
Now restart the service. We have set up the idle timeout as 300 seconds, which is 5 minutes.
SSH warning banner
It is always good practice to create SSH warning banners and Welcome messages to prevent unauthorized entries to our server. You can display these warning messages in two forms: "before login" and "after login".
To create a Warning message before logging in you can use a common warning message file for SSH and it will be located in the "/etc/issue and /etc/issue.net" or we can create a custom file like "/etc/ssh/sshd_banner" and copy the banner path into the sshd_config file. The content will be displayed before the password prompts.
To create a Welcome message after login you can use the "/etc/motd" file. The content of the welcome message will be displayed after every successful ssh login.
$ sudo vi /etc/ssh/sshd_banner
save and exit.
Note:
Now open "/etc/ssh/sshd_config" file and scroll through the file until you see the line starts with "#Banner none". Uncomment/remove the (#) from the beginning of the line and keep the line as "Banner /etc/ssh/sshd-banner" as highlighted below:
$ sudo vi /etc/ssh/sshd_config
Banner /etc/ssh/sshd-banner
save and exit.
Next, add the Welcome message after successfully logging in to the "/etc/motd" file".
$ sudo vi /etc/motd
Note:
Finally, restart the service, do the test and see both Warning and Welcome messages.
$ sudo ssh [email protected] -p 1875
Output:
Conclusion
I hope this guide can help Linux users to understand how to install and secure the SSH server in Linux. If you know what and where to tweak, then hardening is much simpler than you think.
Thank you for taking the time to read! Drop me your feedback/comments. If you like this article, kindly share it and it may help others as well.
Thank you!
Support My Work
Thank you for your support and for being a part of my journey, I would be very grateful if you could consider buying me a coffee. The contributions you make will help me to continue to produce quality content and enhance my readers' experience.