我正在尝试使用 Paramiko 在专用网络上的两台服务器之间进行 SSH 通信。客户端服务器是一个 Web 服务器,主机服务器将是一个“工作”服务器。这个想法是不向工作服务器开放 HTTP 连接。唯一需要进行的通信是 Web 服务器需要将字符串传递给工作服务器上的脚本。为此,我希望使用 Paramiko 并通过 SSH 将信息传递给脚本。
我设置了一个新用户并在 Python 3 中创建了一个测试脚本,当我从我自己用户的 SSH 会话中从命令行运行它时,该脚本就可以工作。我将相同的代码放入我的 Django Web 应用程序中,认为它应该可以工作,因为它从命令行测试正常,但我收到以下错误:
在known_hosts中找不到服务器“worker-server”
现在,我想我理解了这个错误。在执行测试脚本时,我使用某个用户来访问服务器,并且已知的主机信息被保存到
~/.ssh/known_hosts
,即使该用户实际上是专门为此一项作业创建的第三方用户。因此,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 successful. Closing connection" )
stdout = stdout.readlines()
client.close()
print ( "Connection closed" )
output = ""
for line in stdout:
output = output + line
if output!="":
print ( output )
else:
print ( "There was no output for this command" )
HostKeys.add
: 在 Python 代码中硬编码主机密钥
import paramiko
from base64 import decodebytes
keydata = b"""AAAAB3NzaC1yc2EAAAABIwAAAQEA0hV..."""
key = paramiko.RSAKey(data=decodebytes(keydata))
client = paramiko.SSHClient()
client.get_host_keys().add('example.com', 'ssh-rsa', key)
client.connect(...)
这是基于我的回答:
Paramiko“未知服务器”.
要了解如何获取在代码中使用的指纹,请参阅我的回答:
使用 pysftp 验证主机密钥。
如果使用 pysftp,而不是直接使用 Paramiko,请参阅:
部署 Django/Heroku 时,PySFTP 失败,并显示“找不到主机 X 的主机密钥”
AutoAddPolicy
: 完全放弃验证主机密钥
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(...)
(只有当您确实不需要安全连接时才可以这样做)
除了Martin Prikryl答案之外,也许您正在为一个不知道此信息的动态环境进行编码,那么您可以自己验证主机,然后添加到know_hosts文件中。这个答案是面向系统管理员的。
直接添加:
$ ssh-keyscan sample.host.com >> ~/.ssh/known_hosts
o
$ ssh-keyscan 192.168.1.20 >> ~/.ssh/known_hosts
需要用户输入:
$ ssh sample.host.com
o
$ ssh 192.168.1.20
请记住,您必须拥有正确的凭据才能成功连接。