The following is valid for OpenSSH_8.2p1 as shipped with Ubuntu 20.04.3 LTS “Focal Fossa”

Ciphers Suites

Similar to our Cipher Suite Selection we limit our SSH server to a safe and recommended set of encryption algorithms and set preferences as which ones are preferred over others.


The supported cipher suites depend on the used SSH software and version. Clients and servers must both share a common set of supported ciphers suites.

Host Key Algorithms

You can get a list of host key algorithms supported by your version of OpenSSH with the command:

$ ssh -Q key
  • ssh-ed25519

  • ssh-ed25519-cert-v01

  • sk-ssh-ed25519

  • sk-ssh-ed25519-cert-v01

Good algorithms, but weak implementation:
  • rsa-sha2-256

  • rsa-sha2-256-cert-v01

  • rsa-sha2-512

  • rsa-sha2-512-cert-v01

Avoid NIST P-curves:
  • ecdsa-sha2-nistp256

  • ecdsa-sha2-nistp256-cert-v01

  • ecdsa-sha2-nistp384

  • ecdsa-sha2-nistp384-cert-v01

  • ecdsa-sha2-nistp521

  • ecdsa-sha2-nistp521-cert-v01

  • sk-ecdsa-sha2-nistp256

  • sk-ecdsa-sha2-nistp256-cert-v01

Don’t use DSA (aka DSS) and SHA-1:
  • ssh-dss

  • ssh-dss-cert-v01

  • ssh-rsa

  • ssh-rsa-cert-v01

Key exchange (KEX)

You can get a list of key exchange algorithms supported by your version of OpenSSH with the command:

$ ssh -Q kex
  • curve25519-sha256

  • diffie-hellman-group-exchange-sha256

Probably OK:
  • diffie-hellman-group16-sha512

  • diffie-hellman-group18-sha512

Good Algorithm, but weak implementation:
  • diffie-hellman-group14-sha256

Avoid NIST-curves if better alternatives are available:
  • ecdh-sha2-nistp521

  • ecdh-sha2-nistp384

  • ecdh-sha2-nistp256

Don’t use SHA-1:
  • diffie-hellman-group1-sha1

  • diffie-hellman-group14-sha1

  • diffie-hellman-group-exchange-sha1

Experimental post-quantum hybrid key exchange methods based on Streamlined NTRU Prime coupled with X25519:
  • sntrup4591761x25519-sha512@

  • sntrup761x25519-sha512

Symmetric ciphers

You can check which symmetric ciphers are supported by your version of OpenSSH with the command:

$ ssh -Q cipher
Avoid CTR algorithms, if better alternatives are available:
  • aes256-ctr

  • aes192-ctr

  • aes128-ctr

Don’t use 3DES and CBC algorithms:

Message Authentication (MAC)

You can check which message integrity codes are supported by your version of OpenSSH with the command:

$ ssh -Q mac
Preferred Ecrypt-then-MAC (ETM):
Avoid if possible (weaker then ETM):
Don’t use:

Server Keys

After we improved our systems Entropy, its time to discard the old SSH server keys, who have been created by the Ubuntu server installation process, with a fresh set

Note that we only create ed25519 and RSA keys. Other types are not recommended.

The supported key types depend on the SSH software version. Both client and server must support it. You can check which key types are supported by your version of OpenSSH with the command ssh -Q key.

$ sudo rm  /etc/ssh/ssh_host_*key*
$ sudo  ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
$ sudo  ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""


Don’t forget to re-distribute the new server public keys to any SSH clients you connect to from this host.

To output DNS server records of you keys:

$ ssh-keygen -r -f
$ ssh-keygen -r -f

Client Keys

As with the SSH server keys, we generate a fresh set of ed25519 and RSA client keys for our own user-profile:

$ rm ~/.ssh/id_* .ssh/id_*.pub
$ ssh-keygen -t ed25519
$ ssh-keygen -t rsa -b 4096

The same has to be done also for the root user:

$ sudo rm /root/.ssh/id_* /root/.ssh/id_*.pub
$ sudo -sH ssh-keygen -t ed25519
$ sudo -sH ssh-keygen -t rsa -b 4096

As well as for all other profiles on the system, who will initiate SSH client connections out of this system:

$ sudo rm /home/<username>/.ssh/id_* /home/<username>/.ssh/id_*.pub
$ sudo -u <username> -sH ssh-keygen -t ed25519
$ sudo -u <username> -sH ssh-keygen -t rsa -b 4096


Don’t forget to re-distribute your public client keys to any SSH servers you connect to from this host.

SSH Server Configuration

Allowed User Group

Create a user-group which later will be used to control who can access the server trough SSH:

$ groupadd sshlogin

Don’t forget to add yourself:

$ sudo adduser $USER sshlogin

Server Configuration File

The server settings are stored in /etc/ssh/sshd_config. Change according to the example below.

The complete configuration file described here is available for download also.

Include Files

# Included files will override any options defined furher below
Include /etc/ssh/sshd_config.d/*.conf

# -------------------------------------

Network and Protocol Settings

By changing the default TCP listening port, we avoid thousands of malicious login attempts every day.


Changing the TCP listening port is not a security feature, but keeps our logs more readable by avoiding this kind of junk.

It also helps, if you have multiple servers in your LAN behind a NAT.

The following bash shell command will return a random TCP port number, which is unlikely to interfere with other services on your server:

$ shuf -i 49152-65535 -n 1

Add this port to your configuration:

# -------------------------------------
# Network and Protocol
# -------------------------------------
# On which TCP ports we listen for SSH client connections
Port 63508

# On which interfaces and IP addresses we listen for SSH client connections
#ListenAddress ::

# -------------------------------------

Server Authentication

They point to our newly created set of ed25519 and RSA host keys:

# -------------------------------------
# Server Authentication
# -------------------------------------

# HostKeys for protocol version 2 - by order of preference
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key

# The host key algorithms that the server will offer
HostKeyAlgorithms ssh-ed25519,,,,rsa-sha2-256,rsa-sha2-512,,

# -------------------------------------

Client and User Authentication

  1. The root user is not allowed at all to login remotely.

  2. Users need a properly installed a SSH public-key.

  3. Other type of authentication, like passwords, are not allowed.

  4. Only members of the specified user-group are allowed.

# -------------------------------------
# Client and User Authentication
# -------------------------------------

# Root login is not allowed for auditing reasons.
# Regular user logins combined with "sudo" ensures a clear audit track.
PermitRootLogin no
#PermitRootLogin without-password

# Only public-key based logins are allowed. Disables password based logins.
AuthenticationMethods publickey

# Don't allow challenge-response passwords
ChallengeResponseAuthentication no

# Disable tunneled clear text passwords
PasswordAuthentication no

# Enable PAM authentication
# If enabled, make sure that 'PasswordAuthentication' and
# 'ChallengeResponseAuthentication' are both set to 'no'.
UsePAM yes

# Don't print /etc/motd when a user logs in
PrintMotd no

# Only users who are member of the following groups are allowed to login
AllowGroups sshlogin

# -------------------------------------

Ciphers Suites Selections

# -------------------------------------
# Ciphers Suites Selections
# -------------------------------------

# Key Exchange (KEX) Algorithms
KexAlgorithms curve25519-sha256,,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512

# Symmetric ciphers

# Message authentication

# -------------------------------------

Other Settings

# -------------------------------------
# Allowed Client Features
# -------------------------------------

# Whether X11 forwarding is permitted
X11Forwarding no

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

# Secure File Transfer Protocol
Subsystem sftp /usr/lib/openssh/sftp-server

# Remove any existing Unix-domain socket file for local or remote port
# forwarding before creating a new one. The default is no.
StreamLocalBindUnlink yes

# -*- mode: ssh_config; indent-tabs-mode: nil; tab-width: 4; -*-

Restart SSH Server


Please be advised that any change in the SSH-Settings of your server might cause problems connecting to the server or starting/reloading the SSH-Daemon itself. So every time you configure your SSH-Settings on a remote server via SSH itself, ensure that you have a second open connection to the server, which you can use to reset or adapt your changes!

After the new host keys and server configurations are in place, restart the SSH server:

$ sudo systemctl reload ssh

SSH Client Configuration

There will be SSH connections out of the server to other SSH servers (i.e. for storing backups or accessing remote files). In that case, the server-system acts as a client to a remote SSH server. Therefore also a “server” needs a well configured SSH client.

The system-wide default client settings are stored in /etc/ssh/ssh_config. Change according to the example below:

Host *
    UseRoaming no



If you domain is not secured with DNSSEC, you should NOT use this feature, as the information received by the clients over DNS can not be trusted.

The hash of the SSH server keys can be published in DNSSEC secured domains.

By publishing a fingerprint of your SSH server public keys in DNS, connecting clients can verify the server identity, without the need to distribute and update your server public keys on all clients.

As of now RSA and ed25519 keys can both be published in DNS according to the IANA assignments DNS SSHFP Resource Record Parameters.


Show DNS Record

The ssh-key-gen utility can be used to display the fingerprints of you host keys pre-formatted for publishing in DNS:

$ ssh-keygen -r -f /etc/ssh/ IN SSHFP 1 1 de63........................0851 IN SSHFP 1 2 466b................................e409

The first line shows the SHA-1 fingerprint and the second line the SHA-256 fingerprint of our RSA key.

If you use PowerDNS server with the Poweradmin web interface, add the SHA-256 record as follows:






1 2 466b…………………………..e409

Don’t add any SHA-1 reocrds.


The SSH Audit website audits the configuration of any SSH server or client and highlights the areas needing improvement.

The CryptCheck website has an online SSH server test.

System Administration over SSH

Since we have now working SSH agent forwarding on our own fully trusted systems, we can take the advantage and solve one if the most annoying system administration problems. In theory system administration should be done in the following way:

  • Don’t use passwords.

  • Don’t allow root login.

  • Use sudo for adminstative tasks.

In practice this is rarely the case:

  • Administrators use SSH keys to login on the remote system, but then need a password for executing sudo operations.

  • sudo is configured to execute administrative task with “NOPASSWD”

  • Administrators login as root to edit and transfer files remotely.

The PAM SSH Agent Authentication module permits PAM authentication via your keyring in a forwarded ssh-agent.

This module can be used to provide authentication for anything run locally that supports PAM. It was written specifically with the intention of permitting authentication for sudo without password entry, and also has been proven useful for use with su as an alternative to wheel.


The PAM module is installable from the Ubuntu sofware repositories:

$ sudo apt install libpam-ssh-agent-auth



Whenever you work on the PAM configuration of your system, there is a risk of locking yourself out!

  • Login as root user if you change configurations for sudo.

  • Use sudo if you change configurations for login.

  • Make sure any @include file exists and is not creating any errors.

Open the :/etc/sudoers file using the following method:

$ sudo visudo

Then change it as follows:

# This file MUST be edited with the 'visudo' command as root.
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
# See the man page for details on how to write a sudoers file.
Defaults        editor=/usr/bin/nano
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

# Required by pam_ssh_agent_auth
Defaults        env_keep += "SSH_AUTH_SOCK"

The configuration is described in its manpage pam_ssh_agent_auth(8).

Create the file /etc/pamd.d/ssh-agent-auth:

# pam_ssh_agent_auth - PAM module for granting permissions based on SSH agent requests
auth sufficient file=/etc/secuurity/authorized_keys

This can then be included in other PAM configurations, where needed.

Edit the file /etc/pamd.d/sudo:


session    required readenv=1 user_readenv=0
session    required readenv=1 envfile=/etc/default/locale user_readenv=0
@include u2f
@include ssh-agent-auth
@include common-auth
@include common-account
@include common-session-noninteractive

Also add it towards the end of the file /etc/pamd.d/su:

# The standard Unix authentication modules, used with
# NIS (man nsswitch) as well as normal /etc/passwd and
# /etc/shadow entries.
@include ssh-agent-auth
@include common-auth
@include common-account
@include common-session