使用Paramiko实现文件往返传输时,远程反向连接本地失败求助
问题原因分析
- 本地网络限制:远程机器无法直接访问本地,比如本地处于内网无公网IP,或者防火墙拦截了SSH端口(默认22),导致远程连接请求被阻断。
- 本地SSH服务未正确配置:本地SSH服务未开启,或者配置文件(如
/etc/ssh/sshd_config)限制了远程连接(比如仅允许内网IP、禁用了对应登录方式)。 - 远程代码未捕获异常:远程端代码在
client.connect()阶段可能抛出错误,但未添加异常处理逻辑,导致程序静默卡住,看起来像是停在client = paramiko.SSHClient()这一步。
替代实现方案(推荐)
无需让远程机器反向连接本地,直接由本地主动拉取处理后的文件,避免网络穿透等复杂问题,具体代码如下:
import paramiko # 配置参数 REMOTE_IP = "远程机器IP" REMOTE_USER = "远程用户名" LOCAL_SOURCE_FILE = "/本地/待上传文件路径" REMOTE_UPLOAD_PATH = "/远程/保存上传文件的路径" REMOTE_PROCESSED_FILE = "/远程/处理完成后的文件路径" LOCAL_SAVE_PATH = "/本地/保存处理后文件的路径" # 建立SSH连接 client = paramiko.SSHClient() client.load_system_host_keys() client.connect(hostname=REMOTE_IP, username=REMOTE_USER) # 上传待处理文件 sftp = client.open_sftp() sftp.put(LOCAL_SOURCE_FILE, REMOTE_UPLOAD_PATH) # 执行远程处理脚本,等待执行完成 stdin, stdout, stderr = client.exec_command("python3 /home/scripts/main.py") # 等待命令执行结束并获取退出状态 exit_code = stdout.channel.recv_exit_status() if exit_code == 0: print("远程文件处理完成") # 拉取处理后的文件到本地 sftp.get(REMOTE_PROCESSED_FILE, LOCAL_SAVE_PATH) else: # 打印错误信息 print(f"处理脚本执行失败: {stderr.read().decode('utf-8')}") # 关闭连接 sftp.close() client.close()
若坚持使用反向连接的排查建议
如果必须让远程机器主动连接本地,需解决以下问题:
- 本地网络穿透:若本地处于内网,需通过路由器端口映射将本地SSH端口(默认22)映射到公网IP,或使用内网穿透工具。
- 开放防火墙端口:在本地防火墙中添加规则,允许远程机器的IP访问本地22端口。
- 修正远程代码:添加异常捕获,打印具体错误信息,定位卡壳原因:
import paramiko import traceback try: client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) print("SSHClient 初始化完成") # 替换为本地公网IP、用户名、认证信息 client.connect(hostname="本地公网IP", username="本地用户名", password="本地登录密码") print("成功连接本地机器") # 传输处理后的文件 sftp = client.open_sftp() sftp.put("/远程/处理完成后的文件", "/本地/目标路径") sftp.close() client.close() except Exception as e: print(f"连接/传输失败: {str(e)}") traceback.print_exc()
内容的提问来源于stack exchange,提问作者AMLO_TACTICO
相关产品推荐
相关产品推荐

