← 返回笔记列表
踩坑:域名解析正常但网站 403,是备案拦截不是防火墙
给域名签 HTTPS 证书时,certbot 报了下面这个错:
Detail: 47.107.100.41: Invalid response from
http://sanshui755.cn/.well-known/acme-challenge/xxx: 403
第一反应是防火墙或 nginx 配置。但排查下来都不是。
三个对照实验
同一台服务器、同一时刻:
| 访问方式 | 结果 | 说明 |
|---|---|---|
http://47.107.100.41/ | 200 | 用 IP 访问不被拦 |
http://sanshui755.cn/ | 403 | 用域名访问被拦 |
服务器内 curl -H "Host: …" | 200 | 本地完全正常 |
结论很明确:服务器本身没问题,是云入口层按域名拦的。返回页面标题写着 Non-compliance ICP Filing——备案拦截。
HTTP-01 为什么必然失败
Let's Encrypt 的校验请求走 80 端口,被拦截层直接返回 403,根本到不了 nginx。所以拿不到校验文件,判定失败。
换域名后缀没用——拦的是「指向内地节点的未备案域名」,与后缀无关。
拦的是域名,不是端口(更正)
2026-10-23 更正:下面这段原本写的是「拦截层只识别 HTTP,原始 TCP 放行」,实测证明那是错的。
带上未备案域名做 TLS 握手,8883 和 443 一样会被重置:
| 探测 | 结果 |
|---|---|
:8883 TLS,SNI=sanshui755.cn | 握手被 RST |
:8883 TLS,无 SNI 或陌生域名 | TLS 1.3 正常,双向收发 |
:80 Host: sanshui755.cn | 403 Server: Beaver |
:80 裸 IP | 200,且 /.well-known/acme-challenge/ 可读 |
所以拦截层看的是握手/请求里出现的域名(TLS 的 SNI、HTTP 的 Host),与端口无关。早期用 nc 往 8883 发裸字节看不到 SNI,才误判成「8883 特殊放行」。
这条更正带来一个更实用的结论:HTTP-01 校验其实能过——把校验请求发给裸 IP 即可(Let's Encrypt 自 2026-01 起也签发 IP 证书,只是强制 6 天档)。设备端用 mqtts://<裸 IP>:8883 同样可行,只要握手里别出现那个未备案域名。这套「裸 IP + IP 证书」的做法已在部署形态定案里落成完整方案。
另一个顺手发现的坑
本地 http://IP 能打开、域名打不开时,很多人会去改 DNS 或防火墙。正确的排查顺序是:
- 先用 IP 访问——能开,说明服务和安全组都没问题;
- 再用域名访问——打不开且返回专门的拦截页,就是备案问题;
- 最后看服务器内 curl 是否正常——正常即排除 nginx 配置。
这三步能把「云入口 / 系统 / 应用」三层问题快速分开。