/home/posts/setup-ssh-server

Setting up an SSH Server

Published on

#Enable SSH Access

One of the first things you’ll want to do after purchasing a remote server is set up the ssh server so that you can remotely (and securely) access the machine. You’ll need to first access your remote server’s command line interface (CLI). This is most often accomplished using your provider’s web terminal feature, which you should be able to find on your provider’s website. Once you get access to the server’s command line (which will likely be in your web browser), we can get to work.

Note: this tutorial will assume you have created and are using a user with sudo permissions on the target server, and that the server is Debian-based (e.g. Ubuntu)

First, install OpenSSH, which is the recommended ssh server software:

bash

$ sudo apt install openssh-server

#Configuring OpenSSH

Now that we have the software installed, we need to configure it. To do that, we’ll need to edit /etc/ssh/sshd_config, which should already exist now that we’ve installed OpenSSH.

bash

$ sudo vim /etc/ssh/sshd_config

The file already contains a lot of default options with explanations, so we’ll leave most of this file untouched. However, there are a few changes we can make to make the server more secure.

Note: for more complete documentation on sshd_config, see man sshd_config

#1. Deny Root Login

/etc/ssh/sshd_config
PermitRootLogin no

It’s easy for attackers to find an IP address running a ssh server and immediately start firing away login attempts at the root user. Every machine has a user named root, and that user is critical to controlling the system. By adding this line, you deny the ability to log in as root, so attackers will instead have to determine the name of another user on the system (which isn’t always easy), and attack that user instead.

#2. Specify List of Allowed Users

/etc/ssh/sshd_config
AllowUsers USERNAME

Once again, we want to limit the users that attackers can attempt to brute force. By adding this line to specify only 1 or 2 usernames available for login, we further limit the users that can be brute forced.

#3. (Optional) Use SSH Keys instead of Passwords

As an alternative to logging into your SSH server with the target user’s password, you can instead set up SSH keys. SSH keys use public-private key encryption to authenticate clients to the SSH server, rather than a password. Once SSH keys are put into place, there’s no reason for password authentication to even be allowed.

1. Create Public and Private SSH Keys

On each client machine that will connect to the SSH server, use ssh-keygen to generate a public and private key (also known as a key pair) associated with your machine.

bash

$ ssh-keygen

In the process, you’ll be asked to name the file to store your key (default location is fine) and to enter a passphrase. It is recommended that you protect your private key with a passphrase. This passphrase encrypts the private key so that even if someone gets the private key, they are unable to use it without the passphrase.

2. Copy the Public Key to the SSH Server

SSH servers keep a record of public keys used to authenticate, usually located at ~/.ssh/authorized_keys. Instead of manually copy your public key to the server, use ssh-copy-id to automate the process (where host is the IP address or domain name of your server):

bash

$ ssh-copy-id user@host

ssh-copy-id will automatically grab the public key you generated earlier and copy it to the server’s authorized_keys file. To do that, you’ll need to login to the server with the target user’s password. Once the public key has been placed on the server, ssh-copy-id will instruct you what to do next:

Now try logging into the machine, with: "ssh user@host"

If you’re able to ssh user@host and login without the target user’s password (remember, if you set up a passphrase while generating your private key earlier, you’ll still have to use that to access your keys), then you’ve properly set up SSH keys. Now that we have no need for using password-based authentication…

3. (Optional) Disable SSH Password Authentication

Now that we don’t need the target user’s password to get into the server, we can prevent brute-force password attacks on the SSH server by disabling password authentication on any user. Make sure public key authentication is also enabled:

/etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes

Results

Once you’ve upgraded from passwords to keys, you won’t have to type in the target user’s password to get into the server. Instead, you’ll just need to know the passphrase to access your private key. It may seem like you’re just giving up one password and creating another, but imagine you were logging into 10 users on 10 machines. Once you’ve copied your public key to each machine, instead of memorizing each user’s password, just know your private key’s passphrase, and you can log into any of them.

In addition, the server is hardened from brute force password-based authentication attacks. It’s still possible for an attacker to brute force your private key, but much more difficult.

Remember: back up your private key. If you’ve disabled password based authentication on the server, the private key is your only way into the server.

#Fail2Ban

Fail2Ban is a program that scans program logs for repeated incorrect authentication attempts and bans the IP they originated from. You can set up Fail2Ban to work on several different programs, but in our case we want it to watch over ssh logins. First, install fail2ban:

bash

$ sudo apt install fail2ban

Next, we need to configure fail2ban to watch over sshd’s logs for attackers. fail2ban has a main configuration file at /etc/fail2ban/jail.conf, but it’s recommended that you copy this file before making changes, as said in the manual:

*.conf files are distributed by Fail2Ban. It is recommended that *.conf files should remain unchanged to ease upgrades. If needed, customizations should be provided in *.local files.

In .local files specify only the settings you would like to change and the rest of the configuration will then come from the corresponding .conf file which is parsed first.

fail2ban manual (man jail.conf)

As suggested, we will create a new file at /etc/fail2ban/jail.local with anything that should override the default options.

bash

$ sudo vim /etc/fail2ban/jail.local

For information on how to configure this file, there are comments within /etc/fail2ban/jail.conf that explain most options. The following is a snippet from /etc/fail2ban/jail.conf showing some default values and their purpose:

/etc/fail2ban/jail.conf
# "bantime" is the number of seconds that a host is banned.
bantime  = 10m

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 10m

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

Inside our jail.local file, we want to tighten these restrictions, as well as enable the sshd jail, with the following:

/etc/fail2ban/jail.local
[DEFAULT]
bantime = 24h
findtime = 1h
maxretry = 5

[sshd]
enabled = true

Once you’ve finished editing jail.local, ask fail2ban to reload its configuration file with systemctl:

bash

$ sudo systemctl reload fail2ban

Finally, you can ensure fail2ban is working by looking at the active jails using fail2ban-client. You should see something like this:

$ sudo fail2ban-client status
Status
|- Number of jail:	1
`- Jail list:	sshd

Remember: source IP adresses can be spoofed. Attackers can pretend like they’re you, attempt to login to your server, and fail2ban will block your IP address, thus locking you out of your own server.

#Conclusion

Always remember, there’s no such thing as perfect security. The steps discussed will increase the security of your SSH server, but depending on your threat model, there may be additional steps you need to take to secure your server, like disabling out-of-date protocols and more.

Meet the Author

John Allbritten

Nashville, TN

I love learning new technologies, and I have a passion for open source. As I learn things, my notes turn into articles to share.

Related Posts