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

服务器A通过SSH随机无法连接远程服务器问题排查求助

随机SSH连接失败问题排查与解决建议

问题背景

我有一台服务器A,需连接多台远程服务器,并将文件从这些远程服务器传输至服务器A的目标目录。编写了如下脚本用于连接服务器并检查文件是否存在,脚本会根据检查结果执行文件传输或打印“文件未找到”提示:

if ssh -n user@${server};
    then
      printf "We are in -- $server --\n"
      if ssh -n user@${server} test -e $SOURCEFILE;
        then
          printf "File found in -- $server --\n\n"
          #command to transfer the files
      else
        printf "File not found in -- $server --\n\n"
      fi
  else
    printf "Unable to access -- $server --\n\n"
  fi

实际运行时,服务器A与远程服务器的SSH连接会随机失败。例如,今日运行脚本时可能服务器B出现错误,明日服务器B恢复正常,但服务器C又出现连接失败问题。已尝试删除并重新生成主机密钥(hostkeys),但问题仍未解决。


1. 重复SSH连接触发资源限制

你的脚本每次判断连接、检查文件都会新建独立SSH连接,批量处理多台服务器时,短时间内大量新建连接容易触发远程服务器sshd的连接数限制(默认MaxStartups参数为10:30:100,即最多10个未认证连接,超过后按比例拒绝请求,直到完全拒绝),这是随机失败的常见原因。

解决建议:

  • 使用SSH连接复用(ControlMaster),让多个操作共享同一个连接,减少连接建立次数:
    # 提前创建控制套接字存储目录
    mkdir -p ~/.ssh/controlmasters
    
    # 建立后台复用连接
    ssh -fN -o ControlMaster=yes -o ControlPath=~/.ssh/controlmasters/%h-%p-%r user@${server}
    if [ $? -eq 0 ]; then
        printf "Connected to -- $server --\n"
        # 通过复用连接执行文件检查
        if ssh -o ControlPath=~/.ssh/controlmasters/%h-%p-%r user@${server} test -e "$SOURCEFILE"; then
            printf "File found in -- $server --\n\n"
            # 用复用连接传输文件(scp同样支持ControlPath参数)
            scp -o ControlPath=~/.ssh/controlmasters/%h-%p-%r user@${server}:"$SOURCEFILE" /your/target/directory/
        else
            printf "File not found in -- $server --\n\n"
        fi
        # 关闭复用连接
        ssh -o ControlPath=~/.ssh/controlmasters/%h-%p-%r user@${server} -O exit
    else
        printf "Unable to access -- $server --\n\n"
    fi
    
  • 调整远程服务器/etc/ssh/sshd_config中的MaxStartups和MaxSessions参数,适当提高连接限制,修改后重启sshd服务。

2. 网络链路不稳定导致随机丢包

路由波动、防火墙临时拦截、DNS解析异常等网络问题,也会引发随机连接失败。

排查与解决:

  • 在脚本中添加SSH调试日志,定位具体失败原因:
    # 连接时输出调试信息到日志文件
    ssh -v -n user@${server} 2>&1 >> ssh_debug_${server}.log
    
    连接失败后查看日志,重点关注Connection refused、Timeout、Host key verification failed这类关键词。
  • 给SSH添加超时和重试机制,避免单次失败直接终止:
    # 最多重试3次,每次连接超时10秒
    retry_count=3
    connect_success=0
    for i in $(seq 1 $retry_count); do
        if ssh -o ConnectTimeout=10 -n user@${server} exit; then
            connect_success=1
            break
        fi
        sleep 2
    done
    if [ $connect_success -eq 0 ]; then
        printf "Failed to connect to -- $server -- after $retry_count retries\n\n"
        continue
    fi
    # 后续执行文件检查、传输操作
    
  • 检查服务器A与远程服务器之间的防火墙规则,确认是否有临时流量限制;尝试用IP代替域名连接,排除DNS解析不稳定的影响。

3. 主机密钥缓存或权限异常

即使重新生成了主机密钥,也可能存在旧密钥残留或文件权限错误的问题:

  • 清理服务器A上~/.ssh/known_hosts中对应远程服务器的旧密钥条目,重新连接时会自动生成新的认证记录。
  • 确保~/.ssh目录权限为700,~/.ssh/known_hosts权限为600,权限过高或过低都会导致SSH认证失败。

4. 远程服务器负载过高

当远程服务器CPU、内存或磁盘IO负载飙升时,sshd服务无法及时响应新连接请求,也会出现随机失败。

排查方法:

  • 在连接失败时,远程执行uptime、top命令查看实时负载;或配置监控工具(如Prometheus+Grafana)长期跟踪服务器负载变化。
  • 若确认是负载问题,关闭远程服务器上不必要的后台进程,优化资源占用,或升级硬件配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:48:08