FreeBSD: SSH Server Security Audit&Hardening (maximum score at SSHAudit online test)

Written by: Özgür Kazanççı -

Category: My FreeBSD Write-ups

Bonum Diem.
In this article, I will discuss about securing&optimization (auditing and hardening) of the SSH server installed on FreeBSD. Today, many system administrators/organizations overlook SSH hardening methods, the security of SSH configurations. While the security of SSH keys is often overlooked as well, misuse or compromise of those keys could lead to unauthorized access, often with high privileges.

The usual default SSH configuration, which comes with a default installation of server operating systems (such as Linux, FreeBSD, OpenBSD), brings a better compatibility rather than high security measures.

Security vulnerabilities discovered in critical system management services such as SSH allow attackers to infiltrate your systems usually by taking advantage of these default configurations.

Therefore, when I setup a new server, to test the security of the SSH service, there’s a great online tool that I occasionally use, called; SSHAudit by Positron Security.
A sample online report:

Adding the hostname of my FreeBSD box into “Target SSH Server:” there, with its port number and picking the “Standard Audit” option, I get a horrible security score like “F”, as seen below;

Before hardening.
SSH server security – before hardening.

By default, my (well, FreeBSD’s) ssh server gets a very low score, usually due to the default Host Key Types, Key Exchange Algorithms, Encryption Ciphers and Message Authentication Codes settings.

These keys and ciphers are vulnerable to attacks. So, let’s tighten&polish them! I begin with, checking the default, base SSH server version:

Well, it seems the current SSH server version is: OpenSSH 7.9, which is a pretty old version comes by the default on a FreeBSD 13 system.

Let’s disable it and install the most (almost) recent version through packages (ver. 8.7 as of today);

As root user, always fetch&upgrade FreeBSD packages’ repository before installing anything. It is best practice to ensure your out-of-date packages are updated, and package repository catalogues are up to date before doing any package installation.

Invoking “pkg upgrade” will cause repository catalogues to be updated automatically.

Then install OpenSSH server package (version 8.7):

To enable this version of SSH server, I add;

in /etc/rc.conf file. And in order to prevent conflict with the current SSH server in the base system, I add/edit the line;

within the same file.

After a reboot, our newly installed SSH server will be activated. But before doing so, you might wish to review your SSH server settings, please note that, the openssh-portable that I installed, will be using its own configuration file from; /usr/local/etc/ssh/sshd_config instead of your current/default one which is likely; /etc/ssh/sshd_config.

So, compare and make your own changes in case of any need, BEFORE rebooting.

After restarting the server, let’s check the ssh server version again;

^^This is the actively running ssh server on our server now. OpenSSH 8.7.

Now, let’s get the maximum SSHAudit score possible; the hardening part begins! Cd into OpenSSH directory and remove the default keys, create new ones then;

I removed the default keys and have just re-generated the RSA (4096-bit) and ED25519 keys for much secure&better exchange, through the commands above.

And always do generate your own SSH moduli! Why? Because the Operating Systems ship pre-computed moduli located as /etc/ssh/moduli (or /usr/local/etc/ssh/moduli) file.

Most users don’t change these moduli files. This facilitates pre-computation attacks. Additionally, these moduli files are often too short (<2048 bit) and vulnerable to attacks.

Shortly, minimum a 3072-bit modulus is needed to provide 128 bits of security.

-Alternatively, if the commands above don’t work (due to openssh version changes) you might consider creating the modulus using the ssh-keygen from OpenSSH package (Thanks to ‘Krond‘ for reporting) like:

With those commands above, first; I generated a 3072-bit moduli file, containing groups for the Diffie-Hellman Group Exchange/DH-GEX protocol. This is a memory-intensive process. And then checked/tested for DH group exchange candidate primes for safety and suitability, a CPU-intensive process.

Now, add the following 4 lines to the bottom of OpenSSH configuration file; /usr/local/etc/ssh/sshd_config

And with those lines; first, I disable the DSA and ECDSA host keys, restrict host keys to ED25519 and RSA only. Then restrict supported key exchange, cipher, and MAC algorithms, setting better&safer ones.

Finally make a configuration file health check and then, if there isn’t any error, restart the OpenSSH server;

We’re done now. Let’s check our SSH security score once again through SSHAudit;

SSH server security - after hardening.
SSH server security – after hardening.

Not bad, is it? Regarding the “Key Exchanges” score, having 4 of 5 passing (80%), SSHAudit states:

Note: Because of a bug in OpenSSH, 2048-bit DH moduli will still be used in some limited circumstances. Only a maximum score of 95% is possible.

By the way, if you’re getting “Invalid CSRF token!” on SSHAudit website, clear your browser’s cache&refresh page.

Well, that’s all from me today.

Ah, of course, all these security measures are not enough in a world that is open to attacks like the Internet. In the SSH server configuration file, there are a series of lines and options that you can tighten your security. There are also various security tightening methods such as;

1- Port-knocking. See:

2- Tarsnap’s spiped SSH:

3- Even “Tor Hidden Service” can be used for SSH, and this has multiple advantages; it provides an additional layer of encryption and server authentication. People looking at your traffic will not know your IP, so they will be unable to scan and target other services running on the same server and client:

I intend to cover all these other security methods in my next articles.

Thank you for reading,
Özgür Kazanççı
Twitter: @ozgurkazancci


Richard 22/11/2021 Reply

There’s a typo in the paragraph talking about copying your current sshd_config settings to the new file. It’s missing a directory: the new file is in `/usr/local/etc/ssh/sshd_config`

Özgür Kazanççı 22/11/2021 Reply

Ouch, my bad! Just corrected it, many thanks Richard!

Gerd 22/11/2021 Reply

That was interesting and very useful! Thanks for this.

dsl 17/08/2022 Reply

Looks detailed. I’ll give it a try. Thanks! 🙂

Leave a Reply