嵌入式开发 · 传感器应用 · 物联网通信 · 学习与作品记录

← 返回笔记列表

踩坑:域名解析正常但网站 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.cn403 Server: Beaver
:80 裸 IP200,且 /.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 或防火墙。正确的排查顺序是:

  1. 先用 IP 访问——能开,说明服务和安全组都没问题;
  2. 再用域名访问——打不开且返回专门的拦截页,就是备案问题;
  3. 最后看服务器内 curl 是否正常——正常即排除 nginx 配置。

这三步能把「云入口 / 系统 / 应用」三层问题快速分开。