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

如何复用已创建的SSH隧道执行远程命令并验证主机密钥?

自动化多远程VNC连接的问题与解决方案

需求背景

我正尝试自动化启动多台远程系统的VNC客户端,目前通过LocalForward 15900 127.0.0.1:5900实现端口转发,但因可能同时运行多个VNC查看器,本地端口需动态配置而非硬编码。计划实现脚本完成以下步骤:

  • 查找未使用的本地端口(freePort);
  • 以指定用户身份SSH连接到远程计算机;
  • 创建从远程5900端口到本地freePort的隧道;
  • 远程执行x11vnc -xkb -display :0 -localhost命令;
  • 本地执行vncviewer localhost:freePort命令。

已实现步骤1,并使用SSHTunnelForwarder完成隧道创建,现在需要解决两个问题:

  1. 如何复用已创建的SSH隧道执行远程命令,而非新建连接?
  2. 如何基于known_hosts数据库验证远程主机密钥?

解决方案

复用已创建的SSH隧道执行远程命令

SSHTunnelForwarder基于paramiko实现,创建并启动隧道后,它的ssh_client属性就是已经建立好的SSH连接实例,直接用这个实例执行远程命令即可,完全不需要新建连接。示例代码如下:

from sshtunnel import SSHTunnelForwarder
import socket
import subprocess

# 步骤1:获取空闲本地端口
def get_free_port():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(('', 0))
        return s.getsockname()[1]

free_port = get_free_port()

# 配置并启动SSH隧道
with SSHTunnelForwarder(
    ('remote_host', 22),
    ssh_username='your_username',
    ssh_pkey='~/.ssh/id_rsa',  # 优先用密钥登录,也可替换为ssh_password
    local_bind_address=('127.0.0.1', free_port),
    remote_bind_address=('127.0.0.1', 5900)
) as tunnel:
    # 复用已有SSH连接执行远程x11vnc命令
    # 加&让命令后台运行,避免阻塞脚本
    stdin, stdout, stderr = tunnel.ssh_client.exec_command(
        'x11vnc -xkb -display :0 -localhost &'
    )
    # 可选:捕获输出用于排查问题
    print("命令输出:", stdout.read().decode())
    print("错误信息:", stderr.read().decode())

    # 步骤5:启动本地VNC查看器
    subprocess.run(['vncviewer', f'localhost:{free_port}'])

基于known_hosts验证远程主机密钥

要让SSH连接严格遵循known_hosts的验证规则,需要加载本地的known_hosts文件,并配置paramiko的密钥验证策略,避免连接到不可信主机。示例代码如下:

from sshtunnel import SSHTunnelForwarder
from paramiko import HostKeys, RejectPolicy
import os
import socket
import subprocess

def get_free_port():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind(('', 0))
        return s.getsockname()[1]

free_port = get_free_port()

# 加载本地known_hosts文件
known_hosts_path = os.path.expanduser('~/.ssh/known_hosts')
host_keys = HostKeys(filename=known_hosts_path)

# 配置带密钥验证的SSH隧道
with SSHTunnelForwarder(
    ('remote_host', 22),
    ssh_username='your_username',
    ssh_pkey='~/.ssh/id_rsa',
    local_bind_address=('127.0.0.1', free_port),
    remote_bind_address=('127.0.0.1', 5900),
    host_keys=host_keys,
    # 拒绝未知主机,若需自动添加可替换为AutoAddPolicy()(不推荐生产环境)
    missing_host_key_policy=RejectPolicy()
) as tunnel:
    # 执行远程命令与启动VNC逻辑同上
    stdin, stdout, stderr = tunnel.ssh_client.exec_command(
        'x11vnc -xkb -display :0 -localhost &'
    )
    subprocess.run(['vncviewer', f'localhost:{free_port}'])

内容的提问来源于stack exchange,提问作者Mikhail T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 10:53:18