Protecting your OpenSSH Server

GeekThis remains completely ad-free with zero trackers for your convenience and privacy. If you would like to support the site, please consider giving a small contribution at Buy Me a Coffee.

SSH is the most valuable tool to manage your servers. As you already know, SSH allows you to remotely connect to your server and access a shell. With the power SSH possess, it’s important to protect SSH to ensure the only trusted people are able to connect. This post will go through the SSH configuration settings that need to be modified to help protect your server.

Editing SSHD Configuration Files

To prevent this tutorial from repeating itself too frequently, here is an overview of how to edit the /etc/ssh/sshd_config file. OpenSSH’s server configuration file is located at /etc/ssh/sshd_config, which is different from the client configuration file /etc/ssh/ssh_config. It’s possible that SSHD is using a different configuration file if the command line argument -f is being used.

Each line of the SSHD configuration file should be treated separately. Lines are ignored if they start with the # character or are empty. In the tutorial below, if you see a line you are supposed to add or edit starting with the # character, you should remove the # character so the line isn’t treated as a comment.

Most directives only use the value that first appears in the file. There are a few directives that can be specified multiple times. Appending a directive at the bottom of the configuration file will not take affect if it was previously declared.

The value for directives are separated by a space, and in some rare cases by a comma. If you need to use a space inside of a value, you can enclose the value with double quotes. Values are case-sensitive.

Once the SSHD configuration file has been modified, the changes won’t take affect until you restart the service. Restarting sshd varies based on your operating system. You can try service sshd restart or /etc/init.d/sshd restart.

Before you log out of the SSH server, open a new SSH client and try logging into your SSH server. If you are unable to login, fix the issues with the initial connection. It’s not uncommon to overlook changing iptables rules, not adding users to the correct ssh group, or having a typo in the configuration file that prevents the ssh server from starting up. It’s better to fix the problem when you still have a connection open to your server.

Change SSH Port

Changing the SSH port helps to prevent many connections to your SSH server and does stop a lot of brute forcing attacks. Many automated attacks will scan only for port 22 and then try brute-forcing common user names and passwords. You can use any port number, but I tend to use ports that are not assigned by IANA and is not a privileged port (ports under 1024).

  1. Verify incoming connections are allowed by your firewall for the new port.
  2. Open /etc/ssh/sshd_config
  3. Find the line Port 22
  4. Change the port number from 22 to your new port.
  5. Restart the SSH server

Prevent Root Login

It’s generally a good idea to not work as root, even if working on a system locally. When you give out root access, you lose the ability to audit who did what on the server. Using sudo allows you to run commands at a higher privilege while still being able to log the account responsible. If you don’t want to use sudo, logging in as an unprivileged user and then using su to gain root access is still better. This way you can see the users who elevated their access to root. A reason to prevent root login through SSH is to prevent brute-forcing against the root account.

  1. Ensure you have a user that can login to SSH.
  2. Ensure the user can elevate their privileges to manage the server.
  3. Open the /etc/ssh/sshd_config file.
  4. Change the directive PermitRootLogin to no.
  5. Restart the SSH server

Restrict SSH to Users and Groups

Not everyone on your system will need SSH access. It’s a good idea to limit the users or groups that can login via SSH. There are four directives that control who’s allowed to connect via SSH, DenyUsers, AllowUsers, DenyGroups, and AllowGroups. I find using AllowGroups as the best option to quickly manage who has SSH access without having to keep modifying the sshd configuration file.

The reason I shy away from the Deny* directives is that new users shouldn’t be automatically allowed to access SSH. It’s much easier to manage who should have access than who shouldn’t.

Use the command groupadd to create a new group. To add existing users to the newly created group, use the command usermod.

  1. Create a new group using groupadd <group_name>.
  2. Add users to the new group using usermod -a -G <group_name> <user_name>
  3. Open /etc/ssh/sshd_config.
  4. Find or add the line AllowGroups <group_name>
  5. Restart the SSH server

Enable Public Key Authentication

Passwords are generally weak and you can’t trust other users on the system to create strong passwords. Even if you set a password policy, nothing prevents a user from creating a “strong” password of “Februrary2018Password!”. The solution is to get rid of passwords and instead use Public Key Authentication. For Public Key Authentication, every user needs to have a public SSH key on the server and a private key stored on their personal device.

Generate SSH Key

First you need to generate a SSH key. Using the command ssh-keygen you can quickly generate a new key pair.

$ ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/vpsinfo/.ssh/id_rsa): [enter for default]
Enter passphrase (empty for no passphrase): [strong passphrase]

The program above will ask where to save the key (press enter for the default location). You will also be prompted to add a passphrase to unlock the private key. The passphrase can be empty but it’s highly recommended to create a strong passphrase. Keep in mind that there is no way to recover the passphrase. In the case where you forget your passphrase you will need to generate a new key pair.

Upload SSH Key

The newly created public key ~/.ssh/ needs to be uploaded to your SSH server. The private key needs to remain private and should not be shared or moved. The easiest way to copy the public key is to use ssh-copy-id.

$ ssh-copy-id user@remote-server

Alternatively, you can manually copy and append the contents of into the file ~/.ssh/authorized_keys. You will want to change the permissions of ~/.ssh/authorized_keys to 0700 using chmod.

Modify SSH Configuration

It’s unlikely that Public Key Authentication is disabled on your server, but if it is, you will need to enable it.

  1. Open the /etc/ssh/sshd_config file.
  2. Find PubkeyAuthentication and set it to yes.
  3. Restart the SSH server.

Prevent Empty Passwords Logins

It’s important to prevent SSH access if an empty password is provided. System accounts don’t have passwords and you don’t want users who accidentally removed their passwords to open up an even larger security flaw.

  1. Open /etc/ssh/sshd_config.
  2. Find the line for PermitEmptyPasswords
  3. Set the value to no.
  4. Restart the SSH server.

Disable Unused Authorization Methods

If you’re not using an authentication method, disable it. There are many different authentication methods for SSH, and most of them are only used in rare cases. It’s better to disable them now and enable them in the future if you need them.

  1. Open /etc/ssh/sshd_config
  2. Find HostbasedAuthentication and set it to no.
  3. Find GSSAPIAuthentication and set it to no.
  4. Find KerberosAuthentication and set it to no.
  5. Find PasswordAuthentication and set it to no.
  6. Restart the SSH server.

Set Listen Address

By default OpenSSH listens on all interfaces. In the future this may cause problems if you add additional network interfaces that you don’t want SSH to be available on. It’s good practice to set the listen address for SSH before you accidentally expose the server.

You can view a list of your network interfaces and IP addresses by running the command ip -o address.

  1. Find the IP address you want SSH to use when listening for connections.
  2. Edit the directive ListenAddress. You can also specify a port number if you are using multiple IP addresses on different ports. You can have multiple ListenAddress directives to specify multiple addresses to listen on.
  3. Save the file and restart the SSH server.

Setup SSH Banner

In some countries a warning is required to be able to bring up charges of unauthorized access to a computer system. To be on the safe side, add a SSH banner to warn users that the server is restricted to authorized users only and unauthorized access will be investigated. Don’t include any identifying information in the banner, such as your company’s name, address, contact information, or any other identifiable information.

  1. Create a new banner file at /etc/ssh/banner
  2. Edit the new banner file and add the warning message you want.
  3. Open /etc/ssh/sshd_config and uncomment the line #Banner none.
  4. Change Banner none to Banner /etc/ssh/banner.
  5. Restart the SSH Server.

Monitor SSH Activity

Monitoring SSH activity is important to understand what is happening on your server. Setting up a monitoring system is out of the scope of this tutorial though, but I will mention a few methods to look into. First, look into remote system logs (e.g. rsyslog) to log all events to a remote server. If someone does gain access to your server, you want logs to be placed elsewhere where the attacker can’t delete or modify them.

Secondly, you want to be alerted when someone logs into the server. Here is a tutorial about receiving an e-mail when someone signs into ssh. This can be adapted to perform other actions such as sending a SMS message, sending an even to a logging service, etc.

Check your logs frequently for unusual activity. Unauthorized login attempts are not too unusual if your server is public facing, but if you notice an increase in SSH activity, you should look into prevent the increase in activity. Monitoring user activity and system resources are also useful. If you notice a spike in system resources (cpu, ram, network, io), it could mean an adversary has connected to your server.

Related Posts

SSH into Multiple Servers using MultiSSH

Learn about the interesting tool MultiSSH (MSSH) that allows you to connect to multiple SSH servers and run the same command on all of them simultaneously.

Send Email Notification after a SSH Login

Learn how to setup a script to send an email notification when a user signs in through SSH. Get alerted via email when any user signs into your SSH server and stay alerted about who accessed your server.

How to Run Scripts after SSH Authentication

Learn how to run scripts automatically after a user signs in through SSH or any other authentication service on your server that uses the Pluggable Authentication Module PAM.

Automatically Start Docker Container

Automatically start Docker containers when your server or computer boots using restart policies and avoiding systemd service files.