首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用pysftp验证主机密钥

用pysftp验证主机密钥
EN

Stack Overflow用户
提问于 2016-08-14 05:30:27
回答 9查看 178.5K关注 0票数 102

我正在使用pysftp编写一个程序,它希望通过C:\Users\JohnCalvin\.ssh\known_hosts验证SSH主机密钥。

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

如何协调pysftp和PuTTY之间的差异?

我的代码是:

代码语言:javascript
复制
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()

我收到的错误响应是:

代码语言:javascript
复制
E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py:61:
UserWarning: Failed to load HostKeys from C:\Users\JohnCalvin\.ssh\known_hosts.  You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
 warnings.warn(wmsg, UserWarning)
Traceback (most recent call last): 
  File "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py", line 14, in <module>
    push_file_to_server()
  File "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py", line 7, in push_file_to_server
    s = sftp.Connection(host='138.99.99.129', username='root', password='********') 
  File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py", line 132, in __init__
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)   
  File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py", line 71, in get_hostkey
    raise SSHException("No hostkey for host %s found." % host) paramiko.ssh_exception.SSHException: No hostkey for host 138.99.99.129 found.
Exception ignored in: <bound method Connection.__del__ of <pysftp.Connection object at 0x00000222FF3A6BE0>>
Traceback (most recent call last):
  File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py", line 1013, in __del__
    self.close()  
  File "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp\__init__.py", line 784, in close
    if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'
EN

回答 9

Stack Overflow用户

发布于 2017-04-13 10:14:59

pysftp在主机密钥处理方面有一些bug,如下所述。另外,pysftp项目似乎也被放弃了。考虑直接使用Paramiko代替。pysftp只是Paramiko上面的一个包装器,它并没有增加任何真正重要的东西。见https://stackoverflow.com/q/48434941/850848

有关Paramiko主机密钥的处理,请参见:

https://stackoverflow.com/q/10670217/850848#43093883

如果您想继续使用pysftp,请不要设置cnopts.hostkeys = None (正如第二个最不正确的答案所示),除非您不关心安全性。这样做就失去了对https://en.wikipedia.org/wiki/Man-in-the-middle_attack的保护。

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

代码语言:javascript
复制
cnopts = pysftp.CnOpts(knownhosts='known_hosts')

with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:

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

代码语言:javascript
复制
example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...

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

代码语言:javascript
复制
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开始,此方法将发出警告,但似乎是一个bug:

使用pysftp连接到SFTP服务器时,“未能加载HostKeys”警告

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

代码语言:javascript
复制
$ ssh-keyscan example.com
# example.com SSH-2.0-OpenSSH_5.3
example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...

(由于pysftp中有一个bug,这个https://stackoverflow.com/q/64438184/850848#64439662 -条目以[example.com]:port +当心开始)

您还可以让应用程序自动执行相同的操作:

与pysftp一起使用Paramiko AutoAddPolicy

(它将自动将新主机的主机键添加到known_hosts,但对于已知的主机密钥,它将不接受更改的密钥)

虽然对于绝对安全,您不应该远程检索主机密钥,因为您不能确定,如果您还没有受到攻击。

见我的文章在哪里可以获得SSH主机密钥指纹来授权服务器?

这是为我的WinSCP SFTP客户端,但大多数信息是有效的。

如果需要仅使用其指纹验证主机密钥,请参见Python / paramiko -使用其指纹验证主机密钥

票数 136
EN

Stack Overflow用户

发布于 2016-08-18 13:14:29

一个选项是禁用主机密钥要求:

代码语言:javascript
复制
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

重要注意事项:

通过设置cnopts.hostkeys=None,您将失去对中间人攻击的保护。使用@martin-prikryl回答来避免这种情况。

票数 101
EN

Stack Overflow用户

发布于 2018-07-23 15:28:08

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

试着用这个:

代码语言:javascript
复制
try:
    ftp = pysftp.Connection(host, username=user, password=password)
 except:
    print("Couldn't connect to ftp")
    return False

为什么要这样?基本上是一个bug,这里有0.2.9的pysftp --所有细节后备/问题/47

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38939454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档