Open pghmcfc opened 1 year ago
Thanks for transferring this report over here, we never would have seen it otherwise.
If I understand correctly what's going on, this error occurs because a server is crafting its host keys with an obsolete, insecure hashing algorithm, in SHA1.
Isn't.... the best solution here to upgrade the server so that it can use a modern, secure algorithm? Instead of changing paramiko to blithely ignore a security-relevant error raised out of cryptography
?
I recognize that a server host key isn't on the same level of importance as an SSL key pair, since server host keys aren't usually backed by third-party CA certs and such, but this seems like an imprudent way to handle the situation.
Rather than accepting this connection by default and warning about an obsolete key being ignored, it seems to me a better solution would be an 'opt in' flag that a user would have to specify... a skip_host_key_verification
boolean or something.
What do you think?
@bskinn, I've updated the bugzilla ticket with your comment so we can get the original reporter's response. I personally would be happy enough with an option to ignore this issue. Regarding updating the server, that may be very tricky in some cases, such as for an embedded device with a server that doesn't support anything more modern in terms of key algorithms.
I've updated the bugzilla ticket with your comment so we can get the original reporter's response.
Great, thanks!
I personally would be happy enough with an option to ignore this issue.
:+1:, it seems to me that's the best approach for the 2.x maintenance line. We'd welcome a PR from anyone interested in working on it.
Do you know, would the new experimental auth strategy features allow user-side handling of this hitch? (3.2 CHANGELOG, scroll down to the first red callout.) One of the big goals of that new machinery (including some as-yet-unimplemented pieces) is to allow users to cope with their hardware weirdness themselves, instead of fixes needed upstream.
We'd also welcome help here, again from anyone interested, testing those new experimental features to see if they can resolve this.
Regarding updating the server, that may be very tricky in some cases, such as for an embedded device with a server that doesn't support anything more modern in terms of key algorithms.
I know, cognitively, that this is a problem, but I've never dealt with it myself and so I keep forgetting to consider it.
Can you help me out by providing some concrete examples of embedded devices like this? Control hardware for chemical process industry? Manufacturing equipment? IoT? Controllers in cars? The specificity will help the category stick in mind.
Can you help me out by providing some concrete examples of embedded devices like this? Control hardware for chemical process industry? Manufacturing equipment? IoT? Controllers in cars? The specificity will help the category stick in mind.
I don't have anything that I use paramiko with. However, I have a couple of Ubiquity WiFi access points (which get regular updates by the way, unusual for this sort of device I think) and I can access them via openssh but I need entries like these in my ~/.ssh/config
:
Host front.ap-ac-lr
HostName front.ap-ac-lr.intranet.example.com
User paul
IdentityFile ~/.ssh/id_rsa
PubkeyAcceptedAlgorithms +ssh-rsa
RequiredRSASize 1024
Host rear.ap-ac-lr
HostName rear.ap-ac-lr.intranet.example.com
User paul
IdentityFile ~/.ssh/id_rsa
PubkeyAcceptedAlgorithms +ssh-rsa
RequiredRSASize 1024
Feedback from reporter:
Of course the best solution is to upgrade the server, but sometimes this isn't a valid option. Either because the server is a proprietary blackbox or it must be kept at a specific stable version, or, simply because noone cared to provide an update to the software to support other algorithms yet. In my case it's about jenkins, it seems only to support rsa sha1 hostkeys for the ssh configuration interface.
Sure, I'm fine with a "skip_host_key_verification" flag if this covers outdated algorithms as well (and not only stuff like mismatching fingerprints).
Thanks!
Ok, sounds like a 'skip' option would be viable for everyone in the conversation here.
And yes, I would expect a skip flag would skip the verification entirely. Certainly that's the first implementation I'd recommend, and we would consider more granular skip-or-not controls once we determined they're not YAGNI.
I'm going to flag this for bitprophet to review at whatever point in the future he does a pass on the flag, so he can weigh in.
But, I'm confident enough in the feature to request anyone interested prepare a PR to implement this.
@gubenkoved -- I think you're looking at the wrong part of the codebase.
id_*
keys are for client authentication, confirming to the server the identity of the client seeking a connection.
The issue here is host validation -- confirming to the client that the server is who they are expecting to be connecting to.
Also, if the underlying cryptography
library in the relevant context doesn't support SHA1, then I don't think it really matters if paramiko
still does. OP's exception is being raised from within cryptography
.
Thank you for your answer, @bskinn! I've removed my comment before you replied as I realised sources of my own confusion here.
In my particular case I was able to work around this issue supplying ssh-rsa
algorithm as disabled_algorithms
to SSHClient.connect
methods.
Additionally, I beleive similar issue can appear for the "client authentication" part of the paramiko as well. Here is the sample traceback. I also want to mention FIPS OpenSSL provider as a reason of SHA1 not being available as RSA digest algorithm in my case.
80BBFC66117F0000:error:1C8000AE:Provider routines:rsa_setup_md:digest not allowed:../../source/openssl-3.0.8-provider/providers/implementations/signature/rsa_sig.c:304:digest=sha1
Traceback (most recent call last):
File "/usr/local/lib/python3.10/dist-packages/paramiko/transport.py", line 2164, in run
handler(self.auth_handler, m)
File "/usr/local/lib/python3.10/dist-packages/paramiko/auth_handler.py", line 395, in _parse_service_accept
sig = self.private_key.sign_ssh_data(blob, algorithm)
File "/usr/local/lib/python3.10/dist-packages/paramiko/rsakey.py", line 126, in sign_ssh_data
sig = self.key.sign(
File "/usr/local/lib/python3.10/dist-packages/cryptography/hazmat/backends/openssl/rsa.py", line 513, in sign
return _rsa_sig_sign(self._backend, padding, algorithm, self, data)
File "/usr/local/lib/python3.10/dist-packages/cryptography/hazmat/backends/openssl/rsa.py", line 275, in _rsa_sig_sign
pkey_ctx = _rsa_sig_setup(
File "/usr/local/lib/python3.10/dist-packages/cryptography/hazmat/backends/openssl/rsa.py", line 236, in _rsa_sig_setup
raise UnsupportedAlgorithm(
cryptography.exceptions.UnsupportedAlgorithm: sha1 is not supported by this backend for RSA signing.
This issue was originally reported in Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2214984
When connecting to an ssh server that provides an rsa host key and the host key is known (either by a known_hosts file or by previous connection attempts), paramiko fails with "cryptography.exceptions.UnsupportedAlgorithm: sha1 is not supported by this backend for RSA signing", giving the following traceback:
This is with paramiko 2.12.0 on Red Hat Enterprise Linux 9 (or a clone thereof), where sha1 is not supported for cryptographic operations.
Steps to Reproduce:
Actual results: the first connect succeeds, the second connect fails with the trace above.
Expected results: both connects successful
The original reporter provided a couple of attachments to help reproduce this issue, running an ssh server in a container. I can attach those and the accompanying instructions here if it's helpful.
My initial thought is that paramiko should trap this exception and treat the case the same as if the host key was not found, possibly providing some warning that that had happened so that users would understand why an existing key was ignored.