首页 文章

使用pysftp验证主机密钥

提问于
浏览
39

我正在使用pysftp编写程序,它想要验证SSH主机密钥对 C:\Users\JohnCalvin\.ssh\known_hosts .

使用PuTTY,终端程序将其保存到Registry [HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys] .

如何调和pysftp和PuTTY之间的区别?

我的代码是:

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()

我收到的错误响应是:

E:\ Program Files(x86)\ Anaconda3 \ lib \ site-packages \ pysftp__init __ . py:61:UserWarning:无法从C:\ Users \ JohnCalvin.ssh \ known_hosts加载HostKeys . 您需要显式加载HostKeys(cnopts.hostkeys.load(filename))或disableHostKey检查(cnopts.hostkeys = None) . warnings.warn(wmsg,UserWarning)Traceback(最近一次调用最后一次):文件“E:\ OneDrive \ Python \ GIT \ DigitalCloud \ pysftp_tutorial.py”,第14行,在push_file_to_server()文件“E:\ OneDrive \ Python \ GIT \ DigitalCloud \ pysftp_tutorial.py“,第7行,在push_file_to_server中s = sftp.Connection(host ='138.99.99.129',用户名='root',密码='********')文件”E :\ Program Files(x86)\ Anaconda3 \ lib \ site-packages \ pysftp__init __ . py“,第132行,在init self._tconnect ['hostkey'] = self._cnopts.get_hostkey(host)文件”E:\ Program Files (x86)\ Anaconda3 \ lib \ site-packages \ pysftp__init __ . py“,第71行,在get_hostkey中引发SSHException(”找不到主机%s的主机密钥 . “%host)paramiko.ssh_exception.SSHException:主机138.99没有主机密钥 . 99.129找到了 . 在以下情况中忽略异常:> Traceback(最近一次调用最后一次):文件“E:\ Program Files(x86)\ Anaconda3 \ lib \ site-packages \ pysftp__init __ . py”,第1013行,在del self.close()文件中“E :\ Program Files(x86)\ Anaconda3 \ lib \ site-packages \ pysftp__init __ . py“,第784行,如果self._sftp_live关闭:AttributeError:'Connection'对象没有属性'_sftp_live'

5 回答

  • -1

    嗨,如果我理解你,我们会遇到同样的问题 . 那么请检查一下pysftp版本're using. If it'的最新版本是0.2.9降级到0.2.8 . 看一下这个 . https://github.com/Yenthe666/auto_backup/issues/47

  • 21

    首先使用使用known_hosts文件的Windows ssh客户端连接到服务器 . PuTTy将数据存储在Windows注册表中,但是OpenSSH使用known_hosts文件,并在连接后在其中添加条目 . 该文件的默认位置是%USERPROFILE%.ssh . 我希望这有帮助

  • 1

    尝试使用0.2.8版本的pysftp库 . $ pip uninstall pysftp && pip install pysftp==0.2.8

    试试这个:

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

    为什么这个?基本上是0.2.9的pysftp错误所有细节https://github.com/Yenthe666/auto_backup/issues/47

  • 48

    以下解决方案适合我:

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

    你可以在这里找到更多信息:https://stackoverflow.com/a/38355117/1060738

  • 2

    Do not set cnopts.hostkeys = None (作为最受欢迎的答案显示),除非您不关心安全性 . 这样做会失去对Man-in-the-middle attacks的保护 .


    使用 CnOpts.hostkeys (返回HostKeys)来管理可信主机密钥 .

    cnopts = pysftp.CnOpts()
    cnopts.hostkeys.load('known_hosts')
    
    with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:
    

    其中 known_hosts 包含服务器公钥[s],格式如下:

    example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...
    

    如果您不想使用外部文件,也可以使用

    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:
    

    以这种格式检索主机密钥的简单方法是使用OpenSSH ssh-keyscan

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

    您还可以使应用程序自动执行相同操作:
    Use Paramiko AutoAddPolicy with pysftp
    (它会自动将新主机的主机密钥添加到 known_hosts ,但对于已知的主机密钥,它不会接受更改的密钥)


    虽然绝对安全,但如果您没有受到攻击,则不应该远程检索主机密钥,因为您无法确定 .

    看我的文章Where do I get SSH host key fingerprint to authorize the server?
    它适用于我的WinSCP SFTP客户端,但大多数信息一般都有效 .


    如果只需使用其指纹验证主机密钥,请参阅Python - pysftp / paramiko - Verify host key using its fingerprint .

相关问题