Securing SSH access to your server

bLd Nodes
bLd Nodes
Mar 29 · 7 min read

In our previous article, we explained how much wecare about security for our Kusama validator node. Talking with the community, we realized how much the crucial point of SSH connection can sometimes be underestimated.

The SSH access is the most standard attack vector for an online server, there is an incredible number of robots and hackers who scan the default port 22 and try to gain access with basic and elaborated credentials.

Wanna see how many there are on your server? Just try this command:

journalctl | grep sshd

Scary right? If you are running a blockchain node like us, as soon as your node connected to other peers and telemetry server, you become a valuable target to hackers.

In this article, we are going to build a secure SSH connection with strong SSH keys as described in here in a simplified version. We will also change the default SSH port to mitigate scans and bruteforce attempts.

We will use the curve25519-sha256 protocol (ECDH over Curve25519 with SHA2) for our keys here as this is considered the most secure nowadays. Its weakness is that it requires a recent OS.

For clarity reasons, we won’t mention the RSA protocol as we consider you are using up-to-date software to run your server in 2021 but some configurations can require it.

This guide was made using Ubuntu 20.04 LTS on the node server side and Debian 10 Buster on the client side.

Note: if you have compatibility problem with ed25519 protocol, you should use the RSA 4096 keys as a 2nd choice.

Server side configuration

Let’s start by moving our actual unsecured host keys into a backup directory:

cd /etc/ssh
sudo mkdir backup
sudo mv ssh_host_* ./backup/

Warning : from here, be very careful to never close your actual session until you’ve tested connection with your new key. You could loose access to SSH connection that would require a physical access to your server to restore.

Open the ssh config file:

sudo nano /etc/ssh/ssh_config

Add the following lines in the Host * section and save:

Host *
KexAlgorithms curve25519-sha256@libssh.org
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
PasswordAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
UseRoaming no

Open the sshd config file:

sudo nano /etc/ssh/sshd_config

Add the following lines and save:
Important: port 2021 is just an example here, please use a different random port inside the range 1024–49151

Port 22
Port 2021
KexAlgorithms curve25519-sha256@libssh.org
HostKey /etc/ssh/ssh_host_ed25519_key
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
AllowGroups ssh-user
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no

In details, by doing that, we tell the host to

  • use the port 2021 instead of default 22: please use a different random port in the range 1024–49151
  • use the curve25519 protocol for authentication
  • use chacha20-poly1305 (prefered), aes-gmc and aes-ctr ciphers for data
  • enable Message Authentication Code MAC for CTR ciphers
  • allow ssh group ssh-user
  • enable key authentication
  • disable password access (all this guide is useless if password authentication is enabeled)

Important: We left here the line Port 22 for the first test on the new port. Once your tests are corrects, you should remove this line.

Note: also check that no other line is active (most options should be commented by default) or that you strictly need the other lines.

Then, create the new SSH host key:

sudo ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N ""

Create the ssh user group and add your user to it. This will prevent any connection to an unexpected user:

sudo groupadd ssh-user
sudo usermod -a -G ssh-user <username>

Note: you have to change <username> by the user you use on your server.

Firewall config

Before continuing, it is very important to open the newly configured SSH port in your firewall (2021 in our example).

Since this configuration depends on your router (for a home server) or provider (for a hosted server), we can’t write a detailed configuration here.

For the first tests, you should let the port 22 open. Once you successfully connected on the new port, you can safely close port 22.

Client side (your computer)

There are 2 different methods depending on the the OS you use and how you feel comfortable with command line:

  • If you run a Linux OS (Debian, Ubuntu…), we will use the Open SSH method that adds an extra layer of security in the passphrase hacking. This method is also suitable with Windows or Mac OS with Open SSH command line installed.
  • If you run a Windows or Mac OS (nobody’s perfect right? :-)) and prefer to use a graphical client like PuTTY, we are going to use PuTTYGen generated keys method.

Using OpenSSH client (command line)

Generate the public keys:

ssh-keygen -t ed25519 -o -a 100

The -a flag will increase the passphrase security by iterating the hash function 100 times here. Of course, use a strong password (but you didn’t need to be told that, right)?

Copy the public key to your server (don’t forget to change the port):

ssh-copy-id -i ~/.ssh/id_ed25519.pub <user@server ip> -p 2021

Note: you have to change <user@server ip> by the user and ip address of your server.

Let’s check on the server that our client public key has been copied:

nano ~/.ssh/authorized_keys

You should see something like this:

ssh-ed25519 AAAAaaaaZZZZzzzzAAAAaaaaZZZZzzzzAAAAaaaaZZZZzzzzAAAAaaaaZZZZzzzzAAAA user@client

Troubleshooting: If you had a problem for copying, you can just edit the file ~/.ssh/authorized_keys on your server and paste the line in the file ~/.ssh/id_ed25519.pub on your local computer.

Great, now let’s restart the ssh service without killing the current session:

sudo kill -SIGHUP $(pgrep -f 'sshd -D')

Attention: you should not send a complete restart of sshd for the moment (don’t ask us for the command, any search engine not name with a G will help if you are that curious), this could close your open session and potentially lose access to your server if something is set wrong.

Check that the sshd service is still running correctly:

systemctl status sshd

Now, let’s connect on the client side:

ssh -i ~/.ssh/id_ed25519 <user@server ip> -p 2021

Congratulation, your SSH connection is secure! Don’t forget to remove port 22 from sshd_config file and firewall, and check that no other key is allowed in authorized_keys file.

Extra: you can also use this key with Putty, please refer to the extra section for this or for troubleshooting.

Jump to conclusion

Using Putty client (graphical interface)

Open PuTTYGen GUI:

PuTTYGen

Select the Ed25519key type and click on Generate:

Putty Key generated

Enter a strong passphrase and save both private and public key in a secure folder. Copy the public key from the text box.

Connect to your server and open the authorized_keysfile.

sudo nano ~/.ssh/authorized_keys

Paste the public key and save.

On the server side, let’s restart the ssh service without killing the current session:

sudo kill -SIGHUP $(pgrep -f 'sshd -D')

Attention: you should not send a complete restart of sshd for the moment (don’t ask us for the command, any search engine not name with a G will help if you are that curious), this would close your open session and potentially lose access to your server if something is set wrong.

Check that the sshd service is still running correctly:

systemctl status sshd

Let’s load the private key in the PuTTY Auth section:

Putty private key path

Don’t forget to use your custom port, then connect:

Putty session

Congratulation, your SSH connection is secure! Don’t forget to remove port 22 from sshd_config file and firewall, and check that no other key is allowed in authorized_keys file.

Conclusion

We learned the fast way how to set up our secure SSH access to our server with the curve25519-sha256 protocol known to be very robust.

If you manage sensitive content on your server, we strongly encourage you to read this article that is providing much more detailed information.

Please feel free to reach for any comment:

  • Twitter : @bLdNodes
  • Mail : bldnodes@gmail.com
  • Matrix : @bld759:matrix.org

Extras

If something is going wrong with the OpenSSH configuration, you should test the connection in verbose mode:

ssh -v -i ~/.ssh/id_ed25519 <user@server ip> -p 2021

If you used OpenSSH to generate your keys and want to use your private key with PuTTY, you need to convert it in PuTTY’s format ppk.

Actually, Putty can’t read the passphrase of a key generated with the -a flag of OpenSSH, so we need a little trick.

Note: by doing that, you loose the extra layer of security provided by the OpenSSH passphrase encryption.

Copy your private key into a temporary one, and disable its password:

cp ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.putty
ssh-keygen -p -f id_ed25519.putty

Generate the key in the PuTTY’s format and delete the temporary one for obvious reasons:

puttygen ~/.ssh/id_ed25519.putty -o ~/.ssh/id_ed25519.ppk -P
rm ~/.ssh/id_ed25519.putty

Load the new file in the PuTTY Auth section:

Don’t forget to use your custom port:

bLd Nodes

Validator nodes for Polkadot blockchains

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store