<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Web 安全 · XB 现场笔记</title><link>https://www.xbcatm.com/zh/series/web-security/</link><description>基于 HTTP、DNS、TLS、Caddy、SSH、发布与恢复的可复现运维现场笔记。</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://www.xbcatm.com/zh/series/web-security/index.xml" rel="self" type="application/rss+xml"/><item><title>证书过期是一个日期，而不是仪表盘上的颜色</title><link>https://www.xbcatm.com/zh/notes/certificate-expiry-is-a-date-not-a-dashboard-color/</link><pubDate>Sat, 22 Aug 2026 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/zh/notes/certificate-expiry-is-a-date-not-a-dashboard-color/</guid><description>检查真实主机名服务的证书，并把剩余天数变成可行动的阈值。</description><content:encoded>&lt;p&gt;HTTPS 进程可能是健康的，而公共证书却临近过期、为错误的名字签发，或在另一条边缘上被不同地提供。一条有用的检查，是向公共端点索取它会给真实客户端的那张证书。&lt;/p&gt;
&lt;h2 id="包含主机名"&gt;包含主机名&lt;/h2&gt;
&lt;p&gt;TLS 虚拟主机依赖服务器名称。把主机名作为 SNI 传入，并检视对端证书：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;www.example.test
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;openssl s_client -connect &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="s2"&gt;:443&amp;#34;&lt;/span&gt; -servername &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &amp;lt;/dev/null 2&amp;gt;/dev/null &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; openssl x509 -noout -subject -issuer -dates -fingerprint -sha256
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这条命令是只读的。它不会续签任何东西，也不能证明每个中间证书都被每个客户端接受。但它确实给出为该主机名呈现的证书的 not-before、not-after、subject、issuer 与指纹。&lt;/p&gt;
&lt;h2 id="在阈值上告警"&gt;在阈值上告警&lt;/h2&gt;
&lt;p&gt;选择能留出续期失败、DNS 问题与人工响应时间的阈值。确切数字属于服务的恢复目标；并非普通的&amp;quot;30 天&amp;quot;规则就能替代这个决定。配套的&lt;a href="https://www.xbcatm.com/zh/resources/"&gt;TLS 过期检查&lt;/a&gt;会打印过期时间，并在剩余区间低于你传入的阈值时以非零退出。&lt;/p&gt;
&lt;p&gt;尽可能从主机外部运行检查。本地进程看到的监听器、证书文件或代理路径，可能与公共网络上的访问者不同。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://caddyserver.com/docs/automatic-https"&gt;Caddy Automatic HTTPS&lt;/a&gt;，自动 TLS 证书管理，已核验 2026-08-22。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.openssl.org/3.0/man1/openssl-s_client/"&gt;OpenSSL &lt;code&gt;s_client&lt;/code&gt; 文档&lt;/a&gt;，SNI 与证书检查选项，已核验 2026-08-22。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.openssl.org/3.0/man1/openssl-x509/"&gt;OpenSSL &lt;code&gt;x509&lt;/code&gt; 文档&lt;/a&gt;，证书解析、日期与指纹，已核验 2026-08-22。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>HSTS 应带着恢复计划来灰度发布</title><link>https://www.xbcatm.com/zh/notes/hsts-should-be-rolled-out-with-a-recovery-plan/</link><pubDate>Sun, 23 Aug 2026 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/zh/notes/hsts-should-be-rolled-out-with-a-recovery-plan/</guid><description>只有在 HTTPS、重定向与每个被子域名覆盖的域名都就绪之后，才增大 max-age。</description><content:encoded>&lt;p&gt;HTTP Strict Transport Security 告诉支持的浏览器，在一个缓存周期内对该主机强制使用 HTTPS。这种持久性既是特性也是风险：移除响应头并不会立刻抹掉客户端已存储的策略。&lt;/p&gt;
&lt;h2 id="先验证-https-路径"&gt;先验证 HTTPS 路径&lt;/h2&gt;
&lt;p&gt;在发送 HSTS 之前，确认规范主机名提供有效证书，并且 HTTP 在不依赖用户输入的情况下重定向到预期的 HTTPS URL：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sS -D - -o /dev/null --max-redirs &lt;span class="m"&gt;0&lt;/span&gt; http://www.example.test/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sS -D - -o /dev/null https://www.example.test/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;检查有代表性的深层路由与错误页。HSTS 无法修复证书错误，因为浏览器在接受该策略之前要求有效的 HTTPS 连接。&lt;/p&gt;
&lt;h2 id="从一个短的-max-age-开始"&gt;从一个短的 max-age 开始&lt;/h2&gt;
&lt;p&gt;分阶段发布能在配置还新的时候限制恢复窗口：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Strict-Transport-Security: max-age=300
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;观察站点与续期路径之后，再有意识地提高时长。记录日期、所选值与回滚条件。最终策略可能用一年，但这个数字是一种承诺，而不是扫描器分数。&lt;/p&gt;
&lt;h2 id="把-includesubdomains-当作独立的决定"&gt;把 includeSubDomains 当作独立的决定&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;includeSubDomains&lt;/code&gt; 把策略扩展到每个子域名。先盘点名称，包括旧服务、委派区，以及只在内部网络使用的主机名。即使只有一个仅 HTTP 的后代，也足以让该选项对收到父级策略的客户端产生破坏。&lt;/p&gt;
&lt;h3 id="预加载不是普通的响应头配置"&gt;预加载不是普通的响应头配置&lt;/h3&gt;
&lt;p&gt;浏览器预加载程序可以在正常响应周期之外分发策略，其要求与移除延迟比设置一个响应头更严格。不要仅仅因为扫描器推荐就申请预加载；请先确认对域名及所有被覆盖名称的长期所有权。&lt;/p&gt;
&lt;h3 id="验证公共响应"&gt;验证公共响应&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sS -D - -o /dev/null https://www.example.test/ &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; awk &lt;span class="s1"&gt;&amp;#39;tolower($1) == &amp;#34;strict-transport-security:&amp;#34; { print }&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;测试规范的公共边缘，而不只是某个源站端口。代理可能添加、移除或重复该响应头。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc6797.html"&gt;RFC 6797 — HTTP Strict Transport Security&lt;/a&gt;，策略处理与作用域，已核验 2026-08-23。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security"&gt;MDN: &lt;code&gt;Strict-Transport-Security&lt;/code&gt;&lt;/a&gt;，指令与部署注意事项，已核验 2026-08-23。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>安全响应头应描述实际页面</title><link>https://www.xbcatm.com/zh/notes/security-headers-should-describe-the-actual-page/</link><pubDate>Sat, 22 Aug 2026 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/zh/notes/security-headers-should-describe-the-actual-page/</guid><description>当紧凑的策略与静态页面真正加载的资源匹配时，它更安全。</description><content:encoded>&lt;p&gt;安全响应头不是安全代码的替代品，但它们让浏览器强制实施有用的边界。策略应描述实际被服务的页面，而不是从另一个项目复制来的泛型模板。&lt;/p&gt;
&lt;h2 id="从资源图开始"&gt;从资源图开始&lt;/h2&gt;
&lt;p&gt;如果站点只提供 HTML、本地样式表、一个 favicon、没有任何可执行 JavaScript，那么一条窄策略是可理解的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Content-Security-Policy: default-src &amp;#39;self&amp;#39;; base-uri &amp;#39;self&amp;#39;; form-action &amp;#39;none&amp;#39;; frame-ancestors &amp;#39;none&amp;#39;; object-src &amp;#39;none&amp;#39;; script-src &amp;#39;none&amp;#39;; style-src &amp;#39;self&amp;#39;; img-src &amp;#39;self&amp;#39; data:
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;script-src 'none'&lt;/code&gt; 只有在站点不需要可执行脚本时才是正确的选择。加入搜索、评论或统计标签会改变资源图，并应触发一次有意识的策略复核。&lt;/p&gt;
&lt;h2 id="增加传输与嵌套保护"&gt;增加传输与嵌套保护&lt;/h2&gt;
&lt;p&gt;对仅 HTTPS 的站点，下列响应头是常见起点：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Strict-Transport-Security: max-age=31536000; includeSubDomains
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Content-Type-Options: nosniff
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;X-Frame-Options: DENY
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Referrer-Policy: strict-origin-when-cross-origin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;只有当每个子域名都准备好提供 HTTPS 时才启用带 includeSubDomains 的 HSTS。响应头是与未来部署的契约，而不只是扫描器里的一个分数。&lt;/p&gt;
&lt;h2 id="检查行为而不只是存在"&gt;检查行为，而不只是存在&lt;/h2&gt;
&lt;p&gt;请求一个正常页面、一个缺失页面与一个静态资源。错误响应应携带与成功响应同样重要的安全响应头。还要确认压缩与缓存不会改变内容类型，也不会暴露内部路径。&lt;/p&gt;
&lt;p&gt;本站的&lt;a href="https://www.xbcatm.com/zh/resources/"&gt;Caddy 示例&lt;/a&gt;只是一个起点，不是普适策略。请根据你自己的部署调整主机名、证书处理与应用路由。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP"&gt;MDN: Content Security Policy guide&lt;/a&gt;，CSP 指令名称与语法，已核验 2026-08-22。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security"&gt;MDN: &lt;code&gt;Strict-Transport-Security&lt;/code&gt;&lt;/a&gt;，HSTS 指令与部署注意事项，已核验 2026-08-22。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://caddyserver.com/docs/caddyfile/directives/header"&gt;Caddy &lt;code&gt;header&lt;/code&gt; 指令&lt;/a&gt;，响应头操作指令，已核验 2026-08-22。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>SSH 主机密钥是部署记录的一部分</title><link>https://www.xbcatm.com/zh/notes/ssh-host-keys-are-part-of-the-deployment-record/</link><pubDate>Sat, 22 Aug 2026 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/zh/notes/ssh-host-keys-are-part-of-the-deployment-record/</guid><description>让首次接触保持显式，并拒绝未预期的主机密钥变化。</description><content:encoded>&lt;p&gt;SSH 私钥认证客户端，但它并不告诉客户端到达的是哪台服务器。服务器的主机密钥与本地 &lt;code&gt;known_hosts&lt;/code&gt; 数据库，提供身份检查的后一半。&lt;/p&gt;
&lt;h2 id="把首次接触与轮换分开"&gt;把首次接触与轮换分开&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;StrictHostKeyChecking=yes&lt;/code&gt; 下，SSH 拒绝未知主机与变化的密钥。对于一个固定生产端点，只要期望密钥通过可信渠道安装，这就是最安全的默认值。&lt;code&gt;accept-new&lt;/code&gt; 是面向预期会出现新主机的、更窄的方便选项：它接受一个从未见过的密钥，但仍拒绝被更改的密钥。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-sshconfig" data-lang="sshconfig"&gt;Host production-site
HostName www.example.test
User deploy
IdentityFile ~/.ssh/site_ed25519
StrictHostKeyChecking yes
UserKnownHostsFile ~/.ssh/known_hosts
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;不要通过给部署脚本加 &lt;code&gt;StrictHostKeyChecking=no&lt;/code&gt; 来&amp;quot;修复&amp;quot;警告。那会把有用的信号变成静默接受。如果主机被重建，请记录替换后的指纹，并复核旧密钥为何不再有效。&lt;/p&gt;
&lt;h2 id="让指纹可复核"&gt;让指纹可复核&lt;/h2&gt;
&lt;p&gt;在首次连接之前，从主机所有者或控制台获取指纹，再与客户端看到的值比较。密钥变更应有工单、维护说明或其他他人可检视的解释。&lt;/p&gt;
&lt;p&gt;同一规则适用于自动化：known-hosts 文件是带有安全后果的配置，不是可丢弃的缓存数据。把它与部署记录一起备份，但不要把私钥或复制的凭据随站点制品一起公开。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://man.openbsd.org/ssh_config"&gt;OpenBSD &lt;code&gt;ssh_config&lt;/code&gt;&lt;/a&gt;，&lt;code&gt;StrictHostKeyChecking&lt;/code&gt; 与 &lt;code&gt;UserKnownHostsFile&lt;/code&gt;，已核验 2026-08-22。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://man.openbsd.org/ssh-keygen"&gt;OpenSSH &lt;code&gt;ssh-keygen&lt;/code&gt; 手册&lt;/a&gt;，指纹检视，已核验 2026-08-22。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Cookie 作用域应比应用边界更窄</title><link>https://www.xbcatm.com/zh/notes/cookie-scope-should-be-narrower-than-the-application-boundary/</link><pubDate>Sun, 23 Aug 2026 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/zh/notes/cookie-scope-should-be-narrower-than-the-application-boundary/</guid><description>把 Domain、Path、Secure、HttpOnly 与 SameSite 当作同一份浏览器存储契约来复核。</description><content:encoded>&lt;p&gt;Cookie 依据浏览器规则附加到请求，而不是依据最初设置它的服务器组件。宽泛的 &lt;code&gt;Domain&lt;/code&gt; 或 &lt;code&gt;Path&lt;/code&gt; 会把状态暴露给无关的路由或子域名，而缺失传输与脚本限制则会放大其他失败造成的损害。&lt;/p&gt;
&lt;h2 id="偏好仅主机-cookie"&gt;偏好仅主机 Cookie&lt;/h2&gt;
&lt;p&gt;当省略 &lt;code&gt;Domain&lt;/code&gt; 时，Cookie 被限定在设置它的主机内。加上 &lt;code&gt;Domain=example.test&lt;/code&gt; 则它也允许发给符合条件子域名。只有多个主机确实共享同一应用与信任边界时才使用更宽的形式。&lt;/p&gt;
&lt;p&gt;检视响应而不把真实 Cookie 值打进日志：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -sS -D - -o /dev/null https://app.example.test/login &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;|&lt;/span&gt; awk &lt;span class="s1"&gt;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; tolower($1) == &amp;#34;set-cookie:&amp;#34; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; sub(/Set-Cookie: [^;]*/, &amp;#34;Set-Cookie: [value redacted]&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; print
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="一起复核这些属性"&gt;一起复核这些属性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Secure&lt;/code&gt; 把传输限制在安全上下文中。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HttpOnly&lt;/code&gt; 通过 &lt;code&gt;document.cookie&lt;/code&gt; 阻止 JavaScript 访问；它不会阻止浏览器发送该 Cookie。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SameSite&lt;/code&gt; 影响跨站请求，必须匹配应用的导航或嵌入需求。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Path&lt;/code&gt; 控制发送时机，但它不是同一主机上不同应用之间的授权边界。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在现代浏览器中，&lt;code&gt;SameSite=None&lt;/code&gt; 的 Cookie 还需要 &lt;code&gt;Secure&lt;/code&gt;。避免把这对组合复制进不需要跨站用途的应用。&lt;/p&gt;
&lt;h2 id="在其约束契合时使用前缀"&gt;在其约束契合时使用前缀&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;__Secure-&lt;/code&gt; 与 &lt;code&gt;__Host-&lt;/code&gt; 等 Cookie 名称前缀，让支持的浏览器强制额外的要求。&lt;code&gt;__Host-&lt;/code&gt; Cookie 必须使用 &lt;code&gt;Secure&lt;/code&gt;、省略 &lt;code&gt;Domain&lt;/code&gt;、并使用 &lt;code&gt;Path=/&lt;/code&gt;，这使主机专用的意图变得显式。&lt;/p&gt;
&lt;h2 id="用相同作用域测试删除"&gt;用相同作用域测试删除&lt;/h2&gt;
&lt;p&gt;删除 Cookie 需要一条与存储它所用属性匹配的过期指令，尤其是名称、域名与路径。只清除一个变体的登出可能让另一个 Cookie 仍然有效。&lt;/p&gt;
&lt;h2 id="让静态站点免-cookie"&gt;让静态站点免 Cookie&lt;/h2&gt;
&lt;p&gt;一个真正静态的文档站点通常没有理由设置应用 Cookie。核验公共响应不含 &lt;code&gt;Set-Cookie&lt;/code&gt; 响应头，而不是为站点并不需要的存储增加一个同意界面。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc6265.html"&gt;RFC 6265 — HTTP State Management Mechanism&lt;/a&gt;，Cookie 存储与作用域，已核验 2026-08-23。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie"&gt;MDN: &lt;code&gt;Set-Cookie&lt;/code&gt;&lt;/a&gt;，属性与名称前缀，已核验 2026-08-23。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>CAA 记录应授权你实际使用的签发者</title><link>https://www.xbcatm.com/zh/notes/caa-records-should-authorize-the-issuer-you-actually-use/</link><pubDate>Sun, 23 Aug 2026 00:00:00 +0000</pubDate><guid>https://www.xbcatm.com/zh/notes/caa-records-should-authorize-the-issuer-you-actually-use/</guid><description>在限制哪些证书签发机构能为一个域名签发之前，先检视继承的 CAA 策略。</description><content:encoded>&lt;p&gt;认证机构授权（CAA）记录让域名持有者声明，哪些证书颁发机构可以为该域名签发证书。只有当记录与真实续期路径一致、且操作者理解策略如何从父级名称继承时，它才有用。&lt;/p&gt;
&lt;h2 id="检视当前策略"&gt;检视当前策略&lt;/h2&gt;
&lt;p&gt;查询确切主机名及其父名称：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; name in www.example.test example.test test&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;== %s\n&amp;#39;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; dig +noall +answer CAA &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;叶子处空的应答不一定意味着没有适用策略。根据 DNS 规则，CAA 处理可能继续向上。诊断变更时使用权威应答，并与至少一个递归解析器比较。&lt;/p&gt;
&lt;h2 id="匹配账户的签发者标识"&gt;匹配账户的签发者标识&lt;/h2&gt;
&lt;p&gt;记录使用如 &lt;code&gt;issue&lt;/code&gt; 或 &lt;code&gt;issuewild&lt;/code&gt; 等标签与一个签发者域值：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;example.test. 3600 IN CAA 0 issue &amp;#34;letsencrypt.org&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;该值是授权标识，不是证书里的显示名。在证书颁发机构的当前文档中确认它。通配符授权可能需要单独的 &lt;code&gt;issuewild&lt;/code&gt; 策略。&lt;/p&gt;
&lt;h2 id="在续期前编排-dns-变更"&gt;在续期前编排 DNS 变更&lt;/h2&gt;
&lt;p&gt;在当前证书健康时添加或收紧 CAA。从整上一个 TTL 等待，查询权威与递归应答，并运行 ACME 客户端支持的暂存或续期测试。准备好回滚记录。&lt;/p&gt;
&lt;p&gt;不要在过期事故期间添加限制性记录，除非签发者路径已验证。一条语法正确但错误的策略，会把自动续期变成硬失败。&lt;/p&gt;
&lt;h2 id="观察签发失败"&gt;观察签发失败&lt;/h2&gt;
&lt;p&gt;CAA 检查发生在签发时，而不是每次 HTTPS 请求。因此证书监控必须同时覆盖当前过期与续期尝试。把有效的 DNS 应答随 ACME 失败一起记录，而不是只记录一条笼统的授权错误。&lt;/p&gt;
&lt;h2 id="来源"&gt;来源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc8659.html"&gt;RFC 8659 — DNS Certification Authority Authorization&lt;/a&gt;，CAA 查询与属性语义，已核验 2026-08-23。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://letsencrypt.org/docs/caa/"&gt;Let&amp;rsquo;s Encrypt: CAA&lt;/a&gt;，签发者标识与运维指引，已核验 2026-08-23。&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>