Skip to content

CDN 资源加载失败 — /etc/hosts 硬编码 IP 失效问题

归类:网络排查 / CDN / 本地环境配置
发生时间:2026-03-06
涉及域名assets.example-cdn.com
状态:✅ 已修复


一、问题现象

浏览器访问内部系统(如 portal.example-internal.com)时,页面白屏或样式/脚本全部加载失败。打开 DevTools → Network 面板,可以看到以下资源的请求状态均为红色错误:

https://assets.example-cdn.com/static/theme/index.css
https://assets.example-cdn.com/static/...(多个 JS/CSS/字体)

错误特征:

  • 请求状态均为失败(无 HTTP 状态码)
  • DevTools 提示 net::ERR_CONNECTION_RESET 或请求超时

二、排查过程

第一步:确认是否代理问题

查看系统代理配置(macOS):

bash
networksetup -getsecurewebproxy "Wi-Fi"
# Enabled: Yes
# Server: 127.0.0.1
# Port: 7897

系统代理开启(clash 等工具监听 127.0.0.1:7897)。

尝试绕过代理直连:

bash
curl --noproxy "*" -v "https://assets.example-cdn.com/..."
# 结果:LibreSSL SSL_connect: SSL_ERROR_SYSCALL — TLS 握手失败

结论:绕过代理后依然失败,排除代理干扰。


第二步:排查 DNS 解析

bash
nslookup assets.example-cdn.com        # 默认 DNS
nslookup assets.example-cdn.com 114.114.114.114  # 公共 DNS
nslookup assets.example-cdn.com 8.8.8.8          # Google DNS

三个 DNS 全部解析到同一个 IP:203.0.113.10

结论:DNS 解析本身没有问题,也没有被污染。


第三步:发现 /etc/hosts 硬编码

bash
grep "example-cdn" /etc/hosts
# 203.0.113.10 assets.example-cdn.com

/etc/hosts 第 31 行存在一条历史记录,将 assets.example-cdn.com 硬绑定到 203.0.113.10


第四步:验证该 IP 是否可达

bash
ping -c 3 assets.example-cdn.com
# 100% packet loss — IP 完全不响应 ICMP

openssl s_client -connect assets.example-cdn.com:443 -servername assets.example-cdn.com </dev/null
# no peer certificate available
# SSL handshake has read 0 bytes — TLS 握手阶段直接被中断

结论:203.0.113.10 这个 CDN 节点已下线/失效,TCP 可以建立连接(端口打开),但 TLS 握手阶段服务端直接断开,导致所有 HTTPS 资源无法加载。


根本原因链路

1. /etc/hosts 硬编码旧 IP

2. 所有 DNS 查询被绕过,强制走 203.0.113.10

3. 该节点 TLS 握手失败(服务端无证书响应)

4. 浏览器资源全部加载失败 → 页面白屏

三、影响范围

受影响项说明
浏览器资源加载所有来自 assets.example-cdn.com 的 CSS / JS / 字体全部失败
curl / wget命令行工具下载同域名资源也失败
系统代理代理无法解决,因为 IP 在 hosts 层面已被覆盖
其他 CDN 子域只影响 hosts 中硬编码的域名,其他 CDN 域名不受影响

四、修复方式

方案:删除 hosts 中的硬编码记录

bash
# 删除 /etc/hosts 中的硬编码记录(需要 sudo 权限)
sudo sed -i '' '/assets.example-cdn.com/d' /etc/hosts

# 验证已删除
grep "example-cdn" /etc/hosts || echo "记录已删除"

# 验证 CDN 是否恢复可用
curl -I "https://assets.example-cdn.com/static/theme/index.css"

修复后响应结果(正常):

HTTP/2 200
server: Tengine
content-type: text/css
cdn-from: edge
content-length: 509150

五、为何 hosts 中会出现这条记录

常见原因:

原因说明
历史手动绑定开发或调试阶段为加速 CDN 访问,手动将当时的 CDN IP 写入 hosts
工具自动写入部分抓包/代理工具(如 SwitchHosts、Charles)会自动修改 hosts
CDN 节点轮换CDN 服务商节点 IP 会定期变更,旧 IP 逐渐下线

核心风险:hosts 中的 IP 与 CDN 动态调度机制冲突——CDN 会根据用户位置、节点健康状态自动切换 IP,但 hosts 硬编码绕过了 DNS,导致始终访问同一个(可能已失效的)节点。


六、预防建议

  1. 不要在 /etc/hosts 中硬编码 CDN 域名,CDN 节点 IP 是动态的,绑死 IP 有失效风险。
  2. 使用 SwitchHosts 等工具时,定期清理不再需要的 hosts 规则。
  3. 遇到 CDN 资源加载失败时,排查顺序建议:
/etc/hosts 检查 → DNS 解析检查 → IP 连通性检查 → 代理配置检查 → CDN 服务端检查
  1. 快速排查命令
bash
# 一键检查 /etc/hosts 中是否有该域名的硬编码
grep "<域名关键词>" /etc/hosts

# 检查 IP 是否可达
ping -c 3 <>

# 检查 TLS 握手是否正常
openssl s_client -connect <>:443 -servername <> </dev/null 2>&1 | head -10

七、参考信息

项目
故障域名assets.example-cdn.com
失效 IP203.0.113.10
CDN 服务商某 CDN 服务商
Node.js 环境v20.20.0
操作系统macOS
修复耗时< 5 分钟