即使cnopts.hostkeys设置为None,但在pysftp代码中仍“找不到...的主机密钥”

时间:2019-03-14 04:36:30

标签: python sftp pysftp

背景

要通过SFTP到另一台服务器,我在UNIX命令行中使用以下命令:

sftp -i /some_dir/another_dir/key -oPort=12345 user@12.123.456.789

我要实现的目标

我想将此转换为与PySFTP一起使用的命令。

我尝试过的事情

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None

# source: https://pysftp.readthedocs.io/en/release_0.2.7/pysftp.html
srv = pysftp.Connection("user@12.123.456.789", port="12345",  
                         private_key_pass="/some_dir/another_dir/key")

遇到的错误

File "./aws_sql_dumper.py", line 14, in <module>
    srv = pysftp.Connection("user@12.123.456.789", port="12345",  private_key_pass="/some_dir/another_dir/key")
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 132, in __init__
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
  File "/usr/local/lib/python3.4/dist-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 user@12.123.456.789 found.
Exception ignored in: <bound method Connection.__del__ of <pysftp.Connection object at 0x7f6067c7ea20>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 1013, in __del__
    self.close()
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 784, in close
    if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'

已完成研究

我已阅读以下内容:

问题

我认为我在做一些根本性的错误。如何采用UNIX命令行中使用的SFTP命令以被pysftp接受/解释?


更改

我改变了一些事情

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys.load('/home/some_dir/.ssh/known_hosts')

# source: https://pysftp.readthedocs.io/en/release_0.2.7/pysftp.html
srv = pysftp.Connection("user@12.123.456.789", port="12345",  
                         private_key="/some_dir/another_dir/key", cnopts=cnopts)

更改后输出

Traceback (most recent call last):
  File "./aws_sql_dumper.py", line 17, in <module>
    srv = pysftp.Connection("user@12.123.456.789", port="12345",  private_key="/some_dir/another_dir/key", cnopts=cnopts)
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 132, in __init__
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
  File "/usr/local/lib/python3.4/dist-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 user@12.123.456.789" found.
Exception ignored in: <bound method Connection.__del__ of <pysftp.Connection object at 0x7f8120dc6438>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 1013, in __del__
    self.close()
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 784, in close
    if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live

3 个答案:

答案 0 :(得分:0)

您永远不会使用cnopts变量。

您需要将其传递给cnopts类的Connection参数,如对Verify host key with pysftp(虽然最受欢迎)的答案所示。

解决此问题后,私钥就会出现问题,因为将其传递给private_key_pass参数(“私钥密码” )而不是{{1} }。

private_key

尽管您不应该这样做srv = pysftp.Connection("user@12.123.456.789", port="12345", private_key="/some_dir/another_dir/key", cnopts=cnopts) ,因为这样做会失去安全性。正确的解决方案是验证主机密钥。检查my answer to the same question以获得正确的解决方案。

答案 1 :(得分:0)

经过反复试验,将以下SFTP命令转换为终端:

sftp -i /some_dir/another_dir/key -oPort=12345 user@12.123.456.789

可以翻译成*:

paramiko.SSHClient().connect(hostname='12.123.456.789', username='user', port=12345,
                             key_filename='/some_dir/another_dir/key')

整个压缩代码为:

#!/usr/bin/python3

import paramiko

try:
    client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.WarningPolicy)
    client.connect(hostname='12.123.456.789', username='user', port=12345, 
                   key_filename='/some_dir/another_dir/key')

    # -------------------------- [ just for testing ] --------------------------
    stdin, stdout, stderr = client.exec_command('ls -la')   # THIS IS FOR TESTING
    print(stdout.read())                                    # AND PRINTING OUT

finally:
    client.close()

答案 2 :(得分:0)

我遇到了类似的问题(主机密钥问题)并找到了一个很好的解决方案。我正在尝试从 Windows 框(源)连接到 Linux 框(目标)。在我的 Windows 机器中,我们已经在我登录的地方安装了 CYGWIN 并执行了以下操作

1. Logged in using my ID
2. Ran the command ssh-keygen -b 2048 -t rsa
3. under my cygwin home dir (~/.ssh) folder was created with pub and private key.
4. Physically this folder would be in c:\cygwin\home\/.ssh
5. Copy this folder and paste in the c:\user\\.ssh (windows home dir)
6. also open the pub key in the folder and paste that in the destination server ~\.ssh\authroized_keys. This is for password less login.

此后 pysftp 能够在没有密码的情况下进行连接。主机密钥将被检测到没有任何问题

-Prasanna.K