3、网络故障排查(下):HTTP状态码详解(4xx/5xx)、SSL/TLS握手失败、防火墙与安全组规则排查

3.1 从一次“白屏”事故说起

我记得有一次深夜被叫起来,说线上核心业务全部“白屏”。用户访问页面,浏览器转圈圈,最后显示“无法访问此网站”。

我第一反应不是看代码,而是先看网络层。你想想看,如果是代码逻辑挂了,通常返回的是500或者业务异常页面,而不是浏览器直接报错。这种“连不上”的情况,十有八九是网络层或者安全组出了问题。

那天晚上排查下来,发现是新上线的WAF规则误拦截了所有POST请求。嗯,这就是典型的“安全组/防火墙规则”搞的鬼。所以今天咱们就把网络故障排查里最核心的三个模块讲透:HTTP状态码、SSL/TLS握手、以及防火墙规则。

核心观点:网络故障排查,80%的问题集中在“状态码异常”、“证书握手失败”、“安全组/防火墙拦截”这三类。掌握了它们,你就掌握了网络排障的半壁江山。

网络故障排查核心 HTTP状态码 SSL/TLS握手 防火墙/安全组 4xx 客户端错误 5xx 服务端错误 重定向/信息类 证书验证失败 密码套件不匹配 SNI/域名问题 入站规则拦截 出站规则拦截 WAF/IPS误报

3.2 HTTP状态码:4xx 和 5xx 的“潜台词”

HTTP状态码其实就像服务器给你的“暗号”。4xx开头的,意思是“你的请求有问题”;5xx开头的,意思是“我(服务器)内部出问题了”。

我个人习惯,遇到问题先看状态码,再看响应体。很多时候状态码已经告诉你80%的真相了。

3.2.1 常见的4xx状态码

状态码 含义 常见原因 排查方向
400 Bad Request 请求格式错误 JSON格式不对、参数缺失、请求头错误 检查请求体、Content-Type、参数格式
401 Unauthorized 未认证 缺少Token、Token过期、Basic Auth错误 检查Authorization头、刷新Token
403 Forbidden 无权限 IP被限制、安全组拒绝、WAF拦截 检查安全组规则、WAF日志、IP白名单
404 Not Found 资源不存在 URL写错、路由未配置、后端服务未部署 检查URL路径、Nginx路由、服务部署状态
405 Method Not Allowed 请求方法不支持 API只支持POST,但用了GET 确认API文档支持的HTTP方法
429 Too Many Requests 请求频率过高 触发了限流策略 检查限流配置、增加重试间隔

实战技巧:遇到403时,别急着改代码。先curl一下看看返回头里有没有X-Request-Id或者X-Cache字段。如果有,说明请求到了WAF或者CDN层,问题大概率出在中间件上。我曾经花了两小时查代码,最后发现是CDN的Referer防盗链规则没配好。

3.2.2 常见的5xx状态码

状态码 含义 常见原因 排查方向
500 Internal Server Error 服务器内部错误 代码异常、数据库连接失败、配置错误 查看应用日志、检查数据库连接池
502 Bad Gateway 网关/代理错误 上游服务挂了、Nginx连不上后端 检查后端服务健康状态、Nginx upstream配置
503 Service Unavailable 服务暂时不可用 服务过载、正在重启、维护中 检查负载、查看是否有人发布
504 Gateway Timeout 网关超时 后端响应太慢、Nginx超时配置太短 检查后端慢查询、增加proxy_read_timeout

注意:502和504经常被混淆。502是“连不上”,504是“连上了但等不到回复”。排查502时,先telnet后端端口通不通;排查504时,先看后端接口响应时间。

3.3 SSL/TLS握手失败:证书与密码套件的“爱恨情仇”

SSL/TLS握手失败,说白了就是客户端和服务器在“对暗号”时没对上。我见过最离谱的一次,是有人把生产环境的证书配成了测试环境的,域名完全对不上,结果用户访问时浏览器直接报“您的连接不是私密连接”。

3.3.1 握手失败的典型场景

  1. 证书过期:证书有有效期,过期了浏览器就不认了。我建议在证书到期前30天设置自动告警。
  2. 域名不匹配:证书里的CN/SAN和用户访问的域名不一致。比如证书是给api.example.com的,但用户访问的是www.example.com。
  3. 密码套件不兼容:客户端只支持TLS 1.2,但服务器只开了TLS 1.3。或者客户端要求用AES-GCM,但服务器只支持CBC模式。
  4. 中间人设备阻断:防火墙、IPS、WAF等设备检测到“可疑”的TLS握手特征,直接丢包。

3.3.2 排查命令与工具

我个人最常用的排查命令是 openssl s_client,它能模拟一次完整的TLS握手,并输出详细的握手过程。

# 检查证书链和握手状态
openssl s_client -connect example.com:443 -servername example.com

# 指定TLS版本测试
openssl s_client -connect example.com:443 -tls1_2

# 查看支持的密码套件
openssl ciphers -v 'HIGH:!aNULL:!eNULL'

小技巧:如果openssl s_client卡住不动,大概率是防火墙拦截了443端口。这时候用telnet example.com 443先测一下端口通不通。如果不通,问题出在网络层;如果通但握手失败,问题出在TLS层。

3.3.3 一个真实的排查案例

有一次客户反馈说“手机端能访问,PC端访问不了”。我第一反应是证书问题。用openssl s_client一查,发现服务器只返回了叶子证书,没有返回中间证书。手机浏览器自动补全了中间证书,但PC浏览器没有。解决方案很简单:在Nginx配置里加上中间证书链。

# Nginx 配置示例:正确配置证书链
server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate     /etc/nginx/ssl/example.com.pem;      # 包含叶子证书 + 中间证书
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
}

3.4 防火墙与安全组规则排查:看不见的“隐形墙”

防火墙和安全组,说白了就是网络层的“门卫”。门卫太严了,好人进不来;门卫太松了,坏人随便进。我见过太多因为安全组规则配错导致的故障了。

3.4.1 安全组排查的“三板斧”

  1. 查入站规则:客户端能不能连上你的服务器?检查源IP、源端口、协议(TCP/UDP)是否放行。
  2. 查出站规则:你的服务器能不能连出去?比如服务器要访问数据库、调用外部API,出站规则必须放行。
  3. 查默认规则:很多云厂商的安全组默认规则是“拒绝所有入站,允许所有出站”。如果你改了默认规则,记得检查。

3.4.2 防火墙日志分析

遇到“连不上”的问题,别瞎猜。直接去看防火墙日志。以AWS安全组为例:

# 查看安全组日志(VPC Flow Logs)
# 日志格式:版本号 账户ID 接口ID 源IP 目标IP 源端口 目标端口 协议 动作 状态
2 123456789012 eni-xxx 192.168.1.1 10.0.0.1 54321 443 6 ACCEPT OK
2 123456789012 eni-xxx 10.0.0.1 192.168.1.1 443 54321 6 REJECT OK

看到REJECT了吗?那就是安全组在说“不”。

避坑指南:我曾经遇到过一个案例,安全组规则看起来完全正确,但就是连不上。排查了半天,发现是NACL(网络ACL)也配置了规则,而且NACL的优先级比安全组高。记住:安全组是“状态化”的,NACL是“无状态”的。两个都配了规则时,以更严格的为准。

3.4.3 快速排查命令

# 测试端口连通性
telnet 10.0.0.1 443

# 或者用nc(更推荐)
nc -zv 10.0.0.1 443

# 查看本机防火墙规则(Linux)
iptables -L -n -v

# 查看本机监听端口
ss -tlnp | grep 443

3.5 总结:网络排障的“黄金三步法”

好了,咱们把今天的内容串一下。遇到网络故障,我建议按这个顺序来:

  1. 看状态码:4xx还是5xx?4xx查请求,5xx查服务。
  2. 看TLS握手:用openssl s_client模拟握手,看证书、密码套件、协议版本。
  3. 看防火墙/安全组:用telnet或nc测端口,查安全组日志和NACL规则。

这三步走完,90%的网络问题都能定位到根因。剩下的10%,嗯,那可能是DNS解析问题、路由问题、或者物理链路问题——那些咱们后面章节再聊。

一句话记住:网络排障,先看状态码,再查握手,最后翻防火墙日志。别一上来就改代码,那是浪费时间。

可可精品资料库