To fully understand how to configure the algorithms, it is essential to have a basic understanding of the SSH protocol and how OTP SSH app handles the corresponding items
The first subsection will give a short background of the SSH protocol while later sections describes the implementation and provides some examples
SSH uses different sets of algorithms in different phases of a session. Which
algorithms to use is negotiated by the client and the server at the beginning of a session.
See
The negotiation is simple: both peers sends their list of supported alghorithms to the other part. The first algorithm on the client's list that also in on the server's list is selected. So it is the client's orderering of the list that gives the priority for the algorithms.
There are five lists exchanged in the connection setup. Three of them are also divided in two directions, to and from the server.
The lists are (named as in the SSH application's options):
Key exchange.
An algorithm is selected for computing a secret encryption key. Among examples are:
the old nowadays week
Server host key
The asymetric encryption algorithm used in the server's private-public host key pair.
Examples include the well-known RSA
Symetric cipher algorithm used for the payload encryption. This algorithm will use the key calculated
in the kex phase (together with other info) to genereate the actual key used. Examples are
tripple-DES
This list is actually two - one for each direction server-to-client and client-to-server. Therefore it is possible but rare to have different algorithms in the two directions in one connection.
Message authentication code
"Check sum" of each message sent between the peers. Examples are SHA
This list is also divided into two for the both directions
If and how to compress the message. Examples are
This list is also divided into two for the both directions
The set of algorithms that the SSH app uses by default depends on the algoritms supported by the:
The cryptolib OTP is linked with, usally the one the OS uses, probably OpenSSL,
and finaly what the SSH app implements
Due to this, it impossible to list in documentation what algorithms that are available in a certain installation.
There is an important command to list the actual algorithms and their ordering:
0> ssh:default_algorithms().
[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['aes256-gcm@openssh.com',
'aes256-ctr','aes192-ctr','aes128-gcm@openssh.com',
'aes128-ctr','aes128-cbc','3des-cbc']},
{server2client,['aes256-gcm@openssh.com','aes256-ctr',
'aes192-ctr','aes128-gcm@openssh.com','aes128-ctr',
'aes128-cbc','3des-cbc']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',zlib]}]}]
To change the algorithm list, there are two options which can be used in
The options are
See the
Here follows a series of examples ranging from simple to more complex.
To forsee the effect of an option there is an experimental function
Replace the kex algorithms list with the single algorithm
1> ssh:chk_algos_opts(
[{preferred_algorithms,
[{kex, ['diffie-hellman-group14-sha256']}
]
}
]).
[{kex,['diffie-hellman-group14-sha256']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['aes256-gcm@openssh.com',
'aes256-ctr','aes192-ctr','aes128-gcm@openssh.com',
'aes128-ctr','aes128-cbc','3des-cbc']},
{server2client,['aes256-gcm@openssh.com','aes256-ctr',
'aes192-ctr','aes128-gcm@openssh.com','aes128-ctr',
'aes128-cbc','3des-cbc']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',zlib]}]}]
Note that the unmentioned lists (
In the lists that are divided in two for the two directions (c.f
2> ssh:chk_algos_opts(
[{preferred_algorithms,
[{cipher,['aes128-ctr']}
]
}
]).
[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['aes128-ctr']},
{server2client,['aes128-ctr']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',zlib]}]}]
Note that both lists in
In the lists that are divided in two for the two directions (c.f
3> ssh:chk_algos_opts(
[{preferred_algorithms,
[{cipher,[{client2server,['aes128-ctr']}]}
]
}
]).
[{kex,['ecdh-sha2-nistp384','ecdh-sha2-nistp521',
'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['aes128-ctr']},
{server2client,['aes256-gcm@openssh.com','aes256-ctr',
'aes192-ctr','aes128-gcm@openssh.com','aes128-ctr',
'aes128-cbc','3des-cbc']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',zlib]}]}]
It is of course possible to change more than one list:
4> ssh:chk_algos_opts(
[{preferred_algorithms,
[{cipher,['aes128-ctr']},
{mac,['hmac-sha2-256']},
{kex,['ecdh-sha2-nistp384']},
{public_key,['ssh-rsa']},
{compression,[{server2client,[none]},
{client2server,[zlib]}]}
]
}
]).
[{kex,['ecdh-sha2-nistp384']},
{public_key,['ssh-rsa']},
{cipher,[{client2server,['aes128-ctr']},
{server2client,['aes128-ctr']}]},
{mac,[{client2server,['hmac-sha2-256']},
{server2client,['hmac-sha2-256']}]},
{compression,[{client2server,[zlib]},
{server2client,[none]}]}]
Note that the ordering of the tuples in the lists didn't matter.
A situation where it might be useful to add an algorithm is when one need to use a supported but disabled one.
An example is the
The option
To facilitate addition or removal of algorithms the option
The option takes a list with instructions to append, prepend or remove algorithms:
{modify_algorithms, [{append, ...},
{prepend, ...},
{rm, ...}
]}
Each of the
As an example let's add the Diffie-Hellman Group1 first in the kex list. It is supported according to
5> ssh:chk_algos_opts(
[{modify_algorithms,
[{prepend,
[{kex,['diffie-hellman-group1-sha1']}]
}
]
}
]).
[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384',
'ecdh-sha2-nistp521','ecdh-sha2-nistp256',
'diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
'ecdsa-sha2-nistp256','ssh-rsa','rsa-sha2-256',
'rsa-sha2-512','ssh-dss']},
{cipher,[{client2server,['aes256-gcm@openssh.com',
'aes256-ctr','aes192-ctr','aes128-gcm@openssh.com',
'aes128-ctr','aes128-cbc','3des-cbc']},
{server2client,['aes256-gcm@openssh.com','aes256-ctr',
'aes192-ctr','aes128-gcm@openssh.com','aes128-ctr',
'aes128-cbc','3des-cbc']}]},
{mac,[{client2server,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']},
{server2client,['hmac-sha2-256','hmac-sha2-512',
'hmac-sha1']}]},
{compression,[{client2server,[none,'zlib@openssh.com',zlib]},
{server2client,[none,'zlib@openssh.com',zlib]}]}]
And the result shows that the Diffie-Hellman Group1 is added at the head of the kex list
In this example, we in put the 'diffie-hellman-group1-sha1' first and also move the
6> ssh:chk_algos_opts(
[{modify_algorithms,
[{prepend,
[{kex, ['diffie-hellman-group1-sha1']}
]},
{append,
[{kex, ['ecdh-sha2-nistp521']}
]}
]
}
]).
[{kex,['diffie-hellman-group1-sha1','ecdh-sha2-nistp384',
'ecdh-sha2-nistp256','diffie-hellman-group-exchange-sha256',
'diffie-hellman-group16-sha512',
'diffie-hellman-group18-sha512',
'diffie-hellman-group14-sha256',
'diffie-hellman-group14-sha1',
'diffie-hellman-group-exchange-sha1','ecdh-sha2-nistp521']},
{public_key,['ecdsa-sha2-nistp384','ecdsa-sha2-nistp521',
.....
]
Note that the appended algorithm is removed from its original place and then appended to the same list.
In this example, we use both options (
7> ssh:chk_algos_opts(
[{preferred_algorithms,
[{cipher,['aes128-ctr']},
{mac,['hmac-sha2-256']},
{kex,['ecdh-sha2-nistp384']},
{public_key,['ssh-rsa']},
{compression,[{server2client,[none]},
{client2server,[zlib]}]}
]
},
{modify_algorithms,
[{prepend,
[{kex, ['some unsupported algorithm']}
]},
{append,
[{kex, ['diffie-hellman-group1-sha1']}
]}
]
}
]).
[{kex,['ecdh-sha2-nistp384','diffie-hellman-group1-sha1']},
{public_key,['ssh-rsa']},
{cipher,[{client2server,['aes128-ctr']},
{server2client,['aes128-ctr']}]},
{mac,[{client2server,['hmac-sha2-256']},
{server2client,['hmac-sha2-256']}]},
{compression,[{client2server,[zlib]},
{server2client,[none]}]}]
It is of course questionable why anyone would like to use the both these options together, but it is possible if an unforeseen need should arise.