I have an old host that works as a NAS basically for backups. It has a linux inside and allows some (by then) fancy stuff out of the box. Recently I was leveraging it as a resource for backups via SSH and I ran into this error. Took me a bit to get the clue and a minimal explanation.
This small post explains it.
So the host I am trying to connect is a WesternDigital MyCloud 3TB that I already talked about. Let's call it backups
like how my local DNS knows it (its address is 192.168.1.241
). I stopped all services but the mandatory ones to perform the tasks of a NAS to host backups and hold a single share to communicate.
Later I researched a bit more to discover that I can actually log in properly through SSH and the idea was to also make it manage the backups from my fediverse instances with some scripts I'll create.
I am trying to connect from a Raspberry Pi 4 with Bullseye installed and a generated id_ed25519 key (just to be clear, but does not affect the case).
Trying to acces it from one of my Raspberry Pi machines, it quickly complained:
$ ssh root@backups
Unable to negotiate with 192.168.1.241 port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss
A quick internet search throw a post from StackOverflow that suggests the following in a our ~/.ssh/config
file:
Host backups
HostKeyAlgorithms +ssh-rsa
If you don't have this file, simply create it.
Wait, but I need to understand what's actually wrong...
In the same answer there is a quick explanation:
The traditional
ssh-rsa
andssh-dsa
algorithms use SHA-1 for signatures, either with RSA or with DSA. SHA-1 is presently considered very weak and practical attacks have been demonstrated on it. In addition, DSA in OpenSSH is limited to 1024-bit keys, which provide an inadequate 80-bit security level (128 bits is the minimum recommended level).As such, OpenSSH has disabled these algorithms because they are insecure, and if you are using them, the security of your connection cannot be assured. If possible, you should upgrade the firmware on your device to a newer version that will have appropriate patches applied. You should do this anyway, since if the version of the SSH server is old, it will probably have other security problems as well.
If you really cannot upgrade and you must continue to use this, then you can specify the configuration in your
~/.ssh/config
.
So I search for the directive and I find its description from the man pages:
HostKeyAlgorithms Specifies the protocol version 2 host key algorithms that the client wants to use in order of preference. The default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, ecdsa-sha2-nistp521-cert-v01@openssh.com, ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com, ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com, ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, ssh-rsa,ssh-dss If hostkeys are known for the destination host then this default is modified to prefer their algorithms.
... and a command to discover our current accepted host keys:
$ ssh -Q HostKeyAlgorithms
ssh-ed25519
ssh-ed25519-cert-v01@openssh.com
sk-ssh-ed25519@openssh.com
sk-ssh-ed25519-cert-v01@openssh.com
ecdsa-sha2-nistp256
ecdsa-sha2-nistp256-cert-v01@openssh.com
ecdsa-sha2-nistp384
ecdsa-sha2-nistp384-cert-v01@openssh.com
ecdsa-sha2-nistp521
ecdsa-sha2-nistp521-cert-v01@openssh.com
sk-ecdsa-sha2-nistp256@openssh.com
sk-ecdsa-sha2-nistp256-cert-v01@openssh.com
webauthn-sk-ecdsa-sha2-nistp256@openssh.com
ssh-dss
ssh-dss-cert-v01@openssh.com
ssh-rsa
ssh-rsa-cert-v01@openssh.com
rsa-sha2-256
rsa-sha2-256-cert-v01@openssh.com
rsa-sha2-512
rsa-sha2-512-cert-v01@openssh.com
Well, nice, but the error mentions ssh-rsa,ssh-dss
that I not only have, also they're part of the default values according to the docs.
Then, what happens?
At this point, trying to get a clue, I read the nice explanation in this post by Ikarus on a similar (and yet more complex) adventure on SSH interconnectivity, but in his case PubKeyAcceptedAlgorithms
was the key directive.
Long story short, we can check what HostKeyAlgorithms
do we use when connecting to a specific host with:
$ ssh -G root@backups | grep hostkeyalgorithms
hostkeyalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256
If you look closely the line, ssh-rsa
does not appear, so it is not used. Why? because as explained in the Ikaru's post my OpenSSH has it deprecated and does not actually use it.
When we apply the fix above the answer is:
$ ssh -G root@backups | grep hostkeyalgorithms
hostkeyalgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,sk-ssh-ed25519-cert-v01@openssh.com,sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ssh-ed25519@openssh.com,sk-ecdsa-sha2-nistp256@openssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa
So you can see that ssh-rsa
has been added at the end, therefore now usable in the communication.
I cared to specify a fix that works and does not introduce new issues. And I mention that because some other sites mentioned the following content for the ~/.ssh/config
file:
HostKeyAlgorithms ssh-rsa
PubkeyAcceptedKeyTypes ssh-rsa
This fix has 2 interconnected extra issues:
This means that from now on, all ssh communication will use ssh-rsa
discarding the previous set up. At least this should be with a plus +
sign so that ssh-rsa
is ADDED to the Host Keys and not REPLACING them.
This would make it unable to continue communicating with other systems with Ed25519
keys.
For example, a better approach would have been:
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa
Which in my tests it made me loose the connection to GitHub, as I was using Ed25519
to communicate to them.
The proposed fix should have focused to the connection we want to stablish. Taking in account that RSA has been tagged as insecure, we want to use it only where there is no other way, and this means to target the fix only to the intended host and no other one
For example:
Host backups
HostKeyAlgorithms ssh-rsa
PubkeyAcceptedKeyTypes ssh-rsa
Also, I found no change/benefit on applying the PubkeyAcceptedKeyTypes
, so I ended up discarding the directive when proposing the fix above.
So, finally, when the fix is applied, the communication happens successfully:
ssh root@backups
The authenticity of host 'backups (192.168.1.241)' can't be established.
RSA key fingerprint is SHA256:1234567890abcdef.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'backups' (RSA) to the list of known hosts.
root@backups's password:
Linux MyCloud-3TB 3.2.26 #1 SMP Thu Jul 9 11:14:15 PDT 2015 wd-2.4-rel armv7l
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
MyCloud-3TB:~#