These are the settings that I use on my servers. You may want to also review the settings that are used at Mozilla.

Basic configuration

There are a few basic things that most admins will already know (and that tiger will warn you about if you forget):

  • only allow version 2 of the protocol
  • disable root logins
  • disable password authentication

This is what my /etc/ssh/sshd_config.d/mozilla-tls.conf contains:

# https://infosec.mozilla.org/guidelines/openssh
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key

KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
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

AuthenticationMethods publickey

LogLevel VERBOSE

PermitRootLogin no

Once you've done that, make sure you have all of the required host keys by running:

ssh-keygen -A

as root.

Note that I periodically check that list of ciphers and hash functions against the Mozilla recommendations.

I also have the following in my /etc/ssh/sshd_config.d/local.conf:

AuthorizedKeysFile  .ssh/authorized_keys
AcceptEnv LANG LC_* TZ
AllowGroups sshuser

I also used to disable short Diffie-Hellman moduli:

awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.tmp
mv /etc/ssh/moduli.tmp /etc/ssh/moduli

but that's annoying since it causes merge conflicts on distro upgrades.

Finally, if you don't need sftp support, Mozilla recommends disabling it, which can be done by commenting out this line in /etc/ssh/sshd_config:

#Subsystem     sftp    /usr/lib/openssh/sftp-server

On the other hand, if you do need it, it's generally better to replace it with the internal sftp server:

Subsystem     sftp    internal-sftp

Whitelist approach to giving users ssh access

To ensure that only a few users have ssh access to the server and that newly created users don't have it enabled by default, create a new group:

addgroup sshuser

and then add the relevant users to it:

adduser francois sshuser

Finally, add this to /etc/ssh/sshd_config:

AllowGroups sshuser

Deterring brute-force (or dictionary) attacks

One way to ban attackers who try to brute-force your ssh server is to install the fail2ban package. It keeps an eye on the ssh log file (/var/log/auth.log) and temporarily blocks IP addresses after a number of failed login attempts.

To prevent your own IP addresses from being blocked, add them to /etc/fail2ban/jail.d/local.conf:

[DEFAULT]
ignoreip = 127.0.0.1/8 1.2.3.4

Another approach is to hide the ssh service using Single-Packet Authentication. I have fwknop installed on some of my servers and use small wrapper scripts to connect to them.

Restricting shell access

For those users who only need an ssh account on the server in order to transfer files (using scp or rsync), it's a good idea to restrict their access further. I used to switch these users' shell (via chsh) to a restricted one like rssh, but that project has been abandoned.

I now use a different approach which consists of using an essentially empty chroot for these users and limiting them to internal-sftp by putting the following in /etc/ssh/sshd_config:

Match Group sftponly
  ForceCommand internal-sftp
  ChrootDirectory /mnt/data

creating a group:

adduser sftponly

and a base chroot directory:

mkdir -p /mnt/data/home

Note that the base directory, and each parent directory all the way to the root directory, must be owned by root:root (user and group) otherwise you'll see an unhelpful error message like this when you try to connect via sftp:

$ sftp user1@server.example
client_loop: send disconnect: Broken pipe

Then for each user, we need to do the following:

adduser user1 sftp-only
chsh user1 -s /bin/false
mkdir -p /mnt/data/home/user1
chown user1:user1 /mnt/data/home/user1
chmod 700 /mnt/data/home/user1

before restarting the ssh daemon:

systemctl restart sshd.service

Should one of these users attempt to connect via ssh instead of stp, they will see the following:

$ ssh user1@server.example
This service allows sftp connections only.
Connection to server.example closed.

Restricting authorized keys to certain IP addresses

In addition to listing all of the public keys that are allowed to log into a user account, the ~/.ssh/authorized_keys file also allows (as the man page points out) a user to impose a number of restrictions.

Perhaps the most useful option is from which allows a user to restrict the IP addresses which can login using a specific key.

Here's what one of my authorized_keys looks like:

from="192.0.2.2" ssh-rsa AAAAB3Nz...zvCn bot@example

You may also want to include the following options to each entry: no-X11-forwarding, no-user-rc, no-pty, no-agent-forwarding and no-port-forwarding.