我正在使用pysftp编写程序,它想要验证SSH主机密钥C:\Users\JohnCalvin\.ssh\known_hosts.
使用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()
Run Code Online (Sandbox Code Playgroud)
我收到的错误响应是:
E:\ Program Files(x86)\ Anaconda3\lib\site-packages\pysftp__init __.py:61:UserWarning:
无法从C:\ Users\JohnCalvin.ssh\known_hosts加载HostKeys.
您需要显式加载HostKeys(cnopts.hostkeys.load(filename))或disableHostKey检查(cnopts.hostkeys = None).warnings.warn(wmsg,UserWarning)Traceback(最近一次调用最后一次):文件"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中s = sftp.Connection(host ='138.99.99.129',用户名='root',密码='********')文件"E :\ Program Files(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找到了.在以下情况中忽略异常:> Traceback(最近一次调用最后一次):文件"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行,如果self._sftp_live关闭:AttributeError:'Connection'对象没有属性'_sftp_live'
我正在尝试使用 Paramiko 在专用网络上的两台服务器之间进行 SSH 通信。客户端服务器是一个 Web 服务器,而主机服务器将是一个“工人”服务器。这个想法是不向 HTTP 连接开放工作服务器。唯一需要发生的通信是 Web 服务器需要将字符串传递给工作服务器上的脚本。为此,我希望使用 Paramiko 并通过 SSH 将信息传递给脚本。
我设置了一个新用户并在 Python 3 中创建了一个测试脚本,当我从我自己用户的 SSH 会话中的命令行运行它时,它可以工作。我将相同的代码放入我的 Django Web 应用程序中,认为它应该可以工作,因为它从命令行测试正常,但出现以下错误:
在 known_hosts 中找不到服务器“worker-server”
现在,我想我明白这个错误了。在执行测试脚本时,我使用某个用户访问服务器,~/.ssh/known_hosts即使该用户实际上是为这项工作创建的第 3 方用户,但已知主机信息仍会保存。因此 Django 应用程序正在另一个用户下运行,该用户找不到已保存的已知主机信息,因为它无权访问该文件夹。据我所知,Apache 用来执行 Django 脚本的用户没有主目录。
有没有办法以Django进程可以看到的方式添加这个已知主机?
脚本:
import paramiko
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('worker-server', 22, 'workeruser', 'workerpass')
code = "123wfdv"
survey_id = 111
stdin, stdout, stderr =
client.exec_command('python3 /path/to/test_script/test.py %s %s' % ( code, survey_id ))
print( "ssh succuessful. Closing connection" )
stdout = stdout.readlines()
client.close()
print ( …Run Code Online (Sandbox Code Playgroud) 此代码引发异常。如何在不将其存储在文件中的情况下验证 SSH 指纹?我相信下面的代码是为公钥设计的。但是带有 SFTP 服务器的客户端验证了指纹并且没有给我公钥。
import os
import shutil
import pysftp
import paramiko
connection_info = {
'server': "example.com",
'user': "user",
'passwd': "password",
'target_dir': "out/prod",
'hostkey': "ssh-rsa 2048 d8:4e:f1:f1:f1:f1:f1:f1:21:31:41:14:13:12:11:aa",
}
def move_files_from_server_to_local(server, localpath):
target_dir = server['target_dir']
keydata = "d8:4e:f1:f1:f1:f1:f1:f1:21:31:41:14:13:12:11:aa"
key = paramiko.RSAKey(data=decodebytes(keydata))
options = pysftp.CnOpts()
options.hostkeys.add('example.com', 'ssh-rsa', key)
with pysftp.Connection(
server['server'],
username=server['user'],
password=server['passwd'],
cnopts=options) as conn:
conn.get_d(target_dir, localpath)
delete_files_from_dir(conn, target_dir)
move_files_from_server_to_local(connection_info, "/")
Run Code Online (Sandbox Code Playgroud)
该代码基于使用 pysftp 验证主机密钥。