3、网络故障排查(下):HTTP状态码详解(4xx/5xx)、SSL/TLS握手失败、防火墙与安全组规则排查
3.1 从一次“白屏”事故说起
我记得有一次深夜被叫起来,说线上核心业务全部“白屏”。用户访问页面,浏览器转圈圈,最后显示“无法访问此网站”。
我第一反应不是看代码,而是先看网络层。你想想看,如果是代码逻辑挂了,通常返回的是500或者业务异常页面,而不是浏览器直接报错。这种“连不上”的情况,十有八九是网络层或者安全组出了问题。
那天晚上排查下来,发现是新上线的WAF规则误拦截了所有POST请求。嗯,这就是典型的“安全组/防火墙规则”搞的鬼。所以今天咱们就把网络故障排查里最核心的三个模块讲透:HTTP状态码、SSL/TLS握手、以及防火墙规则。
核心观点:网络故障排查,80%的问题集中在“状态码异常”、“证书握手失败”、“安全组/防火墙拦截”这三类。掌握了它们,你就掌握了网络排障的半壁江山。
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 握手失败的典型场景
- 证书过期:证书有有效期,过期了浏览器就不认了。我建议在证书到期前30天设置自动告警。
- 域名不匹配:证书里的CN/SAN和用户访问的域名不一致。比如证书是给
api.example.com的,但用户访问的是www.example.com。 - 密码套件不兼容:客户端只支持TLS 1.2,但服务器只开了TLS 1.3。或者客户端要求用AES-GCM,但服务器只支持CBC模式。
- 中间人设备阻断:防火墙、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 安全组排查的“三板斧”
- 查入站规则:客户端能不能连上你的服务器?检查源IP、源端口、协议(TCP/UDP)是否放行。
- 查出站规则:你的服务器能不能连出去?比如服务器要访问数据库、调用外部API,出站规则必须放行。
- 查默认规则:很多云厂商的安全组默认规则是“拒绝所有入站,允许所有出站”。如果你改了默认规则,记得检查。
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 总结:网络排障的“黄金三步法”
好了,咱们把今天的内容串一下。遇到网络故障,我建议按这个顺序来:
- 看状态码:4xx还是5xx?4xx查请求,5xx查服务。
- 看TLS握手:用
openssl s_client模拟握手,看证书、密码套件、协议版本。 - 看防火墙/安全组:用
telnet或nc测端口,查安全组日志和NACL规则。
这三步走完,90%的网络问题都能定位到根因。剩下的10%,嗯,那可能是DNS解析问题、路由问题、或者物理链路问题——那些咱们后面章节再聊。
一句话记住:网络排障,先看状态码,再查握手,最后翻防火墙日志。别一上来就改代码,那是浪费时间。