如何用Python经已连接的实例A远程SSH访问实例B并执行命令
Python 实现多SSH跳转的方案
1. 基于 Paramiko 原生实现(无需额外库)
既然你已经用 Paramiko 连好了实例A,可以直接利用现有连接建立到实例B的通道,不用嵌套执行ssh命令:
- 核心思路:借助实例A的SSH传输层,直接打通到实例B的TCP通道,再基于这个通道建立到B的SSH连接
- 代码示例:
import paramiko # 已有的实例A连接(假设你已经完成这部分配置) a_client = paramiko.SSHClient() a_client.load_system_host_keys() a_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) a_client.connect('实例A的IP/主机名', username='A的用户名', password='A的密码') # 获取实例A的传输对象,打开到实例B的TCP通道 a_transport = a_client.get_transport() dest_addr = ('实例B的IP/主机名', 22) local_addr = ('实例A的IP/主机名', 22) channel = a_transport.open_channel("direct-tcpip", dest_addr, local_addr) # 通过通道建立实例B的SSH连接 b_client = paramiko.SSHClient() b_client.load_system_host_keys() b_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) b_client.connect('实例B的IP/主机名', username='B的用户名', password='B的密码', sock=channel) # 在实例B上执行命令 stdin, stdout, stderr = b_client.exec_command('你要执行的命令') print(stdout.read().decode()) # 关闭连接 b_client.close() a_client.close()
注:这种方式不需要在实例A的shell中执行sudo su,直接通过网络转发实现跳转,更高效可靠。
2. 使用 sshtunnel 库简化隧道创建
sshtunnel专门封装了SSH隧道逻辑,配置更简洁:
- 先安装依赖:
pip install sshtunnel - 代码示例:
from sshtunnel import SSHTunnelForwarder import paramiko # 建立本地到实例B的隧道,通过实例A中转 with SSHTunnelForwarder( ('实例A的IP/主机名', 22), ssh_username='A的用户名', ssh_password='A的密码', remote_bind_address=('实例B的IP/主机名', 22) ) as tunnel: # 本地的tunnel.local_bind_port对应实例B的22端口 b_client = paramiko.SSHClient() b_client.load_system_host_keys() b_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) b_client.connect('127.0.0.1', username='B的用户名', password='B的密码', port=tunnel.local_bind_port) # 执行命令 stdin, stdout, stderr = b_client.exec_command('你的命令') print(stdout.read().decode()) b_client.close()
3. 使用 Fabric 框架(适合批量多主机操作)
Fabric v2+ 原生支持跳板机配置,适合需要在多台机器上批量执行命令的场景:
- 安装依赖:
pip install fabric - 代码示例:
from fabric import Connection # 定义实例A作为网关连接 gateway_conn = Connection( host='实例A的IP/主机名', user='A的用户名', connect_kwargs={'password': 'A的密码'} ) # 定义实例B的连接,指定网关为A b_conn = Connection( host='实例B的IP/主机名', user='B的用户名', connect_kwargs={'password': 'B的密码'}, gateway=gateway_conn ) # 在实例B上执行命令 result = b_conn.run('你的命令', hide=True) print(result.stdout)
非Python实现方案
如果不想用Python,直接借助系统SSH工具更简单:
- 利用OpenSSH的
ProxyJump特性(7.4版本以上支持),直接命令行跳转执行:
ssh -J A的用户名@实例A的IP B的用户名@实例B的IP "要执行的命令"
- 如果需要先在实例A执行
sudo su再跳转,可调整命令:
ssh A的用户名@实例A的IP "sudo su -c 'ssh B的用户名@实例B的IP \"要执行的命令\"'"
若要在Python中调用这个逻辑,推荐用subprocess替代os.system,便于捕获输出:
import subprocess cmd = "ssh -J A用户名@AIP B用户名@BIP '你的命令'" result = subprocess.run(cmd, shell=True, capture_output=True, text=True) print(result.stdout)
内容的提问来源于stack exchange,提问作者Hitesh Jarwani
相关产品推荐
相关产品推荐

