2025-10-05 11:23:33 +08:00

8.7 KiB
Raw Permalink Blame History

以下是为提供的 Python 代码编写的 Markdown 格式技术文档,涵盖了模块功能、类说明、方法描述及使用示例。


SSH 连接管理模块技术文档

概述

本模块基于 asyncssh 实现了异步 SSH 客户端连接能力支持通过跳板机Jump Server链式连接远程主机并提供文件传输、命令执行和交互式 Shell 等高级功能。适用于批量运维操作、自动化部署与安全网络环境下的远程控制。

主要特性:

  • 异步非阻塞 I/O高并发处理多台服务器
  • 支持密码或密钥认证
  • 支持多级跳板机穿透
  • 提供 SCP 文件上传下载接口
  • 支持交互式命令执行(如 Bash
  • 封装简洁易用的高层 API

依赖库:

pip install asyncssh shlex

模块导入说明

import os
import sys
import time
import shlex
from traceback import format_exc
from contextlib import asynccontextmanager
from functools import partial
from threading import Thread
from appPublic.myTE import tmpTml
from appPublic.log import debug, exception
import asyncio
import asyncssh

注意:appPublic.* 是项目自定义工具包,包含日志记录与模板引擎等功能。


核心类说明

1. SSHServer

表示一个可通过跳板机访问的目标 SSH 服务器。

初始化参数

参数 类型 说明
server dict 目标服务器配置,格式见下表
jumpservers list[dict] 跳板机列表(可选),每个元素结构同 server

server 字典字段说明:

键名 类型 默认值 说明
host str 必填 主机地址IP 或域名)
username str 'root' 登录用户名
port int 22 SSH 端口
password str None 登录密码(优先级低于密钥)
client_keys list[str] [] 私钥路径列表(如 ['~/.ssh/id_rsa']
passphrase str None 密钥加密口令
jumpservers list[dict] None 内嵌跳板机配置(若未传构造函数参数)

方法

_connect_server(server: dict, refconn=None) -> asyncssh.SSHClientConnection

内部方法,建立到指定服务器的连接。

  • refconn 存在,则通过已有连接隧道建立新连接(用于跳板穿透)
  • 支持密钥或密码认证自动选择
get_connector() -> Async Context Manager

上下文管理器,返回目标主机连接对象,自动处理连接建立与释放。

示例:

async with ssh_server.get_connector() as conn:
    result = await conn.run('ls -l')
    print(result.stdout)

自动关闭所有跳板机连接,异常时捕获并记录日志。


2. SSHNode

增强版 SSH 节点,封装完整生命周期管理与多种操作接口。

初始化参数

参数 类型 默认值 说明
host str 必填 目标主机地址
username str 'root' 用户名
port int 22 SSH 端口
password str None 登录密码
client_keys list[str] [] 客户端私钥路径
passphrase str None 私钥解密口令
jumpers list[dict] [] 跳板机列表

属性

  • conn: 当前节点主连接 (asyncssh.SSHClientConnection)
  • jumper_conns: 所有跳板连接列表
  • batch_cmds: 待执行命令队列(暂未完全实现)

方法

方法 功能
info() → dict 返回当前节点信息快照
asjumper() → list[dict] 返回可用于其他节点跳板的配置列表
set_jumpers(jumpers) 动态设置跳板机
connect() 建立完整连接链(跳板 + 主机)
close() 关闭所有连接资源
run(cmd, ...) 执行单条命令(自动连接/关闭)
_cmd, _run, _process, _l2r, _r2l 内部操作封装
run(cmd, input=None, stdin=None, stdout=None)

执行远程命令,支持以下特殊语法:

  • l2r <local_path> <remote_path>:本地 → 远程复制SCP
  • r2l <remote_path> <local_path>:远程 → 本地复制SCP

否则调用 conn.run() 执行普通命令。

_xcmd(cmd, xmsgs=[], ns={}, show_input=None, show_stdout=None)

执行交互式命令,支持定时输入模拟。

  • xmsgs: 输入消息列表,格式 [ (delay_sec, template_string), ... ]
  • ns: 模板变量命名空间
  • show_input, show_stdout: 回调函数,用于输出监控

示例:自动登录 CLI 工具、数据库等需要逐步输入的场景。


3. SSHNodes

批量管理多个 SSHNode 的容器类,支持并行执行。

初始化参数

参数 类型 说明
nodes list[str] 主机名/IP 列表
username str 统一用户名
port int 统一端口
jumpers list[dict] 共享跳板机配置

方法

方法 功能
append_cmd(cmd, stdin, stdout) 添加待批处理命令
run(cmd, ...) 并发运行命令于所有节点
exe_batch() 执行预设批处理命令队列(注意:当前存在 bug

使用 asyncio.gather(..., return_exceptions=True) 避免单个失败中断整体流程。

示例

hosts = ['192.168.1.10', '192.168.1.11']
jump = {"host": "jumper.example.com", "username": "jumpuser", "port": 22}
cluster = SSHNodes(hosts, jumpers=[jump])

results = await cluster.run("uptime")
for r in results:
    if isinstance(r, Exception):
        print("Error:", r)
    else:
        print(r.stdout.strip())

4. SSHBash

实现交互式远程 Bash Shell 会话,支持实时输入输出转发。

构造函数

SSHBash(node: SSHNode, loop=None)
  • node: 已配置的 SSHNode 实例
  • loop: 可选事件循环(默认使用当前)

内部启动独立线程运行子事件循环,避免阻塞主线程。

核心方法

run(read_co, write_co)

启动交互式 Bash 会话。

  • read_co: 异步可调用对象,用于读取用户输入(例如从 stdin
  • write_co: 异步回调,用于写入输出内容(如打印到终端)

底层使用 create_process('bash', term_type='xterm-256color')

feed_stdin(f)

将输入数据推送到远程进程 stdin。

exit()

清理资源:关闭连接、停止子线程事件循环。

使用示例

async def read_input():
    return os.read(sys.stdin.fileno(), 65535)

async def write_output(data):
    sys.stdout.write(data.decode('utf-8'))
    sys.stdout.flush()

bash = SSHBash(my_ssh_node)
await bash.run(read_input, write_output)

5. SshConnector

轻量级连接包装器,提供更直观的操作接口。

⚠️ Bug 提示l2r 方法中 recurse=Tree 应为 recurse=True

方法

方法 功能
r2l(rf, lf) 下载文件:远程 → 本地
l2r(lf, rf) 上传文件:本地 → 远程
run_process(*args, **kw) 创建远程进程
run(cmdline, ...) 执行命令并返回结果

辅助函数与入口点

main()

命令行交互入口,演示如何动态输入命令对多个主机批量执行。

python script.py "df -h" host1 host2 ...

当前版本进入无限循环等待用户输入。

test_sshbash()

测试交互式 Bash 功能的示例函数。


已知问题与改进建议

问题 描述 建议修复
SSHNodes.__init__ 拼写错误 usernmaeusername 更正拼写
exe_batch()return_excetion=True 拼写错误导致异常不被捕获 改为 return_exceptions=True
exe_batch()gather 后仍有代码 return 后不会执行后续行 移动 for 循环至 gather 之后
SshConnector.l2rself.comm 应为 self.conn 修正属性引用
show_result() 中变量 e 未定义 print('Exception:', e) 报错 改为 print('Exception:', x)
recurse=Tree 应为布尔值 True 修改为 recurse=True

总结

该模块构建了一个灵活高效的异步 SSH 操作框架,特别适合在受限网络环境中通过跳板机批量管理服务器。结合 asyncssh 的强大功能,实现了文件传输、命令执行、交互式 Shell 等核心运维需求。

建议进一步完善单元测试、增加连接池、超时控制与重试机制以提升稳定性。


📌 维护建议

  • 添加类型注解Type Hints
  • 补充 docstring 文档字符串
  • 分离配置加载逻辑
  • 增加连接健康检查机制

适用场景

  • 自动化部署系统
  • 多数据中心运维脚本
  • DevOps 流水线中的远程操作环节
  • 内网服务器集中管理平台

文档版本v1.0
最后更新2025年4月5日