观察、决策、行动三个面板,旁边的标题说明Caddy 自动处理 HTTPS 证书签发与续期。

Caddy 自动管理 HTTPS 证书的签发与续期

Caddy 可以自动获取并续签受管理的证书,不需要运维人员手工实现 ACME 协议。自动化省去了重复操作,却没有取消签发前提,也不能代替对失败的监控。今天证书有效,不证明下次续期仍能完成,更不证明整条链路中的每一跳都使用同一张证书。应先明确服务名称、验证路径、持久存储和 TLS 终止位置,再判断自动化覆盖到哪里。 先让自动 HTTPS 知道服务名称 当配置让 Caddy 知道符合条件的主机名或地址时,自动 HTTPS 才会按规则启用,同时还要考虑文档列出的例外与显式覆盖。Caddyfile 中的站点地址包含主机名,是常见触发方式。file_server 指令负责提供文件,本身并不等于为某个尚未指定的域名申请公开证书,不能把文件服务功能与证书管理的启用条件混在一起。 命令行区别很明确:不带参数的 caddy file-server 默认监听八十端口;提供 --domain 后,才会尝试为指定主机名启用 HTTPS,并将默认监听端口改为四百四十三。无论命令怎样拼写,都不能单独证明 DNS、端口转发或证书授权已经正确。显式 HTTP 配置、手动加载的证书等条件,也可能改变自动行为,应该检查实际生效配置。 本地开发还有不同的信任边界。对于内部名称,Caddy 可以使用自己的本地证书机构。客户端需要通过适当流程信任该机构;某台机器能够正常访问,不代表这张证书已经获得公网客户端的普遍信任。更不能为了修复客户端信任问题,把私有 CA 的签名密钥发给所有客户端。信任根分发与私钥保管是两项不同工作。 让挑战方式与真实路径匹配 Caddy 默认同时启用 HTTP-01 与 TLS-ALPN-01。前者通过公网八十端口验证,后者通过四百四十三端口上的特殊 TLS 握手验证;Caddy 可以在可用方式之间选择。某次 HTTP 挑战失败,并不说明 DNS 验证就是唯一替代方案。应先从日志确认实际失败的是哪种挑战,再检查该方式的入口、转发和防火墙规则。 ...

一月 21, 2027 · 2 分钟 · XB Field Notes
观察、决策、行动三个方框,旁边强调先验证 TLS,再检查响应。

检查 HTTPS,而不只是那把锁

HTTPS 保护一条连接,并按照客户端的信任规则认证对端。但它不会证明网站意图、业务正确性或服务可用性。地址栏的安全指示既不只是“字节已加密”的标签,也不是完整健康报告。有效检查应分别判断 TLS 连接、HTTP 响应,以及服务实际应该提供的行为,不能把三个问题合成一个模糊的绿灯。 分别提出具体问题 首先确认目标与身份。连接预期入口的同时,应按照证书 SAN 和可接受的信任链验证预期主机名。IP 地址正确,或者能够打印证书主题,都不足以完成身份验证。为了让探针通过而关闭验证,只会移除原本想取得的证据,并不能证明对端已经变得正确。 接着检查有效时间和协商协议。叶证书的到期日期仍在未来,不代表整条证书链可用;一次 TLS 协商成功,也只说明这个客户端实际选中了哪个版本和套件,并没有枚举服务端可能接受的全部配置。配置或库升级之后,仍应另外验证明确的允许和拒绝策略,不能用一次成功连接概括全部安全条件。 最后定义应用成功的条件。HTTP 状态、预期内容、重定向和相关依赖各自回答不同问题。静态站也可能提供有效证书,却返回不存在的页面、旧版本内容或上游错误。即使应用只负责发送文件,TLS 也不是整段访问的全部,更不能替代页面和发布结果的检查。 坏掉的样子 HTTP 库收到一个可正常读取的 503 响应时,未必会把它当成传输错误。若探针只检查 err 是否为空,就可能把不可用服务判断为健康。同样,HTTP 200 也可能来自错误虚拟主机、登录页面或被缓存的错误文档,因此应核验稳定、属于目标服务自身的响应约定。 自动跟随重定向可能隐藏真正被检查的入口。最初的 HTTPS 响应可能指向 HTTP 或非预期地址,最终只看到一个 200 就会丢失中途发生的变化。应依据明确策略检查跳转链,不能为了把请求跑通,就顺手把凭据转发到新的目标地址。 TLS 终止位置同样重要。CDN 证书验证通过,认证的是客户端到 CDN 的这一跳,并不自动认证之后到源站的每一跳。公共访问路径和相关上游路径需要分别监控。诊断应保留目标及观察时间,区分证书故障与 HTTP 故障,同时避免把凭据和私有请求数据写进输出。 快速验证 保存为 health_probe.go,使用 Go 1.23 或更新版本运行 go run health_probe.go。本地 TLS 1.3 服务提供四种应用响应,另一个明文服务充当重定向目标。客户端使用 httptest 提供的配置来信任测试服务器证书,不改变全局信任库,也不访问任何公共入口。 ...

十一月 9, 2026 · 3 分钟 · XB Field Notes
观察、决策、行动三个方框,旁边强调 SNI 选择证书、客户端验证名称。

SNI 根据请求主机名选择 TLS 证书

服务器名称指示 SNI 在 TLS 服务器选择握手参数和证书时,提供客户端希望访问的主机名。本文讨论的是证书认证且没有 early data 的路径,因此选择发生在普通 HTTP 字节发送之前,不是网络上任何字节都还没出现的时候。SNI 只是帮助选择,客户端仍然必须验证返回的证书身份。 同一个地址上的不同决策 客户端把 server_name 放在 ClientHello 中,托管多个名称的服务器可以据此选择证书或安全配置。TLS 1.3 在 ServerHello 之后加密证书消息,所以“选证书和传证书都在加密开始之前完成”不是准确描述。应区分先收到选择提示,和随后如何保护证书及其他握手消息。 SNI 中的 DNS 主机名不等于建立连接时使用的目标 IP,填写名称也不要求实验域名真的经过公共 DNS 解析。RFC 6066 不允许在 HostName 字段直接放入 IPv4、IPv6 字面地址,并规定 DNS 主机名比较不区分大小写。客户端直接按 IP 访问时,可以不发送 DNS SNI,转而验证对应的 IP 身份。 ...

十一月 8, 2026 · 4 分钟 · XB Field Notes
观察、决策、行动三个方框,旁边强调记住 HTTPS 并明确策略范围。

HSTS 让浏览器记住 HTTPS

HTTP 严格传输安全 HSTS 告诉支持它的客户端:以后访问记住的主机名时使用 HTTPS。它可以消除重定向之前的那次明文 HTTP 请求,但前提是客户端已经通过此前可信响应或受支持的预加载机制知道策略。只在服务器添加一个 Header,不能追溯保护未知客户端第一次发出的 HTTP 请求。 客户端记住的是主机名 客户端通过没有安全错误的 HTTPS 收到有效 Strict-Transport-Security 后,才建立或刷新策略。max-age 是从接收时刻起计算的秒数。明文 HTTP 上的同名 Header 不能建立这种信任;后来某次响应没有 Header,也不会删除尚未过期的记录。状态由各个客户端分别维护,浏览器之间不存在自动共享的统一缓存。 策略范围是 DNS 主机名,不是包含协议和端口的 HTTP origin。includeSubDomains 向下覆盖子域名,不覆盖父域或同级名称。升级 URL 时,显式的 80 端口会改为 443,其他显式端口保持不变。因此,原本在另一个端口上提供的 HTTP-only 服务,也可能在客户端学习策略后变得不可用。 这条规则改变的是客户端处理 URL 的方式,不会自动把服务器的明文监听器变成 TLS 监听器;升级后的目标必须事先具备 HTTPS 服务。下面的实验故意在 HTTP 响应中发送 HSTS,只作为反向测试,并不是部署建议。两个测试服务都不返回重定向,因此从 HTTP URL 进入 TLS handler,证明的是客户端主动升级,而非成功跟随了一串服务端跳转。 ...

十月 8, 2026 · 4 分钟 · XB Field Notes
观察、决策、行动三个方框,旁边强调设置 TLS 下限并验证正反两侧。

设定 TLS 版本下限并验证边界

TLS 版本策略决定一个端点愿意接受哪些握手。应明确最低版本,而不是假定库每次升级后的默认值都符合自己的要求。最高版本是另一项独立约束,没有必要地把它固定死,可能阻止以后采用库已经支持的新协议。无论设置了哪种上下限,都不能替代证书身份验证、合适的算法以及持续的安全更新。 最低版本与最高版本是两回事 RFC 8996 已废弃 TLS 1.0 和 1.1;RFC 9325 同时排除 SSLv2、SSLv3,建议支持 TLS 1.3 并在实现支持时优先协商它,也给出了继续使用 TLS 1.2 时应满足的安全要求。对于客户端群体明确的服务,可以评估兼容性后只允许 TLS 1.3;但不能因为存在更严格的配置,就把所有 TLS 1.2 连接一律说成不安全。 双方都支持 TLS 1.3 时,服务器同时允许 TLS 1.2,不等于攻击者可以随意强迫它们选择最弱的版本。TLS 有经过认证的协商过程,也有针对降级攻击的保护。不过,真实的旧版客户端仍然可能合法选择服务器允许的较旧版本,不安全的重试逻辑也可能削弱策略。最低版本应在每条新连接上执行,不能把“最后总算连上”当作唯一验收标准。 抓包里的版本数字还必须结合字段含义解读。TLS 1.3 为兼容性把 hello 中的旧版本字段设为 0x0303,实际版本则通过 supported_versions 协商。因此,单独看到这个旧字段,不能断定连接正在使用 TLS 1.2。有条件时应读取 TLS 库提供的最终协商状态,而不是从某一个兼容字段猜测协议。 ...

九月 23, 2026 · 3 分钟 · XB Field Notes
观察、决策、行动三个方框,旁边强调 TLS 1.3 握手需要验证身份。

TLS 1.3 握手基础

TLS 1.3 握手负责建立流量密钥,并按照应用指定的信任规则认证对端。普通 HTTPS 通常认证服务器,客户端证书需要另外配置,并不是连接一加密就自动双向认证。TCP 建连成功只说明传输连接建立了,既不证明证书身份正确,也不证明 HTTP 服务能够完成请求。 一次往返究竟计算什么 常见的证书认证握手由 ClientHello 开始,其中包含客户端支持的版本、算法和密钥份额。服务器通过 ServerHello 选择参数并提交自己的份额,随后发送加密扩展、证书、CertificateVerify 和 Finished。客户端验证证书与握手证明后,才发送自己的 Finished 和普通应用数据,而不是看到任意证书就立即信任对端。 没有 HelloRetryRequest 时,客户端可以在已建立的传输连接上经过一次 TLS 往返后发送这些数据。这一数字不包含 DNS 查询、TCP 建连,以及 HTTP 请求发出后的响应路程。如果客户端首次没有提供服务器需要的密钥份额,服务器可能要求 HelloRetryRequest,增加一次交换;如果根本没有共同参数,协商则可能直接失败。因此,一次 RTT 描述的是特定协议路径,不是整个网页加载时间的承诺。 TLS 1.3 的密码套件名称表示记录加密算法与哈希,并不会独自告诉你证书使用了什么签名算法,也不完整表示协商出的密钥交换组。看到套件里有 AES,不等于已经确认身份验证成功,更不能据此推断它使用了哪种临时交换。 身份认证与前向保密 在证书认证的临时 Diffie-Hellman 交换中,只要临时机密正确销毁、通信期间端点没有被攻破,攻击者日后仅取得证书私钥,不能据此还原此前记录的会话。这是有前提的前向保密,不是对任何形式的端点入侵都免疫。RSA 证书仍可以给临时交换做认证;证书是 RSA,不代表正在使用旧式 RSA 密钥传输。 ...

八月 6, 2026 · 2 分钟 · XB Field Notes
公共边缘的信任清单,从头与 TLS 身份到证书链与 CAA。

审计公共边缘的信任

检查安全策略、经过验证的 TLS 身份、签发限制与部署信任,并明确每项检查的边界。

八月 6, 2026 · 2 分钟 · XB Field Notes
一条 HSTS 策略,在覆盖子域名之前先经过分级的 max-age 阶梯。

HSTS 应带着恢复计划来灰度发布

HSTS 是被缓存的浏览器策略,因此一个配置错误可能比创建它的服务器变更活得更久。

六月 23, 2026 · 1 分钟 · XB Field Notes