即使提供了 known_hosts 文件,pysftp 也会抛出 paramiko.ssh_exception.SSHException?
pysftp throwing paramiko.ssh_exception.SSHException even though known_hosts file provided?
获取错误
paramiko.ssh_exception.SSHException: No hostkey for host target.org found.
在使用 pysftp
时(对于需要特定端口的连接),即使我提供了最初用于连接到该位置的相同 known_hosts 文件(在 post here)。 IE。做了...
[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, "configs", "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 hostkeys 条目似乎确实包含正确的主机密钥...
<HostKeyEntry ['[target.org]:15259', '[205.172.2.88]:15259']: <paramiko.rsakey.RSAKey object at 0x7f8d752d4208>>
请注意,hostkey 条目是 '[target.org]:15259'(即它结合了指定的端口),即使该名称作为连接的服务名称提供函数只是 'target.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。
- 或者通过将
known_hosts
文件中的 [target.org]:15259
替换为 target.org
来破解它。
TLDR:代码期望 pystfp.Connection
主机名与主机密钥文件中的主机名相匹配(例如 ~/.ssh/known_hosts
),但是如果 rsa 条目在hostkey 文件条目是使用指定端口的连接创建的,因此导致 known_hosts 中的 rsa 条目以 pysftp
无法理解/处理的方式格式化 ,
喜欢...
[airflow@airflowetl reporting]$ sftp -oPort=15259 my_user@target.org
创建的 rsa 条目看起来像...
'[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
)但只找到
"[target.org]:15259"
(hostkey / known_hosts 文件中的条目为您连接的特定端口格式化)因此抛出错误。
另请注意,您不能只使用 "[target.org]:15259" 作为 pysftp.Connection()
函数的 hostname
要么只是为了在 pysftp
代码执行此内部检查时使其匹配,因为它会说它无法识别服务名称,因为(显然)这不是有效的服务名称表示(即它不会只知道将该字符串分成 hostname
和 port
组件)。
我要做的是...
- 复制我最初连接到 target.org 主机时创建的 known_hosts 文件
- 然后在那个文件中,手动编辑它看起来像
'target.org,205.172.2.88 ssh-rsa AAAAB3HJGVJGCTCKHGVYTVKUH===...'
具体在代码中,pysftp.Connection()
函数...
- 尝试get the hostkey
- 并使用底层
Paraminko
模块尝试从 cnopt
arg 中给出的 knownhosts
文件中 find the hostkey entry
- 它使用函数 here 将主机密钥文件中的字符串 文字 条目与您作为 [=31= 输入的
hostname
相匹配] arg(如果您连接到使用特定端口,则创建一个 rsa 条目,当作为文字使用时,它的格式与您可能传递 hostname
arg 的方式不同,甚至不是有效的主机名) ,从而混淆了匹配逻辑并导致它找不到任何匹配项
- 从而引发异常,here回到
pysftp
代码
获取错误
paramiko.ssh_exception.SSHException: No hostkey for host target.org found.
在使用 pysftp
时(对于需要特定端口的连接),即使我提供了最初用于连接到该位置的相同 known_hosts 文件(在 post here)。 IE。做了...
[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, "configs", "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 hostkeys 条目似乎确实包含正确的主机密钥...
<HostKeyEntry ['[target.org]:15259', '[205.172.2.88]:15259']: <paramiko.rsakey.RSAKey object at 0x7f8d752d4208>>
请注意,hostkey 条目是 '[target.org]:15259'(即它结合了指定的端口),即使该名称作为连接的服务名称提供函数只是 'target.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。
- 或者通过将
known_hosts
文件中的[target.org]:15259
替换为target.org
来破解它。
TLDR:代码期望 pystfp.Connection
主机名与主机密钥文件中的主机名相匹配(例如 ~/.ssh/known_hosts
),但是如果 rsa 条目在hostkey 文件条目是使用指定端口的连接创建的,因此导致 known_hosts 中的 rsa 条目以 pysftp
无法理解/处理的方式格式化 ,
喜欢...
[airflow@airflowetl reporting]$ sftp -oPort=15259 my_user@target.org
创建的 rsa 条目看起来像...
'[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
)但只找到
"[target.org]:15259"
(hostkey / known_hosts 文件中的条目为您连接的特定端口格式化)因此抛出错误。
另请注意,您不能只使用 "[target.org]:15259" 作为 pysftp.Connection()
函数的 hostname
要么只是为了在 pysftp
代码执行此内部检查时使其匹配,因为它会说它无法识别服务名称,因为(显然)这不是有效的服务名称表示(即它不会只知道将该字符串分成 hostname
和 port
组件)。
我要做的是...
- 复制我最初连接到 target.org 主机时创建的 known_hosts 文件
- 然后在那个文件中,手动编辑它看起来像
'target.org,205.172.2.88 ssh-rsa AAAAB3HJGVJGCTCKHGVYTVKUH===...'
具体在代码中,pysftp.Connection()
函数...
- 尝试get the hostkey
- 并使用底层
Paraminko
模块尝试从cnopt
arg 中给出的 - 它使用函数 here 将主机密钥文件中的字符串 文字 条目与您作为 [=31= 输入的
hostname
相匹配] arg(如果您连接到使用特定端口,则创建一个 rsa 条目,当作为文字使用时,它的格式与您可能传递hostname
arg 的方式不同,甚至不是有效的主机名) ,从而混淆了匹配逻辑并导致它找不到任何匹配项 - 从而引发异常,here回到
pysftp
代码
knownhosts
文件中 find the hostkey entry