分层才能不靠猜
远程连接失败时,最浪费时间的做法是从应用报错开始猜。连接是逐层建立的:名字解析、路由可达、端口放行、服务监听、身份认证、权限与环境,任何一层不同,报错表现就完全不同,有的立刻失败,有的挂着不动直到超时。分层的意义是把「连不上」拆成可判定的问题,每一层都有对应的观测命令和明确结论,据此决定往上游还是下游继续查。
基本信息
| 适用对象 | SSH、数据库、HTTP API、后端服务之间的连接 |
|---|---|
| 分层顺序 | 解析 → 路由 → 端口 → 监听 → 认证 → 授权 → 应用 |
| 关键判据 | 立刻被拒绝说明对端有响应;一直挂起多为路径丢弃 |
| 常见误判 | 把 ICMP 应答当成 TCP 可达 |
| 耗时 | 按层推进通常几分钟内定位到方向 |
逐层推进顺序
- 先解析:确认域名解析到的地址与预期一致,排除解析结果过期或走错机房
- 再看路由:确认丢包发生在哪一跳,区分本地出口、中间链路与对端入口
- 再测端口:区分连接被拒绝、被静默丢弃、被重置三种结局,它们指向不同责任方
- 再查监听:确认服务真的在目标地址与端口上监听,而不是只监听回环
- 再验认证:确认密钥或口令可用、账号未被锁定、来源未被禁止
- 最后看授权与环境:命令能连上但执行失败,多与权限、路径、环境变量、字符集有关
一套常用的判据命令
一套常用的判据命令
getent hosts app.example.com # 解析结果是否与预期地址一致
mtr -rwzc 20 app.example.com # 看丢包出现在本地、中间还是对端
nc -vz app.example.com 443 # 端口通不通,报拒绝还是超时
ss -lntp | grep ':443' # 对端本机:谁在监听,监听地址是哪个
telnet app.example.com 443 # 无 nc 时的替代,立刻失败多为拒绝
curl -sv --max-time 5 https://app.example.com/ 2>&1 | head -20 # 应用层握手过程
ssh -vvv user@app.example.com 2>&1 | tail -30 # 认证阶段在哪一步停住现象与所属层
| 现象 | 最可能的层 | 下一步 |
|---|---|---|
| 名称或地址无法解析 | 解析层 | 核对解析记录与本机解析配置 |
| 一直挂起直到超时 | 路由或过滤层 | 用 mtr 定位丢弃点,检查放行策略 |
| 立刻连接被拒绝 | 端口或监听层 | 确认服务监听地址与端口 |
| 连接建立后被断开 | 认证或策略层 | 看对端登录日志与被拒原因 |
| 连上但命令报错 | 授权与环境层 | 检查权限、路径与环境变量 |
「被拒绝」和「被丢弃」的区分很关键:被拒绝说明包到达了对端且被明确回应,问题在对端主机或服务;被丢弃通常意味着路径上有设备静默丢掉包,责任在中间策略或路由。前者看服务日志,后者看链路与放行策略。
排查要记录时间点。连接失败往往是间歇性的,没有确切时间就无法在日志里定位对应记录;同时对端与客户端的时钟要大致同步,否则两边的日志无法按时间对齐。