This guide assumes you’re running Ubuntu Server 24.04 and OpenSSH 9.6

Many people are often afraid to expose their SSH server to the internet, and they fall for a false sense of security by using the delusional security by obscurity of the likes of switching the port SSH listens on, which will hardly save you. Further, gimmicky things like fail2ban won’t really do much more other than waste resources.

The real way to secure your SSH server is by, well, securing your SSH server, duh! So, let’s talk about how to harden your OpenSSH install.

  • First of all, what we can do is being very selective about what algorithms we want to use, and making sure to only use a limited set of modern and safe algorithms for the host key, key exchange, ciphers and MACs.
  • Second, we want to make sure that only publickey authentication is enabled: You don’t want password authentication, as that can potentially be brute-forced.
  • Third, we make sure to increase OpenSSH’s log level to keep an audit track during logins, but also for SFTP to keep track of what files were messed with.
  • Fourth, we limit the number of connections *before* authentication (e.g. like the kinds used by scanners/attackers).
  • Fifth, we use sandboxing mechanisms where possible.
  • Sixth, we make sure that root logins are disabled, this forces users to log in instead, which keeps auditing possible.

Now, of course, before changing your config you need to make sure that:

  • You have your non-root user accounts set up and
  • that they can sign in through SSH with a public key
  • and that they can use sudo (where root is needed)

Otherwise you’re locked out!

Now that you got everything ready, you can create the file /etc/ssh/sshd_config.d/harden.conf:

HostKey /etc/ssh/ssh_host_ed25519_key

KexAlgorithms [email protected]

Ciphers [email protected],aes256-ctr

MACs [email protected],[email protected],[email protected]

# Password based logins are disabled - only public key based logins are allowed.
AuthenticationMethods publickey

# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear audit track of which key was using to log in.
LogLevel VERBOSE

# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise.
Subsystem sftp  /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO

# Throttle connections to counteract the DHEat DoS attack (CVE-2002-20001)
PerSourceMaxStartups 1

# Use kernel sandbox mechanisms where possible in unprivileged processes
# Systrace on OpenBSD, Seccomp on Linux, seatbelt on MacOSX/Darwin, rlimit elsewhere.
UsePrivilegeSeparation sandbox

# Root login is not allowed for auditing reasons. This is because it's difficult to track which process belongs to which root user:
#
# On Linux, user sessions are tracking using a kernel-side session id, however, this session id is not recorded by OpenSSH.
# Additionally, only tools such as systemd and auditd record the process session id.
# On other OSes, the user session id is not necessarily recorded at all kernel-side.
# Using regular users in combination with /bin/su or /usr/bin/sudo ensure a clear audit track.
PermitRootLogin No

This is my opinionated config. Now run systemctl restart ssh and make sure you can connect to a new SSH session before signing out or you might lock yourself out if something breaks!

I hope I could help you out. Feel free to donate a cup of coffee. Goodnight.

Sources (or further reading):

  • https://infosec.mozilla.org/guidelines/openssh
  • https://man.openbsd.org/sshd_config
  • my opinions