<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>DNS on aloneowo's blog</title><link>https://blog.hatsune01.de/tags/dns/</link><description>Recent content in DNS on aloneowo's blog</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sat, 11 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.hatsune01.de/tags/dns/index.xml" rel="self" type="application/rss+xml"/><item><title>有关GFW阻断的个人观察总结</title><link>https://blog.hatsune01.de/p/%E6%9C%89%E5%85%B3gfw%E9%98%BB%E6%96%AD%E7%9A%84%E4%B8%AA%E4%BA%BA%E8%A7%82%E5%AF%9F%E6%80%BB%E7%BB%93/</link><pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.hatsune01.de/p/%E6%9C%89%E5%85%B3gfw%E9%98%BB%E6%96%AD%E7%9A%84%E4%B8%AA%E4%BA%BA%E8%A7%82%E5%AF%9F%E6%80%BB%E7%BB%93/</guid><description>&lt;h1 id="有关gfw阻断的个人观察"&gt;&lt;a href="#%e6%9c%89%e5%85%b3gfw%e9%98%bb%e6%96%ad%e7%9a%84%e4%b8%aa%e4%ba%ba%e8%a7%82%e5%af%9f" class="header-anchor"&gt;&lt;/a&gt;有关GFW阻断的个人观察
&lt;/h1&gt;&lt;h2 id="前言"&gt;&lt;a href="#%e5%89%8d%e8%a8%80" class="header-anchor"&gt;&lt;/a&gt;前言
&lt;/h2&gt;&lt;p&gt;本文是对GFW的个人观测结果，受限于个人测试环境和信息获取渠道，仅作为个人观点&lt;/p&gt;
&lt;p&gt;作为一个计算机学生，对于科学上网是既必须又无奈的需求。不得不承认国外的资料确实多且全。最近看到了 XTLS BBS 里面提到了有关使用 ECH + DoH 的&lt;a class="link" href="https://github.com/XTLS/BBS/issues/13" target="_blank" rel="noopener"
 &gt;讨论&lt;/a&gt;，以及由于这个帖子启发而自己手搓的worker的DoH涉及到了大量对GFW策略的试探。本文不对绕过GFW做叙述，只分享一些GFW常用的阻断策略。&lt;/p&gt;
&lt;p&gt;当前 GFW 使用的阻断方式总的可以归于 3 类：&lt;strong&gt;DNS 污染&lt;/strong&gt;、&lt;strong&gt;SNI 阻断&lt;/strong&gt;以及 &lt;strong&gt;IP 黑洞&lt;/strong&gt;。其中，使用 ECH + DoH 可以有效避免前两者的影响，但不能对后者抗干扰。据我所知，IP 黑洞应该是无解的。&lt;/p&gt;
&lt;h2 id="声明"&gt;&lt;a href="#%e5%a3%b0%e6%98%8e" class="header-anchor"&gt;&lt;/a&gt;声明
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;p&gt;这个算是一个比较敏感的话题，所以我先声明一下几点内容：在这篇文章里，我不会提及任何关于突破内容审查机制的关键词，不介绍、传播、扩散任何关于突破内容审查机制的工具。任何技术探究均在个人的局域网中完成，使用的信道均为国家网络运营商提供的合法有效的信道。&lt;/p&gt;

 &lt;/blockquote&gt;

 &lt;blockquote&gt;
 &lt;p&gt;友情提示：GFW在2021年11月中国国家互联网信息办公室发布的《网络数据安全管理条例（征求意见稿）》中被称为跨境安全网关，用于阻断访问境外反动网站和有害信息、防止来自境外的网络攻击、管控跨境网络数据传输、防范侦查打击跨境网络犯罪。擅自使用、搭建国际信道涉嫌违法，并有因此而被逮捕的事例，请各位慎重行事。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="dns-污染"&gt;&lt;a href="#dns-%e6%b1%a1%e6%9f%93" class="header-anchor"&gt;&lt;/a&gt;DNS 污染
&lt;/h2&gt;&lt;p&gt;我们在访问网站的时候，多数使用的是域名访问（我至少没看到谁闲的无聊用 IP 访问网站的）。在计算机网络中，计算机与计算机之间只能使用 IP 相互访问，域名的设计是为了让人类好记。人类是好记了，那机器怎么办？&lt;/p&gt;
&lt;p&gt;于是就出现了 &lt;code&gt;DNS&lt;/code&gt; 这个东西。DNS 负责将域名转换为 IP 返回给计算机，再让计算机访问那个 IP。比如说我要访问 &lt;code&gt;baidu.com&lt;/code&gt;，那么会先在 DNS 上查询 &lt;code&gt;baidu.com&lt;/code&gt; 的 &lt;code&gt;A&lt;/code&gt; / &lt;code&gt;AAAA&lt;/code&gt; 解析的 IP，然后计算机访问这个归属于百度的 IP。&lt;/p&gt;
&lt;p&gt;那么假如说某一个用户尝试访问 &lt;code&gt;google.com&lt;/code&gt;，按照 DNS 的标准理应返回 &lt;code&gt;google.com&lt;/code&gt; 的 &lt;code&gt;A&lt;/code&gt; / &lt;code&gt;AAAA&lt;/code&gt; 解析，但是由于众所周知的原因，google 配不上东大。于是 GFW 搞了个 DNS 污染：当用户访问不被允许的网站的时候，DNS 直接返回一个错误的 IP，比如某个 DNS 非常的喜欢返回 &lt;code&gt;localhost&lt;/code&gt;（感兴趣的可以查查）。由于客户端没有识别机制，那么计算机就会尝试去访问那个错误的 IP，很明显并不会有返回，那么这样最简单的 DNS 污染就实现了。&lt;/p&gt;
&lt;p&gt;那么就有人要问了：换一个没有被污染的 DNS 不就可以了吗。早期确实是这样的，但是现在 &lt;code&gt;1.1.1.1&lt;/code&gt;、&lt;code&gt;8.8.8.8&lt;/code&gt; 还有 &lt;code&gt;9.9.9.9&lt;/code&gt; 会被劫持到运营商的 DNS 上，同 IP 的 DoH 倒是没有被劫持，可能与 GFW 的逻辑有关。&lt;/p&gt;
&lt;h2 id="sni-阻断rst阻断"&gt;&lt;a href="#sni-%e9%98%bb%e6%96%adrst%e9%98%bb%e6%96%ad" class="header-anchor"&gt;&lt;/a&gt;SNI 阻断（RST阻断）
&lt;/h2&gt;&lt;p&gt;如果你能成功解决 DNS 污染的问题（比如用 DoH），恭喜你，你来到了第二关：SNI 阻断。现在大部分网站都上了 HTTPS，而 HTTPS 依赖于 TLS 握手。在 TLS 握手的第一个包——&lt;code&gt;ClientHello&lt;/code&gt; 中，客户端会告诉服务器自己要访问哪个域名。这个字段就叫 &lt;strong&gt;SNI（Server Name Indication）&lt;/strong&gt;。问题在于，TLS 1.2 及以下的 &lt;code&gt;ClientHello&lt;/code&gt; 是&lt;strong&gt;明文&lt;/strong&gt;传输的。也就是说，GFW 不需要解密你的流量，只需要读取 &lt;code&gt;ClientHello&lt;/code&gt; 里的 SNI 字段，就知道你要访问哪个网站。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;一个 IP 上可能托管了几百个网站（比如 Cloudflare 的 CDN），SNI 就是用来告诉服务器「我要访问的是你托管的那几百个网站里的哪一个」。（一部分 CDN 厂商的策略如 &lt;code&gt;cf&lt;/code&gt; 导致了其优化解析会非常简单，由于篇幅原因暂且不表）&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;如果说你尝试访问 &lt;code&gt;google.com&lt;/code&gt;，那么你的数据包会经历那么几个环节：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;客户端发送 &lt;code&gt;ClientHello&lt;/code&gt;，其中 &lt;code&gt;SNI = google.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;GFW 的 DPI（深度包检测）设备看到这个 SNI&lt;/li&gt;
&lt;li&gt;匹配到黑名单 → GFW 向客户端和服务器&lt;strong&gt;同时&lt;/strong&gt;发送伪造的 &lt;code&gt;TCP RST&lt;/code&gt; 包&lt;/li&gt;
&lt;li&gt;连接被重置，浏览器显示 &lt;code&gt;ERR_CONNECTION_RESET&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个过程非常快，通常在 TLS 握手完成之前就结束了。而且由于是双向 RST，即使客户端忽略 RST 继续发包，服务器那边也已经断开了。&lt;/p&gt;
&lt;h3 id="为什么-sni-阻断比-dns-污染更难搞"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88-sni-%e9%98%bb%e6%96%ad%e6%af%94-dns-%e6%b1%a1%e6%9f%93%e6%9b%b4%e9%9a%be%e6%90%9e" class="header-anchor"&gt;&lt;/a&gt;为什么 SNI 阻断比 DNS 污染更难搞
&lt;/h3&gt;&lt;p&gt;DNS 污染好歹可以通过用 DoH / DoT 来解决——毕竟只是换了个地图。但 SNI 阻断不同，它是直接在你和服务器之间的路上设卡，你不管问谁的路，最后走到这条路上都会被拦并接受检查。&lt;/p&gt;
&lt;p&gt;不过有个细节值得注意：&lt;strong&gt;GFW 目前主要检查的是 TLS 1.2 及以下的 ClientHello&lt;/strong&gt;。如果你用 TLS 1.3，情况会稍有不同，因为 TLS 1.3 支持 &lt;strong&gt;ECH（Encrypted ClientHello）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;ECH 的全称是 Encrypted ClientHello，由 Cloudflare、AWS 几个互联网厂商制定的 DNS 规则。它的核心思路很简单：既然 GFW 是通过明文的 SNI 来判断你要访问哪个网站的，那把 SNI 加密了不就完了？&lt;/p&gt;
&lt;p&gt;ECH 会把真正的 &lt;code&gt;ClientHello&lt;/code&gt;（含 SNI）用服务器提前公布的公钥加密，外面再套一层&lt;strong&gt;明文的掩护 SNI&lt;/strong&gt;——一般是 CDN 的泛域名，比如 &lt;code&gt;cloudflare-ech.com&lt;/code&gt;。GFW 看到的就是一个去 Cloudflare 的普通握手包，真正的目标域名藏在加密层里，它无从得知。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;以 X 为例，当向 X 发送 &lt;code&gt;ClientHello&lt;/code&gt; 时，GFW 会收到一个发往 &lt;code&gt;cloudflare-ech.com&lt;/code&gt; 的握手包，目标 IP 是 Cloudflare 的节点。此时对于 GFW 来说并不能判断出数据包是发往 X。而 X 的边缘节点正好有部署在 Cloudflare，所以此时 Cloudflare 的节点就会解包并转发到 X 的服务器。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;但是 ECH 有几个现实问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;需要服务器支持&lt;/strong&gt;：服务器必须提前公布 ECH 公钥（通常通过 DNS &lt;code&gt;HTTPS&lt;/code&gt; 记录发布），客户端才能加密 &lt;code&gt;ClientHello&lt;/code&gt;。目前支持 ECH 的网站还不算多，但是目前已知 Cloudflare 和 Meta 已开启 ECH 的支持。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;需要客户端支持&lt;/strong&gt;：浏览器要开启 ECH。Chrome、Firefox 都支持，但需要手动开启或者等默认启用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GFW 可能直接封 IP&lt;/strong&gt;：如果你访问的 IP 本身就在黑名单里，即使 SNI 加密了也没用，比如说访问 Facebook 时不小心解析到了被墙的 IP——这就是下面要说的 IP 黑洞。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="ech--doh-的组合"&gt;&lt;a href="#ech--doh-%e7%9a%84%e7%bb%84%e5%90%88" class="header-anchor"&gt;&lt;/a&gt;ECH + DoH 的组合
&lt;/h2&gt;&lt;p&gt;DoH 解决 DNS 层面的污染，ECH 解决 SNI 层面的阻断。两者结合，理论上可以绕过 GFW 的前两道防线。这也是开头提到的那个 XTLS BBS 帖子的核心思路。&lt;/p&gt;
&lt;p&gt;但这里有个坑：&lt;strong&gt;DoH 的域名本身可能被 SNI 阻断&lt;/strong&gt;。如果你用 &lt;code&gt;dns.google&lt;/code&gt; 作为 DoH 服务器，那客户端在连接 Google DNS 的时候发的 &lt;code&gt;ClientHello&lt;/code&gt; 里 SNI 就是 &lt;code&gt;dns.google&lt;/code&gt;——这不又被拦了？所以实际操作中需要选一个没被墙的 DoH 域名，或者在 Cloudflare Workers 上自建 DoH。&lt;/p&gt;
&lt;div class="github-card-box" id="gh-3265653561303738343663623836393537643338326139396665363231333164"&gt;
 &lt;a class="github-card-link" href="https://github.com/aloneowo0/Workers-DoH" target="_blank" rel="noopener noreferrer"&gt;
 &lt;div class="gc-header"&gt;
 &lt;div class="gc-title-wrap"&gt;
 &lt;div class="gc-avatar" id="gh-3265653561303738343663623836393537643338326139396665363231333164-avatar"&gt;
 &lt;svg viewBox="0 0 16 16" width="28" height="28" fill="currentColor"&gt;
 &lt;path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;div class="gc-name-text"&gt;
 &lt;span class="gc-owner"&gt;aloneowo0&lt;/span&gt;
 &lt;span class="gc-slash"&gt;/&lt;/span&gt;
 &lt;span class="gc-repo"&gt;Workers-DoH&lt;/span&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="gc-logo" title="View on GitHub"&gt;
 &lt;svg viewBox="0 0 16 16" width="36" height="36" fill="currentColor"&gt;
 &lt;path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;/div&gt;

 &lt;div class="gc-desc" id="gh-3265653561303738343663623836393537643338326139396665363231333164-desc"&gt;正在读取仓库简介...&lt;/div&gt;

 &lt;div class="gc-meta" id="gh-3265653561303738343663623836393537643338326139396665363231333164-meta"&gt;
 &lt;div class="gc-stats"&gt;
 &lt;span class="gc-item" id="gh-3265653561303738343663623836393537643338326139396665363231333164-stars"&gt;
 &lt;svg viewBox="0 0 16 16" width="22" height="22" fill="currentColor"&gt;&lt;path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"/&gt;&lt;/svg&gt;
 &lt;span class="val"&gt;--&lt;/span&gt;
 &lt;/span&gt;
 &lt;span class="gc-item" id="gh-3265653561303738343663623836393537643338326139396665363231333164-forks"&gt;
 &lt;svg viewBox="0 0 16 16" width="22" height="22" fill="currentColor"&gt;&lt;path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"/&gt;&lt;/svg&gt;
 &lt;span class="val"&gt;--&lt;/span&gt;
 &lt;/span&gt;
 &lt;span class="gc-item" id="gh-3265653561303738343663623836393537643338326139396665363231333164-license" style="display:none;"&gt;
 &lt;svg viewBox="0 0 16 16" width="22" height="22" fill="currentColor"&gt;&lt;path d="M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z"/&gt;&lt;/svg&gt;
 &lt;span class="val"&gt;&lt;/span&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="gc-lang-wrap"&gt;
 &lt;span class="gc-item" id="gh-3265653561303738343663623836393537643338326139396665363231333164-lang" style="display:none;"&gt;
 &lt;span class="gc-dot"&gt;&lt;/span&gt;
 &lt;span class="val"&gt;&lt;/span&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/a&gt;

 &lt;style&gt;
 .github-card-box {
 margin: 1.8rem 0;
 width: 100%;
 max-width: 585px;
 box-sizing: border-box;
 }
 .github-card-box .github-card-link {
 display: block;
 padding: 1.7rem 1.9rem;
 border-radius: 18px;
 background: var(--card-background, rgba(125, 125, 125, 0.05));
 border: 1px solid rgba(125, 125, 125, 0.18);
 box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
 text-decoration: none !important;
 color: inherit;
 transition: all 0.2s ease;
 box-sizing: border-box;
 }
 .github-card-box .github-card-link:hover {
 background: rgba(125, 125, 125, 0.09);
 border-color: rgba(99, 102, 241, 0.45);
 transform: translateY(-2px);
 box-shadow: 0 10px 28px rgba(0, 0, 0, 0.09);
 }
 .github-card-box .gc-header {
 display: flex;
 align-items: center;
 justify-content: space-between;
 margin-bottom: 1.05rem;
 }
 .github-card-box .gc-title-wrap {
 display: flex;
 align-items: center;
 gap: 0.9rem;
 font-size: 1.58rem;
 line-height: 1.35;
 overflow: hidden;
 }
 .github-card-box .gc-avatar {
 width: 48px;
 height: 48px;
 border-radius: 50%;
 overflow: hidden;
 display: flex;
 align-items: center;
 justify-content: center;
 background: rgba(125, 125, 125, 0.2);
 flex-shrink: 0;
 }
 .github-card-box .gc-avatar img {
 width: 100%;
 height: 100%;
 object-fit: cover;
 margin: 0 !important;
 display: block;
 }
 .github-card-box .gc-name-text {
 display: flex;
 align-items: center;
 gap: 0.55rem;
 white-space: nowrap;
 overflow: hidden;
 text-overflow: ellipsis;
 }
 .github-card-box .gc-owner {
 opacity: 0.75;
 font-weight: 400;
 }
 .github-card-box .gc-slash {
 opacity: 0.35;
 }
 .github-card-box .gc-repo {
 font-weight: 600;
 color: #3b82f6;
 }
 .github-card-box .gc-logo {
 opacity: 0.55;
 display: flex;
 align-items: center;
 flex-shrink: 0;
 }
 .github-card-box .gc-desc {
 font-size: 1.22rem;
 line-height: 1.65;
 opacity: 0.84;
 margin: 0 0 1.2rem 0;
 display: -webkit-box;
 -webkit-line-clamp: 2;
 -webkit-box-orient: vertical;
 overflow: hidden;
 }
 .github-card-box .gc-meta {
 display: flex;
 align-items: center;
 justify-content: space-between;
 padding-top: 1.1rem;
 border-top: 1px solid rgba(125, 125, 125, 0.14);
 font-size: 1.14rem;
 opacity: 0.82;
 }
 .github-card-box .gc-stats {
 display: flex;
 align-items: center;
 gap: 1.75rem;
 }
 .github-card-box .gc-item {
 display: inline-flex;
 align-items: center;
 gap: 0.55rem;
 }
 .github-card-box .gc-dot {
 width: 14px;
 height: 14px;
 border-radius: 50%;
 background: #3b82f6;
 display: inline-block;
 }
 .github-card-box:not(.gc-loaded) .gc-desc {
 opacity: 0.4;
 animation: gc-pulse 1.5s infinite ease-in-out;
 }
 @keyframes gc-pulse {
 0% { opacity: 0.3; }
 50% { opacity: 0.65; }
 100% { opacity: 0.3; }
 }
 [data-scheme="dark"] .github-card-box .gc-repo {
 color: #60a5fa;
 }
 [data-scheme="dark"] .github-card-box .github-card-link {
 background: rgba(255, 255, 255, 0.04);
 border-color: rgba(255, 255, 255, 0.12);
 }
 [data-scheme="dark"] .github-card-box .github-card-link:hover {
 background: rgba(255, 255, 255, 0.08);
 border-color: rgba(96, 165, 250, 0.55);
 }
 [data-scheme="dark"] .github-card-box .gc-meta {
 border-top-color: rgba(255, 255, 255, 0.1);
 }
 &lt;/style&gt;

 &lt;script&gt;
 (function() {
 const box = document.getElementById("gh-3265653561303738343663623836393537643338326139396665363231333164");
 const desc = document.getElementById("gh-3265653561303738343663623836393537643338326139396665363231333164-desc");
 const stars = document.getElementById("gh-3265653561303738343663623836393537643338326139396665363231333164-stars");
 const forks = document.getElementById("gh-3265653561303738343663623836393537643338326139396665363231333164-forks");
 const license = document.getElementById("gh-3265653561303738343663623836393537643338326139396665363231333164-license");
 const lang = document.getElementById("gh-3265653561303738343663623836393537643338326139396665363231333164-lang");
 const avatar = document.getElementById("gh-3265653561303738343663623836393537643338326139396665363231333164-avatar");

 fetch('https://api.github.com/repos/aloneowo0\/Workers-DoH')
 .then(r =&gt; {
 if (!r.ok) throw new Error(r.status);
 return r.json();
 })
 .then(d =&gt; {
 desc.textContent = d.description || "暂无项目描述";
 if (d.stargazers_count != null) {
 stars.querySelector(".val").textContent = Intl.NumberFormat('en-US', { notation: "compact" }).format(d.stargazers_count);
 }
 if (d.forks_count != null) {
 forks.querySelector(".val").textContent = Intl.NumberFormat('en-US', { notation: "compact" }).format(d.forks_count);
 }
 if (d.license &amp;&amp; d.license.spdx_id &amp;&amp; d.license.spdx_id !== "NOASSERTION") {
 license.style.display = "inline-flex";
 license.querySelector(".val").textContent = d.license.spdx_id;
 }
 if (d.language) {
 lang.style.display = "inline-flex";
 lang.querySelector(".val").textContent = d.language;
 }
 if (d.owner &amp;&amp; d.owner.avatar_url) {
 avatar.innerHTML = '&lt;img src="' + d.owner.avatar_url + '" alt="aloneowo0" loading="lazy" /&gt;';
 }
 box.classList.add("gc-loaded");
 })
 .catch(() =&gt; {
 desc.textContent = "在 GitHub 上查看项目源码与文档";
 box.classList.add("gc-loaded");
 });
 })();
 &lt;/script&gt;
&lt;/div&gt;

&lt;p&gt;我设计 DoH 思路就是将支持 ECH 的网站，使用各种方式获取对应网站 ECH 字段并植入到返回的 DoH 请求中，从而实现对大部分网站的 ECH 支持。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;当然这个方案也有问题，从流量特征的角度来说，其由于把 ECH 和外层 SNI 放到同一个包中，MTU 会变得巨大以至于可以轻松地检测出其是否使用了 ECH。&lt;del&gt;人家GFW只是懒得管不是看不见&lt;/del&gt;，该工具为学习使用，请勿滥用&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="ip-黑洞"&gt;&lt;a href="#ip-%e9%bb%91%e6%b4%9e" class="header-anchor"&gt;&lt;/a&gt;IP 黑洞
&lt;/h2&gt;&lt;p&gt;即使你完美解决了 DNS 污染和 SNI 阻断，你还有一个绕不开的问题：&lt;strong&gt;你总得和服务器建立连接&lt;/strong&gt;。而建立连接就需要知道对方的 IP 地址，并且向这个 IP 发包。&lt;/p&gt;
&lt;p&gt;GFW 维护了一个庞大的 IP 黑名单。当你的数据包的目的 IP 在黑名单里时，GFW 的边界路由器会直接&lt;strong&gt;丢弃&lt;/strong&gt;这些包——不给你任何回应，不发 &lt;code&gt;RST&lt;/code&gt;，什么都不发。从你的视角看，就是连接超时。&lt;/p&gt;
&lt;p&gt;这比 SNI 阻断更底层、更暴力，因为它不依赖协议层面的特征，只看 IP。&lt;/p&gt;
&lt;p&gt;SNI 阻断可以用 ECH 加密，DNS 污染可以用 DoH 绕过。但 IP 黑洞不同——&lt;strong&gt;IP 地址是网络层的寻址基础，你没法「隐藏」目的 IP&lt;/strong&gt;。就好像你寄信总得写收件人地址，不可能把地址也加密了。&lt;/p&gt;
&lt;p&gt;据我所知，目前在单机层面没有直接绕过 IP 黑洞的办法。你不可能让 GFW 的路由器不检查你的目的 IP。&lt;/p&gt;
&lt;p&gt;据不可靠渠道所说，IPv6 的阻拦会比 IPv4 小不少，具体原因未知，但是似乎确实有这个情况。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;以上均为个人观察总结，受限于测试环境与信息渠道，部分细节可能与实际情况存在偏差。技术本身是中立的，本文仅讨论技术原理，不构成任何操作建议，请遵守中国大陆法律。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一些个人的话26711"&gt;&lt;a href="#%e4%b8%80%e4%ba%9b%e4%b8%aa%e4%ba%ba%e7%9a%84%e8%af%9d26711" class="header-anchor"&gt;&lt;/a&gt;一些个人的话（26.7.11）
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;ECH&lt;/code&gt;这个东西跟&lt;code&gt;WG&lt;/code&gt;有点像，属于是&lt;del&gt;比较的安全&lt;/del&gt;但是&lt;strong&gt;特征及其明显&lt;/strong&gt;，&lt;del&gt;我也是无语了&lt;/del&gt;&lt;code&gt;RFC&lt;/code&gt;给的流量隐藏标准竟然是让所有流量都带上&lt;code&gt;ECH&lt;/code&gt;？！&lt;/p&gt;
&lt;p&gt;属实是嫌GFW不知道你是&lt;code&gt;ECH&lt;/code&gt;的重度用户了😂&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“The client offers ECH if it is in possession of a compatible ECH configuration and sends GREASE ECH otherwise.”&lt;/p&gt;

 &lt;/blockquote&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“客户端持有兼容的 ECH 配置时发送真实 ECH；否则发送 GREASE ECH。”&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;而且通过&lt;code&gt;DoH&lt;/code&gt;+&lt;code&gt;ECH&lt;/code&gt;的方法有很大的&lt;strong&gt;弊端&lt;/strong&gt;，就是你先要有一个可以直接使用的&lt;code&gt;DoH&lt;/code&gt;端点然后才能获取&lt;code&gt;ECH&lt;/code&gt;密钥。&lt;/p&gt;
&lt;p&gt;那么如果说&lt;code&gt;DoH&lt;/code&gt;被污染了呢？&lt;/p&gt;
&lt;p&gt;先不说比较困难的&lt;code&gt;SNI&lt;/code&gt;阻断（&lt;code&gt;RST&lt;/code&gt;阻断），光光&lt;code&gt;DNS&lt;/code&gt;污染就够喝一壶的了。如果你要使用这个&lt;code&gt;DoH&lt;/code&gt;端点，首先客户端会去&lt;code&gt;53&lt;/code&gt;端口上的明文&lt;code&gt;DNS&lt;/code&gt;上查询这个&lt;code&gt;DoH&lt;/code&gt;端点，假如说这一步就被拿下那连连接都没建立就&lt;del&gt;死&lt;/del&gt;了。&lt;/p&gt;
&lt;p&gt;如果要抗这个&lt;code&gt;DNS&lt;/code&gt;污染那么你就要换一个干净的&lt;code&gt;DNS&lt;/code&gt;或者在本地写好&lt;code&gt;DoH&lt;/code&gt;的初始&lt;code&gt;ip&lt;/code&gt;。前者需要用一个干净的&lt;code&gt;DNS&lt;/code&gt;去访问另一个&lt;code&gt;DoH&lt;/code&gt;的端点，&lt;del&gt;我都有干净的DNS了我用什么DoH啊？&lt;/del&gt;，后者需要改&lt;code&gt;host&lt;/code&gt;，配置比较麻烦倒也不是不行。&lt;/p&gt;
&lt;p&gt;如果&lt;code&gt;DoH&lt;/code&gt;端点还上了&lt;code&gt;SNI&lt;/code&gt;阻断那更完蛋：要么上&lt;code&gt;ECH&lt;/code&gt;，要么上&lt;code&gt;sni前置&lt;/code&gt;伪装。前者跟之前一样是&lt;strong&gt;套娃&lt;/strong&gt;，后者还要为这个东西开&lt;code&gt;tun&lt;/code&gt;接管流量，专门搞一个客户端，感觉相当麻烦。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;整个流程下来问题还是很多的。把这个做好直面GFW我只能说&lt;del&gt;还是代理方便&lt;/del&gt;&lt;/p&gt;

 &lt;/blockquote&gt;</description></item><item><title>SuperDoH：基于 Cloudflare Workers 的多上游 DNS over HTTPS 代理，支持ECH和路由注入</title><link>https://blog.hatsune01.de/p/superdoh%E5%9F%BA%E4%BA%8E-cloudflare-workers-%E7%9A%84%E5%A4%9A%E4%B8%8A%E6%B8%B8-dns-over-https-%E4%BB%A3%E7%90%86%E6%94%AF%E6%8C%81ech%E5%92%8C%E8%B7%AF%E7%94%B1%E6%B3%A8%E5%85%A5/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://blog.hatsune01.de/p/superdoh%E5%9F%BA%E4%BA%8E-cloudflare-workers-%E7%9A%84%E5%A4%9A%E4%B8%8A%E6%B8%B8-dns-over-https-%E4%BB%A3%E7%90%86%E6%94%AF%E6%8C%81ech%E5%92%8C%E8%B7%AF%E7%94%B1%E6%B3%A8%E5%85%A5/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;先推销一下自己的项目（手动 doge）&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="github-card-box" id="gh-3966376462666330306134643435316333316262336236373532613061323434"&gt;
 &lt;a class="github-card-link" href="https://github.com/aloneowo0/SuperDoH" target="_blank" rel="noopener noreferrer"&gt;
 &lt;div class="gc-header"&gt;
 &lt;div class="gc-title-wrap"&gt;
 &lt;div class="gc-avatar" id="gh-3966376462666330306134643435316333316262336236373532613061323434-avatar"&gt;
 &lt;svg viewBox="0 0 16 16" width="28" height="28" fill="currentColor"&gt;
 &lt;path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;div class="gc-name-text"&gt;
 &lt;span class="gc-owner"&gt;aloneowo0&lt;/span&gt;
 &lt;span class="gc-slash"&gt;/&lt;/span&gt;
 &lt;span class="gc-repo"&gt;SuperDoH&lt;/span&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="gc-logo" title="View on GitHub"&gt;
 &lt;svg viewBox="0 0 16 16" width="36" height="36" fill="currentColor"&gt;
 &lt;path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;/div&gt;

 &lt;div class="gc-desc" id="gh-3966376462666330306134643435316333316262336236373532613061323434-desc"&gt;正在读取仓库简介...&lt;/div&gt;

 &lt;div class="gc-meta" id="gh-3966376462666330306134643435316333316262336236373532613061323434-meta"&gt;
 &lt;div class="gc-stats"&gt;
 &lt;span class="gc-item" id="gh-3966376462666330306134643435316333316262336236373532613061323434-stars"&gt;
 &lt;svg viewBox="0 0 16 16" width="22" height="22" fill="currentColor"&gt;&lt;path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"/&gt;&lt;/svg&gt;
 &lt;span class="val"&gt;--&lt;/span&gt;
 &lt;/span&gt;
 &lt;span class="gc-item" id="gh-3966376462666330306134643435316333316262336236373532613061323434-forks"&gt;
 &lt;svg viewBox="0 0 16 16" width="22" height="22" fill="currentColor"&gt;&lt;path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"/&gt;&lt;/svg&gt;
 &lt;span class="val"&gt;--&lt;/span&gt;
 &lt;/span&gt;
 &lt;span class="gc-item" id="gh-3966376462666330306134643435316333316262336236373532613061323434-license" style="display:none;"&gt;
 &lt;svg viewBox="0 0 16 16" width="22" height="22" fill="currentColor"&gt;&lt;path d="M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z"/&gt;&lt;/svg&gt;
 &lt;span class="val"&gt;&lt;/span&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="gc-lang-wrap"&gt;
 &lt;span class="gc-item" id="gh-3966376462666330306134643435316333316262336236373532613061323434-lang" style="display:none;"&gt;
 &lt;span class="gc-dot"&gt;&lt;/span&gt;
 &lt;span class="val"&gt;&lt;/span&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/a&gt;

 &lt;style&gt;
 .github-card-box {
 margin: 1.8rem 0;
 width: 100%;
 max-width: 585px;
 box-sizing: border-box;
 }
 .github-card-box .github-card-link {
 display: block;
 padding: 1.7rem 1.9rem;
 border-radius: 18px;
 background: var(--card-background, rgba(125, 125, 125, 0.05));
 border: 1px solid rgba(125, 125, 125, 0.18);
 box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
 text-decoration: none !important;
 color: inherit;
 transition: all 0.2s ease;
 box-sizing: border-box;
 }
 .github-card-box .github-card-link:hover {
 background: rgba(125, 125, 125, 0.09);
 border-color: rgba(99, 102, 241, 0.45);
 transform: translateY(-2px);
 box-shadow: 0 10px 28px rgba(0, 0, 0, 0.09);
 }
 .github-card-box .gc-header {
 display: flex;
 align-items: center;
 justify-content: space-between;
 margin-bottom: 1.05rem;
 }
 .github-card-box .gc-title-wrap {
 display: flex;
 align-items: center;
 gap: 0.9rem;
 font-size: 1.58rem;
 line-height: 1.35;
 overflow: hidden;
 }
 .github-card-box .gc-avatar {
 width: 48px;
 height: 48px;
 border-radius: 50%;
 overflow: hidden;
 display: flex;
 align-items: center;
 justify-content: center;
 background: rgba(125, 125, 125, 0.2);
 flex-shrink: 0;
 }
 .github-card-box .gc-avatar img {
 width: 100%;
 height: 100%;
 object-fit: cover;
 margin: 0 !important;
 display: block;
 }
 .github-card-box .gc-name-text {
 display: flex;
 align-items: center;
 gap: 0.55rem;
 white-space: nowrap;
 overflow: hidden;
 text-overflow: ellipsis;
 }
 .github-card-box .gc-owner {
 opacity: 0.75;
 font-weight: 400;
 }
 .github-card-box .gc-slash {
 opacity: 0.35;
 }
 .github-card-box .gc-repo {
 font-weight: 600;
 color: #3b82f6;
 }
 .github-card-box .gc-logo {
 opacity: 0.55;
 display: flex;
 align-items: center;
 flex-shrink: 0;
 }
 .github-card-box .gc-desc {
 font-size: 1.22rem;
 line-height: 1.65;
 opacity: 0.84;
 margin: 0 0 1.2rem 0;
 display: -webkit-box;
 -webkit-line-clamp: 2;
 -webkit-box-orient: vertical;
 overflow: hidden;
 }
 .github-card-box .gc-meta {
 display: flex;
 align-items: center;
 justify-content: space-between;
 padding-top: 1.1rem;
 border-top: 1px solid rgba(125, 125, 125, 0.14);
 font-size: 1.14rem;
 opacity: 0.82;
 }
 .github-card-box .gc-stats {
 display: flex;
 align-items: center;
 gap: 1.75rem;
 }
 .github-card-box .gc-item {
 display: inline-flex;
 align-items: center;
 gap: 0.55rem;
 }
 .github-card-box .gc-dot {
 width: 14px;
 height: 14px;
 border-radius: 50%;
 background: #3b82f6;
 display: inline-block;
 }
 .github-card-box:not(.gc-loaded) .gc-desc {
 opacity: 0.4;
 animation: gc-pulse 1.5s infinite ease-in-out;
 }
 @keyframes gc-pulse {
 0% { opacity: 0.3; }
 50% { opacity: 0.65; }
 100% { opacity: 0.3; }
 }
 [data-scheme="dark"] .github-card-box .gc-repo {
 color: #60a5fa;
 }
 [data-scheme="dark"] .github-card-box .github-card-link {
 background: rgba(255, 255, 255, 0.04);
 border-color: rgba(255, 255, 255, 0.12);
 }
 [data-scheme="dark"] .github-card-box .github-card-link:hover {
 background: rgba(255, 255, 255, 0.08);
 border-color: rgba(96, 165, 250, 0.55);
 }
 [data-scheme="dark"] .github-card-box .gc-meta {
 border-top-color: rgba(255, 255, 255, 0.1);
 }
 &lt;/style&gt;

 &lt;script&gt;
 (function() {
 const box = document.getElementById("gh-3966376462666330306134643435316333316262336236373532613061323434");
 const desc = document.getElementById("gh-3966376462666330306134643435316333316262336236373532613061323434-desc");
 const stars = document.getElementById("gh-3966376462666330306134643435316333316262336236373532613061323434-stars");
 const forks = document.getElementById("gh-3966376462666330306134643435316333316262336236373532613061323434-forks");
 const license = document.getElementById("gh-3966376462666330306134643435316333316262336236373532613061323434-license");
 const lang = document.getElementById("gh-3966376462666330306134643435316333316262336236373532613061323434-lang");
 const avatar = document.getElementById("gh-3966376462666330306134643435316333316262336236373532613061323434-avatar");

 fetch('https://api.github.com/repos/aloneowo0\/SuperDoH')
 .then(r =&gt; {
 if (!r.ok) throw new Error(r.status);
 return r.json();
 })
 .then(d =&gt; {
 desc.textContent = d.description || "暂无项目描述";
 if (d.stargazers_count != null) {
 stars.querySelector(".val").textContent = Intl.NumberFormat('en-US', { notation: "compact" }).format(d.stargazers_count);
 }
 if (d.forks_count != null) {
 forks.querySelector(".val").textContent = Intl.NumberFormat('en-US', { notation: "compact" }).format(d.forks_count);
 }
 if (d.license &amp;&amp; d.license.spdx_id &amp;&amp; d.license.spdx_id !== "NOASSERTION") {
 license.style.display = "inline-flex";
 license.querySelector(".val").textContent = d.license.spdx_id;
 }
 if (d.language) {
 lang.style.display = "inline-flex";
 lang.querySelector(".val").textContent = d.language;
 }
 if (d.owner &amp;&amp; d.owner.avatar_url) {
 avatar.innerHTML = '&lt;img src="' + d.owner.avatar_url + '" alt="aloneowo0" loading="lazy" /&gt;';
 }
 box.classList.add("gc-loaded");
 })
 .catch(() =&gt; {
 desc.textContent = "在 GitHub 上查看项目源码与文档";
 box.classList.add("gc-loaded");
 });
 })();
 &lt;/script&gt;
&lt;/div&gt;

&lt;h1 id="搭建一个个人-doh-服务"&gt;&lt;a href="#%e6%90%ad%e5%bb%ba%e4%b8%80%e4%b8%aa%e4%b8%aa%e4%ba%ba-doh-%e6%9c%8d%e5%8a%a1" class="header-anchor"&gt;&lt;/a&gt;搭建一个个人 DoH 服务
&lt;/h1&gt;
 &lt;blockquote&gt;
 &lt;p&gt;Cloudflare 免费计划有每日额度限制，请不要随便公开自己的 DoH 端点。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="前言"&gt;&lt;a href="#%e5%89%8d%e8%a8%80" class="header-anchor"&gt;&lt;/a&gt;前言
&lt;/h2&gt;&lt;p&gt;随便讲一下 DNS 的作用，和主题关系不大&lt;/p&gt;
&lt;p&gt;我们访问互联网时，通常会在浏览器里输入一个网址。但计算机真正用来连接网络资源的是 &lt;code&gt;IP 地址&lt;/code&gt;，而不是域名。因为 IP 地址不好记，所以才有了 &lt;code&gt;DNS&lt;/code&gt;：它负责把 &lt;code&gt;baidu.com&lt;/code&gt; 这样的域名转换成对应的 IP 地址。&lt;/p&gt;
&lt;p&gt;&lt;img alt="ipv6 真长……" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.hatsune01.de/images/posts/workers-doh/01.webp"&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;能硬背 32 位 IPv6 地址的也是个狠人&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;传统 DNS 通常运行在 &lt;code&gt;UDP 53&lt;/code&gt; 上，默认不加密，因此安全性和抗劫持能力都比较差。在早期 HTTP 环境下，DNS 劫持并不少见。为了解决这些问题，后来出现了几种加密 DNS 协议，比如 &lt;code&gt;DoT&lt;/code&gt;、&lt;code&gt;DoH&lt;/code&gt; 和 &lt;code&gt;DoQ&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="doh-有什么用"&gt;&lt;a href="#doh-%e6%9c%89%e4%bb%80%e4%b9%88%e7%94%a8" class="header-anchor"&gt;&lt;/a&gt;DoH 有什么用
&lt;/h2&gt;&lt;p&gt;DoH 全称是 &lt;code&gt;DNS over HTTPS&lt;/code&gt;。简单来说，它会把 DNS 查询封装进 HTTPS 请求里，并通过 SSL/TLS 证书来保证传输过程的安全性。这里引用两段来自 Wiki 的数字身份认证说明：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“若注册者认定一个人的身份，是通过注册者信任的另外一个人来进行的。注册者信任的那个人就是身份认证机构（可以是一个自然人）。把数字身份比喻成一个证件，那么数字证书就是身份认证机构盖在数字身份证上的一个章或印（或者说加在数字身份证上的一个签名），这一行为表示身份认证机构已认定这个人。”&lt;/p&gt;

 &lt;/blockquote&gt;

 &lt;blockquote&gt;
 &lt;p&gt;“身份认证机构是人们注册公钥的机构。注册之后，身份认证机构就向注册者发一数字证书，也就是说在注册者的数字身份证上加签。服务有免费，也有收费。身份认证机构也可以是一个自然人，就如 PGP 和 GPG 系统所倡导的。”&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;简单来说，因为 DoH 使用 HTTPS 作为传输层，我们可以降低 DNS 查询被监听或篡改的风险。比如某些喜欢往 DNS 结果里“投毒”、把域名解析到 &lt;code&gt;localhost&lt;/code&gt; 的情况，DoH 就能在一定程度上缓解。&lt;/p&gt;
&lt;h2 id="项目实现的功能-推销"&gt;&lt;a href="#%e9%a1%b9%e7%9b%ae%e5%ae%9e%e7%8e%b0%e7%9a%84%e5%8a%9f%e8%83%bd-%e6%8e%a8%e9%94%80" class="header-anchor"&gt;&lt;/a&gt;项目实现的功能 &lt;del&gt;（推销）&lt;/del&gt;
&lt;/h2&gt;&lt;p&gt;这个项目主要实现了下面几个功能：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;通过 &lt;code&gt;cf-forward-ip&lt;/code&gt; 实现 &lt;code&gt;ECS&lt;/code&gt; 的手动注入。翻译成人话就是：解析结果会尽量根据用户所在地区进行优化。&lt;/li&gt;
&lt;li&gt;使用并发请求加速解析，并返回最快的上游结果。&lt;/li&gt;
&lt;li&gt;为cloudflare，Meta提供了完整的ECH注入&lt;/li&gt;
&lt;li&gt;带有简单过滤逻辑，可以识别错误的 DNS 返回；返回 &lt;code&gt;localhost&lt;/code&gt; 的结果也会被过滤。&lt;/li&gt;
&lt;li&gt;为google解析的内容引用了Sheas Cealing的规则使其可以在国内访问&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="部署"&gt;&lt;a href="#%e9%83%a8%e7%bd%b2" class="header-anchor"&gt;&lt;/a&gt;部署
&lt;/h2&gt;&lt;p&gt;搭建这个服务需要准备：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 Cloudflare 账号&lt;/li&gt;
&lt;li&gt;一个托管到 Cloudflare 的域名&lt;/li&gt;
&lt;li&gt;一个 GitHub 账号&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;部署步骤如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fork 我的项目。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;div class="github-card-box" id="gh-6239323836333039633332653433383137343065333366623731613163386239"&gt;
 &lt;a class="github-card-link" href="https://github.com/aloneowo0/Workers-DoH" target="_blank" rel="noopener noreferrer"&gt;
 &lt;div class="gc-header"&gt;
 &lt;div class="gc-title-wrap"&gt;
 &lt;div class="gc-avatar" id="gh-6239323836333039633332653433383137343065333366623731613163386239-avatar"&gt;
 &lt;svg viewBox="0 0 16 16" width="28" height="28" fill="currentColor"&gt;
 &lt;path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;div class="gc-name-text"&gt;
 &lt;span class="gc-owner"&gt;aloneowo0&lt;/span&gt;
 &lt;span class="gc-slash"&gt;/&lt;/span&gt;
 &lt;span class="gc-repo"&gt;Workers-DoH&lt;/span&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="gc-logo" title="View on GitHub"&gt;
 &lt;svg viewBox="0 0 16 16" width="36" height="36" fill="currentColor"&gt;
 &lt;path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/&gt;
 &lt;/svg&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 
 &lt;div class="gc-desc" id="gh-6239323836333039633332653433383137343065333366623731613163386239-desc"&gt;正在读取仓库简介...&lt;/div&gt;
 
 &lt;div class="gc-meta" id="gh-6239323836333039633332653433383137343065333366623731613163386239-meta"&gt;
 &lt;div class="gc-stats"&gt;
 &lt;span class="gc-item" id="gh-6239323836333039633332653433383137343065333366623731613163386239-stars"&gt;
 &lt;svg viewBox="0 0 16 16" width="22" height="22" fill="currentColor"&gt;&lt;path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"/&gt;&lt;/svg&gt;
 &lt;span class="val"&gt;--&lt;/span&gt;
 &lt;/span&gt;
 &lt;span class="gc-item" id="gh-6239323836333039633332653433383137343065333366623731613163386239-forks"&gt;
 &lt;svg viewBox="0 0 16 16" width="22" height="22" fill="currentColor"&gt;&lt;path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"/&gt;&lt;/svg&gt;
 &lt;span class="val"&gt;--&lt;/span&gt;
 &lt;/span&gt;
 &lt;span class="gc-item" id="gh-6239323836333039633332653433383137343065333366623731613163386239-license" style="display:none;"&gt;
 &lt;svg viewBox="0 0 16 16" width="22" height="22" fill="currentColor"&gt;&lt;path d="M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z"/&gt;&lt;/svg&gt;
 &lt;span class="val"&gt;&lt;/span&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;div class="gc-lang-wrap"&gt;
 &lt;span class="gc-item" id="gh-6239323836333039633332653433383137343065333366623731613163386239-lang" style="display:none;"&gt;
 &lt;span class="gc-dot"&gt;&lt;/span&gt;
 &lt;span class="val"&gt;&lt;/span&gt;
 &lt;/span&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/a&gt;
 
 &lt;style&gt;
 .github-card-box {
 margin: 1.8rem 0;
 width: 100%;
 max-width: 585px;
 box-sizing: border-box;
 }
 .github-card-box .github-card-link {
 display: block;
 padding: 1.7rem 1.9rem;
 border-radius: 18px;
 background: var(--card-background, rgba(125, 125, 125, 0.05));
 border: 1px solid rgba(125, 125, 125, 0.18);
 box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
 text-decoration: none !important;
 color: inherit;
 transition: all 0.2s ease;
 box-sizing: border-box;
 }
 .github-card-box .github-card-link:hover {
 background: rgba(125, 125, 125, 0.09);
 border-color: rgba(99, 102, 241, 0.45);
 transform: translateY(-2px);
 box-shadow: 0 10px 28px rgba(0, 0, 0, 0.09);
 }
 .github-card-box .gc-header {
 display: flex;
 align-items: center;
 justify-content: space-between;
 margin-bottom: 1.05rem;
 }
 .github-card-box .gc-title-wrap {
 display: flex;
 align-items: center;
 gap: 0.9rem;
 font-size: 1.58rem;
 line-height: 1.35;
 overflow: hidden;
 }
 .github-card-box .gc-avatar {
 width: 48px;
 height: 48px;
 border-radius: 50%;
 overflow: hidden;
 display: flex;
 align-items: center;
 justify-content: center;
 background: rgba(125, 125, 125, 0.2);
 flex-shrink: 0;
 }
 .github-card-box .gc-avatar img {
 width: 100%;
 height: 100%;
 object-fit: cover;
 margin: 0 !important;
 display: block;
 }
 .github-card-box .gc-name-text {
 display: flex;
 align-items: center;
 gap: 0.55rem;
 white-space: nowrap;
 overflow: hidden;
 text-overflow: ellipsis;
 }
 .github-card-box .gc-owner {
 opacity: 0.75;
 font-weight: 400;
 }
 .github-card-box .gc-slash {
 opacity: 0.35;
 }
 .github-card-box .gc-repo {
 font-weight: 600;
 color: #3b82f6;
 }
 .github-card-box .gc-logo {
 opacity: 0.55;
 display: flex;
 align-items: center;
 flex-shrink: 0;
 }
 .github-card-box .gc-desc {
 font-size: 1.22rem;
 line-height: 1.65;
 opacity: 0.84;
 margin: 0 0 1.2rem 0;
 display: -webkit-box;
 -webkit-line-clamp: 2;
 -webkit-box-orient: vertical;
 overflow: hidden;
 }
 .github-card-box .gc-meta {
 display: flex;
 align-items: center;
 justify-content: space-between;
 padding-top: 1.1rem;
 border-top: 1px solid rgba(125, 125, 125, 0.14);
 font-size: 1.14rem;
 opacity: 0.82;
 }
 .github-card-box .gc-stats {
 display: flex;
 align-items: center;
 gap: 1.75rem;
 }
 .github-card-box .gc-item {
 display: inline-flex;
 align-items: center;
 gap: 0.55rem;
 }
 .github-card-box .gc-dot {
 width: 14px;
 height: 14px;
 border-radius: 50%;
 background: #3b82f6;
 display: inline-block;
 }
 .github-card-box:not(.gc-loaded) .gc-desc {
 opacity: 0.4;
 animation: gc-pulse 1.5s infinite ease-in-out;
 }
 @keyframes gc-pulse {
 0% { opacity: 0.3; }
 50% { opacity: 0.65; }
 100% { opacity: 0.3; }
 }
 [data-scheme="dark"] .github-card-box .gc-repo {
 color: #60a5fa;
 }
 [data-scheme="dark"] .github-card-box .github-card-link {
 background: rgba(255, 255, 255, 0.04);
 border-color: rgba(255, 255, 255, 0.12);
 }
 [data-scheme="dark"] .github-card-box .github-card-link:hover {
 background: rgba(255, 255, 255, 0.08);
 border-color: rgba(96, 165, 250, 0.55);
 }
 [data-scheme="dark"] .github-card-box .gc-meta {
 border-top-color: rgba(255, 255, 255, 0.1);
 }
 &lt;/style&gt;
 
 &lt;script&gt;
 (function() {
 const box = document.getElementById("gh-6239323836333039633332653433383137343065333366623731613163386239");
 const desc = document.getElementById("gh-6239323836333039633332653433383137343065333366623731613163386239-desc");
 const stars = document.getElementById("gh-6239323836333039633332653433383137343065333366623731613163386239-stars");
 const forks = document.getElementById("gh-6239323836333039633332653433383137343065333366623731613163386239-forks");
 const license = document.getElementById("gh-6239323836333039633332653433383137343065333366623731613163386239-license");
 const lang = document.getElementById("gh-6239323836333039633332653433383137343065333366623731613163386239-lang");
 const avatar = document.getElementById("gh-6239323836333039633332653433383137343065333366623731613163386239-avatar");
 
 fetch('https://api.github.com/repos/aloneowo0\/Workers-DoH')
 .then(r =&gt; {
 if (!r.ok) throw new Error(r.status);
 return r.json();
 })
 .then(d =&gt; {
 desc.textContent = d.description || "暂无项目描述";
 if (d.stargazers_count != null) {
 stars.querySelector(".val").textContent = Intl.NumberFormat('en-US', { notation: "compact" }).format(d.stargazers_count);
 }
 if (d.forks_count != null) {
 forks.querySelector(".val").textContent = Intl.NumberFormat('en-US', { notation: "compact" }).format(d.forks_count);
 }
 if (d.license &amp;&amp; d.license.spdx_id &amp;&amp; d.license.spdx_id !== "NOASSERTION") {
 license.style.display = "inline-flex";
 license.querySelector(".val").textContent = d.license.spdx_id;
 }
 if (d.language) {
 lang.style.display = "inline-flex";
 lang.querySelector(".val").textContent = d.language;
 }
 if (d.owner &amp;&amp; d.owner.avatar_url) {
 avatar.innerHTML = '&lt;img src="' + d.owner.avatar_url + '" alt="aloneowo0" loading="lazy" /&gt;';
 }
 box.classList.add("gc-loaded");
 })
 .catch(() =&gt; {
 desc.textContent = "在 GitHub 上查看项目源码与文档";
 box.classList.add("gc-loaded");
 });
 })();
 &lt;/script&gt;
 &lt;/div&gt;

2. 修改 &lt;code&gt;.env&lt;/code&gt; 文件里的内容并保存。如果没有特殊需求，保持默认配置即可。
3. 登录 Cloudflare，进入 &lt;strong&gt;Workers 和 Pages&lt;/strong&gt;，点击创建应用程序。
&lt;img alt="Cloudflare Workers 和 Pages 创建应用程序页面" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.hatsune01.de/images/posts/workers-doh/02.webp"&gt;
4. 选择连接到 GitHub，并选择刚刚 Fork 的项目。保持默认配置，直接部署。
5. 绑定一个域名。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;设置的域名或子域名尽量不要出现敏感词汇，否则容易被阻断。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;等待部署完成后，就可以开始使用了。&lt;/p&gt;
&lt;h2 id="使用"&gt;&lt;a href="#%e4%bd%bf%e7%94%a8" class="header-anchor"&gt;&lt;/a&gt;使用
&lt;/h2&gt;&lt;p&gt;目前我确认 Chrome、Firefox 浏览器和 Windows 11 系统都支持配置 DoH。其他客户端是否支持，建议自行测试。&lt;/p&gt;
&lt;h3 id="ech实现的原理"&gt;&lt;a href="#ech%e5%ae%9e%e7%8e%b0%e7%9a%84%e5%8e%9f%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;ECH实现的原理
&lt;/h3&gt;&lt;p&gt;cloudflare的ECH其实是公开的，而且很离谱的是全部ECH的密钥是同一个，更离谱的是cf关闭ECH的方式是把DNS上HTTPS字段的解析里面的ECH给删掉，所以说如果我们通过构建一个带有正确ECH的DNS解析结果就可以实现通过ECH与网站链接&lt;/p&gt;
&lt;p&gt;Meta的情况会特殊一点。Meta本身是支持ECH的，但是由于不明的原因ECH没有公布在DNS中，跟cloudflare那些没有公布ECH的网站类似都是不公开ECH。问题是Meta的ECH是独立的，获取会比较麻烦。我在github的一个帖子中看到一个获取的方法，使用的是retry来实现ECH的获取。简单点说是如果你发送一个错误的ECH给服务器，如果服务器收到了会返回一个retry_config让你的浏览器重试，这个retry里面就包含正确的ECH字段，从而获取到正确的ECH。&lt;/p&gt;
&lt;p&gt;然后对上述网站进行dns结果重写并注入ECH就可以使用ECH访问了&lt;/p&gt;</description></item></channel></rss>