Minimizing vulnerabilities in your Secure Shell (SSH) protocol is key to ensuring the security of your Linux environment.

In this article, I will talk about 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 safety 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 attacks.

SSH Protocol is now widely used in data centers and 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 just pick one and stick with it.

1. Change the default SSH port.

Using a non-standard port for SSH connection aids in avoiding automated attacks on your server. It also helps reduce the chances for it to appear on the hackers’ radar.

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 on port 22. If your server falls into that group, every such automated attack will create an impact on your log files. Consequently, the load on your server may increase substantially since there are many SSH server exploits running around the clock knocking on every server’s door that fits the criteria.

It is important to note that the default SSH port does not improve the security of your server. However, it definitely helps in keeping away the 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 have a few things in mind:

  • Make sure the port you chose is not in conflict with another application. If you select a port that is reserved for another service, you can run into issues. To make a decision, refer to the list of TCP and UDP port numbers assigned by the Internet Assigned Numbers Authority (IANA).
  • Only root users can listen on ports below 1024; these are well-known ports.
  • Avoid the most common variations of the port 22, such as 222, 2222 and 22222.
  • Verify that the port you decide to use is not blocked.

To change the port on your Linux server, follow these steps:

  1. Connect to the server via SSH as you normally would.
  2. Switch to the root user. One of the ways is using the su command, which will prompt you to enter the server password.
  3. 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 most commonly used today. We advise you to back up the original file before you make the changes.
  4. Run this command to edit the configuration file:
  5. nano /etc/ssh/sshd_config
    In the output of the sshd_config file locate the line which says Port 22.
  6. Change the port number to the value of your choice. Make sure there is no # at the beginning.
  7. Exit the editor and confirm that you want to save the changes.
  8. For changes to take effect, restart the sshd service with this command:
    service sshd restart
  9. Verify that SSH is listening on the port you specified by connecting to it

Note that now you need to specify the port when connecting since your client will always use the default SSH port unless told otherwise.

Benefits

While the procedure of changing the default SSH port does not increase the level of security itself, it takes you off the radar of the most random 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 to a non-standard one. Compare the number of failed logins on your server, and you will see it will 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 move on once the connection is refused.
      • SSH daemon can take a break since it will not get connection requests from scripted attacks. The server load is reduced, and the log file stays clean saving you time in reviewing it.
      • You do not receive as many alerts for the failed logins. If you are using a non-standard port and someone still tries to access your server, it probably means that your server specifically is the target, so the alarm does not come 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 as well, making your server an undesirable target.

Drawbacks

There are some precautions to have 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 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 some downtime for your server.
      • The firewall rules related to SSH service have to be inspected and modified according to the changes you make.

Some of these disadvantages probably do 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 of your server.

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

        1. Start the terminal and run the SSH keygen utility, available with the standard OpenSSH tool.
          ssh-keygen –t rsa
        2. 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 you get the prompt. 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 as id_rsa and the corresponding public key as id_rsa.pub.
        3. Optionally, you can insert the passphrase. If you do not wish to use it, 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      |
|         ..      |
|                 |
+-----------------+

TIP:

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 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 a tool available with OpenSSH: ssh-copy-id.

The procedure is easy:

  1. Type in ssh-copy-id username@host_address.
  2. If you are connecting for the first time to this host, you will get an authenticity message. Type Yes to continue.
  3. Input your password when asked, and the tool will copy the contents of ~/.ssh/ id_rsa.pub key to the authorized_keys file under the ~/.ssh home directory on the server.

Note: no characters will be visible while you are typing your password due to security purposes.

  1. You will get a message:
    Number of key(s) added: 1
    
    Now try logging into the machine, with: "ssh 'username@171.162.153.144'"
    and check to make sure that only the key(s) you wanted were added.

    Your public key has been placed on the remote server, and now you can log into it without entering the account’s password.

  2. To test if the authentication with keys is working, connect to your server with ssh username@host_address. If successful, you will be automatically logged in. In case you have previously set up a passphrase, you will need to enter it first before you are granted access to the server.

    How do the keys work

    In simple terms, a public key is essentially not a key. In fact, 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 need to, and only you will have the right key to unlock them. That is why it is important to keep the private key safe because it unlocks all copies of the ‘padlocks’ you 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 distributions have an outside root access enabled by default which may be a serious 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 root user.

Before you disable root login, make sure that you have added an account that can gain root access and follow the steps below:

  1. Use SSH to log into the server as root.
  2. Use a text editor of your choice 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/Debian use sudo service ssh restart and for Fedora/CentOS use service ssh restart command.
  7. 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 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:

  1. Use SSH keys to log into the server as root or with sudo privileges.
  2. Use a text editor of your choice to open the sshd_config file. We will use vi:

vi /etc/ssh/sshd_config

  1. Look for the line that says PasswordAuthentication and change to PasswordAuthentication_no. Make sure to uncomment the line if the # is present.
  2. Save the changes you made and then exit the text editor.
  3. Restart the SSH service to apply the changes. For Ubuntu/Debian use sudo service ssh restart and for Fedora/CentOS use 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.

4. 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 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 serves but can also stop some DDoS attacks.

While making 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.

  1. This rule will whitelist the IP address that you 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
  2. 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 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 to.

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 of them not mentioned before.

>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, FTP.
-s source – can be an address, name of a host or address, etc.
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
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

Whether you are building a new server or a virtual machine, it is a good practice to implement multiple security layers within your environment. Businesses are usually keen on setting up their infrastructure as soon as possible, but basic security measures have to be applied right from the start. If you combine Linux SSH security methods listed in this article with some general security best practices, you will make it hard for the hackers to penetrate your server(s) and cause any damage. Make sure you implement as many of them as possible before your server is available on the network.