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

Python整合SSH与SCP经中转服务器实现跨多服务器文件拉取

实现方案

脚本仅需在Server1(本地服务器)运行,无需在Server2部署任何代码或文件,核心通过SSH嵌套隧道打通Server1到Server3的传输通路,文件流经Server2内存转发,全程不会在Server2磁盘生成临时文件。

前置依赖

在Server1执行命令安装所需Python库:

pip install paramiko

可直接运行的代码

将代码中服务器地址、认证信息、文件路径替换为实际环境配置即可:

import paramiko
import os

# 环境配置,按需替换
SVR_CONF = {
    "jump": {
        "host": "Server2的公网/可访问IP",
        "port": 22,
        "username": "Server2登录用户名",
        # 密码和密钥认证二选一,推荐密钥
        "password": "Server2登录密码",
        # "key_path": "/本地用户/.ssh/id_rsa"
    },
    "target": {
        "host": "Server3的IP(Server2可直达的内网/公网地址)",
        "port": 22,
        "username": "Server3登录用户名",
        "password": "Server3登录密码",
        # "key_path": "/path/to/server3/key"
    },
    "remote_file": "Server3上待拉取文件的绝对路径",
    "local_save": "Server1上文件保存的绝对路径"
}

def init_ssh(host, port, user, pwd=None, key_path=None, sock=None):
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    if key_path and os.path.exists(key_path):
        pkey = paramiko.RSAKey.from_private_key_file(key_path)
        client.connect(host, port, user, pkey=pkey, sock=sock)
    else:
        client.connect(host, port, user, password=pwd, sock=sock)
    return client

def pull_file():
    # 建立到中转机Server2的连接
    jump_cli = init_ssh(
        SVR_CONF["jump"]["host"],
        SVR_CONF["jump"]["port"],
        SVR_CONF["jump"]["username"],
        SVR_CONF["jump"].get("password"),
        SVR_CONF["jump"].get("key_path")
    )
    # 打通到Server3的转发通道
    jump_trans = jump_cli.get_transport()
    target_chan = jump_trans.open_channel(
        "direct-tcpip",
        (SVR_CONF["target"]["host"], SVR_CONF["target"]["port"]),
        ("", 0)
    )
    # 连接目标Server3
    target_cli = init_ssh(
        SVR_CONF["target"]["host"],
        SVR_CONF["target"]["port"],
        SVR_CONF["target"]["username"],
        SVR_CONF["target"].get("password"),
        SVR_CONF["target"].get("key_path"),
        sock=target_chan
    )
    # SFTP拉取文件
    sftp = target_cli.open_sftp()
    sftp.get(SVR_CONF["remote_file"], SVR_CONF["local_save"])
    # 关闭连接
    sftp.close()
    target_cli.close()
    jump_cli.close()
    print(f"文件拉取完成,已保存到{SVR_CONF['local_save']}")

if __name__ == "__main__":
    pull_file()

补充说明

  • 优先使用SSH密钥认证,安全性更高,配置时注释掉password字段、填写正确的key_path即可
  • 如果需要传输整个目录,只需替换SFTP单文件拉取逻辑为目录递归遍历下载即可,隧道部分无需改动
  • 大文件传输可以给sftp.get()方法添加进度回调函数,实时显示传输进度
  • 如果本地已经在~/.ssh/config中配置了Server3通过Server2跳转的ProxyJump规则,paramiko可以直接读取本地SSH配置,无需手动编写隧道逻辑

内容的提问来源于stack exchange,提问作者darth_vader

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:18:43