Are you using paramiko as a client or server?
Client
What feature(s) aren't working right?
Keys/auth
What version(s) of paramiko are you using?
3.3.1
What version(s) of Python are you using?
3.8.10
What operating system and version are you using?
WSL on Windows 11 and Linux
If you're connecting as a client, which SSH server are you connecting to?
Linux VM
If you're using paramiko as part of another tool, which tool/version?
No response
Expected/desired behavior
Hi - the background for this issue is that in our use case we needed to explicitly limit the set of allowed algorithms to a subset of the default, for example not allowing ssh-rsa because it uses sha1 which is insecure (rsa-sha2-256 is fine). For testing we've set up a test VM with ssh options set so that the only signature algorithm it will offer is sha1.
The following should fail, whether we include the hostkey argument in t.connect or not:
import paramiko
k = paramiko.RSAKey.from_private_key_file("tw4-peri-azure-store-ssh-id.key")
t = paramiko.Transport("10.216.0.10")
secopts = t.get_security_options()
secopts.key_types = ['rsa-sha2-256', 'ecdsa-sha2-nistp256']
t.connect(username="azureuser", pkey=k)
Exception (client): Incompatible ssh peer (no acceptable host key)
Traceback (most recent call last):
File "/home/developer/.local/lib/python3.8/site-packages/paramiko/transport.py", line 2159, in run
self._handler_table[ptype](m)
File "/home/developer/.local/lib/python3.8/site-packages/paramiko/transport.py", line 2279, in _negotiate_keys
self._parse_kex_init(m)
File "/home/developer/.local/lib/python3.8/site-packages/paramiko/transport.py", line 2495, in _parse_kex_init
raise IncompatiblePeer(
paramiko.ssh_exception.IncompatiblePeer: Incompatible ssh peer (no acceptable host key)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/developer/.local/lib/python3.8/site-packages/paramiko/transport.py", line 1369, in connect
self.start_client()
File "/home/developer/.local/lib/python3.8/site-packages/paramiko/transport.py", line 722, in start_client
raise e
File "/home/developer/.local/lib/python3.8/site-packages/paramiko/transport.py", line 2159, in run
self._handler_table[ptype](m)
File "/home/developer/.local/lib/python3.8/site-packages/paramiko/transport.py", line 2279, in _negotiate_keys
self._parse_kex_init(m)
File "/home/developer/.local/lib/python3.8/site-packages/paramiko/transport.py", line 2495, in _parse_kex_init
raise IncompatiblePeer(
paramiko.ssh_exception.IncompatiblePeer: Incompatible ssh peer (no acceptable host key)
However, if we specify a host key to verify against, it connects successfully:
import base64
hk = paramiko.PKey.from_type_string("ssh-rsa", base64.b64decode("..."))
# The `ssh-rsa` here is just the key type - this key will still work with rsa-sha2-* (if the server accepts it)
>>> t = paramiko.Transport("10.216.0.10")
secopts = t.get_security_options()
secopts.key_types = ['rsa-sha2-256', 'ecdsa-sha2-nistp256']
t.connect(username="azureuser", pkey=k, hostkey=hk)
>>> t
<paramiko.Transport at 0xdc47f490 (cipher aes128-ctr, 128 bits) (active; 0 open channel(s))>
>>> cl = paramiko.SFTPClient.from_transport(t)
>>> cl.listdir("/")
['opt', 'var', 'tmp', 'mnt', 'etc', 'sbin', 'sys', 'boot', 'srv', 'run', 'media', 'lib64', 'dev', 'lib32', 'proc', 'home', 'lib', 'root', 'libx32', 'lost+found', 'usr', 'bin']
Actual behavior
Connection should fail even when a host key is specified, as we did not include ssh-rsa (i.e. the sha1 version of rsa-sha2-*) in the security options.
How to reproduce
See above log. The server setup is basically adding the following line to sshd_config:
HostKeyAlgorithms ssh-rsa
Anything else?
I think the likely reason for this issue is in this bit of code:
|
if isinstance(hostkey, RSAKey): |
|
self._preferred_keys = [ |
|
"rsa-sha2-512", |
|
"rsa-sha2-256", |
|
"ssh-rsa", |
|
] |
|
else: |
|
self._preferred_keys = [hostkey.get_name()] |
It should not override _preferred_keys completely, but instead choose a subset of the existing _preferred_keys previously set by SecurityOptions
Are you using paramiko as a client or server?
Client
What feature(s) aren't working right?
Keys/auth
What version(s) of paramiko are you using?
3.3.1
What version(s) of Python are you using?
3.8.10
What operating system and version are you using?
WSL on Windows 11 and Linux
If you're connecting as a client, which SSH server are you connecting to?
Linux VM
If you're using paramiko as part of another tool, which tool/version?
No response
Expected/desired behavior
Hi - the background for this issue is that in our use case we needed to explicitly limit the set of allowed algorithms to a subset of the default, for example not allowing
ssh-rsabecause it uses sha1 which is insecure (rsa-sha2-256is fine). For testing we've set up a test VM with ssh options set so that the only signature algorithm it will offer is sha1.The following should fail, whether we include the
hostkeyargument int.connector not:However, if we specify a host key to verify against, it connects successfully:
Actual behavior
Connection should fail even when a host key is specified, as we did not include
ssh-rsa(i.e. the sha1 version of rsa-sha2-*) in the security options.How to reproduce
See above log. The server setup is basically adding the following line to sshd_config:
Anything else?
I think the likely reason for this issue is in this bit of code:
paramiko/paramiko/transport.py
Lines 1354 to 1361 in d5117fc
It should not override
_preferred_keyscompletely, but instead choose a subset of the existing_preferred_keyspreviously set bySecurityOptions