pythonsshparamikopysftpknown-hosts

pysftp.CnOpts() 'No Host Keys Found' error despite known_hosts file generated using ssh-keyscan


I am trying to follow solution from Verify host key with pysftp.

I run:

import pysftp
fn = r'C:\Users\UWAdmin\.ssh\known_hosts'

cnopts = pysftp.CnOpts()
cnopts.hostkeys.load(fn)

but I get the error:

HostKeysException                         Traceback (most recent call last)
<ipython-input-3-b5b4d53fef6c> in <module>
----> 9 cnopts = pysftp.CnOpts()
     10 cnopts.hostkeys.load(fn)

~\miniconda3\envs\pycontrol\lib\site-packages\pysftp\__init__.py in __init__(self, knownhosts)
     62         else:
     63             if len(self.hostkeys.items()) == 0:
---> 64                 raise HostKeysException('No Host Keys Found')
     65 
     66     def get_hostkey(self, host):

HostKeysException: No Host Keys Found

Even after I did ssh-keyscan 192.168.254.254 > ~/.ssh/known_hosts in Windows PowerShell, what added the following to the ~/.ssh/known_hosts file:

192.168.254.254 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCVlnFrb1SzjijeWRld0w+MJpblrsF8vEutsRnJbxOMHKz8dhqP/qGjYOtG3KCLwNH8odLStd5or5C68XqbdBTxXG1CaTrSd0Z4gWo3cNy3rKjJ4pmTVPuFXEH7iCfd9GNDfPtUOZDeJhbAXID8mUXtnGaw4jH3veWSmLGQk/sbNRgFfVytAqhGxn8wVgBmVt5VGmaQN9f35mikfmyRZtwQXwZ/sbvNYYiGVbd0mnztawAdv9CZhtdJBofj1yqldw/yfN7m/8AkKHqAOlRfbKMIXU+VXkKTwg+try/aYA76HJPmS5jU/C3esc/2wyZBP7t9fMOF6iUbimCsHCC2MP3P
192.168.254.254 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGq3me3LXMVu6S5aHp7JqRMNRgAbdEsJY4PKC4ydS3R8uJklU4EjRDQNNPwSWcrCeqCEn5HgIMOs96q1Zoh9ANY=
192.168.254.254 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAgEX0CF1NzUL0G0+Wf64qzJmj5PBh6JI95Xn5xaS5y6

And, notice that no host keys are found even at cnopts = pysftp.CnOpts()

I have tried reinstalling pysftp still to no avail. Please advise

When I ssh to remote to server and it also prompts me to verify the host key, despite it being on the knbown_hosts file already. When I verify the key, the key added to the C:\\Users\\UWAdmin/.ssh/known_hosts is written in chinese-like symbols:

㤱⸲㘱⸸㔲⸴㔲‴捥獤ⵡ桳㉡渭獩灴㔲‶䅁䅁㉅橖䡚桎塌潎呙瑉浢穬䡤祁呎䅙䅁䥁浢穬䡤祁呎䅙䅁䉂䝂㍱敭䰳䵘畖匶愵灈䨷剱乍杒扁䕤䩳㑙䭐㑃摹㍓㡒䩵汫㑕橅䑒乑偎卷捗䍲煥䕃㕮杈䵉獏㘹ㅱ潚㥨乁㵙਍

Following the suggestion from Martin to try to parse individual lines of known_hosts using paramiko.hostkeys.HostKeyEntry.from_line, I get this in Paramiko log:

INF [20201104-16:36:28.943] thr=1   paramiko.hostkeys: Unable to handle key of type  s s h - r s a 
INF [20201104-16:36:28.943] thr=1   paramiko.hostkeys: Not enough fields found in known_hosts in line 0 ('\x00\n')
INF [20201104-16:36:28.943] thr=1   paramiko.hostkeys: Unable to handle key of type  e c d s a - s h a 2 - n i s t p 2 5 6 
INF [20201104-16:36:28.943] thr=1   paramiko.hostkeys: Not enough fields found in known_hosts in line 0 ('\x00\n')
INF [20201104-16:36:28.943] thr=1   paramiko.hostkeys: Unable to handle key of type  s s h - e d 2 5 5 1 9 
INF [20201104-16:36:28.943] thr=1   paramiko.hostkeys: Not enough fields found in known_hosts in line 0 ('\x00\n')

Solution

  • As you can see in the callstack, you get the error in CnOpts constructor already, even before you call cnopts.hostkeys.load. That's because the constructor tries to load the host keys file from the standard location.

    This should work to specify your custom location:

    cnopts = pysftp.CnOpts(knownhosts=fn)
    

    Though as you are actually loading the key from the standard location, the problem must be in the file format. From the additional information, you have provided, it looks like the file is in UTF-16 encoding. Save it as ASCII/UTF-8 instead.

    It is actually a consequence of calling ssh-keyscan from the PowerShell. PowerShell before version 6 defaults to UTF-16, when processing file redirection. See Why does PowerShell redirection >> change the formatting of the text content? Just run the ssh-keyscan in cmd.exe instead of PowerShell.