本文介绍了使用 pysftp 验证主机密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 pysftp 编写一个程序,它想根据 C:UsersJohnCalvin.sshknown_hosts 验证 SSH 主机密钥.

I am writing a program using pysftp, and it wants to verify the SSH host Key against C:UsersJohnCalvin.sshknown_hosts.

使用 PuTTY,终端程序将其保存到注册表 [HKEY_CURRENT_USERSoftwareSimonTathamPuTTYSshHostKeys].

Using PuTTY, the terminal program is saving it to the Registry [HKEY_CURRENT_USERSoftwareSimonTathamPuTTYSshHostKeys].

如何调和pysftp和PuTTY的区别?

How do I reconcile the difference between pysftp and 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)Anaconda3libsite-packagespysftp__init__.py:61:用户警告:
无法从 C:UsersJohnCalvin.sshknown_hosts 加载主机密钥.
您将需要显式加载 HostKeys(cnopts.hostkeys.load(filename)) 或 disableHostKey 检查(cnopts.hostkeys = 无).warnings.warn(wmsg, UserWarning) 回溯(最近一次通话):文件E:OneDrivePythonGITDigitalCloudpysftp_tutorial.py",第 14 行,在push_file_to_server() 文件E:OneDrivePythonGITDigitalCloudpysftp_tutorial.py",第 7 行,在push_file_to_servers = sftp.Connection(host='138.99.99.129', username='root', password='********') File "E:Program Files(x86)Anaconda3libsite-packagespysftp__init__.py",第 132 行,在初始化self._tconnect['hostkey'] = self._cnopts.get_hostkey(host) File "E:Program Files(x86)Anaconda3libsite-packagespysftp__init__.py",第 71 行,在获取主机密钥引发 SSHException(找不到主机 %s 的主机密钥."% 主机)paramiko.ssh_exception.SSHException:主机 138.99.99.129 没有主机密钥成立.异常被忽略: > 回溯(大多数最近通话最后一次):文件E:Program Files(x86)Anaconda3libsite-packagespysftp__init__.py",第 1013 行,在删除self.close() 文件E:Program Files (x86)Anaconda3libsite-packagespysftp__init__.py",第 784 行,在关闭如果 self._sftp_live: AttributeError: 'Connection' 对象没有属性 '_sftp_live'

推荐答案

pysftp 有一些关于主机密钥处理的错误,如下所述.pysftp 项目似乎也被放弃了.考虑直接使用 Paramiko.pysftp 只是 Paramiko 之上的一个包装器,它没有添加任何真正重要的东西.参见 pysftp 与 Paramiko.

关于在 Paramiko 中处理主机密钥,请参阅:
Paramiko未知服务器"

如果您想继续使用 pysftp,请不要设置 cnopts.hostkeys = None(如第二个投票最多的答案所示),除非您不关心安全性.您失去了对中间人攻击的保护

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

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

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:

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

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:

虽然从 pysftp 0.2.9 开始,这种方法会发出警告,这似乎是一个错误:
无法加载主机密钥"使用 pysftp 连接到 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

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

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

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

(由于 pysftp 中的一个错误,这个 不起作用,如果服务器使用非标准端口 – 条目以 [example.com]:port 开头 + 当心 重定向 ssh-keyscan 到 PowerShell 中的文件)

(due to a bug in pysftp, this does not work, if the server uses non-standard port – the entry starts with [example.com]:port + beware of redirecting ssh-keyscan to a file in PowerShell)

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

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.

请参阅我的文章我从哪里获得 SSH 主机密钥指纹来授权服务器?
它适用于我的 WinSCP SFTP 客户端,但大多数信息一般都是有效的.

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.

如果您只需要使用其指纹验证主机密钥,请参阅Python - pysftp/paramiko - 使用其指纹验证主机密钥.

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

这篇关于使用 pysftp 验证主机密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-12 09:01