Executing a command on remote machine using SSH is failing with the below error:
Traceback (most recent call last): File "ssh.py", line 4, in <module> ssh_client.connect(hostname='10.x.x.x', username='admin', password='password') File "/usr/lib/python3.6/site-packages/paramiko/client.py", line 407, in connect self, server_hostkey_name, server_key File "/usr/lib/python3.6/site-packages/paramiko/client.py", line 790, in missing_host_key key.get_name(), hostname, hexlify(key.get_fingerprint()) File "/usr/lib/python3.6/site-packages/paramiko/pkey.py", line 151, in get_fingerprint return md5(self.asbytes()).digest() ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS The code snippet I'm using is as follows:
import paramiko ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect(hostname='10.x.x.x', username='admin', password='password') command = "sudo sh ~/script.sh" ssh_client.exec_command(command) 11 Answer
I was facing this error too. This is because Paramiko uses MD5 encryption and the machine you want to connect to use FIPS, FIPS not allowed MD5 anymore.
So there is open PR in the Paramiko project.
In this issue above someone named neutronscott suggested editing the Pkey.py file.
Instead
return md5(self.asbytes()).digest() Change to
return md5(self.asbytes(), usedforsecurity=False).digest() So we can do something called 'Monkey patching'
Monkey patching is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code.
This is worked for me:
class _PkeyChild(paramiko.PKey): def get_fingerprint_improved(self): """ Declare that the use of MD5 encryption is not for security purposes. This declaration is to overcome connection to servers with FIPS security standards. """ return md5(self.asbytes(), usedforsecurity=False).digest() ...
paramiko.PKey.get_fingerprint = _PkeyChild.get_fingerprint_improved connection = paramiko.SSHClient() connection.set_missing_host_key_policy(paramiko.AutoAddPolicy()) connection.connect(hostname="host_name", username="username", password="password")