【问题标题】:Use Paramiko AutoAddPolicy with pysftp将 Paramiko AutoAddPolicy 与 pysftp 一起使用
【发布时间】:2019-05-09 00:25:48
【问题描述】:

此代码不起作用:

def sftp_connection(self):
    import pysftp
    connection = pysftp.Connection(self.host, username=self.system_name,
                  private_key=os.path.join(HOME, '.ssh', 'id_rsa'))

    # in the next lines I try to use AutoAddPolicy
    client = connection.sftp_client()
    client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
    client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy)
    return connection

这是个例外:

Traceback (most recent call last):
  File "/home/u/src/myapp-glo/myapp_doxis_archiv/tests/test_doxis_archiv.py", line 85, in test_beleg_to_archiv__ftpservercontext
    info_dict = beleg_to_archiv(beleg, self.archiv_belegart)
  File "/home/u/src/myapp-glo/myapp_doxis_archiv/beleg_to_archiv.py", line 28, in beleg_to_archiv
    transfer_log=send_data_via_ftp(temp_directory, archiv_belegart.doxis_archiv)
  File "/home/u/src/myapp-glo/myapp_doxis_archiv/beleg_to_archiv.py", line 71, in send_data_via_ftp
    with doxis_archiv.sftp_connection() as sftp:
  File "/home/u/src/myapp-glo/myapp_doxis_archiv/models.py", line 43, in sftp_connection
    private_key=os.path.join(HOME, '.ssh', 'id_rsa'))
  File "/home/u/local/lib/python2.7/site-packages/pysftp/__init__.py", line 132, in __init__
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
  File "/home/u/local/lib/python2.7/site-packages/pysftp/__init__.py", line 71, in get_hostkey
    raise SSHException("No hostkey for host %s found." % host)
SSHException: No hostkey for host localhost found.

我在尝试设置 host_key_policy 之前遇到了异常。

我找不到通过 pysftp 访问客户端实例的其他方式。

有没有办法在我得到异常之前设置AutoAddPolicy

有一个相关的question。我的问题是关于如何应用旧问题中提供的几种解决方案之一。

【问题讨论】:

    标签: python ssh paramiko pysftp


    【解决方案1】:

    pysftp 根本不使用 Paramiko SSHClient class,它使用更底层的 Transport class。所以它没有SSHClientMissingHostKeyPolicy功能。

    你必须自己实现它。

    一种可能的实现方式是:

    host = 'example.com'
    
    # Loads .ssh/known_hosts    
    cnopts = CnOpts()
    
    hostkeys = None
    
    if cnopts.hostkeys.lookup(host) == None:
        print("New host - will accept any host key")
        # Backup loaded .ssh/known_hosts file
        hostkeys = cnopts.hostkeys
        # And do not verify host key of the new host
        cnopts.hostkeys = None
    
    with Connection(host, username=user, private_key=pkey, cnopts=cnopts) as sftp:
        if hostkeys != None:
            print("Connected to new host, caching its hostkey")
            hostkeys.add(
                host, sftp.remote_server_key.get_name(), sftp.remote_server_key)
            hostkeys.save(pysftp.helpers.known_hosts())
    

    【讨论】:

    • 只是我在连接块中使用了password=password 而不是private_key = pkey
    • @AbhishekGurjar 我的答案是使用公钥身份验证,因为这就是 OP 所使用的。如果您使用密码进行身份验证,那么您的代码显然会有所不同。
    • 如果~/.ssh/known_hosts 文件为空,cnopts = pysftp.CnOpts() 将在第一次运行时fail
    【解决方案2】:

    我已经在我的pysftp github fork 中实现了auto_add_key

    auto_add_key 将把密钥添加到known_hosts 如果auto_add_key=True
    一旦known_hosts 中的主机存在密钥,就会检查该密钥。

    有关安全问题,请参考Martin Prikryl -> answer

    尽管为了绝对安全,您不应该远程检索主机密钥,因为您无法确定是否已经受到攻击。

    import pysftp as sftp
    
    def push_file_to_server():
        s = sftp.Connection(host='138.99.99.129', username='root', password='pass', auto_add_key=True)
        local_path = "testme.txt"
        remote_path = "/home/testme.txt"
    
        s.put(local_path, remote_path)
        s.close()
    
    push_file_to_server()
    

    【讨论】:

      猜你喜欢
      • 2018-07-04
      • 2020-05-17
      • 1970-01-01
      • 2019-05-08
      • 2018-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多