我正在使用pysftp编写一个程序,它希望通过C:\Users\JohnCalvin\.ssh\known_hosts验证SSH主机密钥。
使用PuTTY,终端程序将其保存到注册表[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: 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'发布于 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)管理受信任的主机密钥。
cnopts = pysftp.CnOpts(knownhosts='known_hosts')
with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:其中known_hosts包含服务器公钥],格式如下:
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:虽然从pysftp 0.2.9开始,此方法将发出警告,但似乎是一个bug:
使用pysftp连接到SFTP服务器时,“未能加载HostKeys”警告
以所需格式检索主机密钥的一种简单方法是使用OpenSSH ssh-keyscan
$ 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,但对于已知的主机密钥,它将不接受更改的密钥)
虽然对于绝对安全,您不应该远程检索主机密钥,因为您不能确定,如果您还没有受到攻击。
这是为我的WinSCP SFTP客户端,但大多数信息是有效的。
如果需要仅使用其指纹验证主机密钥,请参见Python / paramiko -使用其指纹验证主机密钥。
发布于 2016-08-18 13:14:29
一个选项是禁用主机密钥要求:
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回答来避免这种情况。
发布于 2018-07-23 15:28:08
尝试使用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为什么要这样?基本上是一个bug,这里有0.2.9的pysftp --所有细节后备/问题/47
https://stackoverflow.com/questions/38939454
复制相似问题