使用 pysftp 针对使用自定义端口的 known_hosts 文件验证主机密钥
Posted
技术标签:
【中文标题】使用 pysftp 针对使用自定义端口的 known_hosts 文件验证主机密钥【英文标题】:Verify host key with pysftp against known_hosts file with custom port 【发布时间】:2021-10-12 13:10:46 【问题描述】:我正在尝试使用 pysftp
登录 SFTP 服务器。
这是我正在测试的代码:
import pysftp
cnopts = pysftp.CnOpts()
# cnopts.hostkeys = None
host = 'data-nz.metservice.com'
username = 'my_user'
password = 'my_passwd'
ciphers = ['aes128-cbc', '3des-cbc', 'blowfish-cbc', 'aes192-cbc', 'aes256-cbc']
with pysftp.Connection(host, username=username, password=password,
port=9022, ciphers=ciphers, cnopts=cnopts) as sftp:
sftp.listdir()
注意:
-
服务器使用非标准端口
服务器仅使用列出的五个密码来协商连接,因此此选项是强制性的
此代码失败,因为找不到主机密钥:
SSHException: 找不到主机 data-nz.metservice.com 的主机密钥。
我已经阅读了this question,并且我已经成功地使用了设置cnopts.hostkeys=None
的变通方法(请参阅我的代码中注释掉的行)。但显然我想删除这个安全漏洞。但是我不知道如何处理这个异常。我已经使用普通的sftp
登录,以确保将所需的行添加到我的known_hosts
。此操作实际上添加了两行(我的内容并不完全清楚,因为没有明确引用 URL,但无论如何...),现在 sftp
不会抱怨:
|1|l+HfDGPUhea+8cUzCS+jq2HGcBg=|XMWhbkgujRtW1lJ4E93sTidUiCs= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8N65MCdnbHjaEDxkZPPq1QO0RLwP3cdm9Gb9BAMS0mFH39d7/yHIerA6yFZRW27u3NClI7V1F3hDuheoCUomeF9Q9ioaeQ2dlX27hmGf611RpSfI/vGgnmipHYzzHsCIJi0LxuowCouKNw8g1v1e2VzsVWFPaq+cDeuUpDwpBKWnxQUWN7U9mzN1k0sDALimWOzhfQmXtCzPkHqERUcPpdU7/zWP8Xk9H7FQxgiPFa+EC5xuCzn01CcJppQ8VBqL9R6SNNP/d9ymQWh3cotXe6sj5gt2MdfbAUfxddQITW1rU+LSOkG21QPMq0VBDJwWf9RpqhnqcvusZIFVGyOsn
|1|uILdQCq4UAlxnruPlWnb7vwpWbc=|AOjbzHHXJ44ibhLVJJSGk++ep+U= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8N65MCdnbHjaEDxkZPPq1QO0RLwP3cdm9Gb9BAMS0mFH39d7/yHIerA6yFZRW27u3NClI7V1F3hDuheoCUomeF9Q9ioaeQ2dlX27hmGf611RpSfI/vGgnmipHYzzHsCIJi0LxuowCouKNw8g1v1e2VzsVWFPaq+cDeuUpDwpBKWnxQUWN7U9mzN1k0sDALimWOzhfQmXtCzPkHqERUcPpdU7/zWP8Xk9H7FQxgiPFa+EC5xuCzn01CcJppQ8VBqL9R6SNNP/d9ymQWh3cotXe6sj5gt2MdfbAUfxddQITW1rU+LSOkG21QPMq0VBDJwWf9RpqhnqcvusZIFVGyOsn
但是主机密钥似乎仍然没有被 Python 确认。知道我的程序有什么问题吗?
【问题讨论】:
【参考方案1】:我猜问题是pysftp在known_hosts
文件中查找主机密钥时不支持自定义端口。
添加这样的条目:
data-nz.metservice.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8N65MCdnbHjaEDxkZPPq1QO0RLwP3cdm9Gb9BAMS0mFH39d7/yHIerA6yFZRW27u3NClI7V1F3hDuheoCUomeF9Q9ioaeQ2dlX27hmGf611RpSfI/vGgnmipHYzzHsCIJi0LxuowCouKNw8g1v1e2VzsVWFPaq+cDeuUpDwpBKWnxQUWN7U9mzN1k0sDALimWOzhfQmXtCzPkHqERUcPpdU7/zWP8Xk9H7FQxgiPFa+EC5xuCzn01CcJppQ8VBqL9R6SNNP/d9ymQWh3cotXe6sj5gt2MdfbAUfxddQITW1rU+LSOkG21QPMq0VBDJwWf9RpqhnqcvusZIFVGyOsn
或者直接使用 Paramiko(pysftp 是 Paramiko 的封装),因为 Paramiko 使用自定义端口正确实现主机密钥查找。
一些背景知识:原始known_hosts
开头的代码是经过哈希处理的host[:port]
标识符。 Pysftp 在查找条目时不使用端口,因此找不到正确的条目。如果您在没有自定义端口的情况下添加虚假(散列与否)条目,pysftp 将能够找到它。
【讨论】:
以上是关于使用 pysftp 针对使用自定义端口的 known_hosts 文件验证主机密钥的主要内容,如果未能解决你的问题,请参考以下文章