Configure SSH on an Arch Linux Server

Setting up Secure Shell (SSH) on a server is a somewhat daunting task. Configure SSH and the firewalls incorrectly and the machine will be left defenseless to malicious bots and individuals. Here, we will try to layout a basic setup, which will render the machine reasonably secure (baring any other changes) and enable SSH access.

Beware: subtle errors and / or changes can leave a server vulnerable. The most secure systems simply reject all (or most) inbound traffic. Enabling SSH, intentionally creates an access point, through which you (or anyone) can attempt to access. Our goal in this article, is to minimize the chances of finding the access point (i.e. port number) and block users who attempt to “brute force” the login (try to guess a user & password).

SSH Server Setup

Configure nftables

First item we need to cover is configuring a filter. In this case, we will setup nftables – similar to iptables. The intent is to do packet filtering and define rules or set of rules (chains) to block or direct incoming / outgoing connections. The default in nftables is to block most type of connections, we will continue to use this behavior.

To install and enable the nftables service, execute the following commands:

sudo pacman -Sy nftables
systemctl enable nftables.service && systemctl start nftables.service

After install, we will modify the default config to use a custom SSH port (reduces login attempts from automated bots). Easiest thing to do is add the following rule to your /etc/nftables.conf:

tcp dport <ssh port number> accept

Then remove the following line (blocking the standard SSH port):

tcp ssh accept

The ling above enables TCP connections to port 22 (which is normally SSH, but we are not utilizing that port).

That’s all we will do to the nftables, for now.

Setup OpenSSH

Next step to get SSH setup, install OpenSSH:

sudo pacman -Sy openssh

Then, edit the config /etc/ssh/sshd_config.

Set the custom port by adding in the line:

Port <port number>

Improve security on root (see wiki) by uncommenting:

PermitRootLogin prohibit-password

For even more security, I’d recommend:

PermitRootLogin no

Skip this step for now, but later we will disable text passwords with the following line:

PasswordAuthentication no

Disable x11 forwarding, removing a potential attack surface, add the following:

X11Forwarding no

That covers most of the basics. There more advanced discussions around securing SSH on the web, but this should be “good enough” for most basic server setups. We can start & enable the service on startup via:

sudo systemctl start sshd && sudo systemctl enable sshd

Finally, make the ~/.ssh/ directory for the user you wish to SSH into:

mkdir ~/.ssh
chmod 700 ~/.ssh

Enable SSHGuard

To protect against a brute force attack, SSHGuard (or a similar service) is recommended. This service will ban repeated offenders who are attempting to access the machine, but have to main failed password attempts (aka too high of a risk score). Setup is relatively easy:

sudo pacman -Sy sshguard

Once installed, we’ll have an of edit we need to do in the config file.

Because we are utilizing nftables, edit /etc/sshguard.conf and change the Backend:

BACKEND="/usr/lib/sshguard/sshg-fw-nft-sets"

From there, we just start the service (defaults are pretty decent):

sudo systemctl start sshguard.service && sudo systemctl enable sshguard.service

SSH via Password

At this point, it should be possible to SSH into the machine via the following command (will need password):

ssh <username>@<IP Address> -p <port>

To access the server, type the users password and that should be it.

Note: it is possible a router can block SSH. If there is an issue at this point, ensure the correct IP is being utilized and that the router is allowing TCP connections over the given port.

SSH Key Generation

At this point, hopefully it’s been validated that the server is accessible via SSH (where a password was used for authentication).

For security, it’s best to disable passwords and instead use keys. To utilized keys, we will first to generate them, then add them to the authorized_keys file on the given server. Key generation is advised to be done on a client machine, i.e. not server.

Step one is make the ~/.ssh directory (this is on client and server):

mkdir ~/.ssh
chmod 700 ~/.ssh

The next thing we need to do is generate an SSH key, I tend to use a 4096 bit key:

ssh-keygen -t rsa -b 4096

It is also recommended to add a passphrase to the key (leave empty for no passphrase) :

Enter passphrase (empty for no passphrase):
Enter same passphrase again:

Your identification has been saved in /home/<user>/.ssh/id_rsa.
Your public key has been saved in /home/<user>/.ssh/id_rsa.pub.

Once the key is generated, secure copy (SCP) the public key to the server using a password:

scp id_rsa.pub <username>@<IP address>:/.ssh/ -p <port>

After copying the public key from the client to the server, SSH into the server:

ssh <username>@<IP Address> -p <port>

Authorized Key Setup on Server

Once logged into the server

Append the public key to your authorized_keys list:

cd ~/.ssh
touch authorized_keys
cat id_rsa.pub >> authorized_keys

Then edit /etc/ssh/sshd_config to enable the authorized_keys, uncomment the following line:

PubkeyAuthentication yes

Add the authorized key file (believe this is also default):

AuthorizedKeysFile .ssh/authorized_keys

Disable text passwords, add the following:

PasswordAuthentication no

That should do it!

Now, on the client you can add the following ~/.ssh/config and create a short cut to ssh into the server machine:

Host <desired shortcut name>
    HostName <IP Address/DNS entry>
    User <username on server>
    Port <server port>
    IdentityFile ~/.ssh/secret.key

Once you add an entry in the config it’s possible to quickly ssh into the server:

$ ssh <desired shortcut name>

This will bring you directly to the server.

Closing Remarks

There is a lot of careful consideration that should go into locking down a server. Quite frankly, it makes me sweat thinking about all the potential issues. The primary goal here is the reduction of risk most servers can be broken into.

Here, we attempted to reduce the risk of “brute force” attacks, in which an attacker can gain access to the server via guessing the correct password.

In addition to all of the above, I tend to turn on verbose logging (on the server):

LogLevel Verbose

This will let you later inspect what exactly is going on if / when someone is attempting to access the system.

It is also recommended to isolate SSH access to a subset of users (likely without sudo access). Critical systems should run under users without SSH access, as this will help protect the integrity of the server and mitigate damage, even if there is a breach.

Hope this helps! Feel free to leave comments, email, or contact me in any other way to update / improve this post or if you have questions.

Related Content

Leave a Reply

Your email address will not be published.

 characters available

Time limit is exhausted. Please reload the CAPTCHA.