curl resolve 和 Host 头的两种免 DNS 验证 HTTPS

三个容器在跑,面板上三个站点建好了,反代规则补完,HTTPS 也启用了。

只有一件事没做:域名的 A 记录还指着旧机器。

不切 DNS,公网访问不到新机,没法验。切了 DNS,流量立刻过来。新机但凡哪儿不对,用户当场就看到一个坏站点。想退回去还得等 TTL 慢慢过期,那是解析记录在本地 DNS 上的缓存时间。

我一开始的做法很自然:先切,再盯着浏览器刷新,看它什么时候生效。这等于拿线上流量做验证。

那阵子我卡在一个误解里,以为「域名没解析过来」就等于「没法验证」。这两件事其实毫无关系。

服务器认的是 Host 头,不看 DNS。一台机器上能有几十个站点,它们共用同一个 80 端口,服务器靠 HTTP 请求头里的 Host 区分你要哪一个。只要请求到了本机的 80 端口,Host 又写着目标域名,面板就当这个域名的访问来了,按该站点的反代规则处理。这个域名在公网上解析到哪儿,它根本不看。

HTTPS 比 HTTP 多一层握手,这一层需要域名参与。建连接时先握手,服务器得挑一张证书递过去,客户端在握手最早期就把自己要连的域名明文报上来,这个字段叫 SNI,服务器靠它选证书。

所以验 HTTPS 光伪造 Host 头不够。连接得真的连到本机,还要让 curl 以为这个域名就在本机。--resolve 干的就是这件事:它只改这一条请求的解析结果,把域名指到 127.0.0.1,全局 DNS 不动,hosts 文件也不碰。这下 SNI 还是真实域名,证书对得上,连接却打到了本机 443。

弄清楚这两条,我手上的分工也就出来了。Host 头那条打本机 80,验的是路由规则对不对,站点建没建、location 生没生效,这一层不要证书。--resolve 那条打本机 443,只验 TLS 通不通、证书绑得对不对。

Host 头打本机 80:

bash 复制代码
curl -s -o /dev/null -w "%{http_code}\n" -H 'Host: h5.example.com' http://127.0.0.1/
curl -s -o /dev/null -w "%{http_code}\n" -H 'Host: h5.example.com' http://127.0.0.1/api/v1/products

这组回显里有个反直觉的用法。有回在建站之前跑它,屏幕上出来的是:

复制代码
/              → 200
/api/v1/products → 404

看到 200 我差点松口气,可这里的 200 是坏消息。

因为这个域名还没有站点,请求落到了面板的默认站上。默认站只有 / 能答,/api/... 一律 404。所以这组回显真正说明的是站点还没建,跟后端坏没坏没关系。

我当时是这么判读的:/ 是 200、/api/... 是 404,站点未建,请求落到了面板默认站;/ 是 200、/api/... 也是 200 并且带 JSON,站点已建,两条 location 都生效了;/ 是 000 或者连接被拒,面板 Web 层没在监听 80,先去查它;两个都非 200,站点建了但规则不对,回配置文件里看 location。

接口域名的根路径返回 404 是正常的,纯接口后端本来就没有 / 路由。要验它,得换成 /health 这类健康检查路径。

--resolve 打本机 443,验 TLS 和证书:

bash 复制代码
for d in h5 api admin; do
  printf "%-20s " "$d.example.com"
  curl -skI --resolve $d.example.com:443:127.0.0.1 https://$d.example.com/ | head -1
done

我期望的是 HTTP/2 200。接口域名的 / 有可能是 404,但只要响应头是 HTTP/2,就说明 TLS 握手通了、证书也选对了。这一条验的是传输层,业务层得去 /health 上看。

-k 是拿来跳过证书校验的。跳过校验不等于不检查证书,真想看证书用的是这个:

bash 复制代码
echo | openssl s_client -connect 127.0.0.1:443 -servername h5.example.com 2>/dev/null \
  | openssl x509 -noout -subject -dates

subject 里应该是你的域名,dates 里是起止时间。

这台机器上除了自己的 3 个域名,还有 6 个别人的线上站点。每次动面板 Web 配置的前后,我各跑一次:

bash 复制代码
for h in h5.example.com api.example.com admin.example.com \
         <他人域名1> <他人域名2> <他人域名3> <他人域名4> <他人域名5> <他人域名6>; do
  printf "%-24s " "$h"
  curl -s -o /dev/null -w "%{http_code}\n" --max-time 8 -H "Host: $h" http://127.0.0.1/
done

任何一项从 200 或 301 掉成 4xx、5xx,我立即停手回滚,不想着先改完再说。

改 hosts 也能达到一样的效果,我不改,因为它有三个毛病:它是全局的,改完你在这台机器上看到的一切都被污染;它要 root;最麻烦的是你会忘了改回来,过几天对着一个「配置明明对却不生效」的怪象查半天,其实机器还在走 hosts。

curl -H 和 --resolve 都只活在单条请求里,命令跑完什么都没留下。

更要紧的是,命令本身就是证据。一条 curl 命令能直接贴进文档、贴进群聊,别人拿去就能重跑,回显是可以复现的。而「我改了 hosts 然后访问了一下」复现不了,没人知道你当时改了什么。

顺序我也讲究:先 Host 头,后 --resolve。

先跑 curl -H 'Host:' 打 80。它不要证书、不要 HTTPS 配好,一口气回答三个问题------站点建没建、location 生没生效、后端活着没。这一层不通,后面的 HTTPS 根本不用看。再跑 --resolve 打 443,这一层只回答 TLS 和证书对不对,前提是 HTTP 层已经通了。

反过来先看 TLS 会白费时间。TLS 报的错往往很含糊,证书名不匹配、握手失败,你会分不清是证书的事还是路由的事。

DNS 切换危险,不在于操作有多难,而在于它是第一个不可逆的动作。在它之前你随时能改回去,在它之后你要面对缓存、TTL、两地状态不一致。

有了这两条 curl,切换前的事实清单就能凑齐。

三个站点的路由规则对不对,我用 Host 头看。接口在域名层返回的是 JSON 还是 HTML,用 Host 头加 head -c 120 看响应体。TLS 通不通、证书绑没绑对站点,用 --resolve 看。强制跳转生没生效,80 能不能先跳 301 再到 https,用 Host 头加 grep -i '^location' 看。同机别人的站点受没受影响,跑一遍九站点基线。

切 DNS 那一刻,我已经知道结果了。

还有一条配套动作:切换前 24 小时,把 A 记录的 TTL 从默认的常见 600 秒降到 60 秒,让生效和回退都落在 1 分钟内。这一步很多人漏,它决定的正是出问题时你能不能快速退回去。

我照着这张单子过。

站点已建,curl -H 'Host: <域名>' 分别打 http://127.0.0.1/ 和一个后端专有路径,两个都该是 200。

前端接口分流对不对:

curl -s -H 'Host: h5.example.com' http://127.0.0.1/api/v1/products | head -c 120

返回的该是 JSON。接口域名健康不健康,curl -s -H 'Host: api.example.com' http://127.0.0.1/health,回 status:ok。

TLS 通没通,curl -skI --resolve <域名>:443:127.0.0.1 https://<域名>/,该回 HTTP/2。证书对不对得上,openssl s_client -connect 127.0.0.1:443 -servername <域名>,subject 里要有这个域名,日期得有效。

强制跳转在不在:

curl -sI -H 'Host: <域名>' http://127.0.0.1/ | grep -i '^location'

该指到 https://<域名>/。

九站点基线就是前面那条 for 循环,我改配置前后各跑一次,9 项都要和改前一致。TTL 降没降,提前 24 小时在解析控制台改成 60 秒。回退方案就绪没,能不能在 1 分钟内把 A 记录改回旧机器,这一点得确认过。

服务器看 Host 头,不看 DNS,请求能到本机 80,域名解析在哪儿都无所谓。--resolve 只改这一条请求的解析,SNI 还是真域名,所以验 HTTPS 不用动全局。/ 是 200 而业务路径 404,先怀疑站点没建、请求落到了面板默认站,别先怪后端。

验完再切。

相关推荐
CodeYp20192 小时前
第13讲:HTTPS 协议原理
linux·https
Thanks_ks4 小时前
HTTPS:浏览器地址栏那把锁的工作原理
http·网络安全·https·tls·加密算法·数字证书·中间人攻击
杨凯凡5 小时前
Spring Boot 大文件下载如何实现断点续传?HTTP Range、206 与 416 实战
spring boot·后端·http
吴建旭 智宅焕15 小时前
智能家居全国交付中执行端能力跃迁的架构设计:从标准装调到交付专家的系统化路径
网络·网络协议·智能家居
Dream Cosmos19 小时前
传输层协议之UDP
网络·网络协议·udp
梦到啥说啥21 小时前
Linux网络编程:UDP网络协议
linux·网络协议·udp
FungLeo1 天前
成为全栈·Vue 管理后台篇·用 fetch 建一层可控的请求内核
前端·javascript·vue.js·http·fetch·formdata·接口封装
张小姐的猫1 天前
【基于 WebSocket 的多用户网页五子棋】—— 项目结构设计与实用工具类模块
网络·websocket·网络协议
wuyk5551 天前
Spider-第03讲-HTTP速通与读懂响应
网络·爬虫·网络协议·http
梦到啥说啥2 天前
Linux网络编程:TCP网络协议
网络·网络协议·tcp/ip