Alex F
Alex F

Reputation: 2274

Using Python's pysftp, how do you verify a host key?

I am using Python 2.7 pysftp package to connect to an SFTP server.

import pysftp

DOWNLOAD = {
"USERNAME": "username",
"PASSWORD": "password"
}

FTP_SITE = 'sftp.mysite.com'

srv = pysftp.Connection(host=FTP_SITE, username=DOWNLOAD['USERNAME'], 
                    password=DOWNLOAD['PASSWORD']

When I run the code above I get the error log:

---------------------------------------------------------------------------
SSHException                              Traceback (most recent call last)
<ipython-input-47-205bb7b4b59b> in <module>()
      5 
      6 srv = pysftp.Connection(host=FTP_SITE, username=DOWNLOAD['USERNAME'], 
----> 7                         password=DOWNLOAD['PASSWORD'])

C:\Users\Alex\Anaconda2\lib\site-packages\pysftp\__init__.pyc in __init__(self, host, username, private_key, password, port, private_key_pass, ciphers, log, cnopts, default_path)
    130         # check that we have a hostkey to verify
    131         if self._cnopts.hostkeys is not None:
--> 132             self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
    133 
    134         self._sftp_live = False

C:\Users\Alex\Anaconda2\lib\site-packages\pysftp\__init__.pyc in get_hostkey(self, host)
     69         kval = self.hostkeys.lookup(host)  # None|{keytype: PKey}
     70         if kval is None:
---> 71             raise SSHException("No hostkey for host %s found." % host) 
     72         # return the pkey from the dict
     73         return list(kval.values())[0]

SSHException: No hostkey for host sftp.mysite.com found.

I have the current work around of turning off the checking of host keys by doing the following:

cnopts = pysftp.CnOpts()
cnopts.hostkeys = None 
srv = pysftp.Connection(host=FTP_SITE, username=DOWNLOAD['USERNAME'], 
                         password=DOWNLOAD['PASSWORD'], cnopts=cnopts)

I would like to keep the security feature of the host key. Can anyone provide a link on how to generate the host keys, or provide a small sample of code here? I haven't been able to find much.

Upvotes: 2

Views: 11323

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202232

cnopts = pysftp.CnOpts()
cnopts.hostkeys.load('sftpserver.pub')

where the sftpserver.pub contains a server public key in a format like:

example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...

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

ssh-keyscan example.com

Though for 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 do not want to use an external file, you can also use

cnopts.hostkeys.add(...)

For other options, see: Verify host key with pysftp.


Though pysftp is dead. Better use Paramiko: pysftp vs. Paramiko

Upvotes: 7

Related Questions