Verify host key with pysftp

pysftp private key example
paramiko.ssh_exception.sshexception: bad host key from server
pysftp scp
pysftp slow
pysftp failed to load hostkey
pysftp vs paramiko
pysftp github
sftp host key

I am writing a program using pysftp, and it wants to verify the SSH host Key against C:\Users\JohnCalvin\.ssh\known_hosts.

Using PuTTY, the terminal program is saving it to the Registry [HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys].

How do I reconcile the difference between pysftp and PuTTY?

My code is:

import pysftp as sftp

def push_file_to_server():
    s = sftp.Connection(host='138.99.99.129', username='root', password='*********')
    local_path = "testme.txt"
    remote_path = "/home/testme.txt"

    s.put(local_path, remote_path)
    s.close()

push_file_to_server()

The Error Response I am receiving is:

E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init__.py:61: UserWarning: Failed to load HostKeys from C:\Users\JohnCalvin.ssh\known_hosts. You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None). warnings.warn(wmsg, UserWarning) Traceback (most recent call last): File "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py", line 14, in push_file_to_server() File "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py", line 7, in push_file_to_server s = sftp.Connection(host='138.99.99.129', username='root', password='********') File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init__.py", line 132, in init self._tconnect['hostkey'] = self._cnopts.get_hostkey(host) File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init__.py", line 71, in get_hostkey raise SSHException("No hostkey for host %s found." % host) paramiko.ssh_exception.SSHException: No hostkey for host 138.99.99.129 found. Exception ignored in: > Traceback (most recent call last): File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init__.py", line 1013, in del self.close() File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init__.py", line 784, in close if self._sftp_live: AttributeError: 'Connection' object has no attribute '_sftp_live'


One option is to disable the host key requirement:

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None   
with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:
    sftp.put(local_path, remote_path)

You can find more info about that here: https://stackoverflow.com/a/38355117/1060738

Important note:

By setting cnopts.hostkeys=None you'll lose the protection against Man-in-the-middle attacks by doing so. Use @martin-prikryl answer to avoid that.

Cook Book, ssh/known_hosts but add additional known host keys you can merge with update additional known_host format files by using .load method. import pysftp cnopts =​  # Accept any host key (still wrong see below) cnopts = pysftp.CnOpts() cnopts.hostkeys = None # And authenticate with private key sftp = pysftp.Connection( host='Host', username='username', password='passwd', private_key=".ppk", cnopts=cnopts) But this code will actually blindly accept any host key, what is a security flaw.


Do not set cnopts.hostkeys = None (as the most upvoted answer shows), unless you do not care about security. You lose a protection against Man-in-the-middle attacks by doing so.


Use CnOpts.hostkeys (returns HostKeys) to manage trusted host keys.

cnopts = pysftp.CnOpts(knownhosts='known_hosts')

with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:

where the known_hosts contains a server public key[s] in a format like:

example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...

If you do not want to use an external file, you can also use

from base64 import decodebytes
# ...

keydata = b"""AAAAB3NzaC1yc2EAAAADAQAB..."""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add('example.com', 'ssh-rsa', key)

with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:

Though as of pysftp 0.2.9, this approach will issue a warning, what seems like a bug: "Failed to load HostKeys" warning while connecting to SFTP server with pysftp


An easy way to retrieve the host key in this format is using OpenSSH ssh-keyscan:

$ ssh-keyscan example.com
# example.com SSH-2.0-OpenSSH_5.3
example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...

You can also make the application do the same automatically: Use Paramiko AutoAddPolicy with pysftp (It will automatically add host keys of new hosts to known_hosts, but for known host keys, it will not accept a changed key)


Though for an absolute security, you should not retrieve the host key remotely, as you cannot be sure, if you are not being attacked already.

See my article Where do I get SSH host key fingerprint to authorize the server? It's for my WinSCP SFTP client, but most information there is valid in general.


If you need to verify the host key using its fingerprint only, see Python - pysftp / paramiko - Verify host key using its fingerprint.

Stuck in a pysftp Dilemma - Needing Help, He is teaching us about how to use the module pysftp, and while I have The very first time you connect to a remote server, you will save a host key on your machine. This is a way of verifying that the machine you think you are dealing with  Use CnOpts.hostkeys (returns HostKeys) to manage trusted host keys. cnopts = pysftp. CnOpts cnopts. hostkeys. load ('known_hosts') with pysftp. Connection (host, username, password, cnopts = cnopts) as sftp: where the known_hosts contains a server public key[s] in a format like:


Try to use the 0.2.8 version of pysftp library. $ pip uninstall pysftp && pip install pysftp==0.2.8

And try with this:

try:
    ftp = pysftp.Connection(host, username=user, password=password)
 except:
    print("Couldn't connect to ftp")
    return False

Why this? Basically is a bug with the 0.2.9 of pysftp here all details https://github.com/Yenthe666/auto_backup/issues/47

What are the risk of NOT using a host key for SFTP using pysftp , You confuse your account public key, that you use for authentication, with a host/​server public key, that you should use to verify the server. Here is the public key id_rsa.pub, which we send to the server owner, who will add it to the list of known keys: $ ls /home/vmuser/.ssh/ id_rsa id_rsa.pub known_hosts Once he does this, we can go to that host by SSH:


If You try to connect by pysftp to "normal" FTP You have to set hostkey to None.

import pysftp

cnopts = pysftp.CnOpts()
cnopts.hostkeys = None 
with pysftp.Connection(host='****',username='****',password='***',port=22,cnopts=cnopts) as sftp:
    print('DO SOMETHING')

Verify host key with pysftp, I am writing a program using pysftp, and it wants to verify the SSH host Key against C:UsersJohnCalvin.sshknown_hosts . Using PuTTY, the  def get_conn(self) -> pysftp.Connection: """ Returns an SFTP connection object """ if self.conn is None: cnopts = pysftp.CnOpts() if self.no_host_key_check: cnopts


Cook book to use different ways of pysftp.CnOpts() and hostkeys options.

Source : https://pysftp.readthedocs.io/en/release_0.2.9/cookbook.html

Host Key checking is enabled by default. It will use ~/.ssh/known_hosts by default. If you wish to disable host key checking (NOT ADVISED) you will need to modify the default CnOpts and set the .hostkeys to None.

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts):
    # do stuff here

To use a completely different known_hosts file, you can override CnOpts looking for ~/.ssh/known_hosts by specifying the file when instantiating.

import pysftp
cnopts = pysftp.CnOpts(knownhosts='path/to/your/knownhostsfile')

with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts):
    # do stuff here

If you wish to use ~/.ssh/known_hosts but add additional known host keys you can merge with update additional known_host format files by using .load method.

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys.load('path/to/your/extra_knownhosts')
with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts):
    # do stuff here

Host keys / known_hosts files, Representation of an OpenSSH-style “known hosts” file. Host keys can be read from one or more files, and then individual hosts can be looked up to verify server​  You need to pass it to cnopts parameter of Connection class, as the bad (while the most upvoted) answer to Verify host key with pysftp shows. Once you resolve this, you will have a problem with the private key, as you pass it to private_key_pass parameter ( "private key passphrase" ) instead of to private_key .


Log in with Atlassian account, Log in to Jira, Confluence, and all other Atlassian Cloud products here. Not an Atlassian user? Sign up for free. You confuse your account public key, that you use for authentication, with a host/server public key, that you should use to verify the server. These are unrelated, while serving a similar purpose, just in an opposite direction. The server uses your public key to verify your identity.


Saving host keys fails if .ssh folder doesn't exist · Issue #1525 , If you try to save host keys without manually creating one yourself, you not verify host key of the new host cnopts.hostkeys = None with pysftp. bugfix: correctly implement hostcheck. Now, be default pysftp will verify the host. See pysftp.CnOpts.hostkeys; added pysftp.Connection.remote_server_key - used to retrieve the remote hosts server key. added support for enabling compression, compression (J. Kruth)


Python - pysftp / paramiko - Verify host key using its fingerprint, delete_files_from_dir(conn, target_dir) move_files_from_server_to_local(​connection_info, "/"). The code is based on Verify host key with pysftp. CnOpts cnopts. hostkeys. add ('example.com', 'ssh-rsa', key) with pysftp. Connection (host, username, password, cnopts = cnopts) as sftp: (based on Verify host key with pysftp) In case you need to automate verification of a host key based on its fingerprint. E.g. because the fingerprint comes from an external configuration.