微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

pysftp抛出paramiko.ssh_exception.SSHException即使提供了known_hosts文件?

如何解决pysftp抛出paramiko.ssh_exception.SSHException即使提供了known_hosts文件?

遇到错误

paramiko.ssh_exception.SSHException:找不到主机target.org的主机密钥。

在使用pysftp时(对于需要特定端口的连接),即使我提供的是最初用于连接到该位置的相同kNown_hosts文件(在帖子here之后)。就是做了...

[airflow@airflowetl reporting]$ sftp -oPort=15259 my_user@target.org
The authenticity of host '[target.org]:15259 ([205.172.2.88]:15259)' can't be established.
RSA key fingerprint is SHA256:UM6OflG0rkcYohes7qOlYoJZ4TIqVd0JQSh7HXYZQVA.
RSA key fingerprint is MD5:33:c2:30:22:57:5b:57:98:2f:11:07:4d:a3:4a:10:0f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[target.org]:15259,[205.172.2.88]:15259' (RSA) to the list of kNown hosts.
password
Enter password for my_user
Password:
Connected to target.org.
sftp> ls
csv_drop        test_results    
sftp> exit

然后将/home/me/.ssh/kNown_hosts复制到另一个位置

[airflow@airflowetl .ssh]$ ls -lha
total 8.0K
drwx------   2 airflow airflows   25 Oct 19 17:31 .
drwx------. 32 airflow airflows 4.0K Oct 19 17:31 ..
-rw-r--r--   1 airflow airflows  777 Oct 19 17:32 kNown_hosts
[airflow@airflowetl .ssh]$ ls -lha /home/airflow/projects/backups/reporting/configs/kNown_hosts 
-rw-r--r-- 1 airflow airflows 777 Oct 19 17:34 /home/airflow/projects/backups/reporting/configs/kNown_hosts

(请注意,权限是原始名称和副本的名称)的使用方式类似于...


# connect to ftp location
assert os.path.isfile(os.path.join(PROJECT_HOME,"configs","kNown_hosts"))
cnopts = pysftp.Cnopts(kNownhosts=os.path.join(PROJECT_HOME,"kNown_hosts"))
#cnopts = pysftp.Cnopts(kNownhosts="/home/airflow/.ssh/kNown_hosts")
HOSTNAME = "target.org"
PORT = 15259
sftp = pysftp.Connection(HOSTNAME,port=PORT,username=CREDS["sink"]["ftp_creds"]["username"],password=CREDS["sink"]["ftp_creds"]["password"],cnopts=cnopts)
print(sftp.pwd())
print(sftp.listdir())

sftp.cwd(CONF["reporting_configs"]["to"]["share_folder_path"])
print(sftp.pwd())
print(sftp.listdir())

但是,在运行脚本时,我收到一条错误消息,指出它找不到主机密钥(请注意,即使使用原始的kNown_hosts文件路径也会引发相同的错误(并且无论是使用主机名还是IP都会发生)。是什么原因造成的?还有其他调试步骤可以尝试获取更多信息吗?在这种事情上没有太多经验。

在运行调试器时,我发现cnopts主机密钥条目似乎确实包含正确的主机密钥...

<HostKeyEntry ['[target.org]:15259','[205.172.2.88]:15259']: <paramiko.rsakey.RSAKey object at 0x7f8d752d4208>>

请注意,即使作为连接功能的服务名称提供的名称只是“目标”,主机键条目也为“ ” [target.org]:15259”(即,它正在组合指定的端口)。 org'

完整的回溯看起来像...

Traceback (most recent call last):
  File "./source/local2ftp.2.py",line 52,in <module>
    cnopts=cnopts)
  File "/home/airflow/projects/backups/reporting/venv/lib/python3.6/site-packages/pysftp/__init__.py",line 132,in __init__
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
  File "/home/airflow/projects/backups/reporting/venv/lib/python3.6/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 target.org found.
Exception ignored in: <bound method Connection.__del__ of <pysftp.Connection object at 0x7f1a61df6f98>>
Traceback (most recent call last):
  File "/home/airflow/projects/backups/reporting/venv/lib/python3.6/site-packages/pysftp/__init__.py",line 1013,in __del__
    self.close()
  File "/home/airflow/projects/backups/reporting/venv/lib/python3.6/site-packages/pysftp/__init__.py",line 784,in close
    if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'

请注意,我最初在命令行中通过sftp进行连接并在pysftp脚本中使用的用户不是运行该脚本的用户(我曾经用于连接sftp的用户服务器是一组用于连接的特殊凭据)。我不知道这是否相关。

解决方法

pysftp不支持带有端口的主机密钥条目。

  • 跳过pysftp并直接使用Paramiko。
  • 或者通过将[target.org]:15259文件中的target.org替换为known_hosts来破解它。
,

TLDR :该代码期望pystfp.Connection主机名与主机密钥文件(例如~/.ssh/known_hosts)中的主机名匹配,但是如果 hostkey中的rsa条目文件条目是通过指定端口的连接创建的,因此导致{_1}}无法理解/处理的格式设置了known_hosts中的rsa条目。

喜欢...

pysftp

创建的rsa条目看起来像...

[airflow@airflowetl reporting]$ sftp -oPort=15259 my_user@target.org

因此,当您将此主机密钥文件用于...中的'[target.org]:15259,[205.172.2.88]:15259 ssh-rsa AAAAB3HJGVJGCTCKHGVYTVKUH===...'

knownhosts

代码最终检查主机密钥文件中是否有类似

的条目
cnopts = pysftp.CnOpts(knownhosts=os.path.join(path,to,hostkey,or,known_hosts,file))
hostname = "target.org"
port = 15259
sftp = pysftp.Connection(hostname,port,username=user,password=pass,cnopts=cnopts)

(您以"target.org" 输入的内容)却只能找到

hostname

(hostkey / known_hosts文件中的条目的格式针对您所连接的特定端口),因此会引发错误。

请注意,您不能仅将“ [target.org]:15259” 用作"[target.org]:15259" 函数的hostname,要么只是为了使其匹配当pysftp.Connection()代码执行此内部检查时,因为它会说它不能识别服务名称,因为(显然)这不是有效的服务名称表示形式(即,它不仅仅知道将字符串分隔为{ {1}}和pysftp组件)。

我要做的是...

  • 复制最初连接到target.org主机时创建的known_hosts文件
  • 然后在该文件中,手动对其进行编辑以使其看起来像
hostname

特别是在代码中,port函数...

  1. 尝试访问get the hostkey
  2. 并使用基础的'target.org,205.172.2.88 ssh-rsa AAAAB3HJGVJGCTCKHGVYTVKUH===...' 模块尝试从pysftp.Connection() arg
  3. 中提供的Paraminko文件中find the hostkey entry
  4. 使用功能here将主机密钥文件中的字符串 literal 条目与您输入的knownhosts arg(其中,如果您使用特定端口进行连接,则创建了一个rsa条目,该条目作为文字时未按照您可能在cnopt arg中传递的格式进行格式化,甚至不是有效的主机名),从而使匹配变得混乱逻辑并导致其找不到任何匹配项
  5. 因此导致引发异常,here返回hostname代码

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。