Introduction
Minimizing vulnerabilities in your Secure Shell (SSH) protocol is key to ensuring the security of your Linux environment.
In this article, we cover the most common Linux SSH security measures you can take to make your servers more secure. By changing the default SSH port, using key pairs, and following the other recommended best practices, you can significantly improve the overall security of your system.
What is SSH?
The Secure Shell (SSH) protocol enables cryptographically protected remote system administration and file transfers over insecure networks. Using multiple encryption methods, SSH secures the connection between a client and a server safeguarding the users’ commands, authentication, and output against unauthorized access and attacks.
The SSH protocol is now widely used in data centers and by almost every major enterprise running on any of the UNIX variants.
When it comes to security measures, it is essential to combine them, apply them in layers, and not pick just one and rely on only that solution.
To learn more about SSH connections, visit our article about how SSH works.
1. Change the Default SSH Port
Using a non-standard port for SSH connection helps avoid automated attacks on your server. It also helps reduce the chances of it appearing on a hacker’s radar and makes it a less obvious target.
Note: The majority of hackers who are looking for OpenSSH servers will aim at the default SSH port 22.
In that case, the scripts they are using will look for IP addresses only on port 22. If your server falls into that group, every such automated attack will make an impact on your log files. Consequently, the load on your server may increase substantially since many SSH server exploits are running around the clock knocking on every server’s door.
It is important to note that changing the default SSH port does not improve the security of your server. However, it does help in keeping away automated attacks.
How to Change the Port Number
Before you begin, you need to decide which port you will use instead of the default port 22. Before you make a decision, you should consider a few things:
To change the port on your Linux server, follow these steps:
- Connect to the server via SSH as you usually would.
- Switch to the root user using the su command, which will prompt you to enter the server password.
- Use a text editor of your choice to edit the sshd configuration file located in the
etc/ssh/
directory. If you have never used a text editor within the terminal, it is recommended to use Nano. Otherwise, use vi or vim since they are the most commonly used editors today. We advise you to back up the original file before you make any changes. - Run this command to edit the configuration file:
nano /etc/ssh/sshd_config
- In the output of the sshd_config file locate the line which says “
Port 22
.”
- Change the port number to the value of your choice. Make sure there is no “
#
” at the beginning of the line. - Exit the editor and confirm that you want to save the changes.
- For the changes to take effect, restart the sshd service with this command:
service sshd restart
- Verify that the SSH is listening on the port you specified by connecting to it.
Note that now you will need to specify the port when connecting since your client will always use the default SSH port unless told otherwise.
Benefits
While the procedure for changing the default SSH port does not increase the level of security itself, it takes you off the radar of the most common scans. One easy way to test this is to let your server run for a few days with sshd listening on the default port and then change it to a non-standard one. Compare the number of failed logins on your server, and you will see it decrease substantially.
By using a non-standard port for SSH:
- You avoid being seen by random scans.
- It is more difficult to find your server. Most of the attacks will scan the default port or some variants of it, but will move on once the connection is refused.
- SSH daemon can take a break since it will not get connection requests from scripted attacks. Server load is reduced, and the log file stays clean saving you time in reviewing it.
- You do not receive as many alerts for failed logins. If you are using a non-standard port and someone still tries to access your server, it probably means that your server is specifically being targeted and that the alarm is not coming from a scripted attack.
- You are less exposed to being hacked due to the bugs in sshd or weak private keys.
- Most hackers will be repelled if they see that you are not using the default port. It will be a sign that the server is properly protected and that there are probably other security measures taken as well, making your server an undesirable target.
Drawbacks
There are some precautions to keep in mind before you decide to change the default port for SSH. The disadvantages of running a non-standard port can mean that:
- Anybody who should be able to connect to your server will need to be informed of the change and will have to start using the new port.
- If you are using outsourced monitoring for your server, you also need to make them aware of the change. Otherwise, they may treat this as a potential threat which may lead to server downtime.
- The firewall rules related to the SSH service have to be inspected and modified according to the changes you make.
Some of these disadvantages probably will not apply to your use case but should be taken into consideration. The benefits of changing the port outweigh the drawbacks and prove to be a good additional layer of security for your server.
Note: Refer to our article for a more comprehensive guide on how to change the SSH port.
2. Enhance Linux SSH Security Using Key Pairs
One of the most secure methods to authenticate clients to servers is by using SSH key pairs. Strong passwords may be sufficient to keep your server safe, but persistent brute force attacks can still crack them. This is why you need additional SSH hardening with key pairs.
SSH keys are resilient to such attacks and are virtually impossible to decrypt. An SSH key pair consists of two long series of characters, a private key which is kept secret, and a public key which can be safely shared. Their purpose is similar to passwords, and they allow you to automatically establish an SSH session without the need to type in a password.
How to Generate a Key Pair
To set up SSH keys, you will need to generate a key pair on the client computer which will be used to connect to the server. To do so:
- Start the terminal and run the SSH keygen utility, available with the standard OpenSSH tool.
ssh-keygen –t rsa
- You will get the message “Generating public/private RSA key pair.” If you want to save the key to the default location, press
Enter
when prompted. The key will be saved in the home user’s directory, in the~/.ssh
directory. To change the location, just type in the new path. The recommendation is to stick with the default location, so you do not have to make any changes to your SSH client. The private, or the identification key, will be saved asid_rsa
and the corresponding public key asid_rsa.pub
. - Optionally, you can insert a passphrase. If you do not wish to use one, press
Enter
to continue. The passphrase provides an additional layer of security by encrypting the private key on the local machine. To crack the passphrase, a hacker will need to have access to the system first, since the private key is not exposed on the network. Even then, it will take time to succeed, allowing you to change the used key before the hacker gains access to other servers. The downside is that you will have to enter it every time you try to connect using that key.
The process of generating a key pair is complete.
The final screen will look similar to this:
ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/demo/.ssh/id_rsa.
Your public key has been saved in /home/demo/.ssh/id_rsa.pub.
The key fingerprint is:
8b:cd:0b:f7:38:4a:3f:ed:24:18:8d:54:34:2c:63:56 your_username@host
The key's randomart image is:
+--[ RSA 2048]----+
| ..o. |
| . E.o |
| + . o |
| . = = . |
| ..S |
| = + = + |
| . o + o . |
| . + + o |
| .. |
| |
+-----------------+
Note: You can make the authentication/authorization even more secure by creating larger 4096-bit keys instead of the default 2048 bits. To do so, append –b 4096
to the ssh-keygen
command. It will look like this:
ssh-keygen -t rsa -b 4096
Copying a Public Key
To use the key pair you’ve created on your machine for SSH authentication, you need to place the public key on the desired server. The simplest way to do so is to use the tool available with OpenSSH:
ssh-copy-id
The procedure is easy:
- Type in
ssh-copy-id username@your_host_address
. - If you are connecting for the first time to this host, you will get an authenticity message. Type
Yes
to continue. - Input your password when asked, and the tool will copy the contents of
~/.ssh/ id_rsa.pub
key to theauthorized_keys
file under the~/.ssh
home directory on the server.
Note: No characters will be visible while you are typing the password due to security reasons.
- You will get a message:
Your public key has been placed on the remote server, and now you can log into it without entering the account’s password.
- To test if the authentication with the keys is working, connect to your server with
ssh username@your_host_address
. If successful, you will be automatically logged in. In case you had previously set up a passphrase, you will need to enter it first before you are granted access to the server.
How Keys Work
Essentially, a public key is not a key. It behaves like a padlock that you can put on an SSH account on another machine. When you run the ‘ssh-keygen’ utility, you generate both the padlock and the key that opens it, id_rsa.pub
and id_rsa
respectively.
You can make as many copies of the padlock as necessary, distribute them to any server you like, and only you will have the right key to unlock them all. This is why it is important to keep the private key safe because it unlocks all the copies of the padlocks you’ve handed out.
It does not matter where you put your public key as long as the master key does not get compromised. Since nobody else possesses the private key, this method for authorization and authentication is probably the safest out there and highly recommended.
3. Disable Server SSH Root Login
Linux server distributions have outside root access enabled by default. This can be a severe security threat since hackers can try to crack the password with brute force attacks. It is recommended to disable root login and use a regular account and a su –
command to switch to the root user.
Before you disable the root login, make sure that you have added an account that can gain root access. To do so, follow the steps below:
- Use SSH to log into the server as root.
2. Use a text editor to open the main configuration file. This time, we will use the vi editor.
vi /etc/ssh/sshd_config
3. Find the line that says “PermitRootLogin_yes
“ and change to PermitRootLogin_no
. You may need to scroll down a few lines to find it.
4. It is important to add the user account you will use to log in. Just add another line with the username in question: AllowUsers your_username_here
5. Save the changes you made and then exit the text editor.
6. Restart the SSH service but do not close the root session yet. For Ubuntu and Debian use sudo service ssh restart
and for Fedora/CentOS use the service ssh restart
command.
Open a new terminal window and verify that you can now log in as the user you added. Once you confirm it works, exit the active root session.
4. Disable Password-Based Logins on Your Server
If you are using SSH keys for SSH authentication, you can disable the server password authentication altogether. This is another way to keep your server safe from brute-force attacks and attempts to crack your password. Before you proceed, double-check if SSH key-based authentication is working for the root account on the server or for an account with the sudo access.
When you are ready, complete these steps:
- Use SSH keys to log into the server as root or with sudo privileges.
2. Use a text editor to open the sshd_config file. We will use vi:
vi /etc/ssh/sshd_config
3. Look for the line that says PasswordAuthentication
and change to PasswordAuthentication_no
. Make sure to uncomment the line if the #
is present.
4. Save the changes you’ve made and then exit the text editor.
5. Restart the SSH service to apply the changes. For Ubuntu/Debian use sudo service ssh restart
and for Fedora/CentOS use the service ssh restart
command.
Congratulations, you have successfully disabled the option to log in through SSH using account passwords. SSH Daemon will simply ignore any authentication requests which do not include private/public key pairs.
5. Restrict SSH Access Using iptables
Iptables is a Linux utility used for configuring firewall rules and monitoring/filtering incoming and outgoing traffic to your server. It is included by default with most Linux distributions.
With iptables, you can define rules that limit or permit traffic for different kinds of services by IP address, port or network protocol and thus substantially improve the security of your server. In our case, we will set firewall rules to restrict the incoming SSH traffic for everyone but one IP address or subnet.
This way, blocking port 22 will not only stop unauthorized access to your servers but can also stop or prevent DDoS attacks.
While taking this step, you should make sure you do not lock yourself out by completely blocking SSH traffic.You will need to use only a few commands to allow a specific IP address or subnet for incoming SSH connections.
Note: Commands are case sensitive.
This rule will whitelist the IP address that you’ve typed in. Please replace the example IP in the command with your IP. You can also use a subnet, for example, 10.10.10.0/24.
sudo iptables -A INPUT -p tcp -s 123.456.78.90 -dport 22 -j ACCEPT
You need to save the rules, so you do not lose them after reboot:
sudo iptables-save
If you want to view the list of all iptables rules, you can use the iptables
–L
command. To include more details such as packet, byte and target information, append –v
to the command above. Add -n
to all of it and the output will be displayed in numeric format.
In case you want to reset all rules and start clean, use the flush command iptables –F
. This will clear the iptables configuration which is useful if you are unsure if everything is set up as you want it.
Iptables parameters and Options Definitions
Here are some explanations for iptables parameters, options, and values used in the examples above, as well as a few not mentioned before.
Value | Description |
ACCEPT | Allows the packets to pass through |
DROP | Blocks the packets |
RETURN | Tells to skip the current chain and resume at the next rule in the previous (calling) chain |
>Parameter | Description |
-c | counters – allows setting the packet and byte counters of a specific rule |
-d | destination – can be an address, name of a host or address, etc. |
-f | fragment – applies the rule to the second and the fragments that follow it |
-g | goto chain – states that the action will continue in a user-specified chain |
-i | in-interface – states the name of the interface from where packets come |
-j | jump – specifies the action if a packet matches the rule |
-o | out-interface – the name of the interface of an outgoing package |
-p | protocol – any available protocol such as SSH, TCP, UDP, and FTP |
-s | source – can be an address, name of a host or address, etc. |
Chain | Description |
INPUT | Controls the incoming packets |
FORWARDS | Forwards the packets coming to your server but destined for somewhere else |
OUTPUT | Filters packets going out of your server |
Option | Description |
-A | append – adds one (or more) rules of the selected chain |
-C | check – checks for a rule that matches the criteria in the selected chain |
-D | delete – deletes only one rule from the selected chain |
-F | flush – deletes all defined iptables rules |
-I | insert – insert a rule into the selected chain |
-L | list – displays the rules of the selected chain |
-n | numeric – shows the IP address/hostname and return value in a numeric format |
-N | new-chain <name> – creates a new user-defined chain |
-v | verbose – used in the combination with -L to provide additional information |
-X | delete-chain <name> – deletes the user-defined chain |
Conclusion, SSH Security, and Hardening Best Practices
Whether you are building a new server or a virtual machine, it is good practice to implement multiple security layers within your environment. Businesses are usually keen on setting up their infrastructure as soon as possible, but necessary security measures have to be applied right from the start.
If you employ the Linux SSH security methods listed above, you should be able to avoid common security threats in the cloud.
Make it hard for the hackers to penetrate your server(s) and restrict any damage. Make sure you implement as many of these best practices as possible before making your server available on the network.
Don’t forget to check out our regularly-updated list of Best Cybersecurity Blogs you should be following to keep yourself on top of all the latest trends.