OpenSSH crypto configuration
Note:
This documentation has moved to a new home! Please update your bookmarks to the new URL for the up-to-date version of this page.
Establishing an SSH connection to a remote service involves multiple stages. Each one of these stages will use some form of encryption, and there are configuration settings that control which cryptographic algorithms can be used at each step.
The default selection of algorithms for each stage should be good enough for the majority of deployment scenarios. Sometimes, however, a compliance rule, or a set of legacy servers, or something else, requires a change in this selection. Perhaps a legacy system or piece of hardware that is still in production is not compatible with the current encryption schemes and requires legacy algorithms to be enabled again. Or a compliance rule that isn’t up-to-date with the current crypto standards doesn’t allow a more advanced cipher.
WARNING:
Be careful when restricting cryptographic algorithms in SSH, specially on the server side. You can inadvertently lock yourself out of a remote system!
Algorithm configuration general rules
Most of the configuration options that take a list of cryptographic algorithms follow a defined set of rules. The first algorithm in the list (that the client offers to the server) that matches an offer from the server, is what will be selected. The rules are as follows:
-
The lists are algorithm names separated by commas. For example,
Ciphers [email protected],[email protected]
will replace the current set of ciphers with the two named algorithms. -
Instead of specifying the full list, which will replace the existing default one, some manipulations are allowed. If the list starts with:
-
+
The specified algorithm(s) will be appended to the end of the default set. For example,MACs +hmac-sha2-512,hmac-sha2-256
will append both Message Authentication Code (MAC) algorithms to the end of the current set. -
-
The specified algorithm(s) will be removed from the default set. For example,KexAlgorithms -diffie-hellman-group1-sha1,diffie-hellman-group14-sha1
will remove both key exchange algorithms from the current set. -
^
The specified ciphers will be placed at the beginning of the default set. For example,PubkeyAcceptedAlgorithms ^ssh-ed25519,ecdsa-sha2-nistp256
will move both signature algorithms to the start of the set. -
Wildcards (
*
) are also allowed, but be careful to not inadvertently include or exclude something that wasn’t intended.
-
With rare exceptions, the list of algorithms can be queried by running ssh -Q <config>
, where <config>
is the configuration setting name. For example, ssh -Q ciphers
will show the available list of ciphers.
Note:
The output of thessh -Q <name>
command will not take into consideration the configuration changes that may have been made. It cannot therefore be used to test the crypto configuration changes.
Configuration settings
It’s not the goal of this documentation to repeat the excellent upstream documentation (see the References section at the end of this page). Instead, we will show the configuration options, and some examples of how to use them.
Here are the configuration settings that control the cryptographic algorithms selection. Unless otherwise noted, they apply to both the server and the client.
-
Ciphers
List of symmetric ciphers. Examples includeaes256-ctr
and[email protected]
. -
MACs
List of Message Authentication Code algorithms, used for data integrity protection. The-etm
versions calculate the MAC after encryption and are considered safer. Examples includehmac-sha2-256
and[email protected]
. -
GSSAPIKexAlgorithms
This option is not available in OpenSSH upstream, and is provided via a patch that Ubuntu and many other Linux Distributions carry. It lists the key exchange (kex) algorithms that are offered for Generic Security Services Application Program Interface (GSSAPI) key exchange, and only applies to connections using GSSAPI. Examples includegss-gex-sha1-
andgss-group14-sha256-
. -
KexAlgorithms
List of available key exchange (kex) algorithms. Examples includecurve25519-sha256
and[email protected]
. -
HostKeyAlgorithms
This is a server-only configuration option. It lists the available host key signature algorithms that the server offers. Examples include[email protected]
and[email protected]
. -
PubkeyAcceptedAlgorithms
List of signature algorithms that will be accepted for public key authentication. Examples include[email protected]
and[email protected]
. -
CASignatureAlgorithms
List of algorithms that certificate authorities (CAs) are allowed to use to sign certificates. Certificates signed using any other algorithm will not be accepted for public key or host-based authentication. Examples includessh-ed25519
andecdsa-sha2-nistp384
.
To check what effect a configuration change has on the server, it’s helpful to use the -T
parameter and grep
the output for the configuration key you want to inspect. For example, to check the current value of the Ciphers
configuration setting after having set Ciphers ^3des-cbc
in sshd_config
:
$ sudo sshd -T | grep ciphers
ciphers 3des-cbc,[email protected],aes128-ctr,aes192-ctr,aes256-ctr,[email protected],[email protected]
The output will include changes made to the configuration key. There is no need to restart the service.
OpenSSH examples
Here are some examples of how the cryptographic algorithms can be selected in OpenSSH.
Which cipher was used?
One way to examine which algorithm was selected is to add the -v
parameter to the ssh
client.
For example, assuming password-less public key authentication is being used (so no password prompt), we can use this command to initiate the connection and exit right away:
$ ssh -v <server> exit 2>&1 | grep "cipher:"
debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none
debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none
In the above case, the chacha20
cipher was automatically selected. We can influence this decision and only offer one algorithm:
$ ssh -v -c aes128-ctr <server> exit 2>&1 | grep "cipher:"
debug1: kex: server->client cipher: aes128-ctr MAC: [email protected] compression: none
debug1: kex: client->server cipher: aes128-ctr MAC: [email protected] compression: none
For the other stages in the ssh
connection, like key exchange, or public key authentication, other expressions for the grep
command have to be used. In general, it will all be visible in the full -v
output.
Remove AES 128 from server
Let’s configure an OpenSSH server to only offer the AES 256 bit variant of symmetric ciphers for an ssh
connection.
First, let’s see what the default is:
$ sudo sshd -T | grep ciphers
ciphers [email protected],aes128-ctr,aes192-ctr,aes256-ctr,[email protected],[email protected]
Now let’s make our change. On the server, we can edit /etc/ssh/sshd_config
and add this line:
Ciphers -aes128*
And then check what is left:
$ sudo sshd -T | grep ciphers
ciphers [email protected],aes192-ctr,aes256-ctr,[email protected]
To activate the change, ssh
has to be restarted:
$ sudo systemctl restart ssh.service
After we restart the service, clients will no longer be able to use AES 128 to connect to it:
$ ssh -c aes128-ctr <server>
Unable to negotiate with 10.0.102.49 port 22: no matching cipher found. Their offer: [email protected],aes192-ctr,aes256-ctr,[email protected]
Prioritise AES 256 on the client
If we just want to prioritise a particular cipher, we can use the “^
” character to move it to the front of the list, without disabling any other cipher:
$ ssh -c ^aes256-ctr -v <server> exit 2>&1 | grep "cipher:"
debug1: kex: server->client cipher: aes256-ctr MAC: [email protected] compression: none
debug1: kex: client->server cipher: aes256-ctr MAC: [email protected] compression: none
In this way, if the server we are connecting to does not support AES 256, the negotiation will pick up the next one from the list. If we do that on the server via Ciphers -aes256*
, this is what the same client, with the same command line, now reports:
$ ssh -c ^aes256-ctr -v <server> exit 2>&1 | grep "cipher:"
debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none
debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none