You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 14:42:02