我有一个项目,该项目需要SSH到大量服务器上才能经常调用命令。我以为可以从python脚本中实现,但是我的要求似乎消除了所有潜在的解决方案。我只能从中间堡垒服务器访问服务器,并且只能使用由ssh代理转发的ssh公钥。因此,我的要求是:


并行ssh,这样我就不必等待数小时才能在所有服务器上运行命令以完成操作
ssh公钥支持,因为我无法使用密码身份验证
ssh代理支持,因为如果不通过ssh代理服务器就无法直接ssh到服务器
ssh代理支持,因为我需要将我的(预加载的)ssh公钥通过代理服务器发送到服务器


paramiko似乎提供了上述所有内容,但第一个要求(并行ssh支持)除外。我发现了一个并行ssh模块(https://github.com/pkittenis/parallel-ssh),它充当paramiko的薄包装器,但是可惜,除了并行ssh和公共密钥auth之外,它似乎缺乏对所有其他东西的API支持。

这就是我现在所拥有的,它可以在一些不需要代理或ssh-agent进行访问的本地服务器上运行:

#!/usr/bin/python2.7

import sys
if 'threading' in sys.modules:
        raise Exception('threading module loaded before patching!')
import gevent.monkey; gevent.monkey.patch_thread()
import paramiko
from pssh import ParallelSSHClient

paramiko.util.log_to_file("filename.log")
hosts = ['ocb100','netllama']
client_key = paramiko.DSSKey.from_private_key_file('/home/netllama/.ssh/id_dsa')
client = ParallelSSHClient(hosts, pkey=client_key)

cmds = client.exec_command('uptime')

最佳答案

您前面提到的parallel-ssh模块可以满足您的要求。专门用于代理和代理转发:


SSH代理支持-本机代理和隧道支持,也异步
SSH代理转发-默认情况下启用。 forward_ssh_agent=True关于创建ParallelSSH对象的信息。


您使用ParallelSSH的示例:

from pssh import ParallelSSHClient
hosts = ['ocb100','netllama']
client = ParallelSSHClient(hosts, proxy_host='bastion')
output = client.run_command('uptime')
for host in output:
    for line in output[host]['stdout']:
        print(line)


执行上述操作的用户的SSH密钥是从正在运行的SSH代理自动加载的,无需指定pkey参数。

如果需要更改用户登录名,可以设置user参数,例如ParallelSSHClient(hosts, user='netllama')

根据this issue,SSH代理转发支持已于9月4日添加到ParallelSSH。

ParallelSSH已经使用gevent按文档异步执行所有网络请求,它不像架构那样使用线程或多处理。因此,您也不需要这些gevent导入。

ParallelSSH的文档为here

编辑:更新为最新的库API

09-04 00:48
查看更多