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:
无法从C:\ Users \ JohnCalvin加载HostKeys .ssh \ known_hosts。
您需要显式加载HostKeys
(cnopts.hostkeys.load(filename))或disableHostKey检查
(cnopts.hostkeys = None)。 warnings.warn(wmsg,UserWarning)追溯
(最近一次通话):File
“ 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
(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的主机密钥
。在以下情况中忽略了异常:>追溯(最近一次最近调用):文件“ 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行,在
close
如果self._sftp_live:AttributeError:“连接”对象没有属性“ _sftp_live”
#1 楼
除非您不关心安全性,否则请勿设置cnopts.hostkeys = None
(如第二个最受好评的答案所示)。这样做会使您免受中间人攻击。使用
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开始,此方法将发出警告,似乎是一个错误:使用以下命令连接到SFTP服务器时出现“无法加载HostKeys”警告pysftp
以这种格式检索主机密钥的简单方法是使用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中的文件)您也可以使应用程序执行自动相同:使用Paramiko AutoAddPolicy使用pysftp
(它将自动将新主机的主机密钥添加到
known_hosts
,但是对于已知的主机密钥,它将不接受更改的密钥)尽管出于绝对安全的考虑,您不应无法确定是否已经受到攻击,请从远程检索主机密钥。 ,但是大多数信息通常都是有效的。
如果仅需要使用其指纹来验证主机密钥,请参阅Python-pysftp / paramiko-使用其指纹来验证主机密钥。
评论
cnopts.hostkeys.add()中的主机名参数出现在| 1 | xyzxyzxyz = | abcabcabc =这样的known_hosts中时,应该使用什么?
– marengaz
19年9月10日在9:50
@marengaz使用您在pysftp.Connection中使用的主机名。
–马丁·普里克里(Martin Prikryl)
19-09-10在9:51
#2 楼
一种选择是禁用主机密钥要求: 38355117/1060738重要说明:
通过设置
cnopts.hostkeys=None
,您将失去针对中间人攻击的保护。使用@ martin-prikryl答案可以避免这种情况。评论
是的,这就是我最终解决问题的方式。但是这样做只能忽略主机密钥。我希望能够通过读取实际密钥来保留安全性(如果可能)。
–加百利·狄奥多洛斯(Gabriel Theodoulos)
16年8月20日在21:17
快速说明。如果您的路径中有一个空的known_hosts文件,CnOpts()将失败。
–汤米·斯特兰德
16年8月8日在8:14
请参阅我的答案以寻求解决方案。
–马丁·普里克里(Martin Prikryl)
17年4月13日在10:28
我已将hostkeys设置为None,但这在docker容器内不起作用,发出警告并且未建立连接。
–ronit
6月8日12:15
#3 楼
尝试使用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
为什么?
基本上是pysftp的0.2.9的错误
这里是所有详细信息
https://github.com/Yenthe666/auto_backup/issues/47
评论
您能详细说明一下吗?我浏览了该链接,但实际上没有找到任何合理的解释来说明为什么降级会有所帮助。虽然您的陈述“这里是所有细节”表明应该有一些。
–马丁·普里克里(Martin Prikryl)
18年7月23日在16:36
精彩!!我已经安装了0.2.9。这个帖子挽救了我的一天!
–Ram Dwivedi
18-10-4在16:06
#4 楼
如果尝试通过pysftp连接到“普通” FTP,则必须将主机密钥设置为“无”。import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection(host='****',username='****',password='***',port=22,cnopts=cnopts) as sftp:
print('DO SOMETHING')
#5 楼
编写本书以使用pysftp.CnOpts()和hostkeys选项的不同方式。 br />默认情况下启用主机密钥检查。默认情况下,它将使用〜/ .ssh / known_hosts。如果要禁用主机密钥检查(不建议),则需要修改默认的CnOpts并将.hostkeys设置为None。import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts):
# do stuff here
要使用完全不同的名称如果您要使用〜/ .ssh / known_hosts,则可以通过在实例化时指定该文件来覆盖CnOpts,以查找〜/ .ssh / known_hosts。但是添加其他已知的主机密钥,可以使用.load方法与其他附加的已知主机格式文件合并。
#6 楼
首先使用使用known_hosts文件的Windows ssh客户端连接到服务器。将数据存储在Windows注册表中,但是OpenSSH使用known_hosts文件,并且在连接后将在其中添加条目。该文件的默认位置是%USERPROFILE%.ssh。希望对您有帮助
评论
不公平的评论。你读过这个问题吗?如何调和pysftp和PuTTY之间的区别?
–汉斯·劳滕巴赫
17-6-7-4:36
#7 楼
嗨,如果我很了解您,我们也会遇到相同的问题。因此,请检查您正在使用的pysftp版本。如果它是最新版本,降级为0.2.9,则降为0.2.8。请查看此内容。 https://github.com/Yenthe666/auto_backup/issues/47
评论
不要建议人们绕开安全功能,而不解释后果!您正在失去防范MITM攻击的保护。
–马丁·普里克里(Martin Prikryl)
17年4月13日在10:26
#8 楼
我已经在pysftp github分支中实现了auto_add_key
。如果
auto_add_key
,则known_hosts
会将密钥添加到auto_add_key=True
中。一旦在
known_hosts
中为主机提供了密钥,该密钥就会被检查。 /> 请参考Martin Prikryl->有关安全性问题的答案。如果尚未受到攻击。
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()
注意:为什么使用上下文管理器
import pysftp
with pysftp.Connection(host, username="whatever", password="whatever", auto_add_key=True) as sftp:
#do your stuff here
#connection closed
#9 楼
FWIR,如果身份验证仅是用户名和密码,则将远程服务器ip地址添加到known_hosts(例如ssh-keyscan -H 192.168.1.162 >> ~/.ssh/known_hosts
)以获取参考https://www.techrepublic.com/article/how-to-easily-add-an-ssh-fingerprint-to-your -knownhosts-file-in-linux / 评论
仅供参考,这可能更适合作为注释和注释答案
– henrycjc
1月22日1:32
评论
您可以在pysftp文档中找到问题的答案,该文档在此处明确提及了此问题。