<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>luoli</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://blog.ztmss.com/</id>
  <link href="https://blog.ztmss.com/" rel="alternate"/>
  <link href="https://blog.ztmss.com/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, luoli</rights>
  <subtitle>任由时间拉扯，只能被押着向前</subtitle>
  <title>Luoli♥BLOG</title>
  <updated>2026-11-03T04:47:52.530Z</updated>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="D1" scheme="https://blog.ztmss.com/tags/D1/"/>
    <category term="Cloudflare Pages" scheme="https://blog.ztmss.com/tags/Cloudflare-Pages/"/>
    <category term="SunNav" scheme="https://blog.ztmss.com/tags/SunNav/"/>
    <category term="导航站" scheme="https://blog.ztmss.com/tags/%E5%AF%BC%E8%88%AA%E7%AB%99/"/>
    <category term="WebDAV" scheme="https://blog.ztmss.com/tags/WebDAV/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>导航站是最经典的「自建服务入门项目」，但大部分开源方案要么是纯静态页（改个链接要改代码重新构建），要么后端跑在需要买服务器的地方。</p><p><strong>SunNav</strong> 把这两头都解决在 Cloudflare 免费套餐里：前端 React + Tailwind 跑 <strong>Cloudflare Pages</strong>，数据存 <strong>D1（SQLite）</strong>，动态接口用 <strong>Pages Functions</strong>——没有服务器、没有月费，改链接在后台点一下就行。</p><ul><li><strong>项目地址</strong>：<a href="https://github.com/love-ztm/SunNav">https://github.com/love-ztm/SunNav</a></li><li><strong>开源协议</strong>：MIT（基于 <a href="https://github.com/lyan0220/ModernNav">ModernNav</a> 二次开发）</li><li><strong>技术栈</strong>：React 18 · Tailwind CSS · Vite &#x2F; Cloudflare Pages Functions · D1</li></ul><p>它的辨识度在颜值上：<strong>粉色玻璃拟态</strong>——毛玻璃卡片、主题色自动取色、背景模糊参数全部后台可调，亮暗双主题还支持各自独立的壁纸。功能上除了常规的分类&#x2F;链接管理，比较有特色的是<strong>聚合搜索命令面板</strong>（<code>/</code> 键唤起，带拼音首字母匹配）、<strong>私密分类</strong>（访问码登录才可见）和 <strong>WebDAV 双目标定时云备份</strong>（坚果云 &#x2F; InfiniCLOUD &#x2F; AList 都能用，备份列表可查、任意一份一键恢复）。</p><hr><h2 id="功能一览"><a href="#功能一览" class="headerlink" title="功能一览"></a>功能一览</h2><h3 id="前台"><a href="#前台" class="headerlink" title="前台"></a>前台</h3><ul><li><strong>三级结构</strong>：分类 → 子分组 → 链接，玻璃拟态卡片展示</li><li><strong>聚合搜索</strong>：站内 &#x2F; Google &#x2F; Bing 等引擎可配置，<code>/</code> 快捷键唤起命令面板（支持拼音首字母模糊匹配）</li><li><strong>三态主题</strong>：亮色 &#x2F; 暗色 &#x2F; 跟随系统（默认亮色），暗色模式可单独设壁纸</li><li><strong>外观全可调</strong>：每日壁纸、主题色自动取色、背景模糊、卡片毛玻璃参数、卡片宽高 &#x2F; 图标大小 &#x2F; <strong>每行卡片数</strong></li><li><strong>私密分类</strong>：访问码登录可见，访客不可见</li><li><strong>中英双语</strong>：未设置时默认中文</li><li><strong>无闪烁</strong>：首屏主题预渲染，刷新和新浏览器打开都不会黑屏</li><li><strong>PWA</strong>：可添加到主屏幕</li></ul><h3 id="后台（-admin，默认访问码-admin）"><a href="#后台（-admin，默认访问码-admin）" class="headerlink" title="后台（/admin，默认访问码 admin）"></a>后台（<code>/admin</code>，默认访问码 <code>admin</code>）</h3><ul><li>内容管理：分类&#x2F;链接增删改、拖拽排序、⭐ 一键指定「打开站点默认显示的分类」</li><li>外观设置：壁纸、主题色、玻璃质感、布局全参数</li><li><strong>WebDAV 云备份</strong>：同时配置两个网盘、定时自动备份 + 保留份数自动清理、备份列表随时查、任意一份一键恢复</li><li>数据导入导出（JSON）、浏览器书签导入</li><li>访问码修改（PBKDF2 哈希存储，改后所有已登录设备全部失效）</li></ul><hr><h2 id="部署教程（Cloudflare-Pages，四步）"><a href="#部署教程（Cloudflare-Pages，四步）" class="headerlink" title="部署教程（Cloudflare Pages，四步）"></a>部署教程（Cloudflare Pages，四步）</h2><h3 id="第-1-步：Fork-仓库并连接-Pages"><a href="#第-1-步：Fork-仓库并连接-Pages" class="headerlink" title="第 1 步：Fork 仓库并连接 Pages"></a>第 1 步：Fork 仓库并连接 Pages</h3><ol><li>打开 <a href="https://github.com/love-ztm/SunNav">SunNav 仓库</a>，点右上角 <strong>Fork</strong> 到自己账号</li><li>Cloudflare Dashboard → <strong>Workers 和 Pages</strong> → <strong>创建</strong> → <strong>Pages</strong> → <strong>连接到 Git</strong></li><li>选择刚 Fork 的仓库，构建配置：<ul><li><strong>框架预设</strong>：Vite</li><li><strong>构建命令</strong>：<code>npm run build</code></li><li><strong>输出目录</strong>：<code>dist</code></li></ul></li></ol><p>先直接部署一次（此时还没有数据库，但没关系，下一步补上）。</p><h3 id="第-2-步：创建-D1-数据库并建表"><a href="#第-2-步：创建-D1-数据库并建表" class="headerlink" title="第 2 步：创建 D1 数据库并建表"></a>第 2 步：创建 D1 数据库并建表</h3><ol><li>Dashboard → <strong>存储和数据库</strong> → <strong>D1 SQL 数据库</strong> → 创建，名字随意（示例用 <code>sunnav-db</code>），建完记下数据库的名称和区域</li><li>进入该数据库 → <strong>控制台（Console）</strong>，把仓库里的 <a href="https://github.com/love-ztm/SunNav/blob/main/schema-console.sql"><code>schema-console.sql</code></a> 的<strong>全部内容</strong>粘贴进去执行</li></ol><blockquote><p><strong>为什么要区分两份 SQL？</strong> D1 控制台<strong>解析不了带 <code>--</code> 注释的 SQL</strong>，所以仓库提供了一份<strong>无注释版 <code>schema-console.sql</code></strong> 专供控制台粘贴用；带注释的 <code>schema.sql</code> 是给 wrangler CLI 用的（<code>npx wrangler d1 execute sunnav-db --local --file=./schema.sql</code>）。别拿错文件。</p></blockquote><p>建表后一共六张表：<code>config</code>（配置与访问码）、<code>categories</code>、<code>subcategories</code>、<code>links</code>（三级内容）、<code>rate_limits</code>（IP 限流），初始会写入默认访问码 <code>admin</code> 和 schema 版本号。</p><h3 id="第-3-步：绑定-D1-到-Pages"><a href="#第-3-步：绑定-D1-到-Pages" class="headerlink" title="第 3 步：绑定 D1 到 Pages"></a>第 3 步：绑定 D1 到 Pages</h3><p>Pages 项目 → <strong>设置 → 绑定（Bindings）</strong> → 添加 <strong>D1 数据库绑定</strong>：</p><ul><li><strong>变量名</strong>：<code>DB</code>（必须叫这个名字，Functions 代码按 <code>env.DB</code> 取）</li><li><strong>数据库</strong>：选第 2 步创建的 <code>sunnav-db</code></li></ul><p>保存后<strong>重新部署一次</strong>，绑定才会生效。</p><h3 id="第-4-步：登录并改密码"><a href="#第-4-步：登录并改密码" class="headerlink" title="第 4 步：登录并改密码"></a>第 4 步：登录并改密码</h3><ol><li>访问你的 <code>https://&lt;项目名&gt;.pages.dev</code></li><li>点右下角<strong>齿轮</strong>图标进入后台（或直接访问 <code>/admin</code>）</li><li>登录页只需输入访问码：默认 <strong><code>admin</code></strong></li><li><strong>登录后第一件事</strong>：全局设置 → 底部修改访问码</li></ol><blockquote><p>改访问码不是改个字符串那么简单：它以 <strong>PBKDF2 哈希</strong>存储，且修改会<strong>轮换 JWT 签名密钥</strong>——所有已登录设备（包括你自己）都会失效，需要重新登录。这是安全设计，不是 bug。</p></blockquote><p>到这一步部署完成，一个 <code>pages.dev</code> 域名、免费 HTTPS、全球 CDN 的导航站就上线了。想绑自定义域名：Pages 项目 → 自定义域 → 按 CF 提示加 CNAME 即可（域名托管在 CF 账号下会自动配）。</p><hr><h2 id="WebDAV-定时备份说明"><a href="#WebDAV-定时备份说明" class="headerlink" title="WebDAV 定时备份说明"></a>WebDAV 定时备份说明</h2><p>这是 SunNav 最有实用价值的功能，配置前先理解它的<strong>工作机制</strong>，不然会觉得「怎么没准点备份」。</p><h3 id="懒触发机制"><a href="#懒触发机制" class="headerlink" title="懒触发机制"></a>懒触发机制</h3><p>Cloudflare Pages Functions <strong>没有常驻定时器</strong>（不像 Workers 有 Cron Triggers），所以定时备份采用<strong>懒触发</strong>：页面打开时（以及打开期间<strong>每 10 分钟</strong>）静默检查一次，发现「已过设定时间且当天还没备份」就自动执行。</p><p>推论：</p><ul><li><strong>实际备份时刻 &#x3D; 设定时间之后第一次打开站点</strong>。比如设了每天凌晨 3 点，但你 8 点才第一次打开，那备份发生在 8 点</li><li>页面保持打开就会<strong>准点备份</strong>（每 10 分钟的自检兜住）</li><li>就算你从来不打开页面，只要哪天打开了，漏掉的备份会自动补上</li></ul><h3 id="配置步骤"><a href="#配置步骤" class="headerlink" title="配置步骤"></a>配置步骤</h3><p>后台 → <strong>数据 → WebDAV 备份</strong>：</p><ol><li>填 <strong>WebDAV 地址</strong>（必须<strong>公网可达</strong>——局域网 NAS 地址 Cloudflare 的服务器访问不到）、账号、密码、远程目录</li><li>可添加<strong>第二个目标</strong>（双保险：比如坚果云 + AList 各一份）</li><li>设定<strong>每日备份时间</strong>与<strong>保留份数</strong>（超出自动清理最旧的）</li><li>点保存后可用「立即备份」测试一次，备份列表里能看到每份备份的时间与状态</li></ol><h3 id="三条实践建议"><a href="#三条实践建议" class="headerlink" title="三条实践建议"></a>三条实践建议</h3><ul><li><strong>用应用密码</strong>：坚果云走「账户信息 → 安全选项 → 生成应用密码」，别用主密码</li><li><strong>备份内容</strong>：JSON 格式（分类 + 壁纸 + 偏好），与「下载备份文件」的导出格式一致——也就是说手动导出的 JSON 也能直接恢复</li><li><strong>恢复</strong>：备份列表里任意一份一键恢复，覆盖当前站点内容。改了大版本内容前，先手动备份一份</li></ul><hr><h2 id="本地开发"><a href="#本地开发" class="headerlink" title="本地开发"></a>本地开发</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">npm install</span><br><span class="line">npx wrangler d1 execute sunnav-db --<span class="built_in">local</span> --file=./schema.sql   <span class="comment"># 本地 D1 建表</span></span><br><span class="line">npm run dev            <span class="comment"># 纯前端开发（Vite，5173 端口）</span></span><br><span class="line">npm run build          <span class="comment"># 生产构建</span></span><br><span class="line">npx wrangler pages dev ./dist   <span class="comment"># 本地全栈模拟（Functions + D1 都在）</span></span><br></pre></td></tr></table></figure><p>想改代码再提交，仓库自带完整质量链：<code>npm run verify</code> 一次跑完 ESLint + TypeScript 双 tsconfig 检查 + Vitest + 生产构建。CI 里也有相同的检查（GitHub Actions）。</p><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="部署后打开白屏或报-500？"><a href="#部署后打开白屏或报-500？" class="headerlink" title="部署后打开白屏或报 500？"></a>部署后打开白屏或报 500？</h3><p>九成是<strong>第 3 步没做或没重新部署</strong>——D1 绑定是在保存后需要重新部署才生效的。确认绑定变量名是 <code>DB</code>（不是 <code>sunnav-db</code>）。</p><h3 id="建表-SQL-执行报错？"><a href="#建表-SQL-执行报错？" class="headerlink" title="建表 SQL 执行报错？"></a>建表 SQL 执行报错？</h3><p>用的是带 <code>--</code> 注释的 <code>schema.sql</code>。控制台请用无注释的 <code>schema-console.sql</code>。</p><h3 id="后台进不去-密码忘了？"><a href="#后台进不去-密码忘了？" class="headerlink" title="后台进不去 &#x2F; 密码忘了？"></a>后台进不去 &#x2F; 密码忘了？</h3><p>默认访问码是 <code>admin</code>。改过但忘了的话，在 D1 控制台执行 <code>DELETE FROM config WHERE key = &#39;auth_code&#39;</code> 清掉旧码，系统会回退到默认 <code>admin</code>（此操作会删掉配置表中该键，重新登录后再改新码）。</p><h3 id="私密分类访客能看到吗？"><a href="#私密分类访客能看到吗？" class="headerlink" title="私密分类访客能看到吗？"></a>私密分类访客能看到吗？</h3><p>看不到。私密分类要访问码登录后才可见，访客的首页完全不渲染它——不是「点了才提示密码」，是彻底不出现。</p><h3 id="WebDAV-一直失败？"><a href="#WebDAV-一直失败？" class="headerlink" title="WebDAV 一直失败？"></a>WebDAV 一直失败？</h3><p>按顺序查：地址是否公网可达（NAS 内网地址不行）→ 是否用了应用密码 → 远程目录是否存在（程序会自动 MKCOL 创建，405&#x2F;301 属正常中间态）→ 网盘服务商是否限流。</p><h3 id="数据在哪、会不会丢？"><a href="#数据在哪、会不会丢？" class="headerlink" title="数据在哪、会不会丢？"></a>数据在哪、会不会丢？</h3><p>全部在 D1 数据库里（Cloudflare 托管，免费版每天 10 万次写远超导航站用量）。但要防误操作&#x2F;误删，WebDAV 备份就是为此准备的——配好双目标定时备份，等于多了两份异地快照。</p><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>SunNav 是那种「架构选型很聪明」的项目：导航站这种低写入、低流量、个人用的服务，放在 Cloudflare Pages + D1 上是零成本的最优解；而 Pages Functions 没有定时器的短板，用懒触发 + 前端周期自检绕了过去，WebDAV 双目标 + 保留策略又把数据安全补齐。加上玻璃拟态的颜值和 PWA、命令面板这些体验细节，作为个人起始页已经相当完整。</p><p>部署一句话总结：<strong>Fork 连 Pages → D1 建表（无注释版 SQL）→ 绑 <code>DB</code> 重新部署 → <code>admin</code> 登录改密 → 配上双 WebDAV 备份收工。</strong></p><hr><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://github.com/love-ztm/SunNav">SunNav 项目仓库（GitHub）</a></li><li><a href="https://github.com/lyan0220/ModernNav">ModernNav（上游原项目）</a></li><li><a href="https://github.com/love-ztm/SunNav/blob/main/schema-console.sql">schema-console.sql（D1 控制台专用建表）</a></li><li><a href="https://developers.cloudflare.com/pages/functions/">Cloudflare Pages Functions 文档</a></li><li><a href="https://developers.cloudflare.com/d1/">Cloudflare D1 文档</a></li><li><a href="https://developers.cloudflare.com/pages/configuration/build-configuration/">Cloudflare Pages 构建配置</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/11/03/sunnav-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/11/03/sunnav-deployment-tutorial/"/>
    <published>2026-11-03T05:00:00.000Z</published>
    <summary>SunNav 是一套粉色玻璃拟态风格的个人导航仪表盘，React + Tailwind 前端跑在 Cloudflare Pages，Functions + D1 做后端，全部免费套餐承载。支持分类/子分组/链接三级结构、聚合搜索、私密分类、PWA、以及 WebDAV 双目标定时云备份（备份列表可查、一键恢复）。本文给出从 Fork 到上线的四步部署、WebDAV 备份配置与懒触发机制说明、本地开发与常见问题。</summary>
    <title>SunNav 部署教程：Cloudflare Pages 免费搭建粉色玻璃拟态导航站，D1 存储 + WebDAV 双目标云备份</title>
    <updated>2026-11-03T04:47:52.530Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="HiDNS" scheme="https://blog.ztmss.com/tags/HiDNS/"/>
    <category term="DNS管理" scheme="https://blog.ztmss.com/tags/DNS%E7%AE%A1%E7%90%86/"/>
    <category term="Docker部署" scheme="https://blog.ztmss.com/tags/Docker%E9%83%A8%E7%BD%B2/"/>
    <category term="域名解析" scheme="https://blog.ztmss.com/tags/%E5%9F%9F%E5%90%8D%E8%A7%A3%E6%9E%90/"/>
    <category term="自建服务" scheme="https://blog.ztmss.com/tags/%E8%87%AA%E5%BB%BA%E6%9C%8D%E5%8A%A1/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>域名一多，解析记录就散了：主站在阿里云、CDN 在 Cloudflare、小域名扔在 DNSPod、还有几个在华为云和 NameSilo。每次改个解析要登录四五个后台，密码各不相同，谁到期了也记不清。</p><p><strong>HiDNS</strong> 就是解决这个的：一个自托管面板，把 <strong>26 家 DNS 服务商</strong>的解析记录聚合到一起管理，再附带 WHOIS 查询、域名续期调度、NS 监控故障转移这些「顺手的运维能力」。</p><ul><li><strong>项目地址</strong>：<a href="https://github.com/HiPM-Tech/HiDNS">https://github.com/HiPM-Tech/HiDNS</a></li><li><strong>开源协议</strong>：GPL-3.0</li><li><strong>技术栈</strong>：React 19 + Vite 8 前端 &#x2F; Node.js + TypeScript + Express 后端 &#x2F; SQLite（默认）、MySQL、PostgreSQL 三选一</li><li><strong>官方文档站</strong>：<a href="https://hipm-tech.github.io/HiDNS/">https://hipm-tech.github.io/HiDNS/</a></li></ul><hr><h2 id="功能特性"><a href="#功能特性" class="headerlink" title="功能特性"></a>功能特性</h2><h3 id="多服务商聚合（核心卖点）"><a href="#多服务商聚合（核心卖点）" class="headerlink" title="多服务商聚合（核心卖点）"></a>多服务商聚合（核心卖点）</h3><p>一个面板管理 <strong>26 家</strong> DNS 服务商的解析记录，A、AAAA、CNAME、MX、TXT、SRV、CAA 等全类型记录增删改查：</p><table><thead><tr><th align="left">分组</th><th align="left">服务商</th></tr></thead><tbody><tr><td align="left"><strong>国内</strong></td><td align="left">阿里云、DNSPod（腾讯云）、华为云、百度云、火山引擎、京东云、西部数码、青云、宝塔面板、阿里云 ESA、腾讯 EdgeOne、雨云、VPS8</td></tr><tr><td align="left"><strong>国际</strong></td><td align="left">Cloudflare、NameSilo、Spaceship、PowerDNS、DNS.LA、DNSHE、HiDNS、彩虹DNS聚合（CaihongDNS）、Gcore</td></tr></tbody></table><p>创建服务商账号时支持 lego 风格别名（如 <code>alidns</code> → <code>aliyun</code>、<code>edgeone</code> → <code>tencenteo</code>），前端表单由配置字段定义驱动，加新服务商不用改前端代码。</p><h3 id="高级能力（超出「聚合」的部分）"><a href="#高级能力（超出「聚合」的部分）" class="headerlink" title="高级能力（超出「聚合」的部分）"></a>高级能力（超出「聚合」的部分）</h3><table><thead><tr><th align="left">能力</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><strong>WHOIS 查询</strong></td><td align="left">注册商模式，带智能缓存</td></tr><tr><td align="left"><strong>域名续期管理</strong></td><td align="left">自动化续期调度，到期不再靠记性</td></tr><tr><td align="left"><strong>NS 监控与故障转移</strong></td><td align="left">NS 记录异常自动切换（高可用保障）</td></tr><tr><td align="left"><strong>API Token</strong></td><td align="left">细粒度权限控制，方便接自动化脚本</td></tr><tr><td align="left"><strong>登录安全全家桶</strong></td><td align="left">OAuth2&#x2F;OIDC 单点登录、WebAuthn&#x2F;Passkeys 无密码登录、TOTP 双因素</td></tr><tr><td align="left"><strong>审计日志</strong></td><td align="left">完整的操作日志系统 + 安全策略与登录限制</td></tr><tr><td align="left"><strong>多用户与团队</strong></td><td align="left">admin&#x2F;member 角色访问控制，团队共享域名</td></tr><tr><td align="left"><strong>邮件通知</strong></td><td align="left">SMTP 发送 + 模板管理</td></tr><tr><td align="left"><strong>MCP Server</strong></td><td align="left">内置 MCP 服务（可接 AI 助手操作 DNS）</td></tr><tr><td align="left"><strong>API 文档</strong></td><td align="left">Swagger UI，路径 <code>/api/docs</code></td></tr></tbody></table><hr><h2 id="架构速览"><a href="#架构速览" class="headerlink" title="架构速览"></a>架构速览</h2><p>部署前花一分钟看懂结构，后面排障不慌：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">React 19 SPA（client/）</span><br><span class="line">        │</span><br><span class="line">Express API（server/，端口 3001）</span><br><span class="line">        │</span><br><span class="line">统一数据访问层（四层架构）</span><br><span class="line">BAL 业务适配器 → DAL 抽象层 → DL 驱动层 → 数据库</span><br><span class="line">        ＋</span><br><span class="line">DSM 声明式 Schema 管理（自动同步表结构 / 数据迁移）</span><br><span class="line">        ＋</span><br><span class="line">DNS 服务商适配器层（lib/dns/providers/，26 家各一个适配器）</span><br><span class="line">        ＋</span><br><span class="line">后台任务（WHOIS 调度 / 续期调度 / NS 监控 / 服务监控）</span><br></pre></td></tr></table></figure><p>亮点是<strong>数据库四层架构</strong>：所有 SQL 必须经过业务适配器层（BAL），底层驱动可换——这就是它能同时支持 SQLite &#x2F; MySQL &#x2F; PostgreSQL 的原因。DSM 层会自动检测并同步表结构差异，<strong>升级版本不需要手动跑迁移脚本</strong>。</p><hr><h2 id="部署路线-A：Docker-Compose（推荐）"><a href="#部署路线-A：Docker-Compose（推荐）" class="headerlink" title="部署路线 A：Docker Compose（推荐）"></a>部署路线 A：Docker Compose（推荐）</h2><p>最省事的方式，一个文件拉起来。</p><h3 id="1-下载编排文件并启动"><a href="#1-下载编排文件并启动" class="headerlink" title="1. 下载编排文件并启动"></a>1. 下载编排文件并启动</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">curl -O https://raw.githubusercontent.com/HiPM-Tech/HiDNS/main/docker-compose.yml</span><br><span class="line">docker-compose up -d</span><br></pre></td></tr></table></figure><p>默认编排用的是官方预构建镜像 <code>ghcr.io/hipm-tech/hidns:latest</code>，一体化模式（前后端合并在一个容器），端口 <code>3001</code>，数据卷挂载 <code>./data:/app/data</code>。</p><p>内置了健康检查（<code>/api/init/status</code> 接口），容器状态直接反映服务是否就绪，配合 <code>restart: unless-stopped</code> 开机自启。</p><h3 id="2-访问并初始化"><a href="#2-访问并初始化" class="headerlink" title="2. 访问并初始化"></a>2. 访问并初始化</h3><p>浏览器打开：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://服务器IP:3001</span><br></pre></td></tr></table></figure><p><strong>首次启动会跳转初始化向导</strong>：<code>http://localhost:3001/setup</code>。在向导里配置数据库并<strong>创建第一个管理员账号</strong>。</p><blockquote><p>安全设计说明：HiDNS <strong>没有固定默认账号</strong>（不存在 admin&#x2F;admin123 这种），管理员只能通过初始化向导或 <code>/api/init/admin</code> 接口创建。且系统初始化完成后，<code>/api/init/database</code> 会返回 403 拒绝再次初始化——不用担心别人趁虚而入重置你的系统。</p></blockquote><h3 id="3-验证"><a href="#3-验证" class="headerlink" title="3. 验证"></a>3. 验证</h3><ul><li>面板能登录</li><li><code>http://服务器IP:3001/api/docs</code> 能打开 Swagger 文档</li><li><code>docker logs hidns</code> 无报错</li></ul><hr><h2 id="部署路线-B：docker-run-一条命令"><a href="#部署路线-B：docker-run-一条命令" class="headerlink" title="部署路线 B：docker run 一条命令"></a>部署路线 B：docker run 一条命令</h2><p>不想用编排文件的话：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">docker run -d \</span><br><span class="line">  -p 3001:3001 \</span><br><span class="line">  -v $(<span class="built_in">pwd</span>)/data:/app/data \</span><br><span class="line">  --name hidns \</span><br><span class="line">  ghcr.io/hipm-tech/hidns:latest</span><br></pre></td></tr></table></figure><p>效果完全一致（数据卷是关键，<code>/app/data</code> 里存着数据库和配置）。</p><hr><h2 id="部署路线-C：源码运行（开发-想看代码）"><a href="#部署路线-C：源码运行（开发-想看代码）" class="headerlink" title="部署路线 C：源码运行（开发 &#x2F; 想看代码）"></a>部署路线 C：源码运行（开发 &#x2F; 想看代码）</h2><p>环境要求：Node.js ≥ 18 + pnpm（注意：技术栈标注后端依赖 Node 24 的内置 <code>node:sqlite</code>，<strong>用 SQLite 模式建议直接上 Node 24</strong>，避免 <code>node:sqlite</code> 不可用）。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">pnpm install</span><br><span class="line"></span><br><span class="line"><span class="comment"># 开发模式：同时启动后端（3001）与前端（5173）</span></span><br><span class="line">pnpm dev</span><br><span class="line"><span class="comment"># 访问 http://localhost:5173</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 聚合模式（单端口，与 Docker 行为一致）：</span></span><br><span class="line">pnpm --filter client build     <span class="comment"># 先构建前端</span></span><br><span class="line"><span class="built_in">cd</span> server &amp;&amp; pnpm dev          <span class="comment"># 后端同时提供 API 和静态页面</span></span><br><span class="line"><span class="comment"># 访问 http://localhost:3001</span></span><br></pre></td></tr></table></figure><p>想自己构建镜像：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker build -t hidns .</span><br><span class="line">docker run -d -p 3001:3001 -v $(<span class="built_in">pwd</span>)/data:/app/data --name hidns hidns</span><br></pre></td></tr></table></figure><hr><h2 id="数据库选择：SQLite-够用，MySQL-PG-可切换"><a href="#数据库选择：SQLite-够用，MySQL-PG-可切换" class="headerlink" title="数据库选择：SQLite 够用，MySQL&#x2F;PG 可切换"></a>数据库选择：SQLite 够用，MySQL&#x2F;PG 可切换</h2><p>默认 <strong>SQLite</strong>（单文件，就在 <code>./data</code> 里），个人和小团队完全够用。数据量大或要多实例共享时切 MySQL &#x2F; PostgreSQL。</p><p><code>docker-compose.yml</code> 里已经<strong>预置了注释好的 MySQL 和 PostgreSQL 服务段</strong>，取消注释即可：</p><ul><li>MySQL 8.0：<code>mysql-data</code> 卷 + <code>hidns</code> 库 + 自定义密码</li><li>PostgreSQL 15：<code>postgres-data</code> 卷 + <code>hidns</code> 库</li></ul><p>同时在环境变量里把 <code>DB_TYPE</code> 从 <code>sqlite</code> 改成 <code>mysql</code> 或 <code>postgresql</code>，并填上 <code>DB_HOST</code> &#x2F; <code>DB_PORT</code> &#x2F; <code>DB_NAME</code> &#x2F; <code>DB_USER</code> &#x2F; <code>DB_PASSWORD</code>。</p><blockquote><p>切库时机建议：<strong>第一次初始化之前</strong>就定好。初始化向导里也要选一致的库类型，避免「compose 里起了 MySQL、向导里还在用 SQLite」的乌龙。</p></blockquote><hr><h2 id="环境变量详解"><a href="#环境变量详解" class="headerlink" title="环境变量详解"></a>环境变量详解</h2><p>HiDNS 的配置文件是 <code>data/.env</code>（自动加载，优先级最高）或项目根目录 <code>.env</code>——从 <code>.env.example</code> 复制一份开始改：</p><table><thead><tr><th align="left">变量</th><th align="left">默认</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>DB_TYPE</code></td><td align="left"><code>sqlite</code></td><td align="left"><code>sqlite</code> &#x2F; <code>mysql</code> &#x2F; <code>postgresql</code></td></tr><tr><td align="left"><code>DB_PATH</code></td><td align="left"><code>./data/hidns.db</code></td><td align="left">SQLite 数据库文件路径</td></tr><tr><td align="left"><code>DB_SQLITE_WAL</code></td><td align="left"><code>true</code></td><td align="left">SQLite WAL 模式（保持开启）</td></tr><tr><td align="left"><strong><code>JWT_SECRET</code></strong></td><td align="left">未设置</td><td align="left"><strong>生产环境必填</strong>。不设置时每次重启随机生成，所有已登录用户都会被踢下线</td></tr><tr><td align="left"><code>COOKIE_SECURE</code></td><td align="left">自动</td><td align="left"><code>true</code> 强制 HTTPS Cookie；<code>false</code> 允许 HTTP；不设则自动检测协议</td></tr><tr><td align="left"><code>TRUST_PROXY</code></td><td align="left">自动</td><td align="left">反代后取真实 IP 用；不设则生产自动信任内网段，可设 <code>true</code> &#x2F; 跳数 &#x2F; 网段</td></tr><tr><td align="left"><code>PORT</code></td><td align="left"><code>3001</code></td><td align="left">服务端口</td></tr><tr><td align="left"><code>NODE_ENV</code></td><td align="left"><code>development</code></td><td align="left">生产设 <code>production</code></td></tr><tr><td align="left"><code>CORS_ORIGIN</code></td><td align="left">全放行</td><td align="left">生产建议限定为面板域名，如 <code>https://hidns.example.com</code></td></tr><tr><td align="left"><code>WEBAUTHN_RP_ID</code> &#x2F; <code>WEBAUTHN_ORIGIN</code></td><td align="left">—</td><td align="left">用 Passkeys 登录时必填（RP_ID 填域名，ORIGIN 填完整 URL）</td></tr><tr><td align="left"><code>SMTP_TIMEOUT_MS</code></td><td align="left"><code>15000</code></td><td align="left">邮件发送超时</td></tr></tbody></table><p><strong>JWT 双层密钥机制</strong>值得单独说：实际签名密钥 &#x3D; <code>JWT_SECRET</code> + 一个存在数据库 <code>runtime_secrets</code> 表里的运行时密钥。首次初始化创建管理员后会主动轮换一次——这也是为什么没设 <code>JWT_SECRET</code> 的话，容器一重启全员被踢：运行时密钥是随机生成的。</p><hr><h2 id="使用说明"><a href="#使用说明" class="headerlink" title="使用说明"></a>使用说明</h2><h3 id="第一步：接入-DNS-服务商账号"><a href="#第一步：接入-DNS-服务商账号" class="headerlink" title="第一步：接入 DNS 服务商账号"></a>第一步：接入 DNS 服务商账号</h3><p>面板里添加服务商账号，填对应平台的 API 凭证（如阿里云的 AccessKey、Cloudflare 的 API Token）。26 家都在列表里，凭证只存在你自己的数据库里。</p><h3 id="第二步：统一管理解析记录"><a href="#第二步：统一管理解析记录" class="headerlink" title="第二步：统一管理解析记录"></a>第二步：统一管理解析记录</h3><p>选择域名后即可对 A、AAAA、CNAME、MX、TXT、SRV、CAA 等全部类型做增删改查，操作会由对应服务商的适配器转发到上游。</p><p><strong>Cloudflare 专属字段</strong>要注意：Cloudflare 的「代理开关（小黄云）」不在通用 <code>line</code> 字段里，而是用请求&#x2F;响应中的 <code>cloudflare.proxied</code>（<code>true</code> &#x3D; 代理，<code>false</code> &#x3D; 仅 DNS）与 <code>cloudflare.proxiable</code>（当前类型是否支持代理）字段；不传 <code>cloudflare.proxied</code> 时才回退到 <code>line</code>（<code>&#39;1&#39;</code> 代理 &#x2F; <code>&#39;0&#39;</code> 仅 DNS）。</p><h3 id="第三步：运维自动化"><a href="#第三步：运维自动化" class="headerlink" title="第三步：运维自动化"></a>第三步：运维自动化</h3><ul><li><strong>WHOIS 与续期</strong>：录入域名后自动查询 WHOIS（带缓存），续期调度器按到期时间提前提醒&#x2F;调度</li><li><strong>NS 监控</strong>：定时探测 NS 记录，异常时触发故障转移任务</li><li><strong>API Token</strong>：在面板里签发细粒度权限的 Token，给 DDNS 脚本、自动化工具调用，不用把管理员账号到处贴</li><li><strong>API 文档</strong>：<code>/api/docs</code> 的 Swagger 是权威接口文档，写自动化脚本直接照着调</li></ul><h3 id="第四步：安全加固（生产必做）"><a href="#第四步：安全加固（生产必做）" class="headerlink" title="第四步：安全加固（生产必做）"></a>第四步：安全加固（生产必做）</h3><ul><li>面板挂 HTTPS 反代后，设置 <code>COOKIE_SECURE=true</code>（或留空走自动检测）</li><li>面板登录开启 <strong>TOTP 双因素</strong>，或配置 <strong>OAuth2&#x2F;OIDC</strong> 接你自己的 SSO</li><li>支持 <strong>WebAuthn&#x2F;Passkeys</strong>：记得配好 <code>WEBAUTHN_RP_ID</code> 和 <code>WEBAUTHN_ORIGIN</code></li><li>开启 <strong>审计日志</strong> 审查敏感操作</li><li>不想暴露公网：放到内网使用，或在反向代理层加访问控制（IP 白名单 &#x2F; Basic Auth）</li></ul><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="每次重启容器，所有人都被踢下线？"><a href="#每次重启容器，所有人都被踢下线？" class="headerlink" title="每次重启容器，所有人都被踢下线？"></a>每次重启容器，所有人都被踢下线？</h3><p>没设 <code>JWT_SECRET</code>。默认每次重启随机生成密钥，旧 Token 全部失效。生产环境在 <code>data/.env</code> 里设一个 64 位以上随机字符串即可。</p><h3 id="初始化向导打不开-提示-403？"><a href="#初始化向导打不开-提示-403？" class="headerlink" title="初始化向导打不开 &#x2F; 提示 403？"></a>初始化向导打不开 &#x2F; 提示 403？</h3><p>向导只在<strong>未初始化</strong>阶段可用。如果数据库里已经有用户，<code>/api/init/database</code> 会返回 403——这是防重置保护。想重来就清空 <code>./data</code> 目录（<strong>会删掉全部数据</strong>，先备份）。</p><h3 id="面板在-HTTPS-反代后面，登录后-Cookie-异常？"><a href="#面板在-HTTPS-反代后面，登录后-Cookie-异常？" class="headerlink" title="面板在 HTTPS 反代后面，登录后 Cookie 异常？"></a>面板在 HTTPS 反代后面，登录后 Cookie 异常？</h3><p>两个变量配合：<code>COOKIE_SECURE=true</code> + <code>TRUST_PROXY</code>（不设会用生产默认的内网信任段；Nginx 不在内网段时显式设 <code>true</code> 或指定网段）。</p><h3 id="SQLite-和-MySQL-怎么选？"><a href="#SQLite-和-MySQL-怎么选？" class="headerlink" title="SQLite 和 MySQL 怎么选？"></a>SQLite 和 MySQL 怎么选？</h3><p>单机自用、域名几十个以内：SQLite（WAL 模式）足够。多实例、团队并发大、要接现有数据库设施：MySQL &#x2F; PostgreSQL，compose 里取消注释对应段即可。</p><h3 id="界面有英文吗？"><a href="#界面有英文吗？" class="headerlink" title="界面有英文吗？"></a>界面有英文吗？</h3><p>没有。官方明确「界面只有简体中文」，i18n 框架已在重构中整体移除——中文用户友好，但别等英文版了。</p><h3 id="能接-AI-助手吗？"><a href="#能接-AI-助手吗？" class="headerlink" title="能接 AI 助手吗？"></a>能接 AI 助手吗？</h3><p>能。项目内置 <strong>MCP Server</strong>（Model Context Protocol），可以接支持 MCP 的 AI 客户端来查询和操作 DNS 记录，仓库 <code>docs/MCP_*.md</code> 有实现说明。</p><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>HiDNS 这类聚合面板的价值，在于把「N 个服务商后台」收敛成「1 个自己的后台」：解析记录一处改、到期续期有人盯、NS 出事自动切，而且数据全部在自己手里。Docker 一条 <code>docker-compose up -d</code> 就能起，初始化向导零配置文件门槛，SQLite 起步、量大了再切 MySQL——上手成本基本只有「填一遍各家的 API 凭证」。</p><p>域名超过十个还没用聚合面板的话，值得花半小时部署一个。</p><hr><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://github.com/HiPM-Tech/HiDNS">HiDNS 项目仓库（GitHub）</a></li><li><a href="https://hipm-tech.github.io/HiDNS/">HiDNS 官方文档站</a></li><li><a href="https://github.com/HiPM-Tech/HiDNS/pkgs/container/hidns">Docker 镜像（ghcr.io）</a></li><li><a href="https://hipm-tech.github.io/HiDNS/#/api">HiDNS API 文档（部署后 &#x2F;api&#x2F;docs）</a></li><li><a href="https://webauthn.guide/">WebAuthn &#x2F; Passkeys 说明</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/10/31/hidns-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/10/31/hidns-deployment-tutorial/"/>
    <published>2026-10-31T09:00:00.000Z</published>
    <summary>HiDNS 是一个开源的 DNS 聚合管理平台，一个面板管理 26 家 DNS 服务商（阿里云、Cloudflare、DNSPod、华为云等）的解析记录，附带 WHOIS 查询、域名续期调度、NS 监控故障转移、API Token、OAuth2/WebAuthn 登录等能力。本文给出 Docker Compose 部署、环境变量详解、初始化向导、数据库切换 MySQL/PostgreSQL 的完整步骤与使用说明。</summary>
    <title>HiDNS 部署教程：Docker 搭建 26 家 DNS 服务商聚合管理平台，域名解析统一管</title>
    <updated>2026-11-01T08:38:58.268Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="Cloudflare Workers" scheme="https://blog.ztmss.com/tags/Cloudflare-Workers/"/>
    <category term="D1" scheme="https://blog.ztmss.com/tags/D1/"/>
    <category term="Cloudflare for SaaS" scheme="https://blog.ztmss.com/tags/Cloudflare-for-SaaS/"/>
    <category term="多租户" scheme="https://blog.ztmss.com/tags/%E5%A4%9A%E7%A7%9F%E6%88%B7/"/>
    <category term="Custom Hostname" scheme="https://blog.ztmss.com/tags/Custom-Hostname/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>做「给别人提供服务」的东西，迟早会撞上一个问题：<strong>客户想用自己的域名接入，但客户的域名不在你的 Cloudflare 账号里</strong>。</p><p>传统做法是让客户把域名 NS 迁过来——不现实。正确姿势是 Cloudflare 官方的 <strong>Cloudflare for SaaS</strong>：你提供入口，客户只加一条 CNAME 指向你，证书由 Custom Hostname 自动签发。</p><p><strong>cf-saas-tenant-router</strong> 就是把这套能力做成了开箱即用的多租户系统：</p><ul><li><strong>项目地址</strong>：<a href="https://github.com/lzmss-love/cf-saas-tenant-router">https://github.com/lzmss-love/cf-saas-tenant-router</a></li><li><strong>技术栈</strong>：Cloudflare Workers + D1（三张表）+ Custom Hostnames + GitHub Actions</li><li><strong>定位</strong>：客户域名<strong>不托管 CF</strong>，加一条 CNAME 即可把流量接入你的 Worker，按 Host 分流转发到各自的上游（tgproxy &#x2F; cf-erp &#x2F; cf-subcloud 等均可）</li></ul><p>整条链路：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">客户域名（NS 留在客户自己的 DNS）</span><br><span class="line">        │ CNAME → opt.&lt;宿主域名&gt;（优选 IP，灰云 A 记录）</span><br><span class="line">        ▼</span><br><span class="line">Cloudflare 边缘 ── Custom Hostname（证书自动签发）── */* route</span><br><span class="line">        ▼</span><br><span class="line">saas-tenant-router Worker</span><br><span class="line">   ├─ 按 Host 查 D1 租户表 → 转发上游</span><br><span class="line">   ├─ Origin 改写 + 页面域名替换 + WebSocket 透传</span><br><span class="line">   └─ bridge cap 重算（客户手里任何域名版本的接入凭证都能过认证）</span><br></pre></td></tr></table></figure><p>部署完成后你会得到：</p><table><thead><tr><th align="left">资源</th><th align="left">值</th></tr></thead><tbody><tr><td align="left">管理面板</td><td align="left"><code>https://&lt;宿主域名&gt;</code>（ADMIN_TOKEN 账号密码登录）</td></tr><tr><td align="left">客户自助接入页</td><td align="left"><code>https://&lt;宿主域名&gt;/join</code></td></tr><tr><td align="left">Worker</td><td align="left"><code>saas-tenant-router</code>，<code>*/*</code> 路由挂宿主 zone</td></tr><tr><td align="left">D1</td><td align="left"><code>saas-tenants</code>（租户 &#x2F; 接入码 &#x2F; 请求日志三张表）</td></tr><tr><td align="left">DNS</td><td align="left"><code>service</code>（fallback origin）、<code>customers</code>、<code>opt*</code>（优选入口，可多条）</td></tr></tbody></table><hr><h2 id="功能特性"><a href="#功能特性" class="headerlink" title="功能特性"></a>功能特性</h2><h3 id="管理面板（四个标签页）"><a href="#管理面板（四个标签页）" class="headerlink" title="管理面板（四个标签页）"></a>管理面板（四个标签页）</h3><table><thead><tr><th align="left">标签</th><th align="left">功能</th></tr></thead><tbody><tr><td align="left"><strong>租户</strong></td><td align="left">增删改查、详情（直接给出客户要加的 CNAME 指令）、启用&#x2F;停用（suspended 即停止转发）、删除</td></tr><tr><td align="left"><strong>接入码</strong></td><td align="left">生成 8 位码发给客户；客户在 <code>/join</code> 输码 + 域名自助完成接入；一次性、防重放、可作废</td></tr><tr><td align="left"><strong>自定义主机名</strong></td><td align="left">创建&#x2F;删除 Custom Hostname；证书与主机名状态一目了然；详情弹窗直接给出客户要补加的全部 DNS 指令（验证 TXT &#x2F; DCV 委派 CNAME）</td></tr><tr><td align="left"><strong>优选</strong></td><td align="left">多路管理（opt &#x2F; opt2 &#x2F; opt3…，A 记录或 CNAME 双形态）+ <strong>在线测速</strong>（当前线路真实延迟）+ 快捷切换社区优选域名</td></tr></tbody></table><h3 id="几个设计细节（源码确认）"><a href="#几个设计细节（源码确认）" class="headerlink" title="几个设计细节（源码确认）"></a>几个设计细节（源码确认）</h3><ul><li><strong>接入码防呆</strong>：8 位随机码，字符表去掉了 <code>0 O 1 I L</code> 这类易混淆字符，口头报给客户也不会念错</li><li><strong>租户状态机</strong>：<code>pending</code>（没配上游，仅标记）&#x2F; <code>active</code>（配了 upstream，正常转发）&#x2F; <code>suspended</code>（管理员停用，<strong>立即停止转发</strong>）&#x2F; 软删除</li><li><strong>上游两级配置</strong>：租户表里每行可配 <code>upstream_base</code>（租户专属），没配则回落到全局变量 <code>TENANT_UPSTREAM_BASE</code>；两者都没有时返回提示页，而不是报 1016</li><li><strong>面板与 API 只认宿主域名</strong>：管理接口只在宿主 zone（及可选的 workers.dev 后缀）上响应，且需要 <code>ADMIN_TOKEN</code>（格式 <code>账号:密码</code>），客户域名上根本访问不到</li><li><strong>兼容严格上游</strong>：对 tgproxy 这类做 bridge 校验的服务，Worker 会按上游真实 hostname 重算 cap——客户手里任何域名版本的接入凭证都能过认证</li></ul><hr><h2 id="部署前准备（人工三件套，无法-API-化）"><a href="#部署前准备（人工三件套，无法-API-化）" class="headerlink" title="部署前准备（人工三件套，无法 API 化）"></a>部署前准备（人工三件套，无法 API 化）</h2><p>无论用哪种部署方式，每个 Cloudflare 账号都要先手工完成这三步：</p><ol><li><strong>宿主域名加入该 CF 账号</strong>（NS 托管，Free 计划即可）</li><li><strong>Enable Cloudflare for SaaS</strong>：控制台 → SSL&#x2F;TLS → Custom Hostnames → Enable（需要绑卡——这是 CF 唯一不给 API 的步骤）</li><li><strong>Fallback Origin</strong>：同一页面 → Fallback Origin 栏填 <code>service.&lt;你的域名&gt;</code> → 等 Active。注意这一步<strong>只能控制台点</strong>，API 会报 10405（CF 硬限制）</li></ol><p>然后建一个 <strong>API Token</strong>（控制台 → My Profile → API Tokens）。<code>CLOUDFLARE_API_TOKEN</code> 一共需要 <strong>11 项权限</strong>，建 Token 时对着下面的清单逐项勾选即可（级别列标注了它挂在「账户」还是「区域」下）：</p><table><thead><tr><th align="left">#</th><th align="left">级别</th><th align="left">权限名</th><th align="left">用途</th></tr></thead><tbody><tr><td align="left">1</td><td align="left">账户</td><td align="left"><strong>D1 Write</strong></td><td align="left">自动建 &#x2F; 迁移 <code>saas-tenants</code> 数据库</td></tr><tr><td align="left">2</td><td align="left">账户</td><td align="left"><strong>D1 Read</strong></td><td align="left">查询现有 D1 实例，避免重复建库</td></tr><tr><td align="left">3</td><td align="left">账户</td><td align="left"><strong>Workers Scripts Write</strong></td><td align="left"><code>wrangler deploy</code> 部署 &#x2F; 更新 Worker 代码</td></tr><tr><td align="left">4</td><td align="left">账户</td><td align="left"><strong>Workers Scripts Read</strong></td><td align="left">读取现有 Worker 与 secret 状态</td></tr><tr><td align="left">5</td><td align="left">区域</td><td align="left"><strong>DNS Write</strong></td><td align="left">自动建 &#x2F; 改 <code>service</code>、<code>customers</code>、<code>opt*</code> 记录</td></tr><tr><td align="left">6</td><td align="left">区域</td><td align="left"><strong>DNS Read</strong></td><td align="left">读取现有 A &#x2F; CNAME 记录做幂等比对</td></tr><tr><td align="left">7</td><td align="left">区域</td><td align="left"><strong>SSL and Certificates Write</strong></td><td align="left">面板创建 &#x2F; 删除 Custom Hostname（缺了会 403）</td></tr><tr><td align="left">8</td><td align="left">区域</td><td align="left"><strong>SSL and Certificates Read</strong></td><td align="left">面板展示证书签发状态</td></tr><tr><td align="left">9</td><td align="left">区域</td><td align="left"><strong>Workers Routes Write</strong></td><td align="left">写入 <code>*/*</code> 路由</td></tr><tr><td align="left">10</td><td align="left">区域</td><td align="left"><strong>Workers Routes Read</strong></td><td align="left">校验路由是否已挂到本 Worker</td></tr><tr><td align="left">11</td><td align="left">区域</td><td align="left"><strong>Zone Read</strong></td><td align="left">自动查 zone id</td></tr></tbody></table><p><strong>Zone Resources 只选你的宿主 zone</strong>（账户级的 D1 &#x2F; Workers Scripts 权限跟随账户，区域级权限锁定该 zone），最小权限。</p><hr><h2 id="部署路线-A：本机一条命令初始化（推荐）"><a href="#部署路线-A：本机一条命令初始化（推荐）" class="headerlink" title="部署路线 A：本机一条命令初始化（推荐）"></a>部署路线 A：本机一条命令初始化（推荐）</h2><p>仓库是模板化的：拿到任何新 CF 账号，域名&#x2F;账号&#x2F;D1 全部自动配置，<strong>代码零修改</strong>。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1) clone 到一个新目录（重要：不要在已有部署的目录里跑）</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/lzmss-love/cf-saas-tenant-router.git my-new-saas</span><br><span class="line"><span class="built_in">cd</span> my-new-saas &amp;&amp; npm i</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2) 一键初始化（Git Bash 语法）</span></span><br><span class="line">CF_API_TOKEN=xxx node scripts/init.mjs &lt;你的宿主域名&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment"># PowerShell 写法：</span></span><br><span class="line"><span class="comment">#   $env:CF_API_TOKEN=&quot;xxx&quot;; node scripts/init.mjs &lt;你的宿主域名&gt;</span></span><br></pre></td></tr></table></figure><p><code>init.mjs</code> 会自动完成：查 zone id → 建 D1 → 重写本目录的 <code>wrangler.jsonc</code>（routes &#x2F; D1 &#x2F; vars 全部指向新账号）→ 建 DNS 记录（fallback origin &#x2F; customers &#x2F; opt）→ 打印剩余的手动步骤。</p><p>然后收尾两件事：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npx wrangler deploy          <span class="comment"># 部署 Worker + 路由</span></span><br><span class="line">npm run optimize             <span class="comment"># 跑一次优选，把最快的 IP 写进 opt 记录</span></span><br></pre></td></tr></table></figure><blockquote><p>⚠️ <code>init.mjs</code> 会<strong>重写当前目录的 wrangler.jsonc</strong>。在 clone 出来的新目录里跑，不要在已有部署的目录执行，否则当前账号的配置会被覆盖。</p></blockquote><hr><h2 id="部署路线-B：手动部署（想搞懂每一步）"><a href="#部署路线-B：手动部署（想搞懂每一步）" class="headerlink" title="部署路线 B：手动部署（想搞懂每一步）"></a>部署路线 B：手动部署（想搞懂每一步）</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">npm i</span><br><span class="line">npx wrangler d1 create saas-tenants</span><br><span class="line"><span class="comment"># 把输出的 database_id 填进 wrangler.jsonc（从 wrangler.template.jsonc 复制一份开始改）</span></span><br><span class="line">npx wrangler d1 migrations apply saas-tenants --remote</span><br><span class="line">npx wrangler deploy</span><br></pre></td></tr></table></figure><h3 id="三个-secret（存-CF-侧）"><a href="#三个-secret（存-CF-侧）" class="headerlink" title="三个 secret（存 CF 侧）"></a>三个 secret（存 CF 侧）</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npx wrangler secret put ADMIN_TOKEN        <span class="comment"># 面板登录，格式 账号:密码</span></span><br><span class="line">npx wrangler secret put CF_API_TOKEN       <span class="comment"># DNS / Custom Hostnames 操作</span></span><br><span class="line">npx wrangler secret put TGPROXY_SECRET     <span class="comment"># tgproxy 的 SECRET，用于 bridge cap 重算（不接 TG 可不配）</span></span><br></pre></td></tr></table></figure><p><strong>关键纪律</strong>：一切凭证走 secret，<strong>不要</strong>在 Dashboard 建 plain text 变量——<code>wrangler deploy</code> 会用 <code>wrangler.jsonc</code> 的 vars 段整体替换明文变量，Dashboard 里建的会被清掉。secret 不受影响。</p><h3 id="wrangler-jsonc-的-vars-段（配置全在这）"><a href="#wrangler-jsonc-的-vars-段（配置全在这）" class="headerlink" title="wrangler.jsonc 的 vars 段（配置全在这）"></a>wrangler.jsonc 的 vars 段（配置全在这）</h3><table><thead><tr><th align="left">变量</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>OWN_ZONE</code> &#x2F; <code>OWN_ZONE_ID</code></td><td align="left">宿主域名与 zone id</td></tr><tr><td align="left"><code>CNAME_TARGET</code></td><td align="left">客户 CNAME 指向的入口，默认 <code>opt.&lt;宿主域名&gt;</code></td></tr><tr><td align="left"><code>OWN_WORKERSDEV_SUFFIX</code></td><td align="left">workers.dev 验证子域后缀（可选，测试期用）</td></tr><tr><td align="left"><code>TENANT_UPSTREAM_BASE</code></td><td align="left">全局默认上游（可选，租户级 upstream_base 优先）</td></tr><tr><td align="left"><code>OPT_PRESETS</code></td><td align="left">社区优选域名预设（如 <code>vivid43.cf.090227.xyz</code>）</td></tr><tr><td align="left"><code>OPT_TEST_HOST</code></td><td align="left">在线测速用的已激活租户域名（可选）</td></tr></tbody></table><p>配置全部在 vars 里，代码零硬编码。改完 <code>npx wrangler deploy</code> 生效。</p><h3 id="验证"><a href="#验证" class="headerlink" title="验证"></a>验证</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">curl https://&lt;宿主域名&gt;/health</span><br><span class="line"><span class="comment"># &#123;&quot;ok&quot;:true,...&#125;</span></span><br></pre></td></tr></table></figure><p>浏览器打开 <code>https://&lt;宿主域名&gt;</code>，能用 ADMIN_TOKEN 登录面板即部署成功。</p><hr><h2 id="部署路线-C：GitHub-Actions-全自动（push-即上线）"><a href="#部署路线-C：GitHub-Actions-全自动（push-即上线）" class="headerlink" title="部署路线 C：GitHub Actions 全自动（push 即上线）"></a>部署路线 C：GitHub Actions 全自动（push 即上线）</h2><p>仓库自带 <code>.github/workflows/deploy.yml</code>，push 到 <code>master</code>（或手动触发）自动完成全流程：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">查 zone id → 建/找 D1 → 渲染配置 → 部署 Worker → D1 迁移</span><br><span class="line">→ 自动写入运行时密钥 → 幂等补齐 DNS 基础记录</span><br></pre></td></tr></table></figure><h3 id="一次性配置"><a href="#一次性配置" class="headerlink" title="一次性配置"></a>一次性配置</h3><ol><li>建部署专用 API Token：权限与上文「部署前准备」的 <strong>11 项清单完全一致</strong>（D1 &#x2F; Workers Scripts &#x2F; DNS &#x2F; SSL and Certificates &#x2F; Workers Routes 的读写 + Zone Read），Zone Resources 选宿主 zone</li><li>GitHub 仓库 → Settings → Secrets and variables → Actions，配这些 repository secret：</li></ol><table><thead><tr><th align="left">Secret</th><th align="left">值</th><th align="left">必填</th></tr></thead><tbody><tr><td align="left"><code>CF_ZONE</code></td><td align="left">宿主域名（如 <code>xxx.com</code>）</td><td align="left">✅</td></tr><tr><td align="left"><code>CLOUDFLARE_API_TOKEN</code></td><td align="left">上一步的 token</td><td align="left">✅</td></tr><tr><td align="left"><code>CLOUDFLARE_ACCOUNT_ID</code></td><td align="left">Account ID</td><td align="left">✅</td></tr><tr><td align="left"><code>CF_ADMIN_TOKEN</code></td><td align="left">面板密码（<code>账号:密码</code>）</td><td align="left">✅</td></tr><tr><td align="left"><code>CF_DNS_TOKEN</code></td><td align="left">专用 DNS token（不填则复用部署 token）</td><td align="left">⬜</td></tr><tr><td align="left"><code>CF_TGPROXY_SECRET</code></td><td align="left">TG WEB 代理密码（不接 TG 不用填）</td><td align="left">⬜</td></tr><tr><td align="left"><code>CF_WORKERS_DEV_SUFFIX</code></td><td align="left">workers.dev 子域后缀（测试期才用）</td><td align="left">⬜</td></tr><tr><td align="left"><code>CF_OPT_TEST_HOST</code></td><td align="left">在线测速用的已激活租户域名</td><td align="left">⬜</td></tr></tbody></table><p>zone id &#x2F; D1 id &#x2F; CNAME target <strong>都不用填</strong>——Actions 自动解析，D1 不存在会自动创建。</p><h3 id="单仓库管多个-CF-账号（Environments）"><a href="#单仓库管多个-CF-账号（Environments）" class="headerlink" title="单仓库管多个 CF 账号（Environments）"></a>单仓库管多个 CF 账号（Environments）</h3><p>这是这套 CI 的亮点：每个账号一个 GitHub Environment，手动触发时 <code>target</code> 自由输入账号名：</p><ol><li>Settings → Environments → New environment，名称填账号名（如 <code>maowei</code>）</li><li>在该 environment 的 Secrets 里配置<strong>该账号</strong>的一套 secrets</li><li>Actions → Deploy → Run workflow → target 填 <code>maowei</code> → 部署到对应 CF 账号</li></ol><p>指定 target 时，zone&#x2F;D1 会按 zone 名在目标账号<strong>实时解析</strong>（忽略仓库级回退 ID，避免跨账号错绑路由）。新增账号不需要改任何代码；push 自动部署不受影响（无 target &#x3D; 仓库级 secrets &#x3D; 主账号）。</p><hr><h2 id="使用说明"><a href="#使用说明" class="headerlink" title="使用说明"></a>使用说明</h2><h3 id="新客户接入流程（约-3-分钟）"><a href="#新客户接入流程（约-3-分钟）" class="headerlink" title="新客户接入流程（约 3 分钟）"></a>新客户接入流程（约 3 分钟）</h3><ol><li><p>面板「接入码」→ 生成 → 发给客户（复制按钮自带接入地址）</p></li><li><p>客户打开 <code>https://&lt;宿主域名&gt;/join</code> → 输接入码 + 自己的域名 → 页面直接给出要加的 CNAME：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;客户域名&gt;  CNAME  opt.&lt;宿主域名&gt;</span><br></pre></td></tr></table></figure></li><li><p>客户在他的 DNS 服务商添加这条记录。<strong>注意两点：不能用 A 记录；apex 根域名不支持</strong>——让客户用子域（如 <code>app.客户域名</code>）</p></li><li><p>面板「自定义主机名」→ 为该 host 创建 Custom Hostname → 点<strong>详情</strong>，把弹窗里的 DNS 指令发给客户补加（验证 TXT 或 DCV 委派 CNAME，按客户情况二选一）</p></li><li><p>等证书与主机名两个状态都变绿。<strong>如果证书一直「待验证」</strong>：查客户域名的 <strong>CAA 记录</strong>（会沿 DNS 树向上继承），需要授权签发 CA，例如加 <code>0 issue &quot;ssl.com&quot;</code>，或删除现有 CAA</p></li></ol><p>完事之后 Worker 已经自动识别新租户，流量按其 <code>upstream_base</code> 转发。</p><h3 id="日常管理"><a href="#日常管理" class="headerlink" title="日常管理"></a>日常管理</h3><ul><li><p><strong>停用某个客户</strong>：租户页 → 停用（状态变 <code>suspended</code>，立即停止转发，且不影响其 Custom Hostname 证书）</p></li><li><p><strong>给某客户换上游</strong>：编辑该租户的 <code>upstream_base</code>，立即生效，无需重新部署</p></li><li><p><strong>查某个客户为什么打不开</strong>：D1 里有 <code>req_log</code> 请求日志（method &#x2F; path &#x2F; query &#x2F; UA &#x2F; IP &#x2F; status），直接看客户端的真实请求形态：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npx wrangler d1 execute saas-tenants --remote \</span><br><span class="line">  --<span class="built_in">command</span> <span class="string">&quot;SELECT * FROM req_log ORDER BY id DESC LIMIT 20&quot;</span></span><br></pre></td></tr></table></figure></li><li><p><strong>面板按钮没反应</strong>：面板是单文件 HTML 内嵌 JS，先跑 <code>node scripts/check-embedded-js.mjs</code> 做语法检查再部署</p></li></ul><h3 id="优选-IP-维护"><a href="#优选-IP-维护" class="headerlink" title="优选 IP 维护"></a>优选 IP 维护</h3><p>优选解决的是「国内访问 CF 边缘入口慢」：客户域名解析到测速优选的 CF IP，SNI 路由不变。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CF_API_TOKEN=xxx npm run optimize</span><br></pre></td></tr></table></figure><ul><li>对 24 个候选 IP 测 TLS 握手 → 自动把最快的写入优选记录（IP 没变则跳过写入）</li><li><strong>换 IP 只改 DNS 记录</strong>，客户域名不用动，代码不用动</li><li>优选入口支持两种形态：<strong>A 记录</strong>（直指优选 IP）或 <strong>CNAME</strong>（指社区优选域名如 <code>*.cf.090227.xyz</code>，自动更新更省心）；面板更新时保持原类型</li><li><strong>建议每周跑一次</strong>；如果某天客户集体打不开（IP 失效），立即跑一次</li><li>非标端口的反代节点（如 <code>IP:26524</code>）对 TG WEB 类客户端无用（固定 443 且无端口字段），仅适合支持自定义端口的客户端</li></ul><p>面板「优选」标签页也可以直接做多路管理（opt &#x2F; opt2 &#x2F; opt3… 增删改、切换 A&#x2F;CNAME、在线测速），不用碰命令行。</p><hr><h2 id="常见问题速查"><a href="#常见问题速查" class="headerlink" title="常见问题速查"></a>常见问题速查</h2><table><thead><tr><th align="left">现象</th><th align="left">原因 &#x2F; 处理</th></tr></thead><tbody><tr><td align="left">客户域名返回占位页 “Connection”</td><td align="left">bridge cap 与 hostname 不匹配——Worker 会自动重算；若仍出现，查 <code>req_log</code> 看请求形态</td></tr><tr><td align="left">面板登录失败</td><td align="left"><code>ADMIN_TOKEN</code> 是 secret（<code>账号:密码</code>）；确认没在 Dashboard 建同名<strong>明文变量</strong>（会被部署清掉）</td></tr><tr><td align="left">Custom Hostname 操作 403</td><td align="left"><code>CF_API_TOKEN</code> 缺 <strong>Zone → SSL and Certificates → Edit</strong> 权限，重建 token 更新 secret</td></tr><tr><td align="left">证书一直「待验证」</td><td align="left">客户域名或其上级的 <strong>CAA 记录</strong>未授权签发 CA——加 <code>0 issue &quot;ssl.com&quot;</code> 或删除现有 CAA</td></tr><tr><td align="left">Fallback Origin API 报 10405</td><td align="left">该端点不接受 API Token（CF 硬限制）——<strong>必须控制台手点</strong></td></tr><tr><td align="left"><code>wrangler deploy</code> 后变量消失</td><td align="left">部署整体替换明文 vars——凭证一律走 secret</td></tr><tr><td align="left">客户用 apex 根域名接入失败</td><td align="left">Custom Hostname 不支持 apex，让客户改用子域</td></tr></tbody></table><hr><h2 id="安全注意事项"><a href="#安全注意事项" class="headerlink" title="安全注意事项"></a>安全注意事项</h2><ul><li><strong><code>ADMIN_TOKEN</code> 用随机长串</strong>，它是面板与管理 API 的唯一门禁；管理接口本身也只在宿主域名上暴露</li><li><strong><code>CF_API_TOKEN</code> 最小权限</strong>：Zone Resources 锁定宿主 zone，别用 Global API Key</li><li><strong>凭证一律走 secret</strong>，不要写进 <code>wrangler.jsonc</code> 明文 vars（会被 push 和部署清掉，还可能随模板仓库泄漏）</li><li>客户接入码<strong>一次性 + 可作废</strong>，泄露了直接在面板作废重新生成</li><li><code>req_log</code> 是诊断表，会记录客户请求的 path 与 UA——自己留档没问题，对外分享日志时注意脱敏</li></ul><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>这套项目把「Cloudflare for SaaS 多租户」这件事从一堆控制台操作变成了三条可重复的路：<strong>本机 init 一键初始化、手动部署搞懂原理、Actions push 即上线</strong>，再配上接入码自助接入、面板化租户管理、自动优选 IP。适合的场景很明确：你要给多个客户&#x2F;多个域名提供同一种入口服务（代理入口、自建应用、API 网关都行），又不想让客户迁移域名托管。</p><p>部署口径总结成一行：<strong>宿主域名托管 + Enable for SaaS + Fallback Origin 三件套 → init 或 Actions → 发接入码 → 客户加一条 CNAME → 建 Custom Hostname → 双绿灯收工。</strong></p><hr><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://github.com/lzmss-love/cf-saas-tenant-router">cf-saas-tenant-router 项目仓库（GitHub）</a></li><li><a href="https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/">Cloudflare for SaaS 文档（Custom Hostnames）</a></li><li><a href="https://developers.cloudflare.com/d1/">Cloudflare Workers D1 文档</a></li><li><a href="https://developers.cloudflare.com/workers/wrangler/commands/">Wrangler CLI 文档</a></li><li><a href="https://developers.cloudflare.com/fundamentals/api/get-started/create-token/">Cloudflare API Token 权限说明</a></li><li><a href="https://docs.github.com/actions/how-tos/deploy-to-third-party-platforms">GitHub Actions：Environments 使用</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/10/31/cf-saas-tenant-router-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/10/31/cf-saas-tenant-router-deployment-tutorial/"/>
    <published>2026-10-31T07:00:00.000Z</published>
    <summary>cf-saas-tenant-router 是一套跑在 Cloudflare Workers + D1 上的多租户接入系统，客户域名不托管 Cloudflare，加一条 CNAME 即完成接入，Custom Hostname 自动签证书。本文覆盖架构原理、三条部署路线（本机 init 一键初始化、手动部署、GitHub Actions 全自动多账号）、面板四标签使用说明、新客户 3 分钟接入流程、优选 IP 维护与完整排障手册。</summary>
    <title>cf-saas-tenant-router 部署教程：Cloudflare for SaaS 多租户路由，客户域名一条 CNAME 即接入</title>
    <updated>2026-10-31T06:16:15.569Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="Cloudflare Workers" scheme="https://blog.ztmss.com/tags/Cloudflare-Workers/"/>
    <category term="Telegram" scheme="https://blog.ztmss.com/tags/Telegram/"/>
    <category term="Cloudflare Pages" scheme="https://blog.ztmss.com/tags/Cloudflare-Pages/"/>
    <category term="MTProto" scheme="https://blog.ztmss.com/tags/MTProto/"/>
    <category term="代理部署" scheme="https://blog.ztmss.com/tags/%E4%BB%A3%E7%90%86%E9%83%A8%E7%BD%B2/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p><strong>cftgwebproxy</strong> 是一个开源的 Telegram Web Proxy 部署方案：用 Cloudflare 的免费资源把 TG 的 MTProto 代理跑起来，客户端填一个自己的域名就能连。</p><ul><li><strong>项目地址</strong>：<a href="https://github.com/xinyitang3/cftgwebproxy">https://github.com/xinyitang3/cftgwebproxy</a></li><li><strong>开源协议</strong>：MIT</li><li><strong>技术栈</strong>：Cloudflare Pages（主程序）+ Workers（转发层、DNS 定时任务）+ Cloudflare DNS API</li><li><strong>上游</strong>：协议逻辑来自 <a href="https://github.com/ToiCF/CF-Workers-TGProxy">ToiCF&#x2F;CF-Workers-TGProxy</a></li></ul><p>它和我之前写过的单文件 Worker 代理方案不太一样，最大的特点是<strong>拆成三层</strong>：</p><table><thead><tr><th align="left">组件</th><th align="left">跑在哪</th><th align="left">职责</th></tr></thead><tbody><tr><td align="left"><code>telegram_webproxy.js</code></td><td align="left"><strong>Cloudflare Pages</strong>（须改名 <code>_worker.js</code>）</td><td align="left">真正的代理主程序，负责 MTProto 帧协议与连接 Telegram 各 DC</td></tr><tr><td align="left"><code>webproxy-relay.js</code></td><td align="left"><strong>Cloudflare Workers</strong></td><td align="left">纯转发层，让你的优选域名能接到 Pages 主程序上</td></tr><tr><td align="left"><code>domain-dns.js</code></td><td align="left"><strong>Cloudflare Workers + Cron</strong></td><td align="left">定时把优选 IP 同步到域名的 A 记录</td></tr></tbody></table><p>为什么要这么拆？项目 README 给了两个理由，都挺实在：</p><ol><li><strong>避开 1101 &#x2F; 522</strong>：Worker 直接长时间挂着 WebSocket 代理，容易触发 Worker 异常（1101）和源站超时（522），把主程序放 Pages 能显著降低这类报错；</li><li><strong>额度分开算</strong>：按作者的说法，Pages 和 Worker 的请求额度是分开计算的，拆开后总容量更大。</li></ol><p>最终链路是这样：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Telegram 客户端</span><br><span class="line">   → 你的优选域名（A 记录由 Cron 自动更新）</span><br><span class="line">   → Worker 转发层（webproxy-relay.js）</span><br><span class="line">   → Pages 主程序（telegram_webproxy.js）</span><br><span class="line">   → Telegram 服务器（KWS / DC）</span><br></pre></td></tr></table></figure><blockquote><p>本文依据仓库 README 与三个脚本的源码整理，环境变量规则、接口路径、校验逻辑均以源码为准。部署时请以仓库最新提交为准。</p></blockquote><hr><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><p>开干之前，把这几样东西备齐：</p><table><thead><tr><th align="left">项目</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><strong>Cloudflare 账号</strong></td><td align="left">建议准备 <strong>2 个</strong>：一个放 Pages 主程序，另一个放 Worker 转发层（README 的建议做法，能进一步分散风控与额度）</td></tr><tr><td align="left"><strong>一个托管在 Cloudflare 的域名</strong></td><td align="left">用来做「优选域名」。<strong>关键限制</strong>：这个域名所在的 Zone 必须和 Worker 在<strong>同一个 Cloudflare 账号</strong>下，否则加不了路由</td></tr><tr><td align="left"><strong>优选 IP 源</strong></td><td align="left">一个返回 <code>IP:Port</code> 文本列表的接口（每行一条，可带 <code>#</code> 注释）。用于第三层的自动 DNS</td></tr><tr><td align="left"><strong>本地环境</strong></td><td align="left">只用面板操作的话什么都不用装；想用命令生成密钥，需要 <code>openssl</code></td></tr></tbody></table><p>先生成两个密钥，后面两个组件都要用：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># BOOT：建议 ≥16 位随机字符串</span></span><br><span class="line">openssl rand -hex 24</span><br><span class="line"></span><br><span class="line"><span class="comment"># SECRET：32 位小写十六进制（openssl rand -hex 16 刚好 32 个字符）</span></span><br><span class="line">openssl rand -hex 16</span><br></pre></td></tr></table></figure><p><strong>环境变量的两条硬规则</strong>（源码里写死的校验，填错直接 500）：</p><ul><li><code>SECRET</code>：必须是 <strong>32 位小写十六进制</strong>（<code>0-9a-f</code>），或者 <strong><code>dd</code> + 32 位十六进制</strong>（共 34 位）</li><li><code>BOOT</code>：任意<strong>非空</strong>随机字符串，建议 16 位以上</li></ul><blockquote><p>关于 <code>dd</code> 前缀：它是 MTProxy 的可选模式，作用是启用随机填充（Random Padding），把包长随机化。填的时候<strong>必须带上 <code>dd</code> 两个字面字符</strong>，共 34 位；不带前缀就是标准的 32 位 secret。客户端里要填<strong>和这里完全一致</strong>的字符串。</p></blockquote><hr><h2 id="第一步：部署-Pages-主程序"><a href="#第一步：部署-Pages-主程序" class="headerlink" title="第一步：部署 Pages 主程序"></a>第一步：部署 Pages 主程序</h2><p>这一层是整个方案的核心。</p><h3 id="1-1-新建-Pages-项目"><a href="#1-1-新建-Pages-项目" class="headerlink" title="1.1 新建 Pages 项目"></a>1.1 新建 Pages 项目</h3><p>Cloudflare 控制台 → <strong>Workers 和 Pages</strong> → <strong>创建</strong> → <strong>Pages</strong> → <strong>上传资产</strong>（直接上传，最省事）。</p><h3 id="1-2-文件必须改名成-worker-js"><a href="#1-2-文件必须改名成-worker-js" class="headerlink" title="1.2 文件必须改名成 _worker.js"></a>1.2 文件必须改名成 <code>_worker.js</code></h3><p>这是最容易踩的坑：<strong>把 <code>telegram_webproxy.js</code> 重命名为 <code>_worker.js</code></strong>，放在上传目录的<strong>根目录</strong>。</p><p>原因：Pages 的 Functions 高级模式只认根目录下这个固定文件名，名字不对就完全不会执行你的代码，页面只会返回静态 404 或空白页。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">上传目录/</span><br><span class="line">└── _worker.js     ← telegram_webproxy.js 改名而来，必须在根目录</span><br></pre></td></tr></table></figure><h3 id="1-3-配置两个加密变量"><a href="#1-3-配置两个加密变量" class="headerlink" title="1.3 配置两个加密变量"></a>1.3 配置两个加密变量</h3><p>项目 → <strong>设置</strong> → <strong>变量和机密</strong>（Environment variables），两个都建议用**加密（Secret）**方式添加：</p><table><thead><tr><th align="left">变量名</th><th align="left">类型</th><th align="left">值</th></tr></thead><tbody><tr><td align="left"><code>BOOT</code></td><td align="left">机密</td><td align="left">上面 <code>openssl rand -hex 24</code> 的输出</td></tr><tr><td align="left"><code>SECRET</code></td><td align="left">机密</td><td align="left">上面 <code>openssl rand -hex 16</code> 的输出（可加 <code>dd</code> 前缀）</td></tr></tbody></table><p>保存后<strong>重新部署一次</strong>，让变量生效。</p><h3 id="1-4-验证主程序"><a href="#1-4-验证主程序" class="headerlink" title="1.4 验证主程序"></a>1.4 验证主程序</h3><p>部署完成后访问：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://&lt;项目名&gt;.pages.dev/health</span><br></pre></td></tr></table></figure><p>返回下面这行就说明主程序活了：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;ok&quot;</span><span class="punctuation">:</span><span class="literal"><span class="keyword">true</span></span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>如果这里就是 500，别急着往下做——先回去检查 <code>BOOT</code> &#x2F; <code>SECRET</code> 的格式（最常见就是 <code>SECRET</code> 长度不对或包含大写字母）。</p><h3 id="1-5-主程序到底做了什么（看懂再调）"><a href="#1-5-主程序到底做了什么（看懂再调）" class="headerlink" title="1.5 主程序到底做了什么（看懂再调）"></a>1.5 主程序到底做了什么（看懂再调）</h3><p>顺手把源码里的关键设计说一下，排障时很有用：</p><ul><li><strong>对外接口只有四个</strong>：<code>/</code>（桥接页）、<code>/health</code>、<code>/api/v1/session</code>、<code>/api/v1/ws</code>，其他路径一律 404</li><li><strong><code>/api/v1/session</code></strong>：用 <code>BOOT</code> 派生的 Bearer 令牌做鉴权，POST 一段二进制握手数据，成功后通过响应头 <code>X-Session-Token</code> 返回会话令牌</li><li><strong><code>/api/v1/ws</code></strong>：真正的数据通道，要求 <code>Upgrade: websocket</code>，且子协议必须形如 <code>tproxy-lane-v1.&lt;令牌&gt;.&lt;通道号&gt;</code>；<code>Origin</code> 若不等于自身 Origin 会被拒绝</li><li><strong>帧协议</strong>：8 字节帧头（类型 + 会话 ID + 长度），单帧上限 1 MB，单条消息最多 4096 帧；每个令牌最多 128 条并发通道、累计 4096 个通道号</li><li><strong>安全头</strong>：返回的桥接页带 <code>sandbox</code> 的 CSP，且 <code>frame-ancestors</code> 只允许 <code>http://127.0.0.1:*</code>——这是给 Telegram Desktop 的本地页面做嵌入用的</li></ul><p><strong>所以：直接用浏览器打开 <code>https://你的域名/</code> 看到一个几乎空白的 “Connection” 页是正常的。</strong> 那个页面的完整版只有在带上正确签名的 <code>?bridge=</code> 参数时才会渲染，而签名由转发层按 <code>SECRET</code> 计算，客户端会通过本地页自动完成——不需要你手动拼。</p><hr><h2 id="第二步：部署-Worker-转发层"><a href="#第二步：部署-Worker-转发层" class="headerlink" title="第二步：部署 Worker 转发层"></a>第二步：部署 Worker 转发层</h2><p>这一层的唯一任务是：把你的域名请求原样转给 Pages 主程序，并把返回内容里的地址改写回你的域名。</p><h3 id="2-1-新建-Worker"><a href="#2-1-新建-Worker" class="headerlink" title="2.1 新建 Worker"></a>2.1 新建 Worker</h3><p>切换到<strong>第二个 Cloudflare 账号</strong>（如果你按建议分了两个），Workers 和 Pages → 创建 Worker，把 <code>webproxy-relay.js</code> 的内容整体粘贴进去，部署。</p><h3 id="2-2-配置变量"><a href="#2-2-配置变量" class="headerlink" title="2.2 配置变量"></a>2.2 配置变量</h3><table><thead><tr><th align="left">变量名</th><th align="left">类型</th><th align="left">值</th></tr></thead><tbody><tr><td align="left"><code>HOST</code></td><td align="left"><strong>文本</strong>（明文）</td><td align="left">Pages 主程序的默认域名，形如 <code>xxxx.pages.dev</code>，<strong>不要带 <code>https://</code>、不要带路径、不要填自定义域名</strong></td></tr><tr><td align="left"><code>SECRET</code></td><td align="left"><strong>机密</strong></td><td align="left">必须和 Pages 主程序的 <code>SECRET</code> <strong>完全一致</strong></td></tr></tbody></table><p><code>HOST</code> 填错的典型症状是：域名访问全 404 或 502。代码里会自动剥掉协议头和端口，但填自定义域名仍然会错——它要求的是 <code>*.pages.dev</code> 那个原始域名。</p><h3 id="2-3-绑定路由"><a href="#2-3-绑定路由" class="headerlink" title="2.3 绑定路由"></a>2.3 绑定路由</h3><p>Worker → <strong>设置</strong> → <strong>域和路由</strong> → <strong>添加路由</strong>，把你的优选域名挂上去：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">你的域名/*          ← 对应根域名 @</span><br><span class="line">*.你的域名/*        ← 对应任意子域名</span><br></pre></td></tr></table></figure><p>两条都加，覆盖面最全。<strong>注意：该域名的 Zone 必须和这个 Worker 在同一账号</strong>，否则界面根本不会让你选这个 Zone，这是 Cloudflare 的限制，不是项目的问题。</p><h3 id="2-4-验证转发"><a href="#2-4-验证转发" class="headerlink" title="2.4 验证转发"></a>2.4 验证转发</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">curl https://你的域名/health</span><br><span class="line"><span class="comment"># 期望：&#123;&quot;ok&quot;:true&#125;</span></span><br></pre></td></tr></table></figure><p>能通说明「域名 → Worker → Pages」这条链已经打通了。</p><h3 id="2-5-转发层做的三件细活"><a href="#2-5-转发层做的三件细活" class="headerlink" title="2.5 转发层做的三件细活"></a>2.5 转发层做的三件细活</h3><p>源码里有几个处理值得知道，出问题时能对上号：</p><ol><li><strong>重签桥接令牌</strong>：客户端带的 <code>?bridge=</code> 是按「当前域名」用 HMAC-SHA256 算的，转发层会校验并在转发时改写成按 <code>pages.dev</code> 域名计算的版本，这样桥接页在自定义域名下也能正常渲染；</li><li><strong>改写回跳地址</strong>：遇到 3xx 重定向，把 <code>Location</code> 里的 <code>pages.dev</code> 换回你的域名；</li><li><strong>改写 HTML</strong>：对 <code>text/html</code> 响应做字符串替换，把 <code>https://页域名</code> 与 <code>wss://页域名</code> 全部换回你的域名，同时清掉 <code>Content-Length</code>、<code>Content-Encoding</code>、<code>ETag</code> 等会因为改写而失效的头。</li></ol><p>它还严格校验 WebSocket 的 <code>Origin</code>：只有等于 <code>https://你的域名</code> 才放行，否则直接 404。<strong>所以用其他域名或裸 IP 去连是连不上的</strong>，这是设计如此。</p><hr><h2 id="第三步：让优选-IP-自动更新（可选但强烈推荐）"><a href="#第三步：让优选-IP-自动更新（可选但强烈推荐）" class="headerlink" title="第三步：让优选 IP 自动更新（可选但强烈推荐）"></a>第三步：让优选 IP 自动更新（可选但强烈推荐）</h2><p>Cloudflare 的 Anycast 会让你落到就近节点，但不同 IP 段在你的网络环境下质量差很多。这一层用 Cron 定时把「测得快的 IP」写进 A 记录，避免手动维护。</p><h3 id="3-1-建一个有-DNS-编辑权限的-Token"><a href="#3-1-建一个有-DNS-编辑权限的-Token" class="headerlink" title="3.1 建一个有 DNS 编辑权限的 Token"></a>3.1 建一个有 DNS 编辑权限的 Token</h3><p>Cloudflare 控制台 → <strong>我的个人资料</strong> → <strong>API 令牌</strong> → 创建令牌，模板选「<strong>编辑区域 DNS</strong>」：</p><ul><li>权限：<code>Zone</code> → <code>DNS</code> → <code>Edit</code></li><li>区域资源：<strong>只选你的优选域名这一个 Zone</strong>（最小权限）</li><li>创建后把令牌复制保存</li></ul><p>顺手记下这个 Zone 的 <strong>Zone ID</strong>（域名概览页右下角）。</p><h3 id="3-2-新建-Worker-并改三个常量"><a href="#3-2-新建-Worker-并改三个常量" class="headerlink" title="3.2 新建 Worker 并改三个常量"></a>3.2 新建 Worker 并改三个常量</h3><p>再建一个 Worker，粘贴 <code>domain-dns.js</code>，改开头这几个常量：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 优选 IP 源：返回文本，每行 IP:Port，可带 # 注释</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">URL</span> = <span class="string">&#x27;https://你的IP源地址&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 你的优选域名</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">DOMAIN</span> = <span class="string">&#x27;example.com&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 会分别同步 @ 根域名 和 * 通配子域名</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">RECORD_NAMES</span> = [</span><br><span class="line">  &#123; <span class="attr">label</span>: <span class="string">&#x27;@&#x27;</span>, <span class="attr">fqdn</span>: <span class="variable constant_">DOMAIN</span> &#125;,</span><br><span class="line">  &#123; <span class="attr">label</span>: <span class="string">&#x27;*&#x27;</span>, <span class="attr">fqdn</span>: <span class="string">`*.<span class="subst">$&#123;DOMAIN&#125;</span>`</span> &#125;</span><br><span class="line">];</span><br></pre></td></tr></table></figure><h3 id="3-3-配置变量与-Cron"><a href="#3-3-配置变量与-Cron" class="headerlink" title="3.3 配置变量与 Cron"></a>3.3 配置变量与 Cron</h3><table><thead><tr><th align="left">变量名</th><th align="left">类型</th><th align="left">值</th></tr></thead><tbody><tr><td align="left"><code>ZONE_ID</code></td><td align="left"><strong>文本</strong></td><td align="left">你的优选域名 Zone ID</td></tr><tr><td align="left"><code>API_TOKEN</code></td><td align="left"><strong>机密</strong></td><td align="left">上一步创建的 DNS 编辑令牌</td></tr></tbody></table><p>然后在 Worker → <strong>触发器</strong> → <strong>Cron 触发器</strong> 里加一条，例如每 30 分钟：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">*/30 * * * *</span><br></pre></td></tr></table></figure><blockquote><p>免费计划同样支持 Cron 触发器，但每次触发都会计入请求次数，别设得过于频繁（比如每分钟一次完全没必要，优选 IP 的变动频率远低于此）。</p></blockquote><h3 id="3-4-这层脚本的逻辑（便于自查）"><a href="#3-4-这层脚本的逻辑（便于自查）" class="headerlink" title="3.4 这层脚本的逻辑（便于自查）"></a>3.4 这层脚本的逻辑（便于自查）</h3><ul><li>拉取 IP 源文本，<strong>只保留端口为 443 的条目</strong>（其他端口直接忽略）</li><li>对 <code>@</code> 和 <code>*</code> 两条记录：分页读出当前所有 A 记录 → 删掉不在目标列表里的 → 补上缺的</li><li>新记录 <strong>TTL 设为 60 秒</strong>，改动后一分钟内全网生效</li><li>会容忍 Cloudflare 的「记录已存在 &#x2F; 内容重复」类错误码，不会因为并发重复创建而整体失败</li></ul><h3 id="3-5-验证"><a href="#3-5-验证" class="headerlink" title="3.5 验证"></a>3.5 验证</h3><ol><li>Worker 的 <strong>日志</strong> 里能看到每次 Cron 的执行结果（同步了哪些 IP、有没有报错）</li><li>本地查一下记录：</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nslookup 你的域名 1.1.1.1</span><br></pre></td></tr></table></figure><p>返回的 IP 应该和你的优选 IP 源里 443 那批对得上。</p><hr><h2 id="第四步：客户端配置"><a href="#第四步：客户端配置" class="headerlink" title="第四步：客户端配置"></a>第四步：客户端配置</h2><p>到这一步，服务端已经就绪。客户端只需要三个字段：</p><table><thead><tr><th align="left">字段</th><th align="left">填什么</th></tr></thead><tbody><tr><td align="left"><strong>服务器 &#x2F; Server</strong></td><td align="left">你的优选域名（例如 <code>example.com</code>）</td></tr><tr><td align="left"><strong>端口 &#x2F; Port</strong></td><td align="left"><code>443</code></td></tr><tr><td align="left"><strong>密钥 &#x2F; Secret</strong></td><td align="left">和 Pages 主程序一致的 <code>SECRET</code>；如果用了 <code>dd</code> 前缀，<strong>必须连 <code>dd</code> 一起填满 34 位</strong></td></tr></tbody></table><h3 id="Telegram-Desktop（Windows-macOS-Linux）"><a href="#Telegram-Desktop（Windows-macOS-Linux）" class="headerlink" title="Telegram Desktop（Windows &#x2F; macOS &#x2F; Linux）"></a>Telegram Desktop（Windows &#x2F; macOS &#x2F; Linux）</h3><p>设置 → <strong>高级</strong> → <strong>连接类型</strong> → <strong>代理</strong> → <strong>添加代理</strong> → 类型选 <strong>MTProto</strong> → 填入上面三项 → 保存 → 选中该代理。</p><h3 id="Telegram-Android-iOS"><a href="#Telegram-Android-iOS" class="headerlink" title="Telegram Android &#x2F; iOS"></a>Telegram Android &#x2F; iOS</h3><p>设置 → <strong>数据和存储</strong> → <strong>代理</strong>（部分版本在「聊天设置 → 代理」）→ <strong>添加代理</strong> → <strong>MTProto</strong> → 填入三项 → 启用。</p><h3 id="判断是否真的连上了"><a href="#判断是否真的连上了" class="headerlink" title="判断是否真的连上了"></a>判断是否真的连上了</h3><ul><li>客户端代理列表里该条目显示<strong>已连接 &#x2F; Connected</strong></li><li>打开任意频道能正常收发消息</li><li>服务端侧可以访问 <code>https://你的域名/health</code> 确认主程序存活</li></ul><p>如果客户端一直转圈：先确认 <code>https://你的域名/health</code> 返回 <code>{&quot;ok&quot;:true}</code>，再检查客户端里的 secret 有没有少一位或多一位（尤其 <code>dd</code> 前缀很容易漏）。</p><hr><h2 id="额度与性能"><a href="#额度与性能" class="headerlink" title="额度与性能"></a>额度与性能</h2><table><thead><tr><th align="left">项目</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">Workers 免费额度</td><td align="left">每天 10 万次请求，日常个人使用远远够</td></tr><tr><td align="left">Pages 免费额度</td><td align="left">同样有每日请求上限；作者说明与 Worker <strong>分开计算</strong></td></tr><tr><td align="left">Cron</td><td align="left">每次触发算一次请求，频率别拉满</td></tr><tr><td align="left">WebSocket</td><td align="left">长连接本身就是低请求数、高流量模型，比短轮询省额度</td></tr></tbody></table><p>几个实测向的优化建议：</p><ul><li><strong>优选 IP 源的质量决定了 90% 的体验</strong>。换几个源对比延迟再定，别用来源不明的列表</li><li><strong>Cron 频率 30–60 分钟</strong>足够，IP 失效通常不会在几分钟内发生</li><li>如果你只是自己用，<strong>只加 <code>@</code> 根域名那条记录</strong>也行，少一条记录少一次 API 调用</li><li>出现 1101 &#x2F; 522 时，优先检查是不是有人在猛拉流量，或 Workers 侧并发太高；主程序留在 Pages 是这套方案的核心思路，不要改动</li></ul><hr><h2 id="常见故障排查"><a href="#常见故障排查" class="headerlink" title="常见故障排查"></a>常见故障排查</h2><h3 id="health-返回-500"><a href="#health-返回-500" class="headerlink" title="/health 返回 500"></a><code>/health</code> 返回 500</h3><p><code>BOOT</code> 或 <code>SECRET</code> 缺失、格式不对。重点查 <code>SECRET</code>：必须 <strong>32 位小写十六进制</strong>，或 <strong><code>dd</code> + 32 位</strong>；有大写字母、长度 31&#x2F;33 都会失败。</p><h3 id="访问域名全部-404"><a href="#访问域名全部-404" class="headerlink" title="访问域名全部 404"></a>访问域名全部 404</h3><p>三种可能，按顺序排查：</p><ol><li>Worker 路由没加（或缺 <code>*</code> 通配那条）</li><li>域名 Zone 与 Worker <strong>不在同一 Cloudflare 账号</strong></li><li><code>HOST</code> 填错了（必须是最原始的 <code>*.pages.dev</code>，不是自定义域名）</li></ol><h3 id="页面能开，但-Telegram-一直连不上"><a href="#页面能开，但-Telegram-一直连不上" class="headerlink" title="页面能开，但 Telegram 一直连不上"></a>页面能开，但 Telegram 一直连不上</h3><ul><li>Worker 里 <code>SECRET</code> 与 Pages 里不一致 —— 这是最常见原因</li><li>客户端 secret 填错（<code>dd</code> 前缀漏填或重复）</li><li>WebSocket 被中间层拦了：转发层要求 <code>Origin</code> 严格等于 <code>https://你的域名</code></li></ul><h3 id="从浏览器打开-https-你的域名-是一片空白"><a href="#从浏览器打开-https-你的域名-是一片空白" class="headerlink" title="从浏览器打开 https://你的域名/ 是一片空白"></a>从浏览器打开 <code>https://你的域名/</code> 是一片空白</h3><p>正常现象。桥接页需要合法签名的 <code>?bridge=</code> 参数才会完整渲染，客户端会自动处理，不需要手动拼。</p><h3 id="DNS-不自动更新"><a href="#DNS-不自动更新" class="headerlink" title="DNS 不自动更新"></a>DNS 不自动更新</h3><ul><li><code>API_TOKEN</code> 权限不足（必须含该 Zone 的 DNS Edit）</li><li><code>ZONE_ID</code> 填错</li><li>Cron 没启用，或最近一次执行报错（看 Worker 日志）</li><li>IP 源返回的条目里没有 <code>:443</code>，脚本会全部过滤掉</li></ul><h3 id="偶尔-1101-522"><a href="#偶尔-1101-522" class="headerlink" title="偶尔 1101 &#x2F; 522"></a>偶尔 1101 &#x2F; 522</h3><p>1101 是 Worker 运行时抛异常，522 是源站超时。两个都属于「Worker 直接扛代理」的固有问题，这也是本方案把主程序放 Pages 的原因。降低并发、别把域名公开给大量陌生人使用，能明显缓解。</p><h3 id="想换-SECRET-怎么办"><a href="#想换-SECRET-怎么办" class="headerlink" title="想换 SECRET 怎么办"></a>想换 SECRET 怎么办</h3><p>必须<strong>同时</strong>改两处（Pages 主程序 + Worker 转发层），改完重新部署，然后通知所有客户端更新 secret。只改一边会导致全部连不上。</p><hr><h2 id="安全与注意事项"><a href="#安全与注意事项" class="headerlink" title="安全与注意事项"></a>安全与注意事项</h2><ul><li><strong><code>SECRET</code> 就是这台上网的钥匙</strong>：拿到「域名 + secret」的任何人都在白嫖你的代理，<strong>不要发到公开群组或仓库里</strong></li><li><strong><code>API_TOKEN</code> 只给最小权限</strong>：只勾选该 Zone 的 DNS 编辑，别用全局 API Key</li><li>三个组件建议分账号部署，一处泄露不至于全线崩塌</li><li>密钥用「机密（Secret）」类型存，不要写死在代码里再上传</li><li>本项目用于<strong>合法的通信与学习用途</strong>，请自行遵守所在地法律法规以及相关平台的服务条款</li></ul><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>把整套流程压缩成一张清单：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">① Pages：telegram_webproxy.js → 改名 _worker.js → 传根目录</span><br><span class="line">   变量：BOOT（随机串）、SECRET（32 位 hex 或 dd+32 位）</span><br><span class="line">   验证：/health → &#123;&quot;ok&quot;:true&#125;</span><br><span class="line"></span><br><span class="line">② Worker：webproxy-relay.js</span><br><span class="line">   变量：HOST = xxx.pages.dev、SECRET = 同上</span><br><span class="line">   路由：域名/*、*.域名/*</span><br><span class="line">   验证：curl https://域名/health</span><br><span class="line"></span><br><span class="line">③ Worker + Cron：domain-dns.js</span><br><span class="line">   改：URL、DOMAIN</span><br><span class="line">   变量：ZONE_ID、API_TOKEN（DNS Edit）</span><br><span class="line">   Cron：*/30 * * * *（按需）</span><br><span class="line">   验证：nslookup 看 A 记录</span><br><span class="line"></span><br><span class="line">④ 客户端：MTProto · 域名 · 443 · SECRET</span><br></pre></td></tr></table></figure><p>这套方案最值得学的地方，其实是它「<strong>用 Pages 扛长连接、用 Worker 只做转发</strong>」的工程取舍——1101&#x2F;522 这类边缘平台的老问题，靠架构拆分绕过去，比在单文件里加一堆重试优雅得多。想自己搭一套 TG 代理的话，按上面四步走，半小时能跑通。</p><hr><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://github.com/xinyitang3/cftgwebproxy">cftgwebproxy 项目仓库（GitHub）</a></li><li><a href="https://github.com/ToiCF/CF-Workers-TGProxy">上游协议实现：ToiCF&#x2F;CF-Workers-TGProxy</a></li><li><a href="https://developers.cloudflare.com/pages/functions/advanced-mode/">Cloudflare Pages Functions 高级模式（_worker.js）</a></li><li><a href="https://developers.cloudflare.com/workers/configuration/routing/routes/">Cloudflare Workers 路由配置</a></li><li><a href="https://developers.cloudflare.com/workers/configuration/cron-triggers/">Cloudflare Workers Cron 触发器</a></li><li><a href="https://developers.cloudflare.com/api/operations/dns-records-for-a-zone-list-dns-records">Cloudflare API：DNS 记录管理</a></li><li><a href="https://core.telegram.org/mtproto/mtproto-transports#transport-obfuscation">Telegram MTProto 代理说明</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/10/31/cftgwebproxy-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/10/31/cftgwebproxy-deployment-tutorial/"/>
    <published>2026-10-31T04:30:00.000Z</published>
    <summary>cftgwebproxy 是一套基于 Cloudflare Pages + Worker + Cron 自动 DNS 的 Telegram Web Proxy 方案，主程序跑在 Pages 规避 Worker 直连代理常见的 1101/522 错误。本文按三个组件拆解部署步骤：Pages 主程序（_worker.js 与 BOOT/SECRET）、Worker 转发层（HOST 与路由）、Cron 自动优选 IP 的 DNS 同步，并给出客户端填写方法、额度说明与 8 类故障排查。</summary>
    <title>Cloudflare Telegram Web Proxy 部署教程：Pages 主程序 + Worker 转发 + 自动优选 DNS 全流程</title>
    <updated>2026-10-31T04:07:30.198Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="安全" scheme="https://blog.ztmss.com/categories/%E5%AE%89%E5%85%A8/"/>
    <category term="CodeBuddy" scheme="https://blog.ztmss.com/tags/CodeBuddy/"/>
    <category term="WorkBuddy" scheme="https://blog.ztmss.com/tags/WorkBuddy/"/>
    <category term="账号池" scheme="https://blog.ztmss.com/tags/%E8%B4%A6%E5%8F%B7%E6%B1%A0/"/>
    <category term="API网关" scheme="https://blog.ztmss.com/tags/API%E7%BD%91%E5%85%B3/"/>
    <category term="合规风险" scheme="https://blog.ztmss.com/tags/%E5%90%88%E8%A7%84%E9%A3%8E%E9%99%A9/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>2026 年 9 月起，GitHub 上一批新项目突然爆发式增长：把腾讯 <strong>CodeBuddy &#x2F; WorkBuddy</strong> 的账号包装成 <strong>OpenAI 兼容 API</strong>，再配上 Web 管理面板做账号池。代表性的是这两个：</p><table><thead><tr><th align="left">项目</th><th align="left">定位</th><th align="left">语言</th><th align="left">Stars</th></tr></thead><tbody><tr><td align="left"><code>linguo2625469/workbuddy2api-panel</code></td><td align="left">多账号网关 + Web 管理面板（账号池轮转、定时签到保活、成长任务）</td><td align="left">Go</td><td align="left">4600+</td></tr><tr><td align="left"><code>ithtelab/workbuddy-manager</code></td><td align="left">账号池管理控制台 + 内置反代网关（扫码纳管、密钥分发、IP&#x2F;模型白名单、用量统计）</td><td align="left">Python &#x2F; Next.js</td><td align="left">2100+</td></tr></tbody></table><p>两个仓库都是 9 月中旬创建、一个月内涨到数千星，标签里写满了 <code>reverse-proxy</code>、<code>openai-api</code>、<code>account-manager</code>。对想省钱用上大模型 API 的人来说，吸引力很直接：注册个免费账号，扫个码，就能在自己的客户端里用上「兼容 OpenAI 格式」的接口。</p><p><strong>但这篇文章不教部署。</strong> 我要做的是另一件事：把这两个项目<strong>自己在 README 里写下的内容</strong>当作证据，逐条算清楚这笔账——省下的钱，和你要押上去的东西相比，到底值不值。</p><hr><h2 id="先看它们自己怎么说"><a href="#先看它们自己怎么说" class="headerlink" title="先看它们自己怎么说"></a>先看它们自己怎么说</h2><p>这两份 README 的信息量，比任何第三方分析都大。</p><h3 id="证据一：主项目已经自己停维护了"><a href="#证据一：主项目已经自己停维护了" class="headerlink" title="证据一：主项目已经自己停维护了"></a>证据一：主项目已经自己停维护了</h3><p><code>workbuddy2api-panel</code> 在 README 顶部用醒目块写明：<strong>项目已停止维护（2026-10-21）</strong>，不再更新代码、不跟进上游变化、不再处理新的 issue&#x2F;PR。给出的三条原因，值得逐字读：</p><ol><li><strong>上游已开始禁用反代</strong>——WorkBuddy 对非官方客户端的识别与拦截正在收紧（通道校验、账号限制等），反代通道的稳定性与存续周期已不可控，继续做适配意义有限</li><li><strong>一人精力有限</strong>——这是一个人的自用工具，无力长期跟进协议变化与风控对抗</li><li><strong>非法转售泛滥</strong>——发现大量批量注册小号、对外售卖额度、二次加壳 &#x2F; 卡密分发的滥用行为，与本项目初衷完全相悖</li></ol><p>它还明确写了一句：「因使用非官方客户端导致的账号风控 &#x2F; 封禁，由使用者自行承担。」</p><p><strong>这三点等于把这类项目的生命周期判决书写在了脸上</strong>：上游在查、作者跑了、生态里全是转卖的人。</p><h3 id="证据二：上游仓库已经删除了"><a href="#证据二：上游仓库已经删除了" class="headerlink" title="证据二：上游仓库已经删除了"></a>证据二：上游仓库已经删除了</h3><p>同一个 README 里还有一条：本项目是 <code>Sliverkiss/workbuddy2api</code> 的增强分支，而<strong>上游仓库现已删除</strong>。</p><p>一个被上游删除的项目，说明什么？说明平台方的态度已经明确了。你现在照着任何一个 fork 部署，等于在一个已经被官方盯上、原作者已经撤掉的通道上继续跑流量。</p><h3 id="证据三：免责声明把灰产路径写全了"><a href="#证据三：免责声明把灰产路径写全了" class="headerlink" title="证据三：免责声明把灰产路径写全了"></a>证据三：免责声明把灰产路径写全了</h3><p><code>workbuddy-manager</code> 的 README 里有这样一段使用边界：</p><blockquote><p>仅可用于管理本人及亲属自愿授权的账号；<strong>禁止批量注册、账号交易、代注册、接码、盗号、绕过平台风控</strong>，以及任何商业转售或盈利性用途。</p></blockquote><p>需要专门写这么长一串「禁止」，本身就说明了这个生态里实际在发生什么。代注册、接码平台、账号买卖——这些不是边缘现象，是这类工具的<strong>主要使用场景之一</strong>。</p><h3 id="证据四：赞助商是住宅代理，这就是风控对抗的成本"><a href="#证据四：赞助商是住宅代理，这就是风控对抗的成本" class="headerlink" title="证据四：赞助商是住宅代理，这就是风控对抗的成本"></a>证据四：赞助商是住宅代理，这就是风控对抗的成本</h3><p>最耐人寻味的一条：<code>workbuddy-manager</code> 的 README 顶部挂着一个<strong>住宅代理服务</strong>的赞助位，并解释了用法——在代理的用户名里写上国家、城市和会话名，<strong>每个实例走一个住宅 IP，最长 72 小时不变</strong>，换 IP 也留在同一城市。</p><p>为什么一个「账号管理工具」需要给每个账号配一个独立住宅 IP、还要保持城市一致？</p><p>答案不言自明：<strong>因为同 IP 多账号是最典型的批量行为特征，会被风控识别</strong>。这段赞助文案，实际上是一份「规避平台风控的技术需求说明书」。</p><p>这也顺手回答了成本问题：想稳定用这套东西，你还要额外买住宅代理（赞助码还打着 7 折）。<strong>省下的订阅费，先要扣掉一笔代理费。</strong></p><hr><h2 id="五类风险逐条算账"><a href="#五类风险逐条算账" class="headerlink" title="五类风险逐条算账"></a>五类风险逐条算账</h2><h3 id="1-账号风险：封号是设计内的结果，不是意外"><a href="#1-账号风险：封号是设计内的结果，不是意外" class="headerlink" title="1. 账号风险：封号是设计内的结果，不是意外"></a>1. 账号风险：封号是设计内的结果，不是意外</h3><p>这类网关的本质是<strong>用非官方客户端模拟官方流量</strong>，去访问平台的私有接口。平台的服务条款通常明确禁止：自动化访问、接口逆向、账号出借或共享、批量注册。三类行为叠加在一起，被封不是「运气不好」，而是迟早的事。</p><p>更麻烦的是<strong>连坐</strong>：多数人用的腾讯账号是同一个账号体系，一旦因为这个通道被标记，影响范围可能不止于 CodeBuddy。</p><h3 id="2-凭据风险：扫码纳管等于交出登录态"><a href="#2-凭据风险：扫码纳管等于交出登录态" class="headerlink" title="2. 凭据风险：扫码纳管等于交出登录态"></a>2. 凭据风险：扫码纳管等于交出登录态</h3><p>「扫码纳管」听起来无痛，实际操作是把账号的<strong>登录凭证 &#x2F; 会话令牌</strong>交给一个 Web 控制台，由它在后台代表你发请求、签到、保活。</p><p>那么问题来了：你把凭证交给了谁？</p><ul><li>一个 2026 年 9 月创建的仓库</li><li>一个自述「近期 issue&#x2F;PR 处理、代码审查、测试与修复实现<strong>大量由 AI 辅助完成</strong>」的项目</li><li>一个上游已经被删除、主分支已经停维护的生态</li></ul><p>这些描述并不意味着作者有恶意——但<strong>审计难度是客观的</strong>。代码量不小、AI 代写成分高、更新频繁、还带一键自动更新。任何一处后门或漏洞，代价是别人拿着你的登录态为所欲为。<strong>这类凭证往往无法用「改个密码」简单止损，因为会话令牌可能已经长期有效。</strong></p><h3 id="3-供应链风险：签名校验证明不了「作者可信」"><a href="#3-供应链风险：签名校验证明不了「作者可信」" class="headerlink" title="3. 供应链风险：签名校验证明不了「作者可信」"></a>3. 供应链风险：签名校验证明不了「作者可信」</h3><p><code>workbuddy-manager</code> 强调「带签名校验的一键更新」。这是好设计，但要理解它到底保证了什么：</p><ul><li>它保证：<strong>这次更新确实来自同一个作者，没被中间人篡改</strong></li><li>它不保证：<strong>这个作者是可信的</strong></li></ul><p>信任锚点仍然是人。而这个人是匿名 ID、项目一个月新、二进制发布、还会自动更新——这是供应链攻击面里最难审计的一种组合：你运行的是一份没有可复现构建、随时会被替换的二进制。</p><h3 id="4-稳定性风险：协议一改，全部归零"><a href="#4-稳定性风险：协议一改，全部归零" class="headerlink" title="4. 稳定性风险：协议一改，全部归零"></a>4. 稳定性风险：协议一改，全部归零</h3><p>私有接口是逆向出来的，没有任何兼容承诺。平台改一个字段校验、加一层设备指纹、换一次签名算法，你的网关立刻 502。</p><p>这件事已经发生了：<strong>主项目 10 月 21 日停更，理由第一条就是「上游已开始禁用反代」</strong>。你花几小时部署好的东西，可能明天就变成一堆报错的日志——而那时你已经把工作流搭在它上面了。</p><h3 id="5-成本与合规：省的钱可能还没赔的多"><a href="#5-成本与合规：省的钱可能还没赔的多" class="headerlink" title="5. 成本与合规：省的钱可能还没赔的多"></a>5. 成本与合规：省的钱可能还没赔的多</h3><p>把账算全：</p><table><thead><tr><th align="left">项目</th><th align="left">成本</th></tr></thead><tbody><tr><td align="left">订阅费</td><td align="left">省下了（这是唯一收益）</td></tr><tr><td align="left">住宅代理</td><td align="left">额外支出（想稳定跑就要买）</td></tr><tr><td align="left">部署与维护时间</td><td align="left">数小时起步，且要跟着项目更新反复折腾</td></tr><tr><td align="left">账号被封</td><td align="left">账号内数据、历史、其他服务连带风险</td></tr><tr><td align="left">生产事故</td><td align="left">如果拿它接了真实业务，接口随时中断</td></tr><tr><td align="left">法律与合规</td><td align="left">企业环境采购此类通道、内部转售额度，都可能踩线</td></tr></tbody></table><p>在个人娱乐场景，最坏结果是损失一个账号。<strong>但如果这被用在任何有交付责任的地方，赔的就不只是订阅费了。</strong></p><hr><h2 id="为什么这类项目注定活不长"><a href="#为什么这类项目注定活不长" class="headerlink" title="为什么这类项目注定活不长"></a>为什么这类项目注定活不长</h2><p>这不是道德判断，是结构判断。这类项目同时要对抗三件事：</p><ol><li><strong>协议变更</strong>：私有接口没有稳定性承诺，平台每次发版都可能让你的实现失效</li><li><strong>风控识别</strong>：对话补全类产品的账号共享，是最容易被行为特征识别的滥用类型——同 IP、异常频率、非官方客户端指纹</li><li><strong>生态自毁</strong>：一旦有人开始批量注册、卖卡密，平台就会收紧到「所有人一起死」，这正是主项目停维护的第三条原因</li></ol><p>三段式结局几乎固定：<strong>火 → 收紧 → 弃坑</strong>。你选择进入的时间点，决定了你要不要经历最后那段。</p><hr><h2 id="如果你已经上手了：止损清单"><a href="#如果你已经上手了：止损清单" class="headerlink" title="如果你已经上手了：止损清单"></a>如果你已经上手了：止损清单</h2><p>不写操作步骤，只列原则：</p><ol><li><strong>把主账号摘出来</strong>——任何长期使用、绑定真实业务或个人资料的账号，不要放进任何账号池</li><li><strong>不要接生产流量</strong>——把它当玩具，别让任何有交付期限的事依赖它</li><li><strong>清理授权</strong>——检查该账号的登录设备与授权记录，发现不认识的就下线；必要时改密码</li><li><strong>不要转售、不要代注册、不要接码</strong>——这几件事已经从「违反 ToS」跨到可能涉法的区间</li><li><strong>做好随时关停的心理准备</strong>——不要在这条通道上构建任何你无法承担中断的流程</li></ol><hr><h2 id="更划算的合规替代"><a href="#更划算的合规替代" class="headerlink" title="更划算的合规替代"></a>更划算的合规替代</h2><p>如果你的真实需求是「用便宜的 API 额度调大模型」，有两条正路：</p><p><strong>路线一：官方 API + 自建网关。</strong> 用官方发放的 API Key，在自建网关上做多 Key 轮询、限额、日志、模型映射——该有的工程能力一样不少，而且不涉及任何账号共享。同类开源网关（如 new-api、one-api 系）成熟度和社区支持都远好于一个两个月新的逆向项目。本站此前写过 <strong>ai-gateway</strong> 的部署教程，就是这个思路。</p><p><strong>路线二：把官方额度用足。</strong> 各家都有新用户额度、学生认证、低价档模型（Flash &#x2F; Lite &#x2F; Mini 系列）。日常写代码、跑脚本，用便宜档位的官方 API，实际花销经常低于「订阅费 + 住宅代理 + 踩坑时间」的总和。</p><p><strong>核心区别只有一句：官方 Key 是授权给你的，账号池里的凭证是借来的。</strong> 授权的东西可以长期规划，借来的东西随时会被收回。</p><hr><h2 id="评估任何「账号池-反代」项目的五问"><a href="#评估任何「账号池-反代」项目的五问" class="headerlink" title="评估任何「账号池 &#x2F; 反代」项目的五问"></a>评估任何「账号池 &#x2F; 反代」项目的五问</h2><p>以后再遇到类似的工具，按这五条过一遍，基本能判生死：</p><ol><li><strong>它访问的是官方公开 API，还是逆向的私有接口？</strong> 后者没有兼容承诺</li><li><strong>它需要我交出什么？</strong> 只要涉及登录态、Cookie、扫码授权，就要按「交出账号」的严重程度来评估</li><li><strong>它的更新机制是什么？</strong> 二进制 + 自动更新 &#x3D; 把执行权限长期授予一个匿名作者</li><li><strong>它自己的 README 有没有写「禁止批量注册 &#x2F; 商业转售 &#x2F; 绕过风控」？</strong> 写了，说明这就是它的主要用途</li><li><strong>它活了多久、上游还在不在？</strong> 一个月新 + 上游已删除 &#x3D; 别把任何重要事情放上去</li></ol><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>这两个项目本身不算「恶意软件」，作者也明确写了自用定位和禁止转售。但它们所依附的<strong>模式</strong>——逆向私有接口 + 账号池 + 自动化保活 + 住宅代理规避风控——注定是一笔短命的生意：</p><ul><li><strong>技术上</strong>：上游一改协议就失效，主项目已经停更</li><li><strong>账号上</strong>：封号是设计内的结果，还会连坐同账号的其他服务</li><li><strong>安全上</strong>：登录态托管给一个 AI 大量代写、上游已删库的新项目</li><li><strong>成本上</strong>：省下的订阅费，要先付给住宅代理和踩坑时间</li></ul><p>如果你的目的是「便宜地用上大模型」，答案从来不是把别人的账号变成你的管道，而是<strong>用官方 Key 搭自己的网关</strong>——同样是工程活，但这个网关明天还在。</p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://github.com/linguo2625469/workbuddy2api-panel">workbuddy2api-panel（GitHub，已停止维护）</a></li><li><a href="https://github.com/ithtelab/workbuddy-manager">workbuddy-manager（GitHub）</a></li><li><a href="https://github.com/songquanpeng/one-api">One API（开源 OpenAI 兼容网关）</a></li><li><a href="https://github.com/Calcium-Ion/new-api">New API（开源大模型网关）</a></li><li><a href="https://copilot.tencent.com/">腾讯云 CodeBuddy 官网</a></li><li><a href="https://blog.ztmss.com/2026/08/28/ai-gateway-deployment-tutorial/">本站：AI Gateway 部署教程（自建网关思路）</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/10/30/account-pool-gateway-risks/</id>
    <link href="https://blog.ztmss.com/2026/10/30/account-pool-gateway-risks/"/>
    <published>2026-10-30T09:30:00.000Z</published>
    <summary>2026 年 9 月起一批把腾讯 CodeBuddy / WorkBuddy 账号转成 OpenAI 兼容 API 的项目走红，本文不做部署教学，而是把这些项目自己的 README 当作证据，逐条分析账号风控封禁、登录态托管泄露、二进制自动更新的供应链风险、私有接口随时失效、住宅代理成本与合规问题，并给出更划算的合规替代方案与项目评估五问。</summary>
    <title>账号池网关的风险账：把 CodeBuddy / WorkBuddy 账号变成 OpenAI 兼容 API，值不值？</title>
    <updated>2026-10-30T07:44:47.704Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="安全" scheme="https://blog.ztmss.com/categories/%E5%AE%89%E5%85%A8/"/>
    <category term="网络安全" scheme="https://blog.ztmss.com/tags/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/"/>
    <category term="群晖" scheme="https://blog.ztmss.com/tags/%E7%BE%A4%E6%99%96/"/>
    <category term="NAS" scheme="https://blog.ztmss.com/tags/NAS/"/>
    <category term="勒索病毒" scheme="https://blog.ztmss.com/tags/%E5%8B%92%E7%B4%A2%E7%97%85%E6%AF%92/"/>
    <category term="C3RB3R" scheme="https://blog.ztmss.com/tags/C3RB3R/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>2026 年 10 月 28 日下午至 29 日凌晨，NAS 圈炸了锅：国内外大量<strong>群晖（Synology）NAS</strong> 用户发现存储空间里的文档、照片、数据库备份被批量加密，扩展名统一变成 <strong><code>.L0CK3D</code></strong>（部分显示为 <code>.LOCK3D</code>，含数字 0 和 3），每个目录里都多了一份 <strong><code>read-me3.txt</code></strong> 勒索信，内容是 <code>C3RB3R INSTRUCTIONS</code> 和一组 6 位设备 ID，引导受害者用 Tor 浏览器访问暗网自助站点交赎金。</p><p>这件事之所以让人慌，不只是规模大，而是它打破了很多人的安全认知：<strong>受害者里既有跑最新 DSM 7.4.1 的设备，也有开了两步验证、改了默认端口、禁了 SSH 的设备</strong>。360 反勒索团队与 Solar 应急响应团队已相继披露事件，群晖官方也已确认用户数据被加密并发布安全公告。</p><blockquote><p>如果你现在正在读这篇文章、并且 NAS 里有重要数据：<strong>先看第四章「中招后的黄金一小时」</strong>，那里有一条可能让你免费恢复全部数据的自救路径——前提是<strong>千万别断电、别重启</strong>。</p></blockquote><hr><h2 id="事件时间线"><a href="#事件时间线" class="headerlink" title="事件时间线"></a>事件时间线</h2><table><thead><tr><th align="left">时间</th><th align="left">进展</th></tr></thead><tbody><tr><td align="left">10 月上旬</td><td align="left">360 反勒索服务开始陆续接到群晖 NAS 勒索求助</td></tr><tr><td align="left">10 月 28 日下午</td><td align="left">大量用户集中反馈中招，B 站、小红书、LINUX DO、V2EX 出现大量求助帖，部分经销商向客户发出「关闭外网访问」紧急通知</td></tr><tr><td align="left">10 月 29 日</td><td align="left">360 安全团队与 Solar 应急响应团队相继披露分析；社区开发者开始直播自救过程</td></tr><tr><td align="left">10 月 29 日晚</td><td align="left">开源救援工具 soimy&#x2F;c3rb3r-rescue 发布，多名未关机受害者成功解出数据</td></tr><tr><td align="left">10 月 30 日</td><td align="left">群晖官方确认事件并发布补丁版本建议；媒体大范围报道</td></tr></tbody></table><p>受害面从家庭相册（DS918+ 等家用型号）到企业备份服务器、私有 GitLab 代码库都有，有用户报告 <strong>8TB 至数十 TB</strong> 数据被一次性加密，同机备份目录也未能幸免。</p><hr><h2 id="攻击特征：你的-NAS-有没有中招"><a href="#攻击特征：你的-NAS-有没有中招" class="headerlink" title="攻击特征：你的 NAS 有没有中招"></a>攻击特征：你的 NAS 有没有中招</h2><p>对照下面几条，任意一条命中就要立刻处理：</p><ul><li>文件扩展名被追加 <strong><code>.L0CK3D</code></strong></li><li>各级目录和系统根目录出现 <strong><code>read-me3.txt</code></strong>，内含 <code>C3RB3R INSTRUCTIONS</code> 与 6 位设备 ID</li><li><strong>Docker &#x2F; Container Manager 被卸载或容器全部消失</strong></li><li>NAS 风扇<strong>异常狂转</strong>、CPU 占用拉满（加密进程在跑）</li><li>Cloud Sync 正在疯狂同步 <code>read-me3.txt</code> 到异地网盘（说明加密已扩散到同步目录）</li><li>登录 DSM 后套件异常、大量服务不可用</li></ul><p>勒索信里的条件是：<strong>0.085 BTC</strong>，超过 5 天未付则翻倍至 0.17 BTC。攻击者提供「上传一个小于 1024KB 的文件免费试解密」来证明自己确实持有密钥——这是标准施压话术，<strong>不代表付钱一定能拿回全部数据</strong>。</p><hr><h2 id="技术拆解：C3RB3R-是什么"><a href="#技术拆解：C3RB3R-是什么" class="headerlink" title="技术拆解：C3RB3R 是什么"></a>技术拆解：C3RB3R 是什么</h2><p>根据 360 反勒索团队与 Solar 应急响应团队的样本分析：</p><ul><li><strong>家族归属</strong>：老牌勒索家族 <strong>Cerber</strong> 的现代 Linux 变种，被暂命名为 <strong>C3RB3R</strong></li><li><strong>投放方式</strong>：恶意的拉取脚本从远端服务器（报告披露的 IOC 之一：<code>hxxp://46[.]8[.]78[.]122/xdy5.sh</code>）下载对应 CPU 架构（x86_64 &#x2F; aarch64 &#x2F; armv7l）的 <strong>UPX 加壳 ELF 二进制</strong></li><li><strong>伪装</strong>：进程伪装成 <code>/bin/libgld</code>（带参数 <code>-n 308</code>）或 <code>/bin/qnetd</code>（带参数 <code>153</code>），混在系统进程里</li><li><strong>加密行为</strong>：从根目录开始多线程遍历所有挂载的存储空间，跳过 27 个系统关键目录以免把系统搞崩导致加密中断，对 187 种常见扩展名做全文件加密</li><li><strong>加密算法</strong>：为每个文件生成独立的 32 字节密钥与 8 字节 nonce，使用 <strong>ChaCha8</strong> 加密，并在文件末尾固定追加 <strong>588 字节尾部数据</strong>；这 588 字节里包含一段被 <strong>AES-256-CBC 会话主密钥</strong>加密保护的 48 字节密钥记录</li><li><strong>后果</strong>：会话主密钥只存在于加密期间的<strong>运行内存</strong>里，落盘的全是密文——所以断电重启后才彻底失去免费恢复的可能</li></ul><blockquote><p>一句话总结原理：<strong>文件的密钥都在尾部 588 字节里，但解开它们的那把「总钥匙」只在内存中。</strong> 这就是为什么「不要重启」是这次事件里最重要的一条。</p></blockquote><hr><h2 id="三个免登录入侵入口"><a href="#三个免登录入侵入口" class="headerlink" title="三个免登录入侵入口"></a>三个免登录入侵入口</h2><p>驱动之家&#x2F;快科技的溯源报道指出，这波攻击<strong>不是</strong>传统「Windows 电脑中毒 → 通过 SMB 共享感染 NAS」的路径，而是攻击者针对<strong>暴露在公网的群晖设备</strong>，利用无需登录的认证前远程代码执行漏洞做全网自动化扫描攻击。目前披露的入口主要有三类：</p><h3 id="入口一：CVE-2024-10441（群晖官方初步指向的头号元凶）"><a href="#入口一：CVE-2024-10441（群晖官方初步指向的头号元凶）" class="headerlink" title="入口一：CVE-2024-10441（群晖官方初步指向的头号元凶）"></a>入口一：CVE-2024-10441（群晖官方初步指向的头号元凶）</h3><p>群晖官方初步排查认为攻击者利用了 <strong>CVE-2024-10441</strong>（CVSS 9.8，2024 年 12 月已修补）。该漏洞让攻击者无需任何账号密码就能从公网直达 DSM 底层——这也解释了为什么<strong>两步验证、强密码、改端口全都拦不住</strong>。</p><h3 id="入口二：2026-年-9-月披露的两个高危漏洞"><a href="#入口二：2026-年-9-月披露的两个高危漏洞" class="headerlink" title="入口二：2026 年 9 月披露的两个高危漏洞"></a>入口二：2026 年 9 月披露的两个高危漏洞</h3><p>360 的报告指出本轮攻击还使用了两个今年 9 月披露的漏洞（<strong>CVE-2026-13684、CVE-2026-13639</strong>，评分口径在不同来源中标注为 9.8–10.0）。相关补丁已包含在较新的 DSM 中，但<strong>没打补丁的设备仍可被直接攻破</strong>。</p><h3 id="入口三：套件与容器"><a href="#入口三：套件与容器" class="headerlink" title="入口三：套件与容器"></a>入口三：套件与容器</h3><ul><li><strong>原生套件</strong>：群晖安全公告 <strong>Synology-SA-26:14</strong> 涉及 PHP 核心 RCE（<strong>CVE-2026-109618、CVE-2026-109619</strong>），直接影响 <strong>MailStation、Synology Calendar</strong> 等套件——只升级 DSM 系统本体、不升级套件，入口依然敞着</li><li><strong>容器链路</strong>：很多人在 Container Manager 里跑 GitLab、Confluence 等自建服务并把端口映射到公网。GitLab 的未授权 RCE（<strong>CVE-2026-110264、CVE-2026-97229</strong>）被攻破后，攻击者利用高权限容器挂载目录或宿主机逃逸缺陷，把恶意拉取脚本写进 Linux 底层的 <strong><code>/etc/cron.d/</code> 定时任务</strong>里静默潜伏</li></ul><hr><h2 id="破除三个安全错觉"><a href="#破除三个安全错觉" class="headerlink" title="破除三个安全错觉"></a>破除三个安全错觉</h2><p>这次事件最有价值的部分，是它逐一击碎了几个被广泛相信的「安全常识」：</p><h3 id="错觉一：「我升到最新-DSM-7-4-1-了，肯定没事」"><a href="#错觉一：「我升到最新-DSM-7-4-1-了，肯定没事」" class="headerlink" title="错觉一：「我升到最新 DSM 7.4.1 了，肯定没事」"></a>错觉一：「我升到最新 DSM 7.4.1 了，肯定没事」</h3><p>Solar 团队公布的受害设备中，就有运行 <strong>DSM 7.4.1-90080 Update 1</strong> 的设备。原因有两个：一是<strong>升级前就已被人植入 <code>/etc/cron.d/</code> 定时任务后门</strong>，升级不会清掉它，重启后照样继续加密；二是只升了系统本体，<strong>套件中心里的 PHP、日历等高危套件没升</strong>。所以「最新系统」不等于「已修复」。</p><h3 id="错觉二：「我开了两步验证、强密码、禁了-SSH、改了端口」"><a href="#错觉二：「我开了两步验证、强密码、禁了-SSH、改了端口」" class="headerlink" title="错觉二：「我开了两步验证、强密码、禁了 SSH、改了端口」"></a>错觉二：「我开了两步验证、强密码、禁了 SSH、改了端口」</h3><p>这些防的是<strong>登录</strong>，而这次利用的是<strong>认证前漏洞</strong>——请求还没走到登录环节，攻击就已经完成。2FA 在这里一点用没有。</p><h3 id="错觉三：「我没有-IPv4-公网-IP，只开了-IPv6，应该安全」"><a href="#错觉三：「我没有-IPv4-公网-IP，只开了-IPv6，应该安全」" class="headerlink" title="错觉三：「我没有 IPv4 公网 IP，只开了 IPv6，应该安全」"></a>错觉三：「我没有 IPv4 公网 IP，只开了 IPv6，应该安全」</h3><p><strong>IPv6 也是公网。</strong> 只要设备能从外网直达，攻击面就在。评论区的实际受害者里就有只开 IPv6 的。</p><hr><h2 id="中招后的黄金一小时"><a href="#中招后的黄金一小时" class="headerlink" title="中招后的黄金一小时"></a>中招后的黄金一小时</h2><p>这一节请务必按顺序操作。<strong>核心原则：断外网、保电源、保内存。</strong></p><h3 id="第-1-步：立刻切断外网，但不要断电"><a href="#第-1-步：立刻切断外网，但不要断电" class="headerlink" title="第 1 步：立刻切断外网，但不要断电"></a>第 1 步：立刻切断外网，但不要断电</h3><ul><li>拔掉外网网线 &#x2F; 在路由器端阻断该 NAS 的所有外网连接</li><li><strong>保留局域网连接和设备电源</strong></li></ul><p>目的是阻止脚本回传和二次破坏，同时保住内存里的密钥。</p><h3 id="第-2-步：绝对不要做的事"><a href="#第-2-步：绝对不要做的事" class="headerlink" title="第 2 步：绝对不要做的事"></a>第 2 步：绝对不要做的事</h3><ul><li>❌ <strong>不要重启、不要关机</strong>——内存中的会话主密钥会永久丢失</li><li>❌ <strong>不要 <code>kill -9</code> 强杀可疑进程</strong>——同理</li><li>❌ <strong>不要重装系统、不要初始化硬盘、不要删除勒索信</strong>——这些都是取证与恢复的依据</li></ul><h3 id="第-3-步：冻结进程、导出内存"><a href="#第-3-步：冻结进程、导出内存" class="headerlink" title="第 3 步：冻结进程、导出内存"></a>第 3 步：冻结进程、导出内存</h3><p>在本地局域网 SSH 登录 NAS，用 <code>kill -STOP &lt;PID&gt;</code> <strong>暂停</strong>（不是杀死）可疑加密进程（如 <code>libgld</code>、<code>qnetd</code>），然后导出完整的运行内存镜像。</p><h3 id="第-4-步：从内存提取密钥、解密文件"><a href="#第-4-步：从内存提取密钥、解密文件" class="headerlink" title="第 4 步：从内存提取密钥、解密文件"></a>第 4 步：从内存提取密钥、解密文件</h3><p>社区开发者 <strong>@soimy</strong>（V2EX ID Mayday9421）在 LINUX DO 直播完成了这套自救：从 16GiB 内存镜像中提取出 <strong>16 字节 IV + 32 字节 AES-256-CBC 主密钥（共 48 字节会话材料）</strong>，用它解开文件尾部 588 字节里的 ChaCha8 文件密钥，<strong>逐字节无损恢复</strong>了 49GiB 的 GitLab 仓库与设计文档。</p><p>他已把完整取证流程与解密脚本开源：<strong>GitHub 仓库 <code>soimy/c3rb3r-rescue</code></strong>，社区里已有多个未关机的受害者借此 100% 恢复数据。</p><h3 id="如果已经重启-关机了怎么办"><a href="#如果已经重启-关机了怎么办" class="headerlink" title="如果已经重启&#x2F;关机了怎么办"></a>如果已经重启&#x2F;关机了怎么办</h3><p>内存里的主密钥已经丢失，社区路径走不通，只能：从异地备份 &#x2F; Btrfs 快照恢复；保留勒索信与日志等待官方进一步方案；<strong>不建议支付赎金</strong>——没有任何付钱必然拿回数据的保证。</p><hr><h2 id="未中招：今晚就做的加固清单"><a href="#未中招：今晚就做的加固清单" class="headerlink" title="未中招：今晚就做的加固清单"></a>未中招：今晚就做的加固清单</h2><h3 id="1-立即关闭所有公网暴露面"><a href="#1-立即关闭所有公网暴露面" class="headerlink" title="1. 立即关闭所有公网暴露面"></a>1. 立即关闭所有公网暴露面</h3><ul><li>路由器上<strong>关闭端口转发、UPnP、IPv6 入站</strong></li><li>停用 <strong>QuickConnect</strong>、<strong>DDNS 直连</strong>、<strong>Cloudflare Tunnel</strong>、FRP 等一切把 DSM 暴露到公网的方式</li><li>远程访问统一改用 <strong>VPN 组网</strong>：Tailscale、WireGuard、ZeroTier、NetBird、Headscale 任选其一——核心是「必须先授权进网络，服务本身永不暴露公网」</li></ul><h3 id="2-排查系统是否已被潜伏"><a href="#2-排查系统是否已被潜伏" class="headerlink" title="2. 排查系统是否已被潜伏"></a>2. 排查系统是否已被潜伏</h3><p>检查这些位置有没有你不认识的条目：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/etc/cron.d/</span><br><span class="line">/etc/crontab</span><br><span class="line">/var/spool/cron/crontabs/</span><br></pre></td></tr></table></figure><p>同时检查 DSM 里的「计划任务」、未知管理员账号、异常登录记录。发现可疑条目先<strong>记录证据</strong>再处理。</p><h3 id="3-更新系统与套件（两者都要）"><a href="#3-更新系统与套件（两者都要）" class="headerlink" title="3. 更新系统与套件（两者都要）"></a>3. 更新系统与套件（两者都要）</h3><ul><li>DSM 升到官方建议的最低安全版本（见下表）</li><li><strong>套件中心里的所有套件</strong>（尤其 PHP、MailStation、Calendar、Synology Drive）全部升级</li><li>Container Manager 里的容器镜像也要更新，别再让 GitLab 之类服务裸奔在公网</li></ul><h3 id="4-停掉同步类任务，避免污染备份"><a href="#4-停掉同步类任务，避免污染备份" class="headerlink" title="4. 停掉同步类任务，避免污染备份"></a>4. 停掉同步类任务，避免污染备份</h3><p>确认安全之前，<strong>暂停 Hyper Backup、Cloud Sync、Synology Drive 等同步作业</strong>——勒索文件一旦同步上去，会把云端健康备份覆盖掉。</p><h3 id="5-重构备份体系（这次最痛的教训）"><a href="#5-重构备份体系（这次最痛的教训）" class="headerlink" title="5. 重构备份体系（这次最痛的教训）"></a>5. 重构备份体系（这次最痛的教训）</h3><p>同机备份目录在本次事件中<strong>被一并加密</strong>，等于没有备份。正确姿势：</p><ul><li><strong>Btrfs 不可变快照</strong>：快照要开、要锁，让加密进程改不动</li><li><strong>异地 + 离线冷备</strong>：至少一份不联网、不同物理位置的备份</li><li>遵循 3-2-1 原则：3 份数据、2 种介质、1 份异地</li></ul><hr><h2 id="官方回应与补丁版本表"><a href="#官方回应与补丁版本表" class="headerlink" title="官方回应与补丁版本表"></a>官方回应与补丁版本表</h2><p>群晖已确认用户数据被加密并发布安全公告，给出了各分支的最低安全版本：</p><table><thead><tr><th align="left">系统分支</th><th align="left">最低安全版本</th></tr></thead><tbody><tr><td align="left">DSM 6.2</td><td align="left">6.2.4-25556-8 或更高</td></tr><tr><td align="left">DSM 7.1</td><td align="left">7.1.1-42962-7 或更高</td></tr><tr><td align="left">DSM 7.2</td><td align="left">7.2-64570-4 或更高</td></tr><tr><td align="left">DSM 7.2.1</td><td align="left">7.2.1-69057-6 或更高</td></tr><tr><td align="left">DSM 7.2.2</td><td align="left">7.2.2-72806-1 或更高</td></tr><tr><td align="left">BeeStation Manager (BSM)</td><td align="left">1.1-65374 或更高</td></tr><tr><td align="left">Synology Unified Controller</td><td align="left">3.1.4-23079 或更高</td></tr></tbody></table><blockquote><p>注意：有用户反馈<strong>版本高于官方建议仍然中招</strong>，Solar 团队也表示入侵入口仍在分析、不排除存在未知漏洞。所以**「达标」只是必要条件，不等于安全**——关闭公网暴露才是根本。</p></blockquote><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><p><strong>Q：只开 QuickConnect、不开端口映射，安全吗？</strong><br>不算安全。QuickConnect 的实际链路仍可能把服务暴露到公网，本次事件中就有通过此类方式中招的讨论。最稳的方案是 VPN 组网。</p><p><strong>Q：前面挂了 WAF &#x2F; 反向代理能防住吗？</strong><br>防不住认证前 RCE。WAF 拦的是已知特征，而漏洞利用请求对代理来说就是一条正常 HTTP 请求。</p><p><strong>Q：黑群晖受影响吗？</strong><br>受影响。漏洞在 DSM 本体与套件里，和硬件来源无关；而且黑群晖往往无法及时拿到官方补丁，风险更高。</p><p><strong>Q：付 0.085 BTC 能拿回数据吗？</strong><br>不建议。没有任何保证，且会助长攻击；未关机的情况下优先走内存提密钥的免费路径。</p><p><strong>Q：已经关了 NAS 两天，还有希望吗？</strong><br>先确认有没有 Btrfs 快照或异地备份；同时关注官方与社区后续是否公布新的恢复方案。</p><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>这次事件给所有自建服务的人上了一课，结论其实很朴素：</p><ol><li><strong>NAS 不该以任何形式暴露在公网</strong>——不是改端口、不是 2FA、不是 WAF，而是根本不暴露，用 VPN 组网</li><li><strong>漏洞修补要连套件一起打</strong>，容器镜像同样要维护，「系统最新」是错觉</li><li><strong>同机备份等于没有备份</strong>，必须有不可变快照和离线异地副本</li><li><strong>真中招了先保电源保内存</strong>，那 48 字节可能是你唯一的免费出路</li></ol><p>群晖官方公告、社区救援工具都还在更新，事态没有完全收敛。我把这次事件整理成文，希望帮到正在自查或刚中招的人——尤其是那句最容易被忽略的提醒：<strong>别急着拔电源。</strong></p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.360.cn/n/13055.html">Cerber 勒索攻击群晖 NAS 事件预警（360 安全资讯）</a></li><li><a href="https://www.appinn.com/synology-nas-ransomware-2026/">群晖 NAS 遭勒索病毒攻击：最新 DSM 版本也有受害报告（小众软件）</a></li><li><a href="https://news.qq.com/rain/a/20261030A06A9Y00">速速自查！群晖 NAS 惊爆大规模勒索攻击：官方证实呼吁立即更新（腾讯新闻&#x2F;快科技）</a></li><li><a href="https://afengblog.com/blog/synology-nas-c3rb3r-ransomware-rescue-guide.html">群晖 NAS 突发 .L0CK3D 勒索病毒，内存提取密钥自救与加固全指南（AFeng Blog）</a></li><li><a href="https://zhuanlan.zhihu.com/p/2099089476924590077">【勒索预警】群晖 NAS 最新版遭勒索病毒攻击（知乎·Solar 应急响应团队）</a></li><li><a href="https://linux.do/t/topic/3090953">群晖疑出现 0day 漏洞，28-29 日凌晨大量 NAS 用户集体中招（LINUX DO）</a></li><li><a href="https://github.com/soimy/c3rb3r-rescue">soimy&#x2F;c3rb3r-rescue：社区开源自救工具（GitHub）</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/10/30/synology-c3rb3r-ransomware/</id>
    <link href="https://blog.ztmss.com/2026/10/30/synology-c3rb3r-ransomware/"/>
    <published>2026-10-30T07:00:00.000Z</published>
    <summary>2026年10月28日起，全球大量群晖 NAS 用户遭 C3RB3R 勒索病毒攻击，文件被加密为 .L0CK3D 后缀并留下 read-me3.txt 勒索信，最新 DSM 7.4.1 与开启两步验证的设备同样中招。本文梳理事件时间线、三个免登录入侵入口、为什么 2FA 防不住，以及在不断电前提下从内存提取密钥免费恢复数据的黄金一小时自救流程，附官方补丁版本表与完整加固清单。</summary>
    <title>群晖 NAS 遭 C3RB3R 勒索病毒大规模攻击：.L0CK3D 加密、最新 DSM 也中招，自查与自救全指南</title>
    <updated>2026-10-30T06:34:39.767Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="Cloudflare Workers" scheme="https://blog.ztmss.com/tags/Cloudflare-Workers/"/>
    <category term="CF-ERP" scheme="https://blog.ztmss.com/tags/CF-ERP/"/>
    <category term="进销存" scheme="https://blog.ztmss.com/tags/%E8%BF%9B%E9%94%80%E5%AD%98/"/>
    <category term="D1" scheme="https://blog.ztmss.com/tags/D1/"/>
    <category term="开源项目" scheme="https://blog.ztmss.com/tags/%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>开店做生意，进货、卖货、记账三件事躲不开。市面上的进销存软件要么按年收费，要么数据锁在别人服务器里，要么功能重到小店铺用不上。</p><p><strong>CF-ERP</strong> 是一个开源（MIT 协议）的无服务器进销存系统，整套跑在 <strong>Cloudflare Workers + D1（SQLite）</strong> 上——没有服务器、没有月费，Cloudflare 免费额度对个人 &#x2F; 小微企业 &#x2F; 店铺来说<strong>完全够用</strong>。后端 Hono 框架，前端 Vue 3 免构建单页应用，单 Worker 同时承载 API、静态页面和定时备份任务。</p><ul><li><strong>项目地址</strong>：<a href="https://github.com/love-ztm/cf-erp">https://github.com/love-ztm/cf-erp</a></li><li><strong>在线演示</strong>：<a href="https://ycerp.us.ci/">https://ycerp.us.ci</a>（演示账号 <code>admin</code> &#x2F; <code>admin123</code>，演示环境数据可能被其他体验者修改，别存真实业务数据）</li><li><strong>开源协议</strong>：MIT</li></ul><hr><h2 id="功能特点"><a href="#功能特点" class="headerlink" title="功能特点"></a>功能特点</h2><table><thead><tr><th align="left">模块</th><th align="left">功能说明</th></tr></thead><tbody><tr><td align="left">📊 <strong>数据看板</strong></td><td align="left">销售额（已扣优惠）、核心毛利与毛利率、采购支出、资产池账户总余额、应收应付账款、低库存智能预警、最近业务动态</td></tr><tr><td align="left">📦 <strong>商品管理</strong></td><td align="left">商品增删改查、分类、条码、期初库存、建议售价、低库存阈值、服务类商品（不跟踪库存）、成本手动锁定、商品停用</td></tr><tr><td align="left">📥 <strong>采购入库</strong></td><td align="left">多明细采购单、商品输入即搜、行内一键新增商品、整单优惠、结算账户关联、供应商欠款自动记账、采购退货</td></tr><tr><td align="left">📤 <strong>销售出库</strong></td><td align="left">多明细销售单、实时毛利预览、库存不足强拦截、赊销自动挂客户欠款、销售退货（冲减欠款&#x2F;退回账户）、单据直接修改</td></tr><tr><td align="left">🗄️ <strong>库存管理</strong></td><td align="left">实时库存统计、库存价值评估、盘盈盘亏手动调整、商品全生命周期库存流水（进出方向与单价追溯）</td></tr><tr><td align="left">💰 <strong>资金记账</strong></td><td align="left">多结算账户（现金&#x2F;微信&#x2F;支付宝&#x2F;银行卡等）、收款单核销欠款、付款单、其他收支管理、资金日记账</td></tr><tr><td align="left">📈 <strong>统计报表</strong></td><td align="left">商品毛利报表（退货自动反冲 + 整单优惠扣减）、按日毛利趋势、进销存期初期末汇总、往来欠款表、其他收支明细，全部支持 CSV 导出与小票打印</td></tr><tr><td align="left">👥 <strong>往来单位</strong></td><td align="left">供应商与客户档案、期初欠款、实时欠款余额与预收&#x2F;预付状态、联系人及地址管理</td></tr><tr><td align="left">⚙️ <strong>系统设置</strong></td><td align="left">系统标题与公司信息自定义、多用户权限管理（次级用户与权限勾选）、WebDAV 自动备份配置、全量备份下载与还原、双重验证安全清库</td></tr></tbody></table><hr><h2 id="技术架构"><a href="#技术架构" class="headerlink" title="技术架构"></a>技术架构</h2><p>整个系统的架构非常克制——<strong>一个 Worker 打天下</strong>：</p><table><thead><tr><th align="left">层</th><th align="left">技术</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">计算</td><td align="left">Cloudflare Workers</td><td align="left">Hono 路由，API + 静态资源托管 + Cron 三合一</td></tr><tr><td align="left">数据</td><td align="left">Cloudflare D1</td><td align="left">SQLite 数据库，11 张表，绑定名 <code>DB</code></td></tr><tr><td align="left">前端</td><td align="left">Vue 3（CDN 引入）</td><td align="left">免构建单页应用，<code>public/</code> 目录直出，暗黑科技感 UI，适配桌面与手机</td></tr><tr><td align="left">认证</td><td align="left">SHA-256 + HMAC Session Cookie</td><td align="left">密码哈希存储，会话签名防篡改，有效期 7 天</td></tr><tr><td align="left">定时</td><td align="left">Workers Cron Triggers</td><td align="left">每天北京时间凌晨 2 点自动执行 WebDAV 远程备份</td></tr></tbody></table><p>几个架构细节值得一提：</p><ul><li><strong>静态资源与 API 同源</strong>：<code>wrangler.jsonc</code> 里配置 <code>run_worker_first: [&quot;/api/*&quot;]</code>，API 请求先进 Worker，其余路径直接走静态资源，未命中回退 <code>index.html</code>（SPA 路由）</li><li><strong>schema 内嵌</strong>：<code>rules</code> 把 <code>schema.sql</code> 以文本方式打包进 Worker，每个 API 请求前<strong>幂等</strong>执行 <code>ensureSchema</code>——表结构不存在就自动建，列升级自动迁移，部署后零初始化步骤</li><li><strong>默认管理员自举</strong>：users 表为空时自动创建默认管理员（可用 <code>ADMIN_PASSWORD</code> 变量或 Secret 覆盖初始密码）</li></ul><h3 id="成本核算：移动加权平均法"><a href="#成本核算：移动加权平均法" class="headerlink" title="成本核算：移动加权平均法"></a>成本核算：移动加权平均法</h3><p>进销存系统的灵魂在成本。CF-ERP 采用<strong>移动加权平均法</strong>：</p><ul><li>每次采购入库时，按 <code>(原库存 × 原均价 + 新入库量 × 新进价) ÷ 总库存</code> 重算该商品的移动加权成本</li><li>销售出库时，<strong>即时快照固化</strong>当时的成本均价——历史订单的毛利不随日后进价波动而变化</li><li>支持在商品管理中手动指定并<strong>锁定成本均价</strong>（锁定后不随采购流水变动）</li><li>任何历史单据修改或删除后，系统<strong>自动全量重放重算</strong>，确保账实严格相符</li></ul><p>这套机制保证了「商品毛利报表」里的数字是可信赖的，而不是简单用售价减个大概成本。</p><hr><h2 id="部署教程"><a href="#部署教程" class="headerlink" title="部署教程"></a>部署教程</h2><p>部署是一个<strong>全新空系统</strong>（含默认管理员 <code>admin</code> &#x2F; <code>admin123</code>，不含任何业务数据），全程四步，五分钟内完成。</p><h3 id="第-1-步：登录-Cloudflare-并创建-D1-数据库"><a href="#第-1-步：登录-Cloudflare-并创建-D1-数据库" class="headerlink" title="第 1 步：登录 Cloudflare 并创建 D1 数据库"></a>第 1 步：登录 Cloudflare 并创建 D1 数据库</h3><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npx wrangler login</span><br><span class="line">npx wrangler d1 create cf-erp</span><br></pre></td></tr></table></figure><p><code>d1 create</code> 会输出一个 <code>database_id</code>。</p><h3 id="第-2-步：填入-database-id"><a href="#第-2-步：填入-database-id" class="headerlink" title="第 2 步：填入 database_id"></a>第 2 步：填入 database_id</h3><p>把上一步拿到的 <code>database_id</code> 填进项目根目录的 <code>wrangler.jsonc</code>：</p><figure class="highlight jsonc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">&quot;d1_databases&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">  <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;binding&quot;</span><span class="punctuation">:</span> <span class="string">&quot;DB&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;database_name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;cf-erp&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;database_id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&lt;你的 database_id&gt;&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">]</span></span><br></pre></td></tr></table></figure><h3 id="第-3-步：部署"><a href="#第-3-步：部署" class="headerlink" title="第 3 步：部署"></a>第 3 步：部署</h3><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run deploy</span><br></pre></td></tr></table></figure><p>Wrangler 会自动完成 Worker 打包、D1 绑定和静态资源上传，输出你的 Workers 域名（形如 <code>cf-erp.&lt;你的子域&gt;.workers.dev</code>）。</p><h3 id="第-4-步：登录并初始化设置"><a href="#第-4-步：登录并初始化设置" class="headerlink" title="第 4 步：登录并初始化设置"></a>第 4 步：登录并初始化设置</h3><p>访问 Workers 域名，用 <code>admin</code> &#x2F; <code>admin123</code> 登录，然后进「系统设置」：</p><ul><li><strong>公司与系统配置</strong>：修改店铺名称、电话、地址、打印页脚</li><li><strong>用户账号管理</strong>：<strong>立即修改默认密码</strong>，按需添加员工&#x2F;销售账号并勾选权限</li><li><strong>数据备份与恢复</strong>：如有历史数据，上传备份文件一键还原</li></ul><h3 id="两点建议"><a href="#两点建议" class="headerlink" title="两点建议"></a>两点建议</h3><p><strong>绑定自定义域名</strong>：workers.dev 域名在国内部分网络环境访问不稳定，建议在 Cloudflare 后台给 Worker 绑一个自有域名（托管在同一 Cloudflare 账号下的域名加一条 CNAME 即可），稳定且顺手。</p><p><strong>用 Secret 管理初始密码</strong>：<code>wrangler.jsonc</code> 里的 <code>ADMIN_PASSWORD</code> 是明文变量，正式使用建议改用 Secret（Secret 会覆盖 vars）：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx wrangler secret put ADMIN_PASSWORD</span><br></pre></td></tr></table></figure><h3 id="本地开发与测试"><a href="#本地开发与测试" class="headerlink" title="本地开发与测试"></a>本地开发与测试</h3><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">npm install</span><br><span class="line">npm run dev              <span class="comment"># 本地服务 http://127.0.0.1:8787</span></span><br><span class="line">npm run db:init:<span class="built_in">local</span>    <span class="comment"># 手动初始化本地 D1（一般不需要，会自动建表）</span></span><br><span class="line">node <span class="built_in">test</span>/api.test.mjs   <span class="comment"># 跑自动化集成测试</span></span><br></pre></td></tr></table></figure><p>项目自带 <strong>61 个集成测试用例</strong>，覆盖登录鉴权、采购&#x2F;销售&#x2F;退货、欠款核销、成本重算等核心链路，我本地实测 <strong>61 通过 0 失败</strong>——对开源 ERP 来说，这个测试密度是数据可靠性的底气。</p><hr><h2 id="数据备份：双保险"><a href="#数据备份：双保险" class="headerlink" title="数据备份：双保险"></a>数据备份：双保险</h2><p>ERP 数据是最不能丢的数据，CF-ERP 提供两层备份：</p><p><strong>本地全量 JSON 备份</strong>：系统设置里一键下载全量备份（JSON 格式），随时可上传还原，适合手动定期存档。</p><p><strong>WebDAV 远程定时备份</strong>：配置一个 WebDAV 网盘（坚果云 &#x2F; 群晖 &#x2F; AList 等都支持），填入地址、账号、密码和远程目录后，Workers Cron 会在每天北京时间凌晨 2 点自动把全量备份推上去。备份 URL、用户名、密码、远程目录和 cron 时间都可以在系统设置里调整，面板会显示上次备份时间和状态。</p><p>顺带说一句：这个自动备份本质上就是 Workers 的 <code>scheduled</code> 入口——部署时 <code>wrangler.jsonc</code> 里的 <code>triggers.crons</code>（<code>0 18 * * *</code> UTC 即北京凌晨 2 点）就是它的触发器。</p><hr><h2 id="使用建议"><a href="#使用建议" class="headerlink" title="使用建议"></a>使用建议</h2><ul><li><strong>适合谁</strong>：个人副业、小微店铺、需要轻量记账的小团队——不想为 ERP 付月费、又希望数据在自己账号里自主可控的用户</li><li><strong>优点</strong>：零成本、部署极简、免运维（Cloudflare 托管一切）、数据可导出可迁移、移动加权成本核算专业可靠</li><li><strong>边界</strong>：D1 免费额度（每天 10 万行读、1 万行写）对单店铺场景绰绰有余，但如果是高频批量出单的团队，建议留意 Cloudflare 用量面板</li><li><strong>安全提醒</strong>：部署后第一件事就是改默认密码；如果绑定了自定义域名，建议在 Cloudflare 后台开启 Access 或至少启用强密码策略</li></ul><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="部署后打不开-提示-500？"><a href="#部署后打不开-提示-500？" class="headerlink" title="部署后打不开 &#x2F; 提示 500？"></a>部署后打不开 &#x2F; 提示 500？</h3><p>先确认 <code>wrangler.jsonc</code> 里的 <code>database_id</code> 是否已经替换成第 1 步 <code>d1 create</code> 输出的真实 ID。D1 未绑定正确时 API 会报错，页面可以加载但登录失败。</p><h3 id="忘记-admin-密码怎么办？"><a href="#忘记-admin-密码怎么办？" class="headerlink" title="忘记 admin 密码怎么办？"></a>忘记 admin 密码怎么办？</h3><p>用 <code>wrangler d1 execute cf-erp --remote --command &quot;DELETE FROM users&quot;</code> 清空用户表，重新访问系统时会用 <code>ADMIN_PASSWORD</code>（或默认 <code>admin123</code>）自动重建管理员——注意这会删除所有用户账号，业务数据仍在其他表里。</p><h3 id="能导入之前用其他软件的数据吗？"><a href="#能导入之前用其他软件的数据吗？" class="headerlink" title="能导入之前用其他软件的数据吗？"></a>能导入之前用其他软件的数据吗？</h3><p>可以先手工整理成商品&#x2F;客户 CSV 借助界面录入，或者参考项目 <code>tools/</code> 目录里的历史数据迁移脚本；也可以备份 JSON 后直接改 JSON 再还原。</p><h3 id="手机上能用吗？"><a href="#手机上能用吗？" class="headerlink" title="手机上能用吗？"></a>手机上能用吗？</h3><p>前端是响应式设计，手机浏览器直接访问即可完成日常开单、查库存、看报表，小票打印也支持。</p><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>CF-ERP 把「进销存」这个传统上要么付费、要么自己买服务器部署的软件品类，压缩进了一个 Cloudflare 免费套餐里：四条命令部署、61 个测试兜底、移动加权成本核算、WebDAV 自动备份。对于正被记账软件订阅费困扰的小商家，或者想找个真实项目学习 Workers + D1 全栈开发的开发者，它都值得一试。</p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://github.com/love-ztm/cf-erp">CF-ERP GitHub 仓库</a></li><li><a href="https://ycerp.us.ci/">CF-ERP 在线演示</a></li><li><a href="https://hono.dev/">Hono 框架官网</a></li><li><a href="https://developers.cloudflare.com/workers/">Cloudflare Workers 文档</a></li><li><a href="https://developers.cloudflare.com/d1/">Cloudflare D1 文档</a></li><li><a href="https://developers.cloudflare.com/workers/wrangler/commands/">Wrangler CLI 文档</a></li><li><a href="https://cn.vuejs.org/">Vue 3 官方文档</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/09/26/cf-erp-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/09/26/cf-erp-deployment-tutorial/"/>
    <published>2026-09-26T15:30:00.000Z</published>
    <summary>CF-ERP 是一套跑在 Cloudflare Workers + D1 上的无服务器进销存系统，个人和小微店铺用免费额度即可长期使用。本文介绍它的九大功能模块、移动加权成本核算机制，并给出从创建 D1 数据库到部署上线只需四步的完整部署教程，附本地开发、自动化测试与 WebDAV 自动备份配置方法。</summary>
    <title>CF-ERP 部署教程：Cloudflare Workers + D1 免费搭建进销存系统，个人和小微店铺零成本记账</title>
    <updated>2026-09-30T02:23:33.151Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="ZCode" scheme="https://blog.ztmss.com/tags/ZCode/"/>
    <category term="AI智能体" scheme="https://blog.ztmss.com/tags/AI%E6%99%BA%E8%83%BD%E4%BD%93/"/>
    <category term="C盘清理" scheme="https://blog.ztmss.com/tags/C%E7%9B%98%E6%B8%85%E7%90%86/"/>
    <category term="Windows" scheme="https://blog.ztmss.com/tags/Windows/"/>
    <category term="磁盘迁移" scheme="https://blog.ztmss.com/tags/%E7%A3%81%E7%9B%98%E8%BF%81%E7%A7%BB/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>C 盘空间告急大概是 Windows 老用户最持久的痛：180GB 的系统盘，不知不觉就红了。手动找大文件像寻宝——资源管理器不会告诉你哪些文件夹在偷偷长大，设置里的存储分析只给个粗略分类，真正的「空间大户」往往藏在 AppData 这种普通用户一辈子不会点开的角落。</p><p>我的机器就是个典型例子：<strong>C 盘 180GB，已用 117GB</strong>，资源管理器里翻半天也不知道钱花哪儿了。而用 ZCode 这类智能体做这件事的思路完全不同——它擅长的不正是「遍历、统计、分析、批量执行」吗？这篇文章把我查资料 + 结合实际整理出的<strong>四步方案</strong>完整记录下来：体检 → 清理 → 迁移 → 固化。</p><blockquote><p>核心原则先放在最前面：<strong>智能体负责找和算，人负责决定删什么</strong>。全程建议使用 Ask before changes（默认）模式，每一批删除操作前都要过目确认。</p></blockquote><hr><h2 id="先搞清楚：C-盘的钱都花哪儿了"><a href="#先搞清楚：C-盘的钱都花哪儿了" class="headerlink" title="先搞清楚：C 盘的钱都花哪儿了"></a>先搞清楚：C 盘的钱都花哪儿了</h2><p>动手之前，先了解一下 Windows 上真正吃空间的几类东西（这是清理方案的知识基础）：</p><table><thead><tr><th align="left">类别</th><th align="left">典型位置</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><strong>休眠文件</strong></td><td align="left"><code>C:\hiberfil.sys</code></td><td align="left">约为内存大小的 40%，休眠功能开着就一直占着</td></tr><tr><td align="left"><strong>虚拟内存</strong></td><td align="left"><code>C:\pagefile.sys</code></td><td align="left">默认放 C 盘，大小可到数 GB 甚至十几 GB</td></tr><tr><td align="left"><strong>系统组件仓库</strong></td><td align="left"><code>C:\Windows\WinSxS</code></td><td align="left">装补丁积累的旧版本组件，只会越长越大</td></tr><tr><td align="left"><strong>Windows 更新缓存</strong></td><td align="left"><code>C:\Windows\SoftwareDistribution\Download</code></td><td align="left">更新安装包下载缓存，几个 GB 很常见</td></tr><tr><td align="left"><strong>系统还原点</strong></td><td align="left">卷影副本</td><td align="left">保留时间越长占得越多</td></tr><tr><td align="left"><strong>Windows.old</strong></td><td align="left"><code>C:\Windows.old</code></td><td align="left">大版本升级后的旧系统备份，轻松 20GB+</td></tr><tr><td align="left"><strong>用户级缓存</strong></td><td align="left"><code>AppData\Local</code> 下各应用</td><td align="left">浏览器、开发工具链、游戏平台都在这</td></tr><tr><td align="left"><strong>聊天工具文件</strong></td><td align="left">微信 &#x2F; QQ 的 Documents 目录</td><td align="left">微信几年能轻松吃掉几十 GB</td></tr><tr><td align="left"><strong>开发缓存</strong></td><td align="left">npm &#x2F; pip &#x2F; Gradle &#x2F; Maven &#x2F; Cargo 等</td><td align="left">做开发的都知道，这些缓存是无底洞</td></tr><tr><td align="left"><strong>WSL &#x2F; Docker</strong></td><td align="left"><code>ext4.vhdx</code> 虚拟磁盘</td><td align="left">只增不减是出了名的，删了文件 vhdx 也不缩小</td></tr></tbody></table><p>普通用户卡在 C 盘的往往是<strong>聊天工具文件 + 浏览器缓存 + 更新缓存</strong>；开发者还要再加<strong>包管理器缓存 + WSL 虚拟磁盘</strong>两条大项。这些正是下面清理和迁移的主战场。</p><hr><h2 id="用-ZCode-清理的正确姿势"><a href="#用-ZCode-清理的正确姿势" class="headerlink" title="用 ZCode 清理的正确姿势"></a>用 ZCode 清理的正确姿势</h2><p>在开始之前，先把「怎么指挥智能体」这件事说清楚，方法比命令本身重要。</p><h3 id="执行模式：用-Ask-before-changes"><a href="#执行模式：用-Ask-before-changes" class="headerlink" title="执行模式：用 Ask before changes"></a>执行模式：用 Ask before changes</h3><p>清理磁盘是典型的<strong>高风险批量删除</strong>场景。ZCode 默认的 <strong>Ask before changes</strong> 模式是这里唯一合理的选择：每条删除命令、每次文件改动都会先弹出确认，你逐项过目。熟练之后，可以把「只读的体检」放到 Edit automatically 下跑得快一点，但<strong>删除操作永远不要用 Full access 自动放行</strong>。</p><h3 id="让它先报告、后动手"><a href="#让它先报告、后动手" class="headerlink" title="让它先报告、后动手"></a>让它先报告、后动手</h3><p>一次好的清理会话分两个阶段，提示词里要显式分开：</p><p><strong>阶段一——只体检，不删除：</strong></p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">扫描 C 盘，找出占用空间最大的 20 个目录和最大的 10 个文件。</span><br><span class="line">重点覆盖：AppData\Local、用户 Documents、Windows 系统缓存目录、</span><br><span class="line">休眠文件和虚拟内存文件的大小。</span><br><span class="line">以表格输出：路径 / 大小 / 属于哪类（缓存/临时文件/聊天文件/系统文件）/</span><br><span class="line">是否适合安全清理。</span><br><span class="line">只读分析，不要删除任何东西。</span><br></pre></td></tr></table></figure><blockquote><p>小技巧：把「只读分析，不要删除任何东西」写进提示词，或者直接用 Plan mode，让第一轮彻底零风险。</p></blockquote><p><strong>阶段二——按清单清理：</strong></p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">根据上面的体检报告，只清理「缓存和临时文件」这一类：</span><br><span class="line">1. 逐项列出你打算删除的目录、预计释放空间、删除理由</span><br><span class="line">2. 我逐项确认后再执行</span><br><span class="line">3. 执行完重新统计 C 盘可用空间，对比清理前后的变化</span><br></pre></td></tr></table></figure><h3 id="用-Hook-给删除操作上保险"><a href="#用-Hook-给删除操作上保险" class="headerlink" title="用 Hook 给删除操作上保险"></a>用 Hook 给删除操作上保险</h3><p>如果经常做这类清理，可以给 ZCode 配一条 <strong>PreToolUse Hook</strong>：凡是命中 <code>rm</code>、<code>Remove-Item</code>、<code>del</code> 且参数里出现 <code>Windows</code>、<code>Program Files</code> 的删除命令，直接 deny。相当于给智能体的危险操作加了一道硬闸——具体写法见 ZCode 的 Hooks 配置（<code>~/.zcode/cli/config.json</code> 里 <code>hooks.enabled: true</code> 后加 <code>PreToolUse</code> 事件，<code>matcher</code> 匹配 Bash 工具，脚本里检查命令文本并返回非零退出码拦截）。</p><h3 id="空间不足时用目标模式闭环"><a href="#空间不足时用目标模式闭环" class="headerlink" title="空间不足时用目标模式闭环"></a>空间不足时用目标模式闭环</h3><p>清理是个「执行 → 验证 → 再执行」的循环，很适合目标模式：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/goal 在不卸载任何软件、不删除任何个人文件的前提下，</span><br><span class="line">把 C 盘可用空间提升 30GB 以上，所有删除操作逐项向我确认</span><br></pre></td></tr></table></figure><p>智能体会自己循环：体检 → 提方案 → 等确认 → 执行 → 复查 → 不够就找下一个目标——不用反复喊「继续」。</p><hr><h2 id="第一步：空间体检"><a href="#第一步：空间体检" class="headerlink" title="第一步：空间体检"></a>第一步：空间体检</h2><p>体检的目标是拿到一张「钱花哪儿了」的清单。让 ZCode 用命令行工具扫描，比图形界面快得多也细得多，例如：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 各盘剩余空间</span></span><br><span class="line"><span class="built_in">Get-PSDrive</span> <span class="literal">-PSProvider</span> FileSystem</span><br><span class="line"></span><br><span class="line"><span class="comment"># 指定目录总大小（对每个可疑目录执行）</span></span><br><span class="line"><span class="string">&quot;&#123;0:N2&#125; GB&quot;</span> <span class="operator">-f</span> ((<span class="built_in">Get-ChildItem</span> <span class="string">&quot;C:\Users\&lt;用户名&gt;\AppData\Local&quot;</span> <span class="literal">-Recurse</span> <span class="literal">-ErrorAction</span> SilentlyContinue |</span><br><span class="line">    <span class="built_in">Measure-Object</span> Length <span class="literal">-Sum</span>).Sum / <span class="number">1</span>GB)</span><br></pre></td></tr></table></figure><p>一次典型体检跑完，报告大概长这样（数字因机器而异，重点看结构）：</p><table><thead><tr><th align="left">路径</th><th align="left">大小</th><th align="left">分类</th><th align="left">可清理</th></tr></thead><tbody><tr><td align="left"><code>C:\Users\x\Documents\xwechat_files</code></td><td align="left">38 GB</td><td align="left">聊天文件</td><td align="left">迁移</td></tr><tr><td align="left"><code>C:\hiberfil.sys</code></td><td align="left">12 GB</td><td align="left">系统休眠文件</td><td align="left">视需求关闭</td></tr><tr><td align="left"><code>C:\Windows\SoftwareDistribution\Download</code></td><td align="left">6.2 GB</td><td align="left">更新缓存</td><td align="left">清理</td></tr><tr><td align="left"><code>C:\Users\x\AppData\Local\npm-cache</code></td><td align="left">5.1 GB</td><td align="left">开发缓存</td><td align="left">迁移</td></tr><tr><td align="left"><code>C:\Users\x\AppData\Local\Temp</code></td><td align="left">3.8 GB</td><td align="left">临时文件</td><td align="left">清理</td></tr><tr><td align="left"><code>C:\Users\x\AppData\Local\Docker</code></td><td align="left">22 GB</td><td align="left">WSL 虚拟磁盘</td><td align="left">压缩&#x2F;迁移</td></tr><tr><td align="left"><code>C:\Users\x\Downloads</code></td><td align="left">9 GB</td><td align="left">个人文件</td><td align="left">人工整理</td></tr></tbody></table><p>有了这张表，「空间去哪儿了」的谜底就揭开了——接下来的动作都有依据，而不是到处乱删。</p><hr><h2 id="第二步：安全清理（按风险分级）"><a href="#第二步：安全清理（按风险分级）" class="headerlink" title="第二步：安全清理（按风险分级）"></a>第二步：安全清理（按风险分级）</h2><p>ZCode 给出建议后，实际清理可以按下面的分级清单执行。<strong>让智能体按级别分批执行、每批确认一次</strong>，是最稳的节奏。</p><h3 id="零风险：临时文件与回收站"><a href="#零风险：临时文件与回收站" class="headerlink" title="零风险：临时文件与回收站"></a>零风险：临时文件与回收站</h3><table><thead><tr><th align="left">项目</th><th align="left">方法</th></tr></thead><tbody><tr><td align="left">用户临时文件</td><td align="left">删除 <code>%LocalAppData%\Temp</code> 下的内容（正在使用的文件会自动跳过）</td></tr><tr><td align="left">系统临时文件</td><td align="left"><code>C:\Windows\Temp</code>（需要管理员权限）</td></tr><tr><td align="left">回收站</td><td align="left"><code>Clear-RecycleBin -Force</code> 或右键清空</td></tr><tr><td align="left">缩略图&#x2F;DEX 缓存</td><td align="left">磁盘清理工具里的「缩略图」「DirectX 着色器缓存」</td></tr></tbody></table><p>一键方式（图形界面，同样是 ZCode 可以帮你调起的）：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cleanmgr /d C:</span><br></pre></td></tr></table></figure><h3 id="低风险：系统级缓存"><a href="#低风险：系统级缓存" class="headerlink" title="低风险：系统级缓存"></a>低风险：系统级缓存</h3><table><thead><tr><th align="left">项目</th><th align="left">方法</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><strong>Windows 更新缓存</strong></td><td align="left">管理员执行：<code>net stop wuauserv</code> → 清空 <code>SoftwareDistribution\Download</code> → <code>net start wuauserv</code></td><td align="left">已安装的更新不受影响，只删下载缓存</td></tr><tr><td align="left"><strong>组件仓库瘦身</strong></td><td align="left"><code>Dism.exe /Online /Cleanup-Image /StartComponentCleanup</code></td><td align="left">清 WinSxS 旧组件，微软官方支持的方式，跑一次可能要十几分钟</td></tr><tr><td align="left"><strong>系统还原点</strong></td><td align="left">系统属性 → 系统保护 → 配置 → 删除旧还原点 &#x2F; 调小上限</td><td align="left">保留最近一个即可</td></tr><tr><td align="left"><strong>Windows.old</strong></td><td align="left">设置 → 存储 → 临时文件 → 「以前的 Windows 安装」</td><td align="left">大版本升级 10 天后确认没问题再删，动辄 20GB+</td></tr></tbody></table><h3 id="需要确认：休眠文件与虚拟内存"><a href="#需要确认：休眠文件与虚拟内存" class="headerlink" title="需要确认：休眠文件与虚拟内存"></a>需要确认：休眠文件与虚拟内存</h3><p>这两项释放空间立竿见影，但改变系统行为，按需决定：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 关闭休眠 —— hiberfil.sys 立即消失（笔记本合盖不休眠，仍可正常关机睡眠）</span></span><br><span class="line">powercfg <span class="literal">-h</span> off</span><br><span class="line"></span><br><span class="line"><span class="comment"># 或者把休眠文件压到内存的 50%</span></span><br><span class="line">powercfg <span class="literal">-h</span> <span class="literal">-size</span> <span class="number">50</span></span><br></pre></td></tr></table></figure><p>虚拟内存迁移：系统属性 → 高级 → 性能设置 → 高级 → 虚拟内存 → 更改，把 C 盘的页面文件取消「自动管理」，改设到 D 盘（初始大小可以给物理内存的 1–1.5 倍）。一台 32GB 内存的机器，这一项就能给 C 盘腾出 10GB 以上。</p><h3 id="开发者专项：包管理器缓存"><a href="#开发者专项：包管理器缓存" class="headerlink" title="开发者专项：包管理器缓存"></a>开发者专项：包管理器缓存</h3><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">npm cache clean <span class="literal">--force</span></span><br><span class="line">pip cache purge</span><br></pre></td></tr></table></figure><p>不过对开发机来说，这些缓存<strong>删了还会长回来</strong>——真正的解法在第三步的迁移。</p><hr><h2 id="第三步：迁移到其他盘（治本）"><a href="#第三步：迁移到其他盘（治本）" class="headerlink" title="第三步：迁移到其他盘（治本）"></a>第三步：迁移到其他盘（治本）</h2><p>清理只能解决一时，迁移才是治本：<strong>让以后再产生的大文件直接落到 D 盘</strong>。假设 D 盘剩余空间充足，以下按收益从大到小。</p><h3 id="3-1-聊天工具文件（通常是最大单项）"><a href="#3-1-聊天工具文件（通常是最大单项）" class="headerlink" title="3.1 聊天工具文件（通常是最大单项）"></a>3.1 聊天工具文件（通常是最大单项）</h3><p>微信：设置 → 文件管理 → 更改目录，指到 <code>D:\WeChatFiles</code>，旧文件会提示迁移。QQ 同理。这一步经常能一次释放几十 GB，是普通用户收益最大的单项操作。</p><h3 id="3-2-包管理器缓存改位置"><a href="#3-2-包管理器缓存改位置" class="headerlink" title="3.2 包管理器缓存改位置"></a>3.2 包管理器缓存改位置</h3><p>删缓存是下策，改缓存目录是上策——以后所有缓存自动落 D 盘：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># npm</span></span><br><span class="line">npm config <span class="built_in">set</span> cache <span class="string">&quot;D:\dev-cache\npm&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># pip</span></span><br><span class="line">pip config <span class="built_in">set</span> global.cache<span class="literal">-dir</span> <span class="string">&quot;D:\dev-cache\pip&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># pnpm</span></span><br><span class="line">pnpm config <span class="built_in">set</span> store<span class="literal">-dir</span> <span class="string">&quot;D:\dev-cache\pnpm-store&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Yarn Classic</span></span><br><span class="line">yarn config <span class="built_in">set</span> cache<span class="literal">-folder</span> <span class="string">&quot;D:\dev-cache\yarn&quot;</span></span><br></pre></td></tr></table></figure><p>Gradle、Maven、Go、Cargo 走环境变量：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">GRADLE_USER_HOME = D:\dev-cache\gradle</span><br><span class="line">MAVEN 的 settings.xml 里 &lt;localRepository&gt;D:\dev-cache\maven&lt;/localRepository&gt;</span><br><span class="line">GOPATH / GOMODCACHE   = D:\dev-cache\go</span><br><span class="line">CARGO_HOME            = D:\dev-cache\cargo</span><br></pre></td></tr></table></figure><p>让 ZCode 做这件事很合适——它可以把上面所有配置一次性执行完，再各跑一次小下载验证新位置生效。</p><h3 id="3-3-Docker-Desktop-与-WSL"><a href="#3-3-Docker-Desktop-与-WSL" class="headerlink" title="3.3 Docker Desktop 与 WSL"></a>3.3 Docker Desktop 与 WSL</h3><p>Docker Desktop：Settings → Resources → Advanced → <strong>Disk image location</strong> 改到 D 盘，镜像数据整体搬家。</p><p>WSL 的虚拟磁盘（<code>ext4.vhdx</code>）有个著名特性：<strong>在子系统里删文件，vhdx 不会自动缩小</strong>。先在 WSL 里清理，再把磁盘压实：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">wsl <span class="literal">--shutdown</span></span><br><span class="line"><span class="comment"># 以 Ubuntu-22.04 为例，先确认 vhdx 路径，再压缩：</span></span><br><span class="line"><span class="built_in">Optimize-VHD</span> <span class="literal">-Path</span> <span class="string">&quot;C:\...\Ubuntu-22.04\ext4.vhdx&quot;</span> <span class="literal">-Mode</span> Full</span><br></pre></td></tr></table></figure><p><code>Optimize-VHD</code> 需要 Hyper-V 模块；没有的话用 <code>diskpart</code>（<code>select vdisk file=&quot;...&quot;</code> → <code>compact vdisk</code>）等效。整个 vhdx 也可以整体搬去 D 盘：<code>wsl --export</code> 导出 → <code>wsl --import</code> 到 D 盘新位置。</p><h3 id="3-4-大文件夹整体搬家：mklink-目录联调"><a href="#3-4-大文件夹整体搬家：mklink-目录联调" class="headerlink" title="3.4 大文件夹整体搬家：mklink 目录联调"></a>3.4 大文件夹整体搬家：mklink 目录联调</h3><p>有些软件（老版本微信、某些游戏、工程目录）路径写死在 C 盘，改不了设置。这时用 <strong>NTFS 目录联调（junction）</strong>：文件实际存 D 盘，原路径仍然可用，软件毫无感知：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 以把 D:\moved\WeChatFiles 接回原路径为例</span></span><br><span class="line">robocopy <span class="string">&quot;C:\Users\x\Documents\xwechat_files&quot;</span> <span class="string">&quot;D:\moved\xwechat_files&quot;</span> /E /<span class="built_in">MOVE</span> /<span class="built_in">R</span>:<span class="number">1</span> /W:<span class="number">1</span></span><br><span class="line">mklink /J <span class="string">&quot;C:\Users\x\Documents\xwechat_files&quot;</span> <span class="string">&quot;D:\moved\xwechat_files&quot;</span></span><br></pre></td></tr></table></figure><p>执行顺序很重要：<strong>先搬文件（robocopy &#x2F;MOVE），再建链接（mklink &#x2F;J）</strong>；操作前关闭对应软件。让 ZCode 执行时，把这两条命令拆开逐步确认——尤其确认 robocopy 完成之后再建链接。</p><blockquote><p>下载、桌面、文档这些用户文件夹不必用 mklink：资源管理器里右键文件夹 → 属性 → 位置，直接改路径，Windows 原生支持。</p></blockquote><hr><h2 id="第四步：验证与固化"><a href="#第四步：验证与固化" class="headerlink" title="第四步：验证与固化"></a>第四步：验证与固化</h2><p>清理迁移做完，让 ZCode 复跑一次体检脚本，对比前后数字——比如一次典型的成套操作下来，常见收益是：<strong>更新缓存 + Temp + 休眠文件 + 微信迁移 + npm 迁移，合计释放 30–50GB</strong>，C 盘从飘红回到从容。</p><p>想让这件事不反弹，还有两个固化手段：</p><ol><li><strong>定时体检</strong>：用 ZCode 的 Automations 建一个每周任务，「扫描 C 盘可用空间和 Top10 大目录，环比增长超过 2GB 就输出报告」——空间被谁吃掉，一周内就能知道</li><li><strong>Hook 长期护栏</strong>：保留第二步提到的 PreToolUse 拦截 Hook，给以后所有会话里的危险删除命令兜底</li></ol><hr><h2 id="安全红线：这些事不要让智能体做"><a href="#安全红线：这些事不要让智能体做" class="headerlink" title="安全红线：这些事不要让智能体做"></a>安全红线：这些事不要让智能体做</h2><p>最后把红线列清楚，写进你的提示词或 AGENTS.md 都行：</p><ul><li><strong>不要删 <code>C:\Windows</code>、<code>C:\Program Files</code> 下的任何东西</strong>（更新缓存和 DISM 是仅有的两个例外，且用上面给定的官方方式）</li><li><strong>不要用「强制删除&#x2F;递归删除」去清 AppData</strong>——正在运行的软件的缓存目录删了轻则丢登录态，重则丢配置</li><li><strong>WinSxS 不要手动删</strong>，只能走 DISM</li><li><strong>pagefile.sys、swapfile.sys</strong> 不能直接删文件，只能通过虚拟内存设置改</li><li><strong>system32 报错为「拒绝访问」是保护机制</strong>，绕过它的办法只有一个：不要绕</li><li>大规模删除前，<strong>先让智能体把清单写进一个 txt 备着</strong>，误删了还有据可查</li></ul><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="ZCode-会不会乱删文件？"><a href="#ZCode-会不会乱删文件？" class="headerlink" title="ZCode 会不会乱删文件？"></a>ZCode 会不会乱删文件？</h3><p>只要你待在默认的 Ask before changes 模式，每一条删除命令都要你点确认，它「想乱删」也没有执行机会。真正要注意的是不要图省事切到 Full access 跑清理。</p><h3 id="为什么我删了-WSL-里的文件，C-盘还是没变大？"><a href="#为什么我删了-WSL-里的文件，C-盘还是没变大？" class="headerlink" title="为什么我删了 WSL 里的文件，C 盘还是没变大？"></a>为什么我删了 WSL 里的文件，C 盘还是没变大？</h3><p>因为 <code>ext4.vhdx</code> 只增不减——Linux 侧删除只是标记空间空闲，虚拟磁盘文件不会自动收缩，需要 <code>Optimize-VHD</code> 或 <code>diskpart</code> 压实，见 3.3。</p><h3 id="DISM-跑了很久正常吗？"><a href="#DISM-跑了很久正常吗？" class="headerlink" title="DISM 跑了很久正常吗？"></a>DISM 跑了很久正常吗？</h3><p><code>StartComponentCleanup</code> 在补丁装得多的机器上跑十几分钟到半小时都正常，中途别关机。加 <code>/ResetBase</code> 可以清得更狠，但代价是<strong>已装更新无法再卸载</strong>，介意就别加。</p><h3 id="清理和迁移，哪个优先？"><a href="#清理和迁移，哪个优先？" class="headerlink" title="清理和迁移，哪个优先？"></a>清理和迁移，哪个优先？</h3><p>先体检，按报告来。一般顺序是：<strong>先删零风险缓存（快、立刻见效），再迁大文件（慢、治本），最后做系统级瘦身（DISM、休眠文件）</strong>。如果只剩几个 GB 急着救急，前两步就能救回来。</p><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>这套流程的本质，是把「清理 C 盘」从一门玄学变成一条流水线：</p><ol><li><strong>体检</strong>——智能体扫描统计，把空间去向变成一张表</li><li><strong>清理</strong>——按风险分级执行，人在环上逐批确认</li><li><strong>迁移</strong>——缓存改配置、聊天文件改目录、虚拟磁盘搬家、大文件夹上 junction</li><li><strong>固化</strong>——Hook 拦危险命令，定时任务防反弹</li></ol><p>智能体的价值不在于「替你删」，而在于它能把散落在几百个目录里的空间去向<strong>在几分钟内算清楚</strong>，然后把方案摆到你面前——决定权始终在你手里。C 盘飘红的朋友，值得花半小时跑一遍这套流程。</p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://support.microsoft.com/zh-cn/windows">Microsoft：释放 Windows 中的驱动器空间</a></li><li><a href="https://learn.microsoft.com/zh-cn/windows-hardware/manufacture/desktop/dism-capabilities">Microsoft Learn：DISM 命令行选项</a></li><li><a href="https://learn.microsoft.com/windows-hardware/design/device-experiences/powercfg-command-line-options">Microsoft Learn：powercfg 命令行选项</a></li><li><a href="https://learn.microsoft.com/windows-server/administration/windows-commands/mklink">Microsoft Learn：mklink 命令</a></li><li><a href="https://learn.microsoft.com/windows-server/administration/windows-commands/robocopy">Microsoft Learn：robocopy 命令</a></li><li><a href="https://docs.npmjs.com/cli/v10/commands/npm-config">npm 官方文档：npm config</a></li><li><a href="https://pip.pypa.io/en/stable/topics/caching/">pip 官方文档：缓存机制</a></li><li><a href="https://docs.docker.com/desktop/settings-and-maintenance/settings/">Docker Desktop：设置文档</a></li><li><a href="https://learn.microsoft.com/zh-cn/windows/wsl/">Microsoft Learn：WSL 文档</a></li><li><a href="https://zcode.z.ai/">ZCode 官网</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/09/26/zcode-c-drive-cleanup/</id>
    <link href="https://blog.ztmss.com/2026/09/26/zcode-c-drive-cleanup/"/>
    <published>2026-09-26T14:00:00.000Z</published>
    <summary>C 盘空间告急是 Windows 用户的长期痛点。本文结合系统知识与 ZCode 智能体实战，给出完整的四步方案：先用智能体做空间体检找出真正的大头，再按风险分级执行安全清理（Temp、更新缓存、休眠文件、DISM 组件清理），然后把 npm、pip、微信、Docker、WSL 等大文件迁移到其他盘（含 mklink junction 方案），最后固化成定期自动化任务。</summary>
    <title>用 ZCode 清理 C 盘实战：空间体检、安全清理与文件迁移完整指南</title>
    <updated>2026-09-26T10:45:55.982Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="行业观察" scheme="https://blog.ztmss.com/categories/%E8%A1%8C%E4%B8%9A%E8%A7%82%E5%AF%9F/"/>
    <category term="UFO" scheme="https://blog.ztmss.com/tags/UFO/"/>
    <category term="不明飞行物" scheme="https://blog.ztmss.com/tags/%E4%B8%8D%E6%98%8E%E9%A3%9E%E8%A1%8C%E7%89%A9/"/>
    <category term="都江堰" scheme="https://blog.ztmss.com/tags/%E9%83%BD%E6%B1%9F%E5%A0%B0/"/>
    <category term="系留浮空艇" scheme="https://blog.ztmss.com/tags/%E7%B3%BB%E7%95%99%E6%B5%AE%E7%A9%BA%E8%89%87/"/>
    <category term="临近空间" scheme="https://blog.ztmss.com/tags/%E4%B8%B4%E8%BF%91%E7%A9%BA%E9%97%B4/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>2026 年 9 月 23 日清晨，四川成都<strong>都江堰市</strong>上空出现了一个「不速之客」：多位市民抬头看到一个<strong>形似飞艇</strong>的物体悬浮在高空，纷纷拿出手机拍摄，视频和照片迅速在本地社交平台刷屏，随后登上微博热搜，引发全网热议。</p><p>「UFO」三个字一出现，评论区必然分裂成两派：一派高呼「外星人来了」，另一派说「不就是个气球」。这篇文章把 9 月 23 日事件的<strong>已知信息、官方回应、合理推测</strong>完整梳理一遍——最后你会发现，最可能的答案既不是外星人，也不是普通气球，而是一类正在快速发展的航空器。</p><hr><h2 id="事件回顾"><a href="#事件回顾" class="headerlink" title="事件回顾"></a>事件回顾</h2><p>先看目前媒体公开报道中比较一致的信息：</p><table><thead><tr><th align="left">项目</th><th align="left">内容</th></tr></thead><tbody><tr><td align="left"><strong>时间</strong></td><td align="left">2026 年 9 月 23 日早上（清晨）</td></tr><tr><td align="left"><strong>地点</strong></td><td align="left">四川省成都市都江堰市上空</td></tr><tr><td align="left"><strong>目击者</strong></td><td align="left">多位市民</td></tr><tr><td align="left"><strong>外形</strong></td><td align="left">细长椭圆形，形似飞艇（也有人说像潜艇）</td></tr><tr><td align="left"><strong>颜色</strong></td><td align="left">阳光照耀下呈白色、半透明状</td></tr><tr><td align="left"><strong>姿态</strong></td><td align="left">长时间定点悬停，几乎没有位移</td></tr><tr><td align="left"><strong>传播</strong></td><td align="left">实拍视频在本地社交平台刷屏，全网热议</td></tr></tbody></table><p>几个目击特征值得单独强调：</p><ul><li><strong>长时间悬停、几乎没有位移</strong>——这一点和持续上升的普通气球明显不同，也是它引发大规模关注的关键</li><li><strong>飞行姿态与普通飞机、无人机有明显区别</strong>——目击者的直观感受是「这东西不像我平时见过的任何飞行器」</li><li><strong>白色半透明</strong>——在阳光下呈半透明状，说明囊体可能是透光的柔性材料</li></ul><hr><h2 id="官方回应：气象部门排除了探空气球"><a href="#官方回应：气象部门排除了探空气球" class="headerlink" title="官方回应：气象部门排除了探空气球"></a>官方回应：气象部门排除了探空气球</h2><p>事件发酵后，媒体（四川观察）记者向气象部门求证，得到的回复非常明确：</p><blockquote><p>成都施放探空气球<strong>仅有温江国家气候观象台一处</strong>，且是在<strong>规定的时间</strong>施放。都江堰上空出现的这个物体，<strong>并非气象探空气球</strong>。</p></blockquote><p>这个排除是有理有据的，原因有三层：</p><ol><li><strong>施放点唯一</strong>：成都地区的探空气球只有温江国家气候观象台一个施放点，都江堰当天<strong>没有</strong>施放作业</li><li><strong>时间固定</strong>：探空气球按业务规范在固定时刻施放（全球气象业务统一），不是想放就放</li><li><strong>形态不符</strong>：探空气球是球形、持续上升的，而这次目击的物体是细长椭圆、定点悬停——形态和运动特征都对不上</li></ol><p>排除探空气球之后，这个物体在「已知的常规气象活动」里就没有解释了——这正是它成为「不明飞行物」的原因。</p><hr><h2 id="先纠正一个概念：UFO-≠-外星飞船"><a href="#先纠正一个概念：UFO-≠-外星飞船" class="headerlink" title="先纠正一个概念：UFO ≠ 外星飞船"></a>先纠正一个概念：UFO ≠ 外星飞船</h2><p>每次出现不明飞行物，「外星人」必然是流量最高的猜测。但这里必须把概念说清楚：</p><p><strong>UFO（Unidentified Flying Object）的字面含义就是「不明飞行物」</strong>——仅仅代表当下暂时无法识别的空中物体，<strong>不等于外星飞船</strong>。</p><p>回顾国内过往的同类目击事件，市民拍到的「神秘物体」经过后续调查，<strong>绝大多数最终被证实是人造物体或大气光学现象</strong>，常见类型包括：</p><ul><li>商业广告飞艇</li><li>大型高空气球</li><li>无人机编队</li><li>云层光影折射</li></ul><p>所以面对这次都江堰事件，正确的姿势不是二选一站队「外星人 or 气球」，而是<strong>列出所有技术上说得通的候选解释，等官方调查结论</strong>。</p><hr><h2 id="它可能是什么：三个主流推测"><a href="#它可能是什么：三个主流推测" class="headerlink" title="它可能是什么：三个主流推测"></a>它可能是什么：三个主流推测</h2><p>截至发稿，空管、公安等主管单位尚未发布最终身份结论，没有任何官方或研究机构「认领」这个飞行器。但业内和科普圈的主流分析，指向三类人造浮空器：</p><h3 id="1-系留浮空艇（可能性最高）"><a href="#1-系留浮空艇（可能性最高）" class="headerlink" title="1. 系留浮空艇（可能性最高）"></a>1. 系留浮空艇（可能性最高）</h3><p>靠氦气等轻质气体提供浮力、通过地面缆绳实现定点停留的浮空平台，可以<strong>长期悬停</strong>在一个位置上空，常用于：</p><ul><li>地质灾害观测</li><li>环保监测</li><li>安防巡查</li></ul><p>成都平原周边这类设备<strong>已有落地先例</strong>——天府新区此前部署的「云端号」就是同类系留浮空器。系留浮空艇从外形（细长椭圆）和驻空特征（定点悬停）上都和这次目击描述最匹配。</p><h3 id="2-平流层科研飞艇"><a href="#2-平流层科研飞艇" class="headerlink" title="2. 平流层科研飞艇"></a>2. 平流层科研飞艇</h3><p>用于大气环境监测、对地观测等科研任务的高空长航时飞艇。这类飞艇通常也是白色半透明外观（囊体材料透光），具备定点驻空能力。</p><h3 id="3-高空风能发电平台"><a href="#3-高空风能发电平台" class="headerlink" title="3. 高空风能发电平台"></a>3. 高空风能发电平台</h3><p>网传说法中还有一类「S4000」式的高空风能发电平台：用大型气囊把发电和缆绳系统送到数千米高空取风发电，再通过缆绳回传电力。有分析指出，都江堰周边<strong>山地、河道、景区多</strong>，在本地做环境感知或新能源测试并不突兀。</p><h3 id="关于「为什么是半透明的」"><a href="#关于「为什么是半透明的」" class="headerlink" title="关于「为什么是半透明的」"></a>关于「为什么是半透明的」</h3><p>有分析认为，透明或半透明的外观可能与飞艇<strong>气囊采用的特殊柔性材质</strong>有关（透光膜材本身就是浮空器的常见选择），也可能是在特定光线和角度下<strong>日光反射造成的视觉现象</strong>。</p><hr><h2 id="背景：临近空间为什么这么热"><a href="#背景：临近空间为什么这么热" class="headerlink" title="背景：临近空间为什么这么热"></a>背景：临近空间为什么这么热</h2><p>要看懂这类目击事件为什么越来越多，得把视角拉到<strong>临近空间</strong>（距地 20–100 公里）。</p><p>平流层飞艇、高空气球、太阳能无人机都属于 <strong>HAPS（高空平台系统）</strong>。它们的独特价值在于：</p><ul><li><strong>比卫星离地近</strong>——通信延迟低，光学遥感分辨率高</li><li><strong>比普通飞机覆盖广</strong>——单平台驻空时间长、覆盖范围大</li><li><strong>成本低</strong>——不需要火箭发射，可回收重复使用</li></ul><p>典型应用包括：通信基站（应急通信、6G 空天地一体化）、光学遥感、红外探测、气象与环境载荷。2026 年 MWC 上海展会上就展出过平流层飞艇模型，指向 6G 空天地一体化网络；国内科研也在攻关 20 公里级柔性飞艇的成套技术——囊体材料、氦气渗漏控制、自主定点、太阳能储能。</p><p><strong>临近空间应用正在全球范围内升温</strong>，各国都在抢通信、观测、灾害预警的入口。这意味着：以后城市上空出现「长悬停的白色大飞艇」，大概率会从罕见新闻变成常见现象。</p><hr><h2 id="截至目前的状态"><a href="#截至目前的状态" class="headerlink" title="截至目前的状态"></a>截至目前的状态</h2><p>把时间线整理到发稿为止：</p><table><thead><tr><th align="left">时间</th><th align="left">进展</th></tr></thead><tbody><tr><td align="left">9 月 23 日清晨</td><td align="left">多位市民目击拍摄，视频在社交平台刷屏</td></tr><tr><td align="left">9 月 23 日</td><td align="left">四川观察向气象部门求证，明确排除气象探空气球</td></tr><tr><td align="left">9 月 24 日</td><td align="left">话题登上热搜，多路媒体跟进报道</td></tr><tr><td align="left">9 月 25 日</td><td align="left">仍无空管、公安或相关单位发布最终身份结论</td></tr></tbody></table><p><strong>目前没有任何官方或研究机构认领这个飞行器</strong>，最终结论有待相关部门进一步通报。</p><hr><h2 id="如何理性看待"><a href="#如何理性看待" class="headerlink" title="如何理性看待"></a>如何理性看待</h2><p>给关心这件事的读者三条建议：</p><ol><li><strong>别急着站队</strong>。从「外星人」到「气球」之间的巨大空档里，存在系留浮空艇、科研飞艇、风能平台等大量合理候选，等调查结果比猜更有效率</li><li><strong>不造谣、不信谣、不传谣</strong>。「外星人到访」这类博眼球的猜测式谣言，在权威结果出来前一律别转发</li><li><strong>以官方通报为准</strong>。是否系留、定高多少、归属单位、空域是否报批、载荷是监测还是发电——这些信息一旦官方公布，谜底自然揭晓</li></ol><p>我的判断是：<strong>这是一次典型的「新型浮空器被当成 UFO」事件</strong>。它有趣的地方不在于猎奇，而在于它恰好让我们看见了临近空间产业正在悄悄起飞。</p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.weibo.com/1847582585/Rjs0i5PsJ">都江堰上空现不明飞行物（都市快报·微博）</a></li><li><a href="https://www.sohu.com/a/1080241523_121119253">成都都江堰上空现不明飞行物，气象部门：此物体并非气象探空气球（四川观察&#x2F;搜狐）</a></li><li><a href="https://www.163.com/dy/article/L7HEATLE0556PP6X.html">成都都江堰上空出现不明飞行物！市民拍到白色透明物体，气象部门回应（网易）</a></li><li><a href="https://k.sina.cn/article_7096020433_1a6f4add106801oti6.html">成都都江堰悬停不明飞行物，形似飞艇，气象部门排除探空气球（新浪）</a></li><li><a href="https://hk.aboluowang.com/2026/0924/2437682.html">都江堰上空現不明飛行物 白色透明 長時間懸停（阿波羅新聞網）</a></li><li><a href="https://www.toutiao.com/article/7688824960755827242/">都江堰上空拍到不明飞行物！形似飞艇悬停高空（今日头条）</a></li><li><a href="https://www.sohu.com/a/1080746309_122397559">都江堰飞艇状物体引关注！”神秘飞艇”是回应，还是巧合？（搜狐·秒懂科普）</a></li><li><a href="https://www.zhihu.com/question/2086222152437429964">都江堰上空现不明飞行物，气象部门已排除探空气球，最有可能是什么？（知乎）</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/09/26/dujiangyan-ufo-sighting/</id>
    <link href="https://blog.ztmss.com/2026/09/26/dujiangyan-ufo-sighting/"/>
    <published>2026-09-26T12:00:00.000Z</published>
    <summary>2026年9月23日清晨，四川成都都江堰市上空出现形似飞艇的白色半透明不明飞行物，长时间定点悬停引发全网热议。气象部门回应成都探空气球仅在温江国家气候观象台按固定时间施放，明确排除气象探空气球。本文梳理事件经过、官方回应、主流科学推测与临近空间浮空器背景。</summary>
    <title>都江堰上空出现不明飞行物：9月23日事件全梳理，气象部门排除了探空气球</title>
    <updated>2026-09-26T10:05:55.882Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="工具推荐" scheme="https://blog.ztmss.com/categories/%E5%B7%A5%E5%85%B7%E6%8E%A8%E8%8D%90/"/>
    <category term="API代理" scheme="https://blog.ztmss.com/tags/API%E4%BB%A3%E7%90%86/"/>
    <category term="AI API" scheme="https://blog.ztmss.com/tags/AI-API/"/>
    <category term="中转站" scheme="https://blog.ztmss.com/tags/%E4%B8%AD%E8%BD%AC%E7%AB%99/"/>
    <category term="大模型" scheme="https://blog.ztmss.com/tags/%E5%A4%A7%E6%A8%A1%E5%9E%8B/"/>
    <category term="Claude" scheme="https://blog.ztmss.com/tags/Claude/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>用过官方 API 的人都知道几个痛点：<strong>价格贵</strong>（Claude Opus 5 官方定价不便宜）、<strong>需要海外信用卡</strong>、<strong>一个平台只有一种模型</strong>。AI 大模型中转站（也叫 API 代理、API 中转）就是解决这些问题的：它们把多家模型商的 API 统一成一个 <strong>OpenAI 兼容接口</strong>，你注册一个账号、拿到一个 Key，就能在一个地方调用 Claude、GPT、Gemini、DeepSeek、GLM、Kimi 等几十款模型，价格往往只有官方的几分之一。</p><p>本文是我亲测在用的 <strong>7 家中转站</strong>推荐，每家都附注册链接。价格和模型列表会随时间变化，以各平台官网为准。</p><hr><h2 id="推荐列表一览"><a href="#推荐列表一览" class="headerlink" title="推荐列表一览"></a>推荐列表一览</h2><table><thead><tr><th align="left">平台</th><th align="left">模型数量</th><th align="left">特色</th><th align="left">注册链接</th></tr></thead><tbody><tr><td align="left">LlmHost</td><td align="left">47+</td><td align="left">模型全、分组灵活、有免费模型</td><td align="left"><a href="https://llmhost.net/sign-up?aff=ktbA">注册</a></td></tr><tr><td align="left">TaBiToken</td><td align="left">2</td><td align="left">主打 Claude Opus 5</td><td align="left"><a href="https://tabitoken.com/sign-up?aff=184K">注册</a></td></tr><tr><td align="left">GoRouter</td><td align="left">2</td><td align="left">Claude 价格最低档</td><td align="left"><a href="https://gorouter.app/sign-up?aff=rjIV">注册</a></td></tr><tr><td align="left">JustWoker</td><td align="left">2</td><td align="left">Claude Opus 5</td><td align="left"><a href="https://api.justwoker.icu/register?aff=tpEg">注册</a></td></tr><tr><td align="left">Vsllm（维云）</td><td align="left">68+</td><td align="left">模型最多、Gemini 系列齐全</td><td align="left"><a href="https://vsllm.com/register?aff=IWqv">注册</a></td></tr><tr><td align="left">KKToken</td><td align="left">2</td><td align="left">Claude Opus 5</td><td align="left"><a href="https://kktoken.cc/sign-up?aff=HPKn">注册</a></td></tr><tr><td align="left">TokenFreePerDay</td><td align="left">34+</td><td align="left">有免费额度、价格亲民</td><td align="left"><a href="https://api.tokenfreeperday.com/sign-up?aff=Yij7">注册</a></td></tr></tbody></table><hr><h2 id="逐一介绍"><a href="#逐一介绍" class="headerlink" title="逐一介绍"></a>逐一介绍</h2><h3 id="1-LlmHost-—-模型全、分组灵活"><a href="#1-LlmHost-—-模型全、分组灵活" class="headerlink" title="1. LlmHost — 模型全、分组灵活"></a>1. LlmHost — 模型全、分组灵活</h3><p>🔗 <a href="https://llmhost.net/sign-up?aff=ktbA">点击注册</a></p><p><strong>模型覆盖</strong>：47 款以上，涵盖 GLM-5.3、GPT-5.6 系列、Claude 全系（含 Fable 5、Opus 4-6）、Kimi K2.6&#x2F;K3、Qwen 3.5&#x2F;3.6&#x2F;3.7、MiniMax M2.5&#x2F;M3、MiMo V2 Pro、DeepSeek V4 等。</p><p><strong>分组体系</strong>：自动分组包括「付费」「35折分组」「DeepSeek V4 Flash 折扣」，不同分组对应不同折扣力度，灵活选择。</p><p><strong>亮点</strong>：</p><ul><li>有 <strong>ox-alpha-free</strong> 免费模型可用</li><li>模型覆盖面广，从国产 GLM&#x2F;Kimi 到海外 Claude&#x2F;GPT 一站式覆盖</li><li>支持 OpenAI 兼容格式，无缝对接主流客户端</li></ul><hr><h3 id="2-TaBiToken-—-Claude-专属中转"><a href="#2-TaBiToken-—-Claude-专属中转" class="headerlink" title="2. TaBiToken — Claude 专属中转"></a>2. TaBiToken — Claude 专属中转</h3><p>🔗 <a href="https://tabitoken.com/sign-up?aff=184K">点击注册</a></p><p><strong>模型覆盖</strong>：2 款（Claude Opus 5、Claude Opus 5 Thinking）</p><p><strong>定价</strong>：输入 $0.8 &#x2F; M tokens</p><p><strong>适用场景</strong>：只需要 Claude Opus 5 的用户，价格适中，界面简洁。</p><hr><h3 id="3-GoRouter-—-Claude-最低价中转"><a href="#3-GoRouter-—-Claude-最低价中转" class="headerlink" title="3. GoRouter — Claude 最低价中转"></a>3. GoRouter — Claude 最低价中转</h3><p>🔗 <a href="https://gorouter.app/sign-up?aff=rjIV">点击注册</a></p><p><strong>模型覆盖</strong>：2 款（Claude Opus 5、Claude Opus 5 Thinking）</p><p><strong>定价</strong>：输入 <strong>$0.3 &#x2F; M tokens</strong>，是目前这几家里 Claude 单价最低的。</p><p><strong>适用场景</strong>：高频使用 Claude Opus 5、对成本敏感的用户。$0.3 的定价相比官方和同类中转站有明显优势。</p><hr><h3 id="4-JustWoker-—-Claude-中转"><a href="#4-JustWoker-—-Claude-中转" class="headerlink" title="4. JustWoker — Claude 中转"></a>4. JustWoker — Claude 中转</h3><p>🔗 <a href="https://api.justwoker.icu/register?aff=tpEg">点击注册</a></p><p><strong>模型覆盖</strong>：2 款（Claude Opus 5、Claude Opus 5 Thinking）</p><p>基于 New API 搭建，需注册登录后查看定价。支持 OpenAI 兼容格式，适合需要备用 Claude 通道的用户。</p><hr><h3 id="5-Vsllm（维云）—-模型最全的全能选手"><a href="#5-Vsllm（维云）—-模型最全的全能选手" class="headerlink" title="5. Vsllm（维云）— 模型最全的全能选手"></a>5. Vsllm（维云）— 模型最全的全能选手</h3><p>🔗 <a href="https://vsllm.com/register?aff=IWqv">点击注册</a></p><p><strong>模型覆盖</strong>：<strong>68 款以上</strong>，是这 7 家中模型数量最多的。</p><table><thead><tr><th align="left">厂商</th><th align="left">代表模型</th></tr></thead><tbody><tr><td align="left">OpenAI</td><td align="left">GPT-5.4、GPT-5.5 OpenAI Compact、GPT-5.3 Codex Spark</td></tr><tr><td align="left">Claude</td><td align="left">Haiku 4.5、Fable 5、Sonnet 5、Opus 系列</td></tr><tr><td align="left">Google</td><td align="left">Gemini 3.1 Flash Lite、3.1 Pro Request、3.8 Flash API（共 16 款 Gemini）</td></tr><tr><td align="left">国产</td><td align="left">GLM-5.3、GLM-5.3 Flash、Qwen 3.6&#x2F;3.7&#x2F;3.8、Kimi K3、DeepSeek V4 Pro&#x2F;Flash</td></tr><tr><td align="left">其他</td><td align="left">Grok 4.5&#x2F;4.6、MiniMax M2.5&#x2F;M2.7&#x2F;M3</td></tr></tbody></table><p><strong>定价亮点</strong>：</p><ul><li>GLM-4.6V Flash：0.05 ratio，极低</li><li>Gemini 3.1 Flash Lite：0.025 ratio</li><li>Qwen 3.6 Plus：0.03 ratio</li><li>DeepSeek V4 Flash 有折扣分组</li></ul><p><strong>适用场景</strong>：需要同时用到多家模型、尤其是 Gemini 系列齐全的用户。一站式覆盖 GPT&#x2F;Claude&#x2F;Gemini&#x2F;国产全家桶。</p><hr><h3 id="6-KKToken-—-Claude-中转"><a href="#6-KKToken-—-Claude-中转" class="headerlink" title="6. KKToken — Claude 中转"></a>6. KKToken — Claude 中转</h3><p>🔗 <a href="https://kktoken.cc/sign-up?aff=HPKn">点击注册</a></p><p><strong>模型覆盖</strong>：2 款（Claude Opus 5、Claude Opus 5 Thinking）</p><p>基于 New API 搭建，需注册后查看定价。支持 OpenAI 兼容格式，适合作为 Claude 备用通道。</p><hr><h3 id="7-TokenFreePerDay-—-每日免费额度-价格亲民"><a href="#7-TokenFreePerDay-—-每日免费额度-价格亲民" class="headerlink" title="7. TokenFreePerDay — 每日免费额度 + 价格亲民"></a>7. TokenFreePerDay — 每日免费额度 + 价格亲民</h3><p>🔗 <a href="https://api.tokenfreeperday.com/sign-up?aff=Yij7">点击注册</a></p><p><strong>模型覆盖</strong>：34 款以上</p><p><strong>最大亮点</strong>：有 <strong>free 免费模型</strong>，且多数付费模型定价非常亲民：</p><table><thead><tr><th align="left">模型</th><th align="left">价格（ratio）</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">agnes-2.5-pro</td><td align="left">0.0225</td><td align="left">新加坡 AgnesAI，支持文本+图片</td></tr><tr><td align="left">agnes-2.5-flash</td><td align="left">0.0015</td><td align="left">同上轻量版</td></tr><tr><td align="left">deepseek-v4-flash</td><td align="left">0.033</td><td align="left">DeepSeek 最新 Flash</td></tr><tr><td align="left">qwen3.8-flash</td><td align="left">0.0375</td><td align="left">通义千问最新 Flash</td></tr><tr><td align="left">gemini-3.6-flash</td><td align="left">0.005625</td><td align="left">Google Gemini Flash</td></tr><tr><td align="left">glm-5.2</td><td align="left">0.21</td><td align="left">智谱 GLM（官方 3 折）</td></tr></tbody></table><p><strong>覆盖厂商</strong>：GLM、GPT、DeepSeek、Kimi、Qwen、Gemini、MiniMax、MiMo、Claude 等。</p><p><strong>适用场景</strong>：预算有限但想体验多款模型的用户，尤其是需要 Gemini 和 DeepSeek Flash 的场景。</p><hr><h2 id="通用使用教程"><a href="#通用使用教程" class="headerlink" title="通用使用教程"></a>通用使用教程</h2><p>这 7 家中转站全部基于 <strong>New API</strong> 或兼容系统搭建，使用方式完全一致：</p><h3 id="第一步：注册账号"><a href="#第一步：注册账号" class="headerlink" title="第一步：注册账号"></a>第一步：注册账号</h3><p>点击上方对应的注册链接，用邮箱注册即可。</p><h3 id="第二步：获取-API-Key"><a href="#第二步：获取-API-Key" class="headerlink" title="第二步：获取 API Key"></a>第二步：获取 API Key</h3><p>登录后在后台找到「令牌」或「API Keys」页面，创建一个新的 Key。格式通常是 <code>sk-xxxxxxxxxxxx</code>。</p><h3 id="第三步：配置-Base-URL"><a href="#第三步：配置-Base-URL" class="headerlink" title="第三步：配置 Base URL"></a>第三步：配置 Base URL</h3><p>把 API 的 Base URL 填入你的客户端：</p><table><thead><tr><th align="left">中转站</th><th align="left">Base URL</th></tr></thead><tbody><tr><td align="left">LlmHost</td><td align="left"><code>https://llmhost.net/v1</code></td></tr><tr><td align="left">TaBiToken</td><td align="left"><code>https://tabitoken.com/v1</code></td></tr><tr><td align="left">GoRouter</td><td align="left"><code>https://gorouter.app/v1</code></td></tr><tr><td align="left">JustWoker</td><td align="left"><code>https://api.justwoker.icu/v1</code></td></tr><tr><td align="left">Vsllm</td><td align="left"><code>https://vsllm.com/v1</code></td></tr><tr><td align="left">KKToken</td><td align="left"><code>https://kktoken.cc/v1</code></td></tr><tr><td align="left">TokenFreePerDay</td><td align="left"><code>https://api.tokenfreeperday.com/v1</code></td></tr></tbody></table><h3 id="第四步：选择模型"><a href="#第四步：选择模型" class="headerlink" title="第四步：选择模型"></a>第四步：选择模型</h3><p>在客户端的模型选择框里输入对应模型名（如 <code>claude-opus-5</code>、<code>gpt-5.4</code>、<code>glm-5.3</code> 等）。不同中转站支持的模型名可能略有差异，以各平台定价页为准。</p><h3 id="常见客户端"><a href="#常见客户端" class="headerlink" title="常见客户端"></a>常见客户端</h3><ul><li><strong>ChatBox</strong>：桌面&#x2F;手机端，支持自定义 API</li><li><strong>OpenCode &#x2F; ZCode</strong>：AI 编程智能体，可配置模型提供商</li><li><strong>ChatGPT-Next-Web</strong>：自部署 Web 客户端</li><li><strong>LobeChat</strong>：功能丰富的 Web 客户端</li><li><strong>任何支持 OpenAI API 的工具</strong>：直接把 Base URL 和 Key 填进去即可</li></ul><hr><h2 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h2><ol><li><strong>价格会变</strong>。各中转站的定价随上游模型商调整而变化，本文数据基于 2026 年 9 月实测，注册前请以官网最新价格为准。</li><li><strong>不要存敏感数据</strong>。中转站本质上是第三方代理，你的请求会经过它们的服务器。敏感代码、商业数据建议直接走官方 API。</li><li><strong>多备一个</strong>。建议同时注册 2-3 家，一家挂了可以切到另一家。中转站的稳定性不如官方，多通道是基本操作。</li><li><strong>关注分组和折扣</strong>。很多中转站有分组机制（如「35折分组」「DeepSeek 折扣」），同一模型不同分组价格可能差几倍，注册后先看定价页再选。</li><li><strong>免费额度要珍惜</strong>。部分中转站提供每日免费额度或免费模型，适合轻度使用和测试，但重度使用还是需要充值。</li><li><strong>确认模型是否在售</strong>。中转站的模型列表会动态调整，某个模型可能临时下架。重要业务别只绑定一个中转站。</li></ol><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><table><thead><tr><th align="left">需求</th><th align="left">推荐</th></tr></thead><tbody><tr><td align="left">模型最全、一站式</td><td align="left"><strong>Vsllm</strong>（68+ 模型，Gemini 系列最全）</td></tr><tr><td align="left">Claude 最便宜</td><td align="left"><strong>GoRouter</strong>（$0.3 输入）</td></tr><tr><td align="left">综合均衡</td><td align="left"><strong>LlmHost</strong>（47 模型，分组灵活）</td></tr><tr><td align="left">预算有限</td><td align="left"><strong>TokenFreePerDay</strong>（有免费额度，DeepSeek&#x2F;Gemini 极低价）</td></tr><tr><td align="left">纯 Claude 用户</td><td align="left"><strong>TaBiToken</strong> &#x2F; <strong>GoRouter</strong> &#x2F; <strong>JustWoker</strong> &#x2F; <strong>KKToken</strong></td></tr><tr><td align="left">备用通道</td><td align="left"><strong>JustWoker</strong> &#x2F; <strong>KKToken</strong></td></tr></tbody></table><p>没有完美的中转站，只有适合你场景的组合。建议从免费额度试起，确认速度和稳定性后再充值使用。</p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://github.com/songquanpeng/one-api">New API 开源项目</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/09/03/llm-proxy-recommendation/</id>
    <link href="https://blog.ztmss.com/2026/09/03/llm-proxy-recommendation/"/>
    <published>2026-09-03T02:00:00.000Z</published>
    <summary>精选 7 家亲测可用的 AI 大模型中转站，支持 OpenAI 兼容格式，一个 API Key 调用 Claude、GPT、Gemini、DeepSeek、GLM 等数十款模型，价格低至官方几分之一，附注册链接与使用教程。</summary>
    <title>7 家 AI 大模型中转站推荐：统一 API 接口，低价调用 Claude、GPT、Gemini 等主流模型</title>
    <updated>2026-09-03T06:49:13.143Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="行业观察" scheme="https://blog.ztmss.com/categories/%E8%A1%8C%E4%B8%9A%E8%A7%82%E5%AF%9F/"/>
    <category term="长鑫存储" scheme="https://blog.ztmss.com/tags/%E9%95%BF%E9%91%AB%E5%AD%98%E5%82%A8/"/>
    <category term="LPDDR6" scheme="https://blog.ztmss.com/tags/LPDDR6/"/>
    <category term="DRAM" scheme="https://blog.ztmss.com/tags/DRAM/"/>
    <category term="国产存储" scheme="https://blog.ztmss.com/tags/%E5%9B%BD%E4%BA%A7%E5%AD%98%E5%82%A8/"/>
    <category term="半导体" scheme="https://blog.ztmss.com/tags/%E5%8D%8A%E5%AF%BC%E4%BD%93/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>2026 年 8 月 29 日，<strong>长鑫科技</strong>宣布自主研发的最新一代低功耗内存 <strong>LPDDR6 实现量产</strong>，并将首批搭载于小米 18 Fold 折叠旗舰手机。按照长鑫的官方说法，这是<strong>全球 LPDDR6 产品首次落地商用</strong>——中国存储企业第一次在高端内存标准上，抢在三星、SK 海力士之前完成产品首发量产。</p><p>同一天，雷军发文祝贺长鑫「非常了不起」，并宣布：<strong>玄戒 O3 首家支持长鑫 LPDDR6，小米 18 Fold 全球首发搭载</strong>。央视财经对此的评价是：为中国半导体协同突破「提供了新样本」——「从『芯』到『存』，从单点技术突破到产业链协同发力」。</p><p>这篇文章把这次事件的<strong>内容</strong>（LPDDR6 到底是什么、长鑫做到了什么）、<strong>实际意义</strong>（为什么重要）和<strong>影响范围</strong>（会波及哪些领域）一次讲清楚。</p><hr><h2 id="事件回顾"><a href="#事件回顾" class="headerlink" title="事件回顾"></a>事件回顾</h2><p>先把整个时间线捋一遍：</p><table><thead><tr><th align="left">时间</th><th align="left">事件</th></tr></thead><tbody><tr><td align="left">2025 年 7 月</td><td align="left">JEDEC 正式发布 LPDDR6 标准（规范编号 <strong>JESD209-6</strong>），三星同期展示过 12.8Gbps 的 LPDDR6 原型</td></tr><tr><td align="left">2026 年 3 月</td><td align="left">业内传出长鑫 LPDDR6 产品已送测的消息</td></tr><tr><td align="left">2026 年 7 月 27 日</td><td align="left">长鑫科技（688825）登陆上交所科创板，发行价 8.66 元&#x2F;股，开盘涨超 450%，市值突破 3 万亿元，刷新科创板 IPO 纪录</td></tr><tr><td align="left">2026 年 8 月 1 日</td><td align="left">行业人士透露长鑫 LPDDR6 已接近研发验证尾声</td></tr><tr><td align="left">2026 年 8 月 24 日</td><td align="left">小米玄戒芯片技术沟通会发布 <strong>玄戒 O3</strong>（3nm），宣布小米 18 Fold 首发、9 月上市</td></tr><tr><td align="left">2026 年 8 月 28 日</td><td align="left">长鑫披露半年报：LPDDR6 已向关键客户送样验证、正加速推进量产</td></tr><tr><td align="left">2026 年 8 月 29 日</td><td align="left"><strong>长鑫官宣 LPDDR6 量产</strong>，全球首发商用；玄戒 O3 首家支持，小米 18 Fold 首批搭载</td></tr><tr><td align="left">2026 年 9 月</td><td align="left">小米 18 Fold（小米首款阔折叠）预计正式上市</td></tr></tbody></table><p>一句话总结：<strong>从 JEDEC 标准发布到长鑫产品量产，只用了约 13 个月。</strong></p><hr><h2 id="内容解读"><a href="#内容解读" class="headerlink" title="内容解读"></a>内容解读</h2><h3 id="LPDDR6-是什么"><a href="#LPDDR6-是什么" class="headerlink" title="LPDDR6 是什么"></a>LPDDR6 是什么</h3><p>LPDDR（Low Power Double Data Rate）是面向智能手机、平板等移动设备的低功耗 DRAM 标准，由国际标准组织 <strong>JEDEC</strong> 制定。2025 年 7 月发布的 <strong>JESD209-6</strong>，就是这个家族的第六代，官方定位是「显著提升移动设备与 AI 应用的性能、能效与安全」。几个关键技术点：</p><ul><li><strong>双子通道架构</strong>：LPDDR6 的通道位宽为 24bit，由两个 12bit 子通道组成，同时保持最小访问间隔 32 字节——访问粒度更灵活，对小数据量的随机访问（正是 AI 推理负载的典型特征）更友好</li><li><strong>速率区间</strong>：标准初始数据速率为 <strong>10.667Gbps</strong>，最高定义速率 <strong>14.4Gbps</strong></li><li><strong>安全增强</strong>：针对移动与 AI 场景补充了安全性设计</li><li><strong>封装形态扩展</strong>：面向 PC 的 LPDDR6 CAMM2 等扩展形态也在推进中</li></ul><p>JEDEC 在新闻稿里大量强调 AI——这不是蹭热度。端侧大模型的瓶颈恰恰在内存带宽和容量上，LPDDR6 的架构就是冲着这个去的。</p><h3 id="长鑫首发产品做到了什么"><a href="#长鑫首发产品做到了什么" class="headerlink" title="长鑫首发产品做到了什么"></a>长鑫首发产品做到了什么</h3><table><thead><tr><th align="left">参数</th><th align="left">长鑫 LPDDR6</th><th align="left">对比上一代 LPDDR5&#x2F;5X</th></tr></thead><tbody><tr><td align="left">峰值速率</td><td align="left"><strong>12800Mbps（12.8Gbps）</strong></td><td align="left">10667Mbps</td></tr><tr><td align="left">与 SoC 协同运行的基础速率</td><td align="left">10.667Gbps</td><td align="left">—</td></tr><tr><td align="left">单颗最高容量</td><td align="left"><strong>16GB</strong></td><td align="left">—</td></tr><tr><td align="left">封装</td><td align="left">1295 Ball POP 堆叠封装</td><td align="left">—</td></tr><tr><td align="left">带宽</td><td align="left">较 LPDDR5X <strong>提升约 20%</strong></td><td align="left">—</td></tr><tr><td align="left">其他</td><td align="left">低功耗设计、RAS 功能优化</td><td align="left">—</td></tr></tbody></table><p>三个值得注意的点：</p><ol><li><strong>12.8Gbps 不是标版上限，而是「实用档位」</strong>。JEDEC 标准最高定义到 14.4Gbps，三星 2025 年展示的原型速率同为 12.8Gbps——长鑫首发的这个速率，已经和三星原型站在了同一水平线上。首发选择 12.8Gbps 是典型的工程决策：先把「标准起始速率之上、整机稳定可量产」的这一档做出来。</li><li><strong>1295 Ball POP 封装说明它就是给手机准备的</strong>。POP（Package on Package）是内存直接堆叠在 SoC 之上的封装方式，是旗舰手机的标配形态，对基板、良率和厚度控制的要求都很高。</li><li><strong>带宽提升 20% 配合实测数据</strong>。玄戒 O3 搭配 LPDDR6 的实测内存带宽为 <strong>113.8GB&#x2F;s</strong>，比上一代玄戒 O1 提升 48%——内存和 SoC 是协同设计的，不是单方面内存快。</li></ol><h3 id="「全球首发」的含金量"><a href="#「全球首发」的含金量" class="headerlink" title="「全球首发」的含金量"></a>「全球首发」的含金量</h3><p>存储行业过去几十年的惯例是：<strong>新标准由三星、SK 海力士、美光定义节奏，先发量产，其他厂商跟进</strong>。LPDDR6 这一轮，三家海外巨头都在推进，原本的共同目标是 2026 年下半年量产——结果长鑫抢先落地。</p><p>更要紧的是<strong>代差的历史变化</strong>：过去国产存储与国际巨头的新品代差普遍在半年以上，这一轮不但追平，还压缩成了「先发」。从 2026 年 3 月送测、8 月初验证尾声、8 月底官宣量产，节奏和海外第一梯队完全同步甚至更快。</p><h3 id="首发组合：国产-SoC-国产内存"><a href="#首发组合：国产-SoC-国产内存" class="headerlink" title="首发组合：国产 SoC + 国产内存"></a>首发组合：国产 SoC + 国产内存</h3><p>首发机型小米 18 Fold 的含金量不止是「用了国产内存」：</p><ul><li><strong>玄戒 O3</strong>（8 月 24 日发布）：3nm 工艺，十核全大核（C1-Ultra + C1-Premium + C1-Pro，最高 4.35GHz），16 核 G2-Ultra NX GPU，NPU 200TOPS 张量算力，安兔兔跑分 <strong>522 万</strong>（首个突破 500 万的旗舰 SoC）</li><li><strong>小米 18 Fold</strong>：小米首款阔折叠形态旗舰，9 月上市；小米平板 9 Pro Max 同步搭载玄戒 O3</li></ul><p>央视财经点出了这件事的本质：小米「敢于让国产核心器件在高标准的旗舰手机中接受市场检验」，<strong>以量产产品完成严格验证，牵引国产核心器件加速走向规模应用</strong>。旗舰机是内存可靠性、功耗、兼容性最苛刻的试炼场——能进旗舰，才算真正出师。</p><hr><h2 id="实际意义"><a href="#实际意义" class="headerlink" title="实际意义"></a>实际意义</h2><h3 id="对长鑫：从跟随者到规则参与者"><a href="#对长鑫：从跟随者到规则参与者" class="headerlink" title="对长鑫：从跟随者到规则参与者"></a>对长鑫：从跟随者到规则参与者</h3><p>过去长鑫的角色是「追赶者」——做 DDR4、LPDDR4X，再追 LPDDR5。LPDDR6 全球首发意味着它第一次站在了<strong>新产品周期的起点</strong>上：享受完整的产品生命周期红利，而不是在生命周期末端靠价格竞争。Counterpoint 研究副总裁 Neil Shah 的评价很直白：问题「不在于长鑫能否跻身三大内存厂商之列，而在于何时能做到」。</p><p>资本市场的态度也说明了预期：长鑫科技 7 月底上市后市值一度站上 3.98 万亿元、居科创板首位；2026 上半年营收 1503.1 亿元（同比 +873.64%），归母净利润 776.05 亿元、同比扭亏为盈。行业普遍关注其 IPO 募资将如何投向 <strong>HBM 和 LPDDR6 产能扩张</strong>。</p><h3 id="对中国半导体：验证了「协同突破」的路径"><a href="#对中国半导体：验证了「协同突破」的路径" class="headerlink" title="对中国半导体：验证了「协同突破」的路径"></a>对中国半导体：验证了「协同突破」的路径</h3><p>这次首发的样板价值在于<strong>链路完整</strong>：JEDEC 标准内参与 → 长鑫按标准设计产品 → 送样验证 → 国产 SoC（玄戒 O3）首家支持 → 旗舰整机首发 → 规模出货。内存厂商、SoC 厂商、整机厂商三方在同一个时间窗内完成协同，这在国产半导体史上是第一次。</p><p>它还回答了一个老问题：国产高端器件「造出来」和「用起来」之间的鸿沟怎么跨——答案是<strong>让旗舰机当场验证</strong>，用市场反馈倒逼迭代，而不是等完美再上场。</p><h3 id="对消费者：旗舰体验的直接提升"><a href="#对消费者：旗舰体验的直接提升" class="headerlink" title="对消费者：旗舰体验的直接提升"></a>对消费者：旗舰体验的直接提升</h3><p>对普通用户来说，LPDDR6 带来的变化是可感知的：</p><ul><li><strong>端侧 AI 更流畅</strong>：大模型推理吃内存带宽，带宽提升 20% 直接换来响应速度和可运行的模型规模</li><li><strong>游戏与多任务</strong>：折叠屏大屏多任务、高负载游戏更依赖内存吞吐</li><li><strong>能效改善</strong>：低功耗设计意味着同等负载下更省电，对折叠屏这种电池吃紧的形态尤其重要</li></ul><h3 id="对全球-DRAM-格局：四强时代开启"><a href="#对全球-DRAM-格局：四强时代开启" class="headerlink" title="对全球 DRAM 格局：四强时代开启"></a>对全球 DRAM 格局：四强时代开启</h3><p>Counterpoint 数据显示，2026 年 Q2 三星、SK 海力士、美光合计占全球 DRAM 收入约<strong>九成</strong>，长鑫约 <strong>7%</strong>——但已是全球增长最快的 DRAM 供应商（全球第四、中国第一）。LPDDR6 首发是一个信号：在 2026 年 DRAM 供给紧缺、持续涨价的超级周期里，长鑫拿到了切入高端市场的门票。竞争格局从「三强」向「3+N」演变，对下游整机厂意味着多了一个有分量的供应商选项。</p><hr><h2 id="影响范围"><a href="#影响范围" class="headerlink" title="影响范围"></a>影响范围</h2><h3 id="智能手机与端侧-AI（最先落地）"><a href="#智能手机与端侧-AI（最先落地）" class="headerlink" title="智能手机与端侧 AI（最先落地）"></a>智能手机与端侧 AI（最先落地）</h3><p>LPDDR6 的影响首先发生在手机上。未来两年安卓旗舰会把 LPDDR6 作为标配硬件，长鑫的先发意味着国产高端内存有机会进入更多旗舰机型的物料清单。随着良率爬坡和多平台适配完成，渗透会从折叠旗舰逐步下探。</p><h3 id="PC（LPDDR6-CAMM2）"><a href="#PC（LPDDR6-CAMM2）" class="headerlink" title="PC（LPDDR6 CAMM2）"></a>PC（LPDDR6 CAMM2）</h3><p>JEDEC 的 LPDDR6 引入了 CAMM2 等面向 PC 的封装扩展，AI PC 的本地大模型负载同样吃带宽。长鑫若跟进 CAMM2 形态，将直接影响笔记本内存的供应格局。</p><h3 id="智能汽车"><a href="#智能汽车" class="headerlink" title="智能汽车"></a>智能汽车</h3><p>智能座舱正在变成「车里的旗舰手机」——多屏、语音大模型、辅助驾驶感知都吃内存带宽。长鑫官方对 LPDDR6 的应用展望里，<strong>智能汽车</strong>被明确列出，车规市场是下一个增量。</p><h3 id="服务器与-AI-数据中心"><a href="#服务器与-AI-数据中心" class="headerlink" title="服务器与 AI 数据中心"></a>服务器与 AI 数据中心</h3><p>低功耗内存正在服务器领域扮演新角色（如 SoC 集成大内存容量的架构路线）。长鑫官方表示 LPDDR6 未来将在移动设备、服务器等领域广泛运用，端侧与数据中心的内存带宽需求共振，这是产能扩张的底气所在。</p><h3 id="产业链上下游"><a href="#产业链上下游" class="headerlink" title="产业链上下游"></a>产业链上下游</h3><p>存储量产从来不是一家公司的事。据腾讯新闻 7 月报道，长鑫已提前布局供应链——引入新的封装基板供应商海信电子，推动从卷对卷工艺向<strong>面板级封装</strong>转型。LPDDR6 上量会带动基板、封装、测试、设备等一整条国产配套链。</p><h3 id="国际竞争与价格"><a href="#国际竞争与价格" class="headerlink" title="国际竞争与价格"></a>国际竞争与价格</h3><p>三星、SK 海力士的 LPDDR6 也在上市路上，三家的量产窗口重叠意味着高端 DRAM 的竞争会更激烈。叠加当前 DRAM 供给紧缺的涨价周期，长鑫的新增产能每多一分，全球定价博弈的天平就多一分变数——这对下游整机厂是利好，对海外巨头的超额利润是稀释。</p><hr><h2 id="冷静看待：首发之后的挑战"><a href="#冷静看待：首发之后的挑战" class="headerlink" title="冷静看待：首发之后的挑战"></a>冷静看待：首发之后的挑战</h2><p>首发是里程碑，但不是终点，几个现实问题需要时间回答：</p><ol><li><strong>良率与产能爬坡</strong>。首发不等于大规模供应，小米 18 Fold 的备货量、后续机型的导入节奏，取决于良率爬坡速度。这是所有新存储产品的必经之路。</li><li><strong>HBM 差距仍在</strong>。AI 数据中心最紧缺的是 HBM，这是长鑫与国际巨头差距最大的品类；LPDDR6 的 IPO 募资投向之一就是 HBM，追赶需要时间。</li><li><strong>生态验证需要周期</strong>。第一款机型首发只是开始，多平台适配、车规与服务器级验证都需要按年计的周期。</li><li><strong>份额差距客观存在</strong>。7% 对九成，高端市场的实质性突破要靠连续几代产品维持，一两款首发不能定论。</li></ol><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>长鑫 LPDDR6 量产这件事，技术参数上是一次常规迭代（12.8Gbps、16GB、带宽 +20%），但<strong>行业位置上是一次非常规突破</strong>：中国存储第一次在新一代高端内存标准上全球首发商用，且和国产 SoC、国产整机在同一天官宣协同——「从『芯』到『存』」的产业链闭环首次在旗舰级产品上跑通。</p><p>值得记住的时间点：JEDEC 标准发布后 13 个月，长鑫完成了从对齐标准、送样验证到量产商用的全过程，把过去「半年以上」的代差变成了「先发」。至于这能否转化为持续的份额与利润，看接下来的产能、良率与 HBM 进展——但至少在这一代，发令枪是长鑫打响的。</p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://www.guancha.cn/economy/2026_08_29_829101.shtml">长鑫官宣LPDDR6量产，雷军称小米将首发（观察者网）</a></li><li><a href="https://www.sohu.com/a/1069206338_161795">长鑫宣布LPDDR6内存已量产，称打破海外厂商长期垄断（搜狐）</a></li><li><a href="https://www.ithome.com/0/995/852.htm">长鑫科技：自研LPDDR6芯片性能较LPDDR5X全面跃升（IT之家）</a></li><li><a href="https://www.yicai.com/news/103339656.html">长鑫存储：LPDDR6内存正式量产（第一财经）</a></li><li><a href="https://finance.eastmoney.com/a/202608293859189569.html">全球首发！长鑫科技官宣LPDDR6量产（东方财富&#x2F;北京商报）</a></li><li><a href="https://news.qq.com/rain/a/20260828A0BYGA00">长鑫LPDDR6内存芯片送样验证加速量产（腾讯新闻）</a></li><li><a href="https://finance.sina.com.cn/tech/discovery/2026-08-29/doc-inipxyyz9373789.shtml">小米18 Fold首发搭载长鑫LPDDR6+玄戒O3！央视：为中国半导体协同突破提供了新样本（新浪科技&#x2F;快科技）</a></li><li><a href="https://www.ithome.com/0/993/510.htm">小米18 Fold折叠屏手机首发玄戒O3芯片，9月正式上市（IT之家）</a></li><li><a href="https://www.eet-china.com/mp/a420102.html">LPDDR6内存标准正式发布：JEDEC JESD209-6（电子工程专辑）</a></li><li><a href="https://www.jedec.org/sites/default/files/Brett%20Murdock_FINAL_Mobile_2024.pdf">JEDEC LPDDR6 介绍材料（jedec.org）</a></li><li><a href="https://xueqiu.com/3261990793/407225456">长鑫科技LPDDR6量产站上世界第一排（雪球）</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/29/cxmt-lpddr6-mass-production/</id>
    <link href="https://blog.ztmss.com/2026/08/29/cxmt-lpddr6-mass-production/"/>
    <published>2026-08-29T11:00:00.000Z</published>
    <summary>2026年8月29日长鑫科技宣布自研 LPDDR6 内存实现量产，是全球 LPDDR6 产品首次落地商用，首批搭载小米18 Fold（玄戒O3）。本文从 JEDEC 标准与产品参数做内容解读，分析它对中国存储产业和全球 DRAM 格局的实际意义，并梳理其在手机、PC、汽车、服务器等场景的影响范围。</summary>
    <title>长鑫 LPDDR6 量产解读：全球首发背后的技术细节、实际意义与影响范围</title>
    <updated>2026-08-29T05:41:26.106Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="ZCode" scheme="https://blog.ztmss.com/tags/ZCode/"/>
    <category term="AI智能体" scheme="https://blog.ztmss.com/tags/AI%E6%99%BA%E8%83%BD%E4%BD%93/"/>
    <category term="GLM" scheme="https://blog.ztmss.com/tags/GLM/"/>
    <category term="编程助手" scheme="https://blog.ztmss.com/tags/%E7%BC%96%E7%A8%8B%E5%8A%A9%E6%89%8B/"/>
    <category term="MCP" scheme="https://blog.ztmss.com/tags/MCP/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p><strong>ZCode</strong> 是智谱（Z.ai）推出的一款<strong>智能体开发环境（ADE，Agentic Development Environment）</strong>，官方定位是「面向长周期任务的全功能智能体开发环境」。和传统的代码补全插件不同，ZCode 把「智能体」而不是「手写代码」放在中心位置——你描述目标，它自己读项目、写代码、跑命令、验证结果。</p><ul><li><strong>官网</strong>：<a href="https://zcode.z.ai/">https://zcode.z.ai</a></li><li><strong>文档</strong>：<a href="https://zcode.z.ai/en/docs/install">https://zcode.z.ai/en/docs/install</a></li><li><strong>最新版本</strong>：v3.9.2（2026-08-26）</li><li><strong>应用本身免费</strong>，模型能力需要你自己提供（GLM Coding Plan 订阅、BigModel 资源包，或任意兼容的 API Key）</li></ul><blockquote><p>本文中的功能说明与配置路径均来自官方文档与本机实际安装目录，实测环境为 Windows 10 x64 + ZCode 桌面版。</p></blockquote><hr><h2 id="功能介绍"><a href="#功能介绍" class="headerlink" title="功能介绍"></a>功能介绍</h2><table><thead><tr><th align="left">功能</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">🤖 <strong>ZCode Agent</strong></td><td align="left">内置智能体，针对 GLM-5.3 家族调优，官方标称稳定 1M 上下文，强化长轨迹、多轮工具调用、子任务拆解训练</td></tr><tr><td align="left">🎯 <strong>目标模式（Goal Mode）</strong></td><td align="left"><code>/goal</code> 设定一个目标后自动多轮迭代，每轮结束独立校验是否达成，不达成就自动继续，不用反复打「继续」</td></tr><tr><td align="left">👥 <strong>子智能体（Subagents）</strong></td><td align="left">内置 <code>general-purpose</code> 和只读的 <code>Explore</code>，可并行研究代码库；也能自建角色</td></tr><tr><td align="left">🧩 <strong>技能（Skill）</strong></td><td align="left">一个目录 + 一个 <code>SKILL.md</code> 就是一个可复用工作方法，聊天框输入 <code>$</code> 调用</td></tr><tr><td align="left">🔌 <strong>插件（Plugin）</strong></td><td align="left">一个插件可同时打包技能、命令、子智能体、MCP 服务和 Hooks，有官方插件市场</td></tr><tr><td align="left">🔗 <strong>MCP 服务</strong></td><td align="left">支持 stdio &#x2F; HTTP &#x2F; SSE 三种传输，可导入 Claude Code、Codex CLI 等现有配置</td></tr><tr><td align="left">🪝 <strong>Hooks</strong></td><td align="left">七个事件钩子，可在工具调用前后拦截、注入上下文、做权限门禁</td></tr><tr><td align="left">🌐 <strong>浏览器自动化</strong></td><td align="left">内置浏览器面板，智能体自己打开页面、点击、填表、截图，用来自验证前端改动</td></tr><tr><td align="left">📚 <strong>仓库 Wiki</strong></td><td align="left">扫描代码库生成架构指南，每个结论都带可点击的文件路径和行号</td></tr><tr><td align="left">⏰ <strong>自动化任务</strong></td><td align="left">定时任务 + 空闲时段任务，例如每个工作日早上汇总代码变更</td></tr><tr><td align="left">🖥️ <strong>远程开发</strong></td><td align="left">支持 SSH、WSL、Docker 三种远程目标</td></tr><tr><td align="left">📱 <strong>手机远程控制</strong></td><td align="left">扫码把桌面窗口临时开放给手机，或绑定微信 &#x2F; 飞书机器人长期使用</td></tr><tr><td align="left">🕘 <strong>编辑历史</strong></td><td align="left">记录智能体对文件的改动，可回溯</td></tr></tbody></table><hr><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><h3 id="支持的平台"><a href="#支持的平台" class="headerlink" title="支持的平台"></a>支持的平台</h3><p>官方文档明确支持：<strong>macOS</strong>（Apple Silicon &#x2F; Intel）、<strong>Windows</strong>（x64 &#x2F; ARM64）、<strong>Linux</strong>（x64、ARM64，提供 AppImage &#x2F; DEB &#x2F; RPM）。</p><h3 id="下载地址"><a href="#下载地址" class="headerlink" title="下载地址"></a>下载地址</h3><p>打开 <a href="https://zcode.z.ai/">https://zcode.z.ai</a> 点击 <strong>Download ZCode</strong> 会自动匹配你的系统。也可以直接用 CDN 直链（以 v3.9.2 为例）：</p><table><thead><tr><th align="left">平台</th><th align="left">下载链接</th></tr></thead><tbody><tr><td align="left">macOS Apple Silicon</td><td align="left"><code>https://cdn-zcode.z.ai/zcode/electron/releases/3.9.2/macos-arm64/ZCode-3.9.2-mac-arm64.dmg</code></td></tr><tr><td align="left">macOS Intel</td><td align="left"><code>https://cdn-zcode.z.ai/zcode/electron/releases/3.9.2/macos-x64/ZCode-3.9.2-mac-x64.dmg</code></td></tr><tr><td align="left">Windows x64</td><td align="left"><code>https://cdn-zcode.z.ai/zcode/electron/releases/3.9.2/windows-x64/ZCode-3.9.2-win-x64.exe</code></td></tr><tr><td align="left">Windows ARM64</td><td align="left"><code>https://cdn-zcode.z.ai/zcode/electron/releases/3.9.2/windows-arm64/ZCode-3.9.2-win-arm64.exe</code></td></tr><tr><td align="left">Linux x64</td><td align="left"><code>https://cdn-zcode.z.ai/zcode/electron/releases/3.9.2/linux-x64/ZCode-3.9.2-linux-x64.AppImage</code></td></tr></tbody></table><blockquote><p>Windows 安装包约 155 MB。把版本号替换成新版本即可获取对应文件，建议以官网下载页为准。</p></blockquote><h3 id="各平台安装步骤"><a href="#各平台安装步骤" class="headerlink" title="各平台安装步骤"></a>各平台安装步骤</h3><p><strong>Windows</strong></p><ol><li>下载 <code>.exe</code> 安装包</li><li>双击运行，按向导完成安装</li><li>从开始菜单或桌面快捷方式启动</li><li>若被杀毒软件拦截，把安装目录加入白名单</li></ol><p><strong>macOS</strong></p><ol><li>下载并打开 <code>.dmg</code></li><li>把 <code>ZCode.app</code> 拖进「应用程序」文件夹</li><li>从启动台打开</li></ol><p>如果提示「应用已损坏」，是隔离属性导致的，执行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">xattr -dr com.apple.quarantine /Applications/ZCode.app</span><br></pre></td></tr></table></figure><p><strong>Linux</strong></p><p>AppImage 方式：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">chmod</span> +x ZCode-*.AppImage</span><br><span class="line">./ZCode-3.9.2-linux-x64.AppImage</span><br></pre></td></tr></table></figure><p>部分发行版还需要 fuse 依赖（Ubuntu &#x2F; Debian 缺 <code>libfuse2</code> 时无法启动）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt install libfuse2</span><br></pre></td></tr></table></figure><p><code>.deb</code> &#x2F; <code>.rpm</code> 走各自发行版的包管理器安装即可。</p><hr><h2 id="首次启动"><a href="#首次启动" class="headerlink" title="首次启动"></a>首次启动</h2><p>整个流程官方给的预估时间是「约 2 分钟」：</p><ol><li><strong>引导页</strong> — 可以直接「开始使用 ZCode」，也可以走<strong>数据迁移向导</strong>。注意迁移范围有限，目前只导入 Claude Code 和旧版 ZCode Agent 的会话，之后也能在设置里再迁移。</li><li><strong>选择工作区</strong> — 指定一个项目目录。如果不想绑定仓库，可以在工作区菜单里选「在项目外工作」。</li><li><strong>连接模型</strong> — 左下角 <strong>Connect</strong> 按钮，提供三个入口：Connect Z.ai、Connect BigModel、Use API Key。</li><li><strong>冒烟测试</strong> — 随便发一句「列出当前目录的文件」，确认智能体能正常跑起来。</li></ol><hr><h2 id="连接模型"><a href="#连接模型" class="headerlink" title="连接模型"></a>连接模型</h2><p>ZCode 本身不含模型额度，必须先接上模型服务。配置文件落在 <code>~/.zcode/v2/config.json</code>。</p><h3 id="方式一：账号快连（推荐）"><a href="#方式一：账号快连（推荐）" class="headerlink" title="方式一：账号快连（推荐）"></a>方式一：账号快连（推荐）</h3><p>设置 → <strong>模型服务商</strong> → 选择 <strong>Z.ai 开放平台</strong> 或 <strong>BigModel</strong>，走登录流程后 Key 会自动回填。用 GLM Coding Plan 订阅走账号授权时<strong>不需要手填 Base URL</strong>，路由是自动的。</p><h3 id="方式二：手填-Base-URL-API-Key"><a href="#方式二：手填-Base-URL-API-Key" class="headerlink" title="方式二：手填 Base URL + API Key"></a>方式二：手填 Base URL + API Key</h3><p>不同套餐对应的端点<strong>不能混用</strong>，这是最常见的踩坑点：</p><table><thead><tr><th align="left">场景</th><th align="left">OpenAI 兼容端点</th><th align="left">Anthropic 协议端点</th></tr></thead><tbody><tr><td align="left">Coding Plan（Z.ai）</td><td align="left"><code>https://api.z.ai/api/coding/paas/v4</code></td><td align="left"><code>https://api.z.ai/api/anthropic</code></td></tr><tr><td align="left">Coding Plan（BigModel）</td><td align="left"><code>https://open.bigmodel.cn/api/coding/paas/v4</code></td><td align="left"><code>https://open.bigmodel.cn/api/anthropic</code></td></tr><tr><td align="left">资源包 &#x2F; 余额</td><td align="left"><code>https://api.z.ai/api/paas/v4</code></td><td align="left">—</td></tr></tbody></table><p>三类端点的区别：</p><ul><li><code>/api/coding/paas/v4</code> — <strong>仅</strong> Coding Plan 可用</li><li><code>/api/paas/v4</code> — OpenAI 兼容通用端点，用于资源包和余额计费</li><li><code>/api/anthropic</code> — 同样服务资源包，走 Anthropic 协议，<strong>是 ZCode 的默认协议</strong></li></ul><h3 id="其他模型服务商"><a href="#其他模型服务商" class="headerlink" title="其他模型服务商"></a>其他模型服务商</h3><p>除 GLM 外，ZCode 也支持接入：</p><table><thead><tr><th align="left">服务商</th><th align="left">Base URL</th></tr></thead><tbody><tr><td align="left">Anthropic</td><td align="left"><code>https://api.anthropic.com</code></td></tr><tr><td align="left">OpenAI</td><td align="left"><code>https://api.openai.com</code></td></tr><tr><td align="left">OpenRouter</td><td align="left"><code>https://openrouter.ai/api</code></td></tr><tr><td align="left">Moonshot</td><td align="left"><code>https://api.moonshot.cn/anthropic</code></td></tr><tr><td align="left">MiniMax</td><td align="left"><code>https://api.minimaxi.com/anthropic</code></td></tr><tr><td align="left">小米 MiMo</td><td align="left"><code>https://api.xiaomimimo.com/v1</code></td></tr></tbody></table><p>也可以添加任意 Anthropic &#x2F; OpenAI 兼容的自定义服务商。BigModel 新用户有 5 天试用额度：GLM-5.3 每天 300 万 tokens，GLM-5.3-Flash 每天 500 万 tokens。</p><h3 id="两个容易踩的坑"><a href="#两个容易踩的坑" class="headerlink" title="两个容易踩的坑"></a>两个容易踩的坑</h3><ul><li><strong>终端环境变量不会被继承</strong>。你在 shell 里 export 的 GLM Key，桌面应用读不到，必须在应用内配置。</li><li><strong>代理必须在应用内设置</strong>。设置 → 通用里的 HTTP Proxy 留空<strong>不等于跟随系统</strong>，ZCode 完全忽略 <code>HTTP_PROXY</code> 这类环境变量。所以经常出现「终端能联网、应用连不上」的情况。改完代理需要重启应用。另外，代理<strong>不覆盖</strong> SSH 连接和 Web 远程控制通道。</li></ul><hr><h2 id="界面与基础用法"><a href="#界面与基础用法" class="headerlink" title="界面与基础用法"></a>界面与基础用法</h2><h3 id="添加上下文"><a href="#添加上下文" class="headerlink" title="添加上下文"></a>添加上下文</h3><p>聊天框左下角的 <code>+</code> 按钮，或直接输入对应触发字符：</p><table><thead><tr><th align="left">入口</th><th align="left">触发符</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left">添加附件</td><td align="left">—</td><td align="left">上传文件</td></tr><tr><td align="left">Mention</td><td align="left"><code>@</code></td><td align="left">引用文件或整个文件夹</td></tr><tr><td align="left">会话引用</td><td align="left"><code>#</code></td><td align="left">关联一段历史会话</td></tr><tr><td align="left">命令</td><td align="left"><code>/</code></td><td align="left">调用内置命令或自存的提示词</td></tr><tr><td align="left">技能</td><td align="left"><code>$</code></td><td align="left">调用技能</td></tr></tbody></table><p>粘贴长文本会自动转成附件。在回复、推理过程、代码块或工具结果里选中一行，会浮出「添加到当前任务」按钮。</p><h3 id="执行模式（重要）"><a href="#执行模式（重要）" class="headerlink" title="执行模式（重要）"></a>执行模式（重要）</h3><p>输入框聚焦时按 <strong><code>Shift + Tab</code></strong> 循环切换四档权限：</p><table><thead><tr><th align="left">模式</th><th align="left">行为</th><th align="left">适用场景</th></tr></thead><tbody><tr><td align="left"><strong>Ask before changes</strong></td><td align="left">每次改文件、跑命令都要确认（默认）</td><td align="left">高风险代码、生产配置</td></tr><tr><td align="left"><strong>Edit automatically</strong></td><td align="left">编辑直接生效，命令仍需确认</td><td align="left">常规开发</td></tr><tr><td align="left"><strong>Plan mode</strong></td><td align="left">先出方案，你批准后才动手</td><td align="left">多步骤、需要对齐思路的任务</td></tr><tr><td align="left"><strong>Full access</strong></td><td align="left">打断最少，持续推进</td><td align="left">低风险、范围明确的任务</td></tr></tbody></table><h3 id="思考档位"><a href="#思考档位" class="headerlink" title="思考档位"></a>思考档位</h3><p>输入框右下角模型名旁边的思考图标，三档：<strong>Low</strong>（追速度）、<strong>High</strong>（日常平衡）、<strong>Max</strong>（默认，最深，适合架构设计和硬 bug）。</p><h3 id="侧边会话"><a href="#侧边会话" class="headerlink" title="侧边会话"></a>侧边会话</h3><p>不打扰主任务的并行对话，四种打开方式：选中文本后点「在侧边会话中提问」、<code>/side</code> 或 <code>/btw</code> 命令、右侧面板 <code>+</code> 菜单、起始页。它会借用主会话的历史作为上下文，但界面是空的，并且可以调工具、改文件。每个任务每窗口只有一个，关掉即不可恢复。</p><h3 id="分叉（Fork）"><a href="#分叉（Fork）" class="headerlink" title="分叉（Fork）"></a>分叉（Fork）</h3><p>鼠标悬停在<strong>已完成</strong>的助手回复上点 Fork，会生成一个「Fork of &lt;原标题&gt;」的新任务，继承到那一刻的历史、模型、思考档位。原任务继续跑。注意文件不会回滚——两个会话共享同一个工作区。</p><hr><h2 id="目标模式：让它自己「继续」"><a href="#目标模式：让它自己「继续」" class="headerlink" title="目标模式：让它自己「继续」"></a>目标模式：让它自己「继续」</h2><p>长任务最烦的是反复打「继续」。<strong>Goal Mode</strong> 就是解决这个的：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/goal 把 src/ 下所有 TypeScript 类型错误清零，且保持现有测试全绿</span><br></pre></td></tr></table></figure><table><thead><tr><th align="left">命令</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>/goal</code></td><td align="left">查看当前目标</td></tr><tr><td align="left"><code>/goal &lt;目标&gt;</code></td><td align="left">设定目标（会覆盖已有目标）</td></tr><tr><td align="left"><code>/goal replace &lt;目标&gt;</code></td><td align="left">显式替换</td></tr><tr><td align="left"><code>/goal pause</code> &#x2F; <code>/goal resume</code></td><td align="left">暂停 &#x2F; 继续</td></tr><tr><td align="left"><code>/goal clear</code></td><td align="left">清除目标</td></tr></tbody></table><p>运行机制：每一轮结束后有一个<strong>独立的校验环节</strong>判断目标是否达成——不达成就输出下一步并自动开启下一轮，达成就收尾出总结。校验是<strong>证据驱动</strong>的：改动的文件、命令输出、测试结果算证据，而计划、清单、听起来很有信心的文字<strong>不算</strong>。任何未完成的 to-do 都会阻止收尾。</p><p>两种情况会被拒绝并给出原因：<strong>Plan mode 下</strong>（计划模式的目的是先定方案，和自动连轮冲突）和<strong>任务正在运行时</strong>。</p><p>配合 Full access 或 Edit 模式打断最少。目标状态在关闭再打开会话后仍然保留。</p><p><strong>适合什么目标</strong>：一句话能说清、但需要很多轮才能做完的事——模块重构且测试保持通过、清零全部类型错误、把 Lighthouse 分数拉过 90。目标要可校验，「让它更快一点」这种不行。</p><hr><h2 id="子智能体：并行研究代码库"><a href="#子智能体：并行研究代码库" class="headerlink" title="子智能体：并行研究代码库"></a>子智能体：并行研究代码库</h2><p>内置两个角色，都不能改名或删除，但可以给它们单独指定模型和思考档位：</p><ul><li><strong><code>general-purpose</code></strong> — 默认的通用角色，拥有全部工具，适合自成一体的实现、验证跑批、并行工作</li><li><strong><code>Explore</code></strong> — <strong>只读</strong>的代码库研究专家，用来梳理调用链、摸清架构、收集证据。它「不创建、不修改、不移动、不删除文件」</li></ul><p>主智能体判断需要隔离上下文或并行研究时会自动通过 Agent 工具调起。你也可以显式指挥：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">先用 Explore 研究一下这个模块的调用链，再决定怎么改</span><br></pre></td></tr></table></figure><h3 id="自建子智能体（Beta）"><a href="#自建子智能体（Beta）" class="headerlink" title="自建子智能体（Beta）"></a>自建子智能体（Beta）</h3><p>设置 → <strong>Subagents</strong> → <strong>New</strong>，保存后会写入 <code>~/.zcode/agents/&lt;name&gt;.md</code>，下次运行生效。</p><p>Frontmatter 字段（<strong>camelCase，大小写敏感</strong>）：</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">name: code-reviewer</span><br><span class="line">description: 审查当前改动的代码质量、边界条件和安全问题。需要代码评审时使用。</span><br><span class="line">model: glm-5.3</span><br><span class="line">thoughtLevel: high</span><br><span class="line">color: blue</span><br><span class="line">tools:</span><br><span class="line"><span class="bullet">  -</span> Read</span><br><span class="line"><span class="bullet">  -</span> Grep</span><br><span class="line"><span class="bullet">  -</span> Glob</span><br><span class="line">maxTurns: 20</span><br><span class="line"><span class="section">injectAgentsMd: true</span></span><br><span class="line"><span class="section">---</span></span><br><span class="line"></span><br><span class="line">你是一名严格的代码评审者。逐条给出问题、影响范围和修复建议……</span><br></pre></td></tr></table></figure><p>几个容易踩的点：</p><ul><li><code>name</code> 和 <code>description</code> <strong>必填</strong>，缺任一个文件会被忽略并给出诊断</li><li><code>description</code> 直接决定自动选中率，写得越准越容易被自动调用</li><li><code>tools</code> 省略或写 <code>*</code> 表示继承全部（含 MCP）；一旦自定义列表就是<strong>穷举</strong>的，会把所有 MCP 工具排除掉（<code>WebSearch</code> &#x2F; <code>WebFetch</code> 不受影响，因为它们不是 MCP）。需要 MCP 就手动写 <code>mcp__&lt;server&gt;__&lt;tool&gt;</code>，通配符无效</li><li><code>thoughtLevel</code> 只在指定了具体 <code>model</code> 时生效，注意<strong>不是</strong> <code>reasoningEffort</code>，未知字段会静默失败</li><li><code>injectAgentsMd</code> 默认开启，会注入 <code>~/.zcode/AGENTS.md</code> 和工作区的 <code>AGENTS.md</code>；<code>Explore</code> 永远不注入</li></ul><p>限制：目前只支持用户级（<code>~/.zcode/agents/</code>），子智能体<strong>不能再派生子智能体</strong>，只能看到会话启动时已连接的 MCP 服务。</p><p><strong>前台 vs 后台</strong>：前台子智能体并行跑但会阻塞主任务；后台的让主任务继续，自己稍后回报。后台的 <code>Explore</code> 被限制为只读工具。</p><hr><h2 id="指令文件-AGENTS-md"><a href="#指令文件-AGENTS-md" class="headerlink" title="指令文件 AGENTS.md"></a>指令文件 AGENTS.md</h2><p>ZCode 读两个指令文件，<strong>全局在前、工作区在后</strong>，工作区文件视为权威：</p><ul><li><code>~/.zcode/AGENTS.md</code> — 个人跨项目偏好（回复语言、评审风格、本地工作流约定）</li><li><code>&lt;项目根&gt;/AGENTS.md</code> — 项目约定（架构边界、日志规范、测试要求、提交策略）</li></ul><p><strong>没有</strong>多级合并、<strong>不</strong>扫描子目录、<strong>不</strong>展开 <code>@import</code> &#x2F; <code>@include</code>。<code>CLAUDE.md</code> 只作为一次性迁移来源，运行时不会持续读取。</p><p>内置 <code>/init</code> 命令针对的是当前工作区的 <code>AGENTS.md</code>。</p><p>我自己的工作区 <code>AGENTS.md</code> 长这样，纯文本约定就能显著改善智能体行为：</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 工作区约定</span></span><br><span class="line"></span><br><span class="line"><span class="section">## 网络代理</span></span><br><span class="line"><span class="bullet">-</span> 唯一代理：socks5h://192.168.2.8:1081（仅 SOCKS5 模式可用）</span><br><span class="line"><span class="bullet">-</span> 所有访问境外服务的操作一律走此代理</span><br><span class="line"></span><br><span class="line"><span class="section">## 博客写作流程</span></span><br><span class="line"><span class="bullet">-</span> 修改 source/<span class="emphasis">_posts/*.md → 提交推送 hexo 分支 → npx hexo generate → npx hexo deploy</span></span><br><span class="line"><span class="emphasis">- 每篇新文章必须包含 ai: true 与 post_</span>ai 摘要</span><br></pre></td></tr></table></figure><p>另外还有一个独立的 <strong>项目记忆（Project Memory）</strong>，由智能体自己写：设置 → 通用 → Memory（<strong>默认关闭</strong>）。它在成功的轮次后提炼可复用事实，新会话自动加载。代价是额外 token，且只对新会话生效，应用内不能浏览或清除，<strong>只作用于主对话，子智能体既不读也不写</strong>。</p><hr><h2 id="技能（Skill）"><a href="#技能（Skill）" class="headerlink" title="技能（Skill）"></a>技能（Skill）</h2><p>技能是「可复用的工作方法」。命令适合存提示词，技能适合装一整套方法论。</p><h3 id="目录结构"><a href="#目录结构" class="headerlink" title="目录结构"></a>目录结构</h3><p>目录名就是技能名，也是聊天里引用的 token：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">~/.zcode/skills/&lt;skill-name&gt;/SKILL.md</span><br></pre></td></tr></table></figure><p>也可以导入到当前项目作用域。要打包分发就放进插件，<strong>必须是扁平的</strong> <code>skills/&lt;name&gt;/SKILL.md</code> 布局，套一层分组目录会导致识别不到。</p><h3 id="SKILL-md-格式"><a href="#SKILL-md-格式" class="headerlink" title="SKILL.md 格式"></a>SKILL.md 格式</h3><p>Frontmatter 只有两个字段，<strong>都是必填</strong>：</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">name: code-review-checklist</span><br><span class="line"><span class="section">description: 按固定清单审查代码改动，覆盖边界条件、错误处理、并发安全和日志规范。需要代码评审或提交前自查时使用。</span></span><br><span class="line"><span class="section">---</span></span><br><span class="line"></span><br><span class="line"><span class="section"># 代码评审清单</span></span><br><span class="line"></span><br><span class="line"><span class="section">## 何时使用</span></span><br><span class="line">用户要求评审代码、提交前自查，或询问改动有什么风险时。</span><br><span class="line"></span><br><span class="line"><span class="section">## 步骤</span></span><br><span class="line"><span class="bullet">1.</span> 用 git diff 拿到完整改动</span><br><span class="line"><span class="bullet">2.</span> 逐文件检查以下维度……</span><br><span class="line"></span><br><span class="line"><span class="section">## 输出格式</span></span><br><span class="line">按「文件:行号 → 问题 → 影响 → 建议」输出。</span><br></pre></td></tr></table></figure><p>约束：</p><ul><li>缺 <code>name</code> 或 <code>description</code> 会<strong>整个被忽略</strong>，原因在设置诊断里能看到</li><li><code>description</code> 上限 <strong>1024 字符</strong>，超了是<strong>整个技能作废</strong>而不是截断，长内容写正文</li><li>正文超过 <strong>100KB</strong> 会在加载时截断</li></ul><h3 id="调用方式"><a href="#调用方式" class="headerlink" title="调用方式"></a>调用方式</h3><p>聊天框输入 <code>$</code> 选技能，再接你的需求：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$code-review-checklist 审查我当前的改动</span><br></pre></td></tr></table></figure><p>选中的技能会渲染成一个标签。输入 <code>/</code> 也能看到 Skills 分组。</p><h3 id="上下文预算（这点很关键）"><a href="#上下文预算（这点很关键）" class="headerlink" title="上下文预算（这点很关键）"></a>上下文预算（这点很关键）</h3><p><strong>每一轮</strong>都会注入所有已启用技能的元数据：名字 + 最多 250 字符的描述摘要。正文是懒加载的，只在调用时才读。所有技能共享一个固定的元数据预算，<strong>溢出后会降级成只注入名字</strong>——这会直接毁掉模型自动选技能的能力。</p><p>所以技能装得越多，自动触发越不准。技能在面板里能看到但从来不触发，官方给了四个原因：元数据降级、<code>description</code> 太含糊、子智能体的 <code>tools</code> 白名单排除了技能工具、父插件被禁用。</p><h3 id="内置技能"><a href="#内置技能" class="headerlink" title="内置技能"></a>内置技能</h3><p><code>zcode-configuration-guide</code> 默认启用、零配置，它是配置问题的「地图」。配套还有一批诊断技能：</p><ul><li><code>diagnosing-skills</code> — 技能没被发现 &#x2F; 不触发 &#x2F; 被同名遮蔽</li><li><code>diagnosing-commands</code> — <code>/</code> 命令缺失 &#x2F; 被覆盖 &#x2F; frontmatter 报错</li><li><code>diagnosing-mcp</code> — MCP 连不上 &#x2F; 工具不出现 &#x2F; 超时</li><li><code>diagnosing-hooks</code> — Hook 不触发 &#x2F; matcher 不匹配 &#x2F; 脚本没有执行权限</li><li><code>diagnosing-plugins</code> — 插件不在列表 &#x2F; 安装失败 &#x2F; 组件缺失</li></ul><p>目前<strong>没有</strong>独立的技能市场。设置 → Skills 里的导入图标可以扫描 Claude Code、Codex CLI、OpenClaw、Augment、Windsurf 的目录一键导入，可选<strong>软链接</strong>（跟随源变化，依赖路径不变）或<strong>复制</strong>（独立，不再同步）。</p><p>远程 SSH &#x2F; WSL 工作区需要在工作区头部 Sync 下拉里手动 <strong>Sync Skill</strong>，因为用户级技能是本地的。</p><hr><h2 id="插件（Plugin）"><a href="#插件（Plugin）" class="headerlink" title="插件（Plugin）"></a>插件（Plugin）</h2><p>一个插件可以同时打包 <strong>技能、命令、子智能体、MCP 服务、Hooks</strong> 五类组件。开关插件会一次性注册或撤销它的全部组件。</p><h3 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h3><p>设置 → <strong>Plugins</strong> 打开市场（需要先打开一个工作区，否则提示「Open a workspace to manage plugins」）。分两个板块：</p><ul><li><strong>Public</strong> — 官方策展目录，分 Developer Tools、Productivity、Utilities、Guides、Templates 等分类</li><li><strong>Personal</strong> — 你自己添加的源，Claude Code 市场是预置的</li></ul><p>点卡片一键安装，新装的插件<strong>默认启用</strong>。齿轮图标进入「管理已安装」，能看到版本、来源标签、组件数量，支持启停、状态筛选、检查更新和卸载。</p><h3 id="官方插件市场"><a href="#官方插件市场" class="headerlink" title="官方插件市场"></a>官方插件市场</h3><p>ZCode 官方市场地址是 <code>https://cdn-zcode.z.ai/zcode/official-plugin/marketplace.json</code>，当前收录：</p><table><thead><tr><th align="left">插件</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>example-plugin</code></td><td align="left">最小模板插件，演示 manifest &#x2F; command &#x2F; skill &#x2F; hooks &#x2F; MCP 的推荐结构，新建插件可直接复制</td></tr><tr><td align="left"><code>mimosa</code></td><td align="left">代码安全防护，写入前 Hook、任务收尾复查、Git 门禁、安全扫描技能</td></tr><tr><td align="left"><code>github</code></td><td align="left">基于 GitHub CLI 的工作流，覆盖提交、PR、Issue、Release、Actions、Codespaces</td></tr><tr><td align="left"><code>cloudbase-skills</code></td><td align="left">腾讯云 CloudBase 开发技能与 MCP 集成</td></tr><tr><td align="left"><code>video-agent-kit</code></td><td align="left">视频剪辑工具包，云端转录合成、抽帧理解、时间线、预览渲染、TTS</td></tr><tr><td align="left"><code>video2code</code></td><td align="left">用内置 Browser Use 录 WebM 再用 ffmpeg 转 MP4，做 URL 复刻，不需要 Playwright</td></tr></tbody></table><p>内置插件（随应用发布）：</p><table><thead><tr><th align="left">插件</th><th align="left">默认状态</th></tr></thead><tbody><tr><td align="left"><code>document-skills</code>（DOCX &#x2F; PDF 生成）</td><td align="left">启用</td></tr><tr><td align="left"><code>skill-creator</code>（编写本地技能）</td><td align="left">启用</td></tr><tr><td align="left"><code>browser-use</code>（浏览器控制）</td><td align="left">启用</td></tr><tr><td align="left"><code>zcode-guide</code>（配置指南与诊断）</td><td align="left">启用</td></tr><tr><td align="left"><code>android-emulator</code></td><td align="left">关闭</td></tr><tr><td align="left"><code>ios-simulator</code>（仅 macOS）</td><td align="left">关闭</td></tr><tr><td align="left"><code>restore-legacy-sessions</code></td><td align="left">关闭</td></tr></tbody></table><p>内置插件可以禁用但不能卸载——卸载会写一个抑制标记，升级也不会自动装回来。</p><h3 id="插件结构"><a href="#插件结构" class="headerlink" title="插件结构"></a>插件结构</h3><p>manifest 查找顺序是 <code>.zcode-plugin/plugin.json</code>（推荐），兼容回退到 <code>.claude-plugin/plugin.json</code>。它是唯一必需的文件：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;my-plugin&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;0.1.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;示例插件&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;author&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span> <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;你的名字&quot;</span> <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;skills&quot;</span><span class="punctuation">:</span> <span class="string">&quot;skills&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;commands&quot;</span><span class="punctuation">:</span> <span class="string">&quot;commands&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;hooks&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hooks/hooks.json&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;mcpServers&quot;</span><span class="punctuation">:</span> <span class="string">&quot;.mcp.json&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>只有 <code>name</code> 是必填，约束为 <code>^[a-z0-9][a-z0-9._-]{0,127}$</code>。组件目录约定：<code>commands/</code>、<code>skills/&lt;name&gt;/SKILL.md</code>、<code>agents/</code>、<code>hooks/hooks.json</code>、<code>.mcp.json</code>。</p><p><code>channels</code>、<code>lspServers</code>、<code>outputStyles</code>、<code>settings</code> 会被记录但<strong>不执行</strong>。插件提供的 MCP 服务键名会变成 <code>plugin:&lt;插件名&gt;:&lt;服务名&gt;</code>。</p><p>模板变量：<code>${ZCODE_PLUGIN_ROOT}</code>（兼容 <code>${CLAUDE_PLUGIN_ROOT}</code>）、<code>${CLAUDE_PLUGIN_DATA}</code>、<code>${CLAUDE_PROJECT_DIR}</code>、<code>${user_config.key}</code>。</p><blockquote><p>⚠️ <strong>安全提示</strong>：官方文档原话是「启用插件即授予代码执行信任」。第三方插件可以拉起本地进程、读取智能体继承的环境变量。装之前先看一眼它的 <code>hooks/hooks.json</code> 和脚本。</p></blockquote><h3 id="自己发布插件"><a href="#自己发布插件" class="headerlink" title="自己发布插件"></a>自己发布插件</h3><p>更新检测是拿市场条目里的版本号和已安装的 <code>plugin.json</code> 对比，所以<strong>发布时一定要同步 bump <code>marketplace.json</code> 的版本号</strong>，否则用户收不到更新提示。</p><p>市场清单必填 <code>name</code> 和 <code>plugins</code>，条目 <code>source</code> 支持相对路径，或 <code>directory</code> &#x2F; <code>github</code> &#x2F; <code>git</code> &#x2F; <code>file</code> &#x2F; <code>url</code> &#x2F; <code>npm</code> 形式的对象。</p><hr><h2 id="MCP-服务"><a href="#MCP-服务" class="headerlink" title="MCP 服务"></a>MCP 服务</h2><h3 id="添加方式"><a href="#添加方式" class="headerlink" title="添加方式"></a>添加方式</h3><p>设置 → <strong>MCP Servers</strong> → <strong>New MCP Server</strong>。表单模式覆盖大部分场景：选作用域、填名字（比如 <code>memory</code>）、类型保持 stdio、命令填 <code>npx</code>、参数填 <code>-y @modelcontextprotocol/server-memory</code>，Key 和路径放到环境变量里。</p><p>远程服务选 HTTP 或 SSE 填 URL，认证信息放 Headers。也可以切到完整配置模式直接粘 JSON，<code>{&quot;server-name&quot;: {...}}</code> 和 <code>{&quot;mcpServers&quot;: {...}}</code> 两种形状都接受。</p><p>导入图标会扫描这些文件：<code>~/.claude/settings.json</code>、<code>~/.codex/config.toml</code>、<code>~/.config/opencode/opencode.json</code>、<code>~/.agents/mcp.json</code>。原文件不动，导入结果落到 <code>.zcode</code> 里并默认启用。</p><h3 id="配置文件路径"><a href="#配置文件路径" class="headerlink" title="配置文件路径"></a>配置文件路径</h3><table><thead><tr><th align="left">作用域</th><th align="left">路径</th><th align="left">键</th></tr></thead><tbody><tr><td align="left">用户</td><td align="left"><code>~/.zcode/cli/config.json</code></td><td align="left"><code>mcp.servers</code></td></tr><tr><td align="left">工作区</td><td align="left"><code>&lt;项目根&gt;/.zcode/config.json</code></td><td align="left"><code>mcp.servers</code></td></tr><tr><td align="left">用户（兼容）</td><td align="left"><code>~/.agents/mcp.json</code></td><td align="left"><code>mcpServers</code></td></tr><tr><td align="left">工作区（兼容）</td><td align="left"><code>&lt;项目根&gt;/.agents/mcp.json</code></td><td align="left"><code>mcpServers</code></td></tr></tbody></table><blockquote><p>注意这个不对称：用户级原生配置在 <code>.zcode/cli/</code> 下，工作区级直接在 <code>.zcode/</code> 下。</p></blockquote><p>配置示例：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;mcp&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;servers&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;memory&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;command&quot;</span><span class="punctuation">:</span> <span class="string">&quot;npx&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;args&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;-y&quot;</span><span class="punctuation">,</span> <span class="string">&quot;@modelcontextprotocol/server-memory&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;env&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;enable&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>字段：<code>command</code>、<code>args</code>、<code>env</code>、<code>enable</code>。远程条目用 URL 和可选 headers 代替 <code>command</code>。</p><h3 id="加载规则"><a href="#加载规则" class="headerlink" title="加载规则"></a>加载规则</h3><ul><li>先读工作区配置，再读用户配置，两者都会出现在列表里</li><li>同一作用域内 <strong><code>.zcode</code> 优先</strong>：只要它定义了任何服务，同级的 <code>.agents/mcp.json</code> 就<strong>整个被跳过，不做合并</strong></li><li>禁用会写 <code>&quot;enable&quot;: false</code>，字段缺失即启用</li><li>面板里的编辑<strong>只写 <code>.zcode</code></strong>，永远不写 <code>.agents</code></li><li>同名冲突时<strong>用户级覆盖工作区级</strong></li></ul><h3 id="传输方式"><a href="#传输方式" class="headerlink" title="传输方式"></a>传输方式</h3><ul><li><strong>stdio</strong> — 本地命令执行，凭据只能走环境变量</li><li><strong>HTTP &#x2F; SSE</strong> — 远程，支持可选 headers 和 OAuth</li></ul><p>OAuth 服务（官方举例 Figma 官方 MCP）启用 OAuth 后，服务行上会出现「Open authorization」按钮，点它在系统浏览器里授权，ZCode 拿到 token 后重连。它<strong>不会自己弹浏览器窗口</strong>。</p><p>推荐的起步服务：智谱的 <code>zai-mcp-server</code>（视觉）、<code>web-search-prime</code>、<code>web-reader</code>，大多需要智谱 API token。</p><blockquote><p>⚠️ 打开一个项目会<strong>自动连接</strong>它配置里的所有 MCP 服务，这些服务能跑命令、动文件、访问网络。打开不可信仓库前先看一眼 <code>.zcode/config.json</code>。</p></blockquote><hr><h2 id="Hooks"><a href="#Hooks" class="headerlink" title="Hooks"></a>Hooks</h2><p>七个事件钩子，可以在关键节点拦截、注入上下文、做权限门禁：</p><table><thead><tr><th align="left">事件</th><th align="left">matcher 匹配对象</th><th align="left">作用</th></tr></thead><tbody><tr><td align="left"><code>SessionStart</code></td><td align="left"><code>source</code>（<code>startup</code>&#x2F;<code>clear</code>&#x2F;<code>compact</code>）</td><td align="left">首次模型调用前注入环境或项目约束</td></tr><tr><td align="left"><code>UserPromptSubmit</code></td><td align="left">无（忽略 matcher）</td><td align="left">追加上下文或拦截请求，<strong>不能改写原始提示</strong></td></tr><tr><td align="left"><code>PreToolUse</code></td><td align="left">工具名</td><td align="left">allow &#x2F; ask &#x2F; deny，或替换工具输入</td></tr><tr><td align="left"><code>PermissionRequest</code></td><td align="left">工具名</td><td align="left">仅在会弹确认框时触发，可自动放行、拒绝或改权限规则</td></tr><tr><td align="left"><code>PostToolUse</code></td><td align="left">工具名</td><td align="left">成功后追加上下文，不能改输出</td></tr><tr><td align="left"><code>PostToolUseFailure</code></td><td align="left">工具名</td><td align="left">失败后补诊断或重试建议</td></tr><tr><td align="left"><code>Stop</code></td><td align="left">无</td><td align="left">检查收尾轮次，<code>block</code> 可续跑，<strong>最多连续 3 次</strong></td></tr></tbody></table><h3 id="配置"><a href="#配置" class="headerlink" title="配置"></a>配置</h3><p><strong>只有用户级生效</strong>：<code>~/.zcode/cli/config.json</code>，且必须写 <code>hooks.enabled: true</code>（默认关闭）。工作区的 <code>hooks</code> 配置会被<strong>整个丢弃</strong>。插件的 <code>hooks/hooks.json</code> 自动发现，任何插件贡献了 Hook，Hook 运行器就会自动启用。</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;hooks&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;timeoutMs&quot;</span><span class="punctuation">:</span> <span class="number">60000</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;maxOutputBytes&quot;</span><span class="punctuation">:</span> <span class="number">32768</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;events&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;PreToolUse&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">          <span class="attr">&quot;matcher&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Write|Edit&quot;</span><span class="punctuation">,</span></span><br><span class="line">          <span class="attr">&quot;hooks&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">            <span class="punctuation">&#123;</span></span><br><span class="line">              <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;process&quot;</span><span class="punctuation">,</span></span><br><span class="line">              <span class="attr">&quot;command&quot;</span><span class="punctuation">:</span> <span class="string">&quot;python3&quot;</span><span class="punctuation">,</span></span><br><span class="line">              <span class="attr">&quot;args&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;scripts/audit.py&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">              <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">              <span class="attr">&quot;timeoutMs&quot;</span><span class="punctuation">:</span> <span class="number">8000</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">          <span class="punctuation">]</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">      <span class="punctuation">]</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><strong>matcher 语法</strong>：缺省、空串或 <code>*</code> 匹配全部；只含字母、数字、下划线和 <code>|</code> 的字符串按精确名单处理（<code>Write|Edit</code>）；其他一律编译成 JS 正则，非法模式会被跳过并给出诊断。<code>Agent</code> &#x2F; <code>Task</code> 是别名，会解析成真实工具名。</p><p><strong>协议</strong>：ZCode 通过 stdin 发一行 JSON + 换行，字段同时提供 camelCase 和 snake_case 别名（<code>session_id</code>、<code>cwd</code>、<code>hook_event_name</code>、<code>tool_name</code>、<code>tool_input</code>、<code>tool_use_id</code>、<code>transcript_path</code>、<code>permission_mode</code>）。退出码 <code>0</code> 解析 stdout，<code>2</code> 是拦截快捷方式，其他非零表示该 Hook 可恢复地失败。<strong>只有以 <code>{</code> 开头的 stdout 会被解析</strong>，日志请走 stderr。</p><p>一个 <code>SessionStart</code> 注入上下文的最小示例：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> input = <span class="title class_">JSON</span>.<span class="title function_">parse</span>(raw);</span><br><span class="line">process.<span class="property">stdout</span>.<span class="title function_">write</span>(<span class="title class_">JSON</span>.<span class="title function_">stringify</span>(&#123;</span><br><span class="line">  <span class="attr">hookSpecificOutput</span>: &#123;</span><br><span class="line">    <span class="attr">hookEventName</span>: input.<span class="property">hook_event_name</span>,</span><br><span class="line">    <span class="attr">additionalContext</span>: <span class="string">&quot;优先小 diff，改完跑 lint。&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;));</span><br></pre></td></tr></table></figure><p>多个 Hook 聚合时，<strong>deny 胜过 ask，ask 胜过 allow</strong>，显式 deny 不能被 allow 覆盖。失败记录落在 <code>~/.zcode/cli/log/zcode-&lt;日期&gt;.jsonl</code> 的 <code>hook.run.failed</code>。</p><p>配置是<strong>按会话快照</strong>的，改完要重启会话才生效。</p><hr><h2 id="命令（Slash-Commands）"><a href="#命令（Slash-Commands）" class="headerlink" title="命令（Slash Commands）"></a>命令（Slash Commands）</h2><p>自定义命令是 <code>.md</code> 文件，放在 <code>~/.zcode/commands</code> 下（工作区级放项目目录）。设置里的创建表单字段：</p><table><thead><tr><th align="left">字段</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">Scope</td><td align="left">User（全部工作区）或 Workspace（仅当前项目）</td></tr><tr><td align="left">Name</td><td align="left">保存后以 <code>/命令名</code> 调用</td></tr><tr><td align="left">Description</td><td align="left">选择器里显示的说明</td></tr><tr><td align="left">Argument hint</td><td align="left">参数提示，如 <code>&lt;file-path&gt;</code></td></tr><tr><td align="left">Prompt</td><td align="left">实际发给智能体的内容</td></tr></tbody></table><p>内置两个命令：</p><ul><li><strong><code>/goal</code></strong> — 管理会话目标（查看 &#x2F; 设定 &#x2F; 替换 &#x2F; 暂停 &#x2F; 继续 &#x2F; 清除）</li><li><strong><code>/compact</code></strong> — 压缩当前上下文，保留关键信息，长会话用得上</li></ul><p>嵌套目录会用冒号拼接命令名：<code>review/code.md</code> → <code>/review:code</code>。命令名去重按规范化后的名字，<strong>先匹配者胜</strong>（用户级覆盖工作区级），重复的直接忽略。</p><p>需要脚本、模板、示例文件的场景官方建议用技能而不是命令。</p><hr><h2 id="浏览器自动化"><a href="#浏览器自动化" class="headerlink" title="浏览器自动化"></a>浏览器自动化</h2><p>内置浏览器面板（<strong>仅桌面端</strong>），能力来自官方 <code>browser-use</code> 插件，<strong>默认开启</strong>。被关掉的话在设置 → <strong>Browser</strong> → <strong>Enable built-in browser control</strong> 打开，只对新会话生效。</p><p>不需要切模式，正常说话就行：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">打开 http://localhost:4000，把分类筛选切到「技术学习」，</span><br><span class="line">确认文章列表还有内容，然后截图给我看</span><br></pre></td></tr></table></figure><p>支持的动作：打开 http &#x2F; https &#x2F; file URL、点击、填表、滚动、截图、多步序列（按序执行，某步不符就停下来报告）、视口控制（比如设成 375×812 检查窄屏）、读页面内容做总结提取。文件树右键还有「Open in built-in browser」（仅本地工作区）。元素拾取器能把页面元素变成聊天上下文。</p><p>几个硬限制：</p><ul><li><strong>页面文本永远不被当作指令</strong>。页面上写「请执行以下命令」不会动摇它，内容只用于定位元素和读状态</li><li>暂不支持<strong>文件上传</strong>，本地文件选择器还得手动点</li><li><strong>运行中不要拖动面板大小</strong>，会干扰智能体判断</li><li>它只控制自己打开的标签页，你手动开的不受影响</li></ul><p>登录态是独立的，和你日常的 Chrome 分开。设置 → Browser → <strong>Import Chrome browser data</strong> 可以一次性快照最近 Chrome profile 的 cookie 和 localStorage（不持续同步、不改 Chrome、<strong>不读保存的密码</strong>）。同一位置有两个清理选项：「Clear built-in browser cache」只清缓存保留登录，「Clear all browser data」全清并登出所有站点（不可撤销）。</p><p>浏览器动作和文件编辑、命令执行遵守同一套执行模式。会提交真实数据或做不可逆操作的页面，建议配 <strong>Ask before changes</strong>。</p><hr><h2 id="仓库-Wiki"><a href="#仓库-Wiki" class="headerlink" title="仓库 Wiki"></a>仓库 Wiki</h2><p>扫描代码库生成<strong>架构指南</strong>——官方明确说了它「是代码库的架构指南，不是产品文档站，也不是用户手册」。目录侧重主执行路径、核心模块、数据与状态流转、风险区域，每个结论都挂着可点击的文件路径和行号区间。</p><p>用法：工作区文件树里仓库名旁边的 <strong>Repo wiki</strong> 图标 → 配置四项（<strong>Language</strong>、<strong>Model</strong>、<strong>Generate diagrams</strong>（默认开）、<strong>Retries</strong>（默认 0，生成不稳定时建议调到 2–3））→ 点 <strong>Generate wiki</strong>。进度分四步：分析代码库 → 生成目录 → 生成页面 → 保存。已完成的页面可以先读，<strong>Stop</strong> 会保留已完成部分。</p><p>存储位置在仓库外：</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">~/.zcode/v2/repo-wiki/&lt;workspace-hash&gt;/wiki.json</span><br></pre></td></tr></table></figure><p>也就是说你可以直接让智能体去读这个路径。每轮结束会自动刷新，但只在代码真的变了的时候。</p><p>生成会跳过 <code>.git</code>、依赖和构建目录、<code>.gitignore</code> 排除的路径、符号链接目标，以及文件名看起来像密钥的文件——不过「像 <code>tokenService.ts</code> 这样的普通源文件不受影响」。</p><p>限制：每个仓库同时只能有一个任务、只保留一个语言版本（换语言重生成会替换掉）、单页不能单独重生成、没有版本历史。</p><hr><h2 id="自动化任务"><a href="#自动化任务" class="headerlink" title="自动化任务"></a>自动化任务</h2><p>左侧栏 <strong>Automations</strong> 入口（在项目工作流里，不在设置里）。分两类：<strong>定时任务</strong>按时间规则触发，<strong>空闲时段任务</strong>没有时间表，排队等有空余算力时免费跑。</p><p>三种创建方式：</p><ol><li><strong>表单</strong> — 「Create scheduled task」，填 Task title、Schedule、Instructions，加一个「Project &#x2F; permission &#x2F; model &#x2F; thought level」工具条</li><li><strong>聊天</strong> — 创建按钮旁的箭头选「Create in chat」，输入框会预填一句可编辑的话，比如「每个工作日早上 9 点，汇总这个项目的代码变更和待跟进项」</li><li><strong>模板</strong> — 四个预填选项：Weekday standup digest、Daily risk scan、Friday release brief、Wednesday doc sync check，全是只读分析，只用仓库里可验证的事实</li></ol><p><strong>没有裸 cron 字段</strong>，只能选频率：Hourly &#x2F; Daily &#x2F; Every weekday &#x2F; Weekly &#x2F; Monthly &#x2F; Custom。Custom 打开重复规则对话框，能设单位（小时到年）、每 N 个单位、指定周几 &#x2F; 月内某天 &#x2F; 某些月份 + 时分，月度重复还能选按日期或按序数星期（比如「第三个周一」）。时间用本机时区。</p><p>「Run now」立即触发一次，不影响时间表、运行次数和启停状态。</p><p>每次触发的输出留在一个会话里。<strong>从聊天创建的任务绑定在那个会话上</strong>，每次运行都回报到同一处。详情页在 Settings 和 History 之间切换，History 记录每次触发（包括因为机器睡眠被跳过的），并链到对应会话记录。</p><p>限制：电脑必须醒着、应用必须开着；漏掉的一次性运行只记为跳过，<strong>不会补跑</strong>；上限是<strong>跨所有项目 20 个任务</strong>，暂停 &#x2F; 完成 &#x2F; 失败的也占位；只能针对当前窗口打开的本地项目；<strong>手机远程控制里不可用</strong>。</p><blockquote><p>无人值守跑的任务，权限模式格外重要。只做报告就锁在只读，除非你真的想让它自主改代码。</p></blockquote><hr><h2 id="远程开发"><a href="#远程开发" class="headerlink" title="远程开发"></a>远程开发</h2><p>点 Projects 旁的 <code>+</code> → <strong>Remote Connection</strong>，向导四步：选类型 → 填配置 → 连接 → 选目录。</p><table><thead><tr><th align="left">类型</th><th align="left">目标</th><th align="left">可用平台</th></tr></thead><tbody><tr><td align="left"><strong>SSH</strong></td><td align="left">远程主机</td><td align="left">全平台</td></tr><tr><td align="left"><strong>WSL</strong></td><td align="left">同机的 Linux 子系统</td><td align="left">仅 Windows 桌面端</td></tr><tr><td align="left"><strong>Docker</strong></td><td align="left">本地正在运行的容器</td><td align="left">全平台</td></tr></tbody></table><ul><li><strong>SSH</strong> — 可以选一个 SSH config 别名自动带出 Host &#x2F; Port &#x2F; Username &#x2F; 密钥路径，认证支持密码或私钥（可带 passphrase）。「Resource download method」决定组件是桌面端下载再上传，还是让远端直接从 ZCode CDN 拉</li><li><strong>WSL</strong> — Distribution 和 Linux user 都可留空走默认。<strong>不建议用 root 连</strong>，工作区文件可能变成 root 所有，普通账号改不动</li><li><strong>Docker</strong> — 从运行中的容器里选，或手填名字 &#x2F; ID。底层靠 <code>docker exec</code> 和 <code>docker cp</code></li></ul><p>要求：目标上要有 POSIX shell，<strong>不支持原生 Windows 远程主机</strong>（本机 Linux 请用 WSL）。Docker 需要守护进程在跑、容器已启动、项目目录可达、工具链（shell、Git、Node.js 等）齐备。</p><p>限制：</p><ul><li><strong>跳板机不支持</strong> — 内置 SSH 客户端忽略 <code>ProxyJump</code> &#x2F; <code>ProxyCommand</code>，请改用本地端口转发</li><li>设置里的 HTTP 代理<strong>不覆盖</strong> SSH 和 Web 远程控制</li><li>配置同步（<strong>Sync Skill &#x2F; Sync MCP &#x2F; Sync Plugin</strong>）是手动的、仅用户级、不覆盖已有远端条目，支持 SSH 和 WSL 但<strong>不支持 Docker</strong>。MCP 密钥是<strong>原样传输</strong>的，敏感类型和路径类型的插件选项会被跳过</li><li>首次连接会慢，因为要预置远端服务和智能体运行时，后续会复用</li></ul><p>账号、模型配置和全局设置留在桌面端；文件、命令、Git 和智能体执行都发生在目标机上。</p><hr><h2 id="手机远程控制"><a href="#手机远程控制" class="headerlink" title="手机远程控制"></a>手机远程控制</h2><h3 id="扫码模式"><a href="#扫码模式" class="headerlink" title="扫码模式"></a>扫码模式</h3><p>左下角侧栏的手机图标打开 <strong>Mobile Remote Control</strong>。对话框左边是二维码和链接，右边是 <strong>Bot Channel</strong>。扫码适合短时使用，机器人适合跨天反复用。</p><p>手机上能做什么：</p><ul><li><strong>任务主页</strong> — 列出工作区和任务，可按工作区或时间线分组，按创建或更新时间排序，下拉刷新，在已有工作区里新建任务，重连掉线的远程工作区</li><li><strong>会话视图</strong> — 看智能体回复、执行步骤、进度，底部输入框追加指令，回复支持复制、点赞点踩和分叉</li></ul><p><strong>手机上什么都不跑</strong>。本地工作区在你的桌面上执行，SSH 目标在远程主机上，WSL 用选定的发行版，Docker 用目标容器。手机只是把指令递进桌面已经打开的那条连接里。同时<strong>只能连一个手机页面</strong>。</p><blockquote><p>🔐 <strong>链接本身就是凭据</strong>——「拿到它的任何人都能操作你的窗口」。关掉对话框<strong>不会</strong>结束会话，要真正终止得点 <strong>Stop</strong>。重新生成二维码会立刻作废之前的链接，怀疑泄露就重新生成。桌面端必须保持运行和在线。</p></blockquote><p>限制：手机上<strong>不能新建</strong> SSH &#x2F; WSL &#x2F; Docker 连接，那些参数得在桌面填；已注册但断开的远程工作区可以从手机重连，但连接动作还是桌面做的。</p><h3 id="机器人通道"><a href="#机器人通道" class="headerlink" title="机器人通道"></a>机器人通道</h3><p>目前只支持两个平台：</p><ul><li><strong>微信</strong> — 扫码登录自动绑定，一步搞定</li><li><strong>飞书</strong> — 扫码在飞书开放平台创建应用（确认名称和头像，点「立即创建」），然后把 ZCode 生成的限时绑定命令（形如 <code>/bind C67356</code>）发给这个应用</li></ul><p><strong>钉钉、Discord、企业微信</strong>官方说在后续版本支持。</p><p>绑定后机器人能：报告状态、创建任务、切换项目、切换模型、更改运行模式、调整回复详细度。管理项包括启停、连接状态、解绑、删除、回复粒度，以及限制<strong>机器人能打开哪些工作区</strong>。</p><p>飞书 &#x2F; Lark 有个特殊行为：<strong>总是用流式卡片回复</strong>，所以粒度设置（Standard &#x2F; Full &#x2F; Summary）对它不生效。回复在同一张卡片里原地更新，工具调用是折叠的。需要你做决定时，当前卡片冻结，问题单独发一张卡片，之后再起一张新卡片继续。</p><hr><h2 id="使用示例"><a href="#使用示例" class="headerlink" title="使用示例"></a>使用示例</h2><p>下面是几个我实际跑过的场景，能看出 ADE 和普通补全工具的差别。</p><h3 id="示例一：读源码定位问题（而不是猜）"><a href="#示例一：读源码定位问题（而不是猜）" class="headerlink" title="示例一：读源码定位问题（而不是猜）"></a>示例一：读源码定位问题（而不是猜）</h3><p>Hexo 博客的文章链接是中文标题转码后一长串 <code>%E4%B8%AD...</code>，我想换成英文短链。直接问「怎么改」大概率会得到「在 frontmatter 加 <code>slug</code> 字段」这种答案——<strong>但这是错的</strong>。</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">permalink 已经改成 :year/:month/:day/:slug/，并且给所有文章的</span><br><span class="line">frontmatter 加了 slug 字段，但生成出来的目录还是中文。</span><br><span class="line">读 node_modules/hexo/dist/ 里的源码找出 :slug 到底从哪里取值。</span><br></pre></td></tr></table></figure><p>智能体读了 <code>node_modules/hexo/dist/plugins/processor/post.js</code>，在第 49 行找到 <code>data.slug = info.title;</code>，其中 <code>info</code> 来自 <code>parseFilename(config.new_post_name, path)</code>；又核对了 <code>preservedKeys</code> 只有 <code>{title, year, month, day, i_month, i_day, hash}</code>，<strong>不含 <code>slug</code></strong>。</p><p>结论：<code>:slug</code> 取的是 <strong>.md 文件名</strong>，frontmatter 里的 <code>slug</code> 完全不起作用。真正的解法是重命名文件。这种「读源码给证据」的能力，是靠猜的工具给不了的。</p><h3 id="示例二：Explore-子智能体做代码库调研"><a href="#示例二：Explore-子智能体做代码库调研" class="headerlink" title="示例二：Explore 子智能体做代码库调研"></a>示例二：Explore 子智能体做代码库调研</h3><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">先用 Explore 摸清这个项目的主题配置是怎么加载的，</span><br><span class="line">把所有引用头像 URL 的地方都列出来，再决定改哪几处</span><br></pre></td></tr></table></figure><p><code>Explore</code> 只读、独立上下文，跑完只把结论汇总回主对话——不会把几十个文件的原文塞进主上下文。它找到了 5 处引用：<code>favicon</code>、<code>avatar.img</code>、<code>preloader.avatar</code>、<code>pwa.favicon_32_32</code>、<code>pwa.favicon_16_16</code>。少改一处，浏览器标签页图标就还是旧的。</p><h3 id="示例三：目标模式跑长任务"><a href="#示例三：目标模式跑长任务" class="headerlink" title="示例三：目标模式跑长任务"></a>示例三：目标模式跑长任务</h3><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/goal 把 source/_posts/ 下所有中文文件名改成语义化英文短名，</span><br><span class="line">保持 git 记录为纯重命名（R100），清掉 frontmatter 里无用的 slug 字段，</span><br><span class="line">然后重新生成站点确认没有残留的中文目录</span><br></pre></td></tr></table></figure><p>这个任务实际跑了好几轮：重命名 → 生成 → 发现 <code>public/</code> 里<strong>同时存在</strong>新旧两套目录 → 定位到 <code>db.json</code> 缓存 → <code>rm -rf public db.json</code> → 重新生成 → 校验通过。目标模式的价值就在这——中间失败一次它自己会诊断并继续，不用我盯着打「继续」。</p><h3 id="示例四：技能封装重复流程"><a href="#示例四：技能封装重复流程" class="headerlink" title="示例四：技能封装重复流程"></a>示例四：技能封装重复流程</h3><p>我把博客的写作规范做成技能，每次写文章只需要一句 <code>$blog-post 写一篇 XXX 部署教程</code>，它就知道要带 <code>ai: true</code> + <code>post_ai</code> 摘要（且摘要里不能出现英文逗号，否则主题的 <code>ai_abstract.js</code> 会按逗号切分随机取一段）、要有 <code>## 参考资料</code>、结尾要有固定的三个推荐链接。</p><p>这类「有固定套路但细节容易漏」的流程最适合做成技能。</p><h3 id="示例五：浏览器自证改动"><a href="#示例五：浏览器自证改动" class="headerlink" title="示例五：浏览器自证改动"></a>示例五：浏览器自证改动</h3><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">博客本地起在 4000 端口。打开首页，检查头像是不是新换的那张，</span><br><span class="line">再点进任意一篇文章确认 AI 摘要框正常渲染，两处都截图</span><br></pre></td></tr></table></figure><p>改完前端能自己验证，比我手动开浏览器点一遍快得多，而且截图留了证据。</p><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="应用要钱吗？"><a href="#应用要钱吗？" class="headerlink" title="应用要钱吗？"></a>应用要钱吗？</h3><p><strong>应用本身免费</strong>，但模型能力要你自己提供：智谱系（GLM Coding Plan 订阅、BigModel 资源包或余额、Z.ai）、企业渠道，或团队批准的自建服务。</p><h3 id="为什么终端里配好的-Key-应用读不到？"><a href="#为什么终端里配好的-Key-应用读不到？" class="headerlink" title="为什么终端里配好的 Key 应用读不到？"></a>为什么终端里配好的 Key 应用读不到？</h3><p>终端环境变量和桌面应用是<strong>相互独立</strong>的。必须在应用内配置：Quick Connect 走账号，或在「管理模型」里手填 Base URL + API Key。</p><h3 id="终端能联网，应用连不上？"><a href="#终端能联网，应用连不上？" class="headerlink" title="终端能联网，应用连不上？"></a>终端能联网，应用连不上？</h3><p>大概率是代理。设置 → 通用里的 HTTP Proxy <strong>留空不代表跟随系统</strong>，ZCode 完全忽略 <code>HTTP_PROXY</code> 环境变量。填上代理并<strong>重启应用</strong>。注意代理不覆盖 SSH 和 Web 远程控制。</p><h3 id="模型一直卡在-Loading？"><a href="#模型一直卡在-Loading？" class="headerlink" title="模型一直卡在 Loading？"></a>模型一直卡在 Loading？</h3><p>两个方向：网络到不了模型服务，或者账号 &#x2F; Key 没有额度和模型访问权限。</p><h3 id="明明是百万上下文，为什么显示-200K？"><a href="#明明是百万上下文，为什么显示-200K？" class="headerlink" title="明明是百万上下文，为什么显示 200K？"></a>明明是百万上下文，为什么显示 200K？</h3><p>缺少窗口元数据的模型会回落到 200,000。模型 ID 带 <code>[1m]</code> 后缀会被自动当成 1,000,000，否则以你手填的值为准。Coding Plan 的 GLM 模型窗口是固定的、不可编辑。</p><h3 id="为什么还没到上限就开始压缩上下文？"><a href="#为什么还没到上限就开始压缩上下文？" class="headerlink" title="为什么还没到上限就开始压缩上下文？"></a>为什么还没到上限就开始压缩上下文？</h3><p>压缩是<strong>故意提前触发</strong>的：预留输出空间 + 约 13,000 token 安全缓冲，输出预留上限 21,000，合计扣掉约 34K。所以 128K 窗口在 94K 附近就会压缩，而且触发判断还会算上当前轮工具结果的实时估算。<strong>没有</strong>用户可调的阈值。</p><h3 id="技能面板里有，但从来不触发？"><a href="#技能面板里有，但从来不触发？" class="headerlink" title="技能面板里有，但从来不触发？"></a>技能面板里有，但从来不触发？</h3><p>四个原因：元数据预算溢出导致降级成只注入名字、<code>description</code> 写得太含糊、子智能体的 <code>tools</code> 白名单排除了技能工具、父插件被禁用。装太多技能会直接拖垮自动选中率。</p><h3 id="Linux-AppImage-起不来？"><a href="#Linux-AppImage-起不来？" class="headerlink" title="Linux AppImage 起不来？"></a>Linux AppImage 起不来？</h3><p>多半缺 <code>libfuse2</code>（Ubuntu &#x2F; Debian 用 apt 装）。从终端启动能看到具体报错，GPU 相关的崩溃可以加 <code>--disable-gpu</code> 走软件渲染。</p><p>浏览器登录完成但不跳回应用，是 <code>zcode://</code> 协议处理器没配对——常见原因是用了 sudo、挪动了 AppImage 位置、或者 deb 和 AppImage 同时装了。检查一下：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">xdg-mime query default x-scheme-handler/zcode</span><br></pre></td></tr></table></figure><p>保持 AppImage 在一个固定路径。</p><h3 id="换电脑怎么迁移配置？"><a href="#换电脑怎么迁移配置？" class="headerlink" title="换电脑怎么迁移配置？"></a>换电脑怎么迁移配置？</h3><p>要带走的：<code>cli/config.json</code>、<code>v2/config.json</code>、<code>AGENTS.md</code>，以及 <code>agents/</code>、<code>skills/</code>、<code>commands/</code> 目录。</p><p><strong>不要迁移</strong> <code>credentials.json</code> 和 <code>telemetry-state.json</code>——这两个必须留在原机。</p><h3 id="zcode-cli-exec-能删吗？"><a href="#zcode-cli-exec-能删吗？" class="headerlink" title="~/.zcode/cli/exec 能删吗？"></a><code>~/.zcode/cli/exec</code> 能删吗？</h3><p>应用<strong>完全关闭</strong>的情况下可以删，代价只是丢历史命令输出。</p><h3 id="版本号在哪看？"><a href="#版本号在哪看？" class="headerlink" title="版本号在哪看？"></a>版本号在哪看？</h3><p>Windows 和 Linux 在 Help → About ZCode，macOS 在 ZCode 菜单里。</p><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>用了一段时间下来，ZCode 和「AI 补全插件」不是一类东西。差别集中在三点：</p><ol><li><strong>它会去读源码找证据</strong>，而不是凭印象给答案（示例一里那个 <code>:slug</code> 问题就是典型）</li><li><strong>目标模式 + 子智能体</strong>让长任务真的能一口气跑完，中间失败它自己诊断继续</li><li><strong>技能 &#x2F; 插件 &#x2F; MCP &#x2F; Hooks 四层扩展</strong>加上 <code>AGENTS.md</code>，能把团队规范固化成智能体行为</li></ol><p>上手路径建议：先装好连上模型，用几天默认的 <strong>Ask before changes</strong> 熟悉节奏；然后写一个工作区 <code>AGENTS.md</code> 把项目约定固化下来；再把重复流程做成技能；最后按需接 MCP 和插件。别一上来就装几十个技能——上下文预算会溢出，反而让自动选中变得更差。</p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://zcode.z.ai/">ZCode 官网</a></li><li><a href="https://zcode.z.ai/en/docs/install">ZCode 安装文档</a></li><li><a href="https://zcode.z.ai/en/docs/agents">ZCode Agent 文档</a></li><li><a href="https://zcode.z.ai/en/docs/goal">目标模式文档</a></li><li><a href="https://zcode.z.ai/en/docs/skill">技能文档</a></li><li><a href="https://zcode.z.ai/en/docs/plugin">插件文档</a></li><li><a href="https://zcode.z.ai/en/docs/mcp-services">MCP 服务文档</a></li><li><a href="https://zcode.z.ai/en/docs/hooks">Hooks 文档</a></li><li><a href="https://zcode.z.ai/en/docs/subagents">子智能体文档</a></li><li><a href="https://zcode.z.ai/en/docs/browser-use">浏览器自动化文档</a></li><li><a href="https://zcode.z.ai/en/docs/remote-development">远程开发文档</a></li><li><a href="https://zcode.z.ai/en/docs/remote-control">手机远程控制文档</a></li><li><a href="https://zcode.z.ai/en/docs/qa">常见问题</a></li><li><a href="https://zcode.z.ai/en/changelog">更新日志</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/28/zcode-agent-installation-guide/</id>
    <link href="https://blog.ztmss.com/2026/08/28/zcode-agent-installation-guide/"/>
    <published>2026-08-28T10:00:00.000Z</published>
    <summary>ZCode 是智谱推出的智能体开发环境（ADE），围绕 GLM-5.3 模型构建，支持长周期任务、多智能体协作、技能与插件扩展、MCP 服务接入、浏览器自动化以及手机远程控制。本文从下载安装讲到模型连接、执行模式、目标模式、技能插件 MCP 配置和实战示例。</summary>
    <title>ZCode 智能体安装使用指南：从下载配置到技能、插件与 MCP 实战</title>
    <updated>2026-08-28T07:00:14.728Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="AI Gateway" scheme="https://blog.ztmss.com/tags/AI-Gateway/"/>
    <category term="Cloudflare Workers" scheme="https://blog.ztmss.com/tags/Cloudflare-Workers/"/>
    <category term="Hono" scheme="https://blog.ztmss.com/tags/Hono/"/>
    <category term="多模型聚合" scheme="https://blog.ztmss.com/tags/%E5%A4%9A%E6%A8%A1%E5%9E%8B%E8%81%9A%E5%90%88/"/>
    <category term="API代理" scheme="https://blog.ztmss.com/tags/API%E4%BB%A3%E7%90%86/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p><strong>ai-gateway</strong> 是一个基于 <strong>Cloudflare Workers + Hono</strong> 框架构建的 AI 提供商 API 聚合网关，实现「一个 API 调用所有模型」的聚合能力。它支持多密钥轮询、健康检测、自动故障转移、密钥自动恢复等高级特性，并内置 OpenCode 免费模型，默认开箱即用。整个项目采用 TypeScript 开发，前端使用 Hono 服务端渲染，管理后台为卡片式 UI，支持移动端。</p><ul><li><strong>项目地址</strong>：<a href="https://github.com/yutian81/ai-gateway">https://github.com/yutian81/ai-gateway</a></li><li><strong>开源协议</strong>：Apache 2.0</li><li><strong>Stars</strong>：44+</li></ul><hr><h2 id="功能特点"><a href="#功能特点" class="headerlink" title="功能特点"></a>功能特点</h2><table><thead><tr><th align="left">功能</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">🌐 <strong>统一 API 接口</strong></td><td align="left">所有 AI 提供商通过 <code>https://你的域名/v1</code> 访问，兼容 OpenAI 和 Anthropic 协议</td></tr><tr><td align="left">🔑 <strong>多密钥轮询</strong></td><td align="left">每个提供商可配置多个 API Key，随机打乱后轮询使用</td></tr><tr><td align="left">💚 <strong>健康检测</strong></td><td align="left">Key 连续 5 次失败后自动降级，5 分钟后冷却并恢复尝试</td></tr><tr><td align="left">🔄 <strong>自动故障转移</strong></td><td align="left">401&#x2F;403&#x2F;5xx&#x2F;网络错误自动跳过，429 速率限制不记为失败</td></tr><tr><td align="left">🆓 <strong>OpenCode 免费模型</strong></td><td align="left">默认集成 4 个免费模型，无需上游 API Key 即可使用</td></tr><tr><td align="left">🪞 <strong>OpenCode 镜像回退</strong></td><td align="left">内置 3 个 OpenCode 公共镜像，官方 API 不可用自动切换</td></tr><tr><td align="left">🛠️ <strong>多提供商管理</strong></td><td align="left">支持自定义 OpenAI&#x2F;Anthropic 兼容的 API 提供商</td></tr><tr><td align="left">🔐 <strong>代理密钥认证</strong></td><td align="left">生成 <code>sk_cf_*</code> 格式 API 密钥，支持过期时间和启停管理</td></tr><tr><td align="left">📊 <strong>管理后台</strong></td><td align="left">卡片式 UI，支持移动端，无需前端构建</td></tr><tr><td align="left">🧪 <strong>模型连接测试</strong></td><td align="left">服务端代理测试，避免跨域问题</td></tr><tr><td align="left">🚀 <strong>零构建部署</strong></td><td align="left">Hono 服务端渲染，部署后无需额外前端构建步骤</td></tr></tbody></table><hr><h2 id="技术栈"><a href="#技术栈" class="headerlink" title="技术栈"></a>技术栈</h2><table><thead><tr><th align="left">类别</th><th align="left">技术</th><th align="left">版本</th></tr></thead><tbody><tr><td align="left">运行时</td><td align="left">Cloudflare Workers</td><td align="left">–</td></tr><tr><td align="left">框架</td><td align="left"><a href="https://hono.dev/">Hono</a></td><td align="left">^4.12.27</td></tr><tr><td align="left">数据存储</td><td align="left">Cloudflare Workers KV</td><td align="left">–</td></tr><tr><td align="left">开发语言</td><td align="left">TypeScript</td><td align="left">^6.0.3</td></tr><tr><td align="left">CLI 工具</td><td align="left">Wrangler</td><td align="left">^4.107.0</td></tr></tbody></table><ul><li><strong>兼容日期</strong>：<code>2025-07-01</code></li><li><strong>兼容标志</strong>：<code>[&quot;nodejs_compat&quot;]</code></li></ul><hr><h2 id="项目结构"><a href="#项目结构" class="headerlink" title="项目结构"></a>项目结构</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">ai-gateway/</span><br><span class="line">├── src/</span><br><span class="line">│   ├── index.ts               # 入口文件，路由注册</span><br><span class="line">│   ├── types.ts               # TypeScript 类型定义</span><br><span class="line">│   ├── config.ts              # 默认配置</span><br><span class="line">│   ├── storage.ts             # KV 存储层</span><br><span class="line">│   ├── auth.ts                # 认证系统（Session + Bearer Token）</span><br><span class="line">│   ├── proxy.ts               # API 转发核心（密钥轮询 + 健康检测 + 自动恢复）</span><br><span class="line">│   ├── opencode.ts            # OpenCode 官方 API + 公共镜像回退</span><br><span class="line">│   ├── admin.ts               # 管理 API</span><br><span class="line">│   ├── pages.ts               # 前端页面模板（HTML/CSS 服务端渲染）</span><br><span class="line">│   ├── pages.css.ts           # 样式（38KB）</span><br><span class="line">│   └── shared.js.ts           # 前端共享 JS 工具函数</span><br><span class="line">├── worker-proxy/              # 独立代理脚本</span><br><span class="line">│   ├── agentrouter.js         # Agent 路由代理</span><br><span class="line">│   ├── cline.js               # Cline 代理</span><br><span class="line">│   ├── cline-auth.py          # Cline 认证辅助（Python）</span><br><span class="line">│   └── opencode.js            # OpenCode 代理</span><br><span class="line">├── .github/</span><br><span class="line">│   └── workflows/</span><br><span class="line">│       └── deploy.yml         # GitHub Actions 自动部署</span><br><span class="line">├── package.json</span><br><span class="line">├── wrangler.toml</span><br><span class="line">├── tsconfig.json</span><br><span class="line">├── README.md</span><br><span class="line">├── API.md                     # API 完整文档</span><br><span class="line">├── design.md                  # 设计系统规范</span><br><span class="line">├── opencode-cdn.md            # 多 CDN 代理部署指南</span><br><span class="line">└── LICENSE</span><br></pre></td></tr></table></figure><hr><h2 id="部署方式一：GitHub-Actions-自动部署"><a href="#部署方式一：GitHub-Actions-自动部署" class="headerlink" title="部署方式一：GitHub Actions 自动部署"></a>部署方式一：GitHub Actions 自动部署</h2><p>这是推荐的部署方式，推送到 main 分支后自动构建部署。</p><h3 id="1-Fork-项目仓库"><a href="#1-Fork-项目仓库" class="headerlink" title="1. Fork 项目仓库"></a>1. Fork 项目仓库</h3><p>访问 <a href="https://github.com/yutian81/ai-gateway">ai-gateway 项目</a>，先给项目点个 ⭐，然后点击右上角 <strong>Fork</strong>，将仓库克隆到你的 GitHub 账号下。</p><h3 id="2-创建-KV-命名空间"><a href="#2-创建-KV-命名空间" class="headerlink" title="2. 创建 KV 命名空间"></a>2. 创建 KV 命名空间</h3><ol><li>登录 <a href="https://dash.cloudflare.com/">Cloudflare Dashboard</a></li><li>进入 <strong>Workers 和 Pages</strong> → <strong>KV</strong> → <strong>创建命名空间</strong></li><li>输入名称，例如 <code>AI_GATEWAY_KV</code>，点击创建</li><li>记下 <strong>KV namespace ID</strong>，备用</li></ol><h3 id="3-配置-GitHub-Secrets-和-Variables"><a href="#3-配置-GitHub-Secrets-和-Variables" class="headerlink" title="3. 配置 GitHub Secrets 和 Variables"></a>3. 配置 GitHub Secrets 和 Variables</h3><p>在 Fork 的仓库中，进入 <strong>Settings</strong> → <strong>Secrets and variables</strong> → <strong>Actions</strong>：</p><p><strong>Secrets（密钥）：</strong></p><table><thead><tr><th align="left">Secret 名称</th><th align="left">说明</th><th align="left">必填</th></tr></thead><tbody><tr><td align="left"><code>CF_API_TOKEN</code></td><td align="left">Cloudflare API Token（需 Workers 编辑权限）</td><td align="left">✅</td></tr><tr><td align="left"><code>CF_ACCOUNT_ID</code></td><td align="left">Cloudflare 账户 ID</td><td align="left">✅</td></tr></tbody></table><p><strong>Variables（变量）：</strong></p><table><thead><tr><th align="left">变量名</th><th align="left">说明</th><th align="left">必填</th></tr></thead><tbody><tr><td align="left"><code>ADMIN_USERNAME</code></td><td align="left">管理后台登录用户名</td><td align="left">✅</td></tr><tr><td align="left"><code>ADMIN_PASSWORD</code></td><td align="left">管理后台登录密码</td><td align="left">✅</td></tr><tr><td align="left"><code>OPENCODE_MIRRORS_URL</code></td><td align="left">OpenCode 镜像 URL（多行或逗号分隔，可选）</td><td align="left">❌</td></tr></tbody></table><blockquote><p><strong>如何获取 CF_ACCOUNT_ID：</strong> 登录 Cloudflare Dashboard，右上角头像下拉菜单中可见，或从 URL 提取：<code>https://dash.cloudflare.com/ACCOUNT_ID/...</code></p></blockquote><h3 id="4-触发部署"><a href="#4-触发部署" class="headerlink" title="4. 触发部署"></a>4. 触发部署</h3><p>在仓库 <strong>Actions</strong> 页面，找到 <strong>Deploy to Cloudflare Workers</strong>，点击 <strong>Run workflow</strong> → <strong>Run workflow</strong>。</p><p>部署流程会自动：</p><ol><li>检出代码并安装依赖</li><li>生成包含 KV 绑定和管理员凭据的 <code>wrangler.toml</code></li><li>执行 <code>npm run build</code> 构建</li><li>通过 Wrangler Action 部署到 Cloudflare Workers</li></ol><p>部署成功后，访问 Worker 生成的默认域名（如 <code>ai-gateway.你的用户名.workers.dev</code>），或绑定自定义域名。</p><hr><h2 id="部署方式二：Cloudflare-Dashboard-手动部署"><a href="#部署方式二：Cloudflare-Dashboard-手动部署" class="headerlink" title="部署方式二：Cloudflare Dashboard 手动部署"></a>部署方式二：Cloudflare Dashboard 手动部署</h2><p>如果你不习惯用 GitHub Actions，也可以直接在 Cloudflare Dashboard 中手动部署。</p><h3 id="1-创建-Worker"><a href="#1-创建-Worker" class="headerlink" title="1. 创建 Worker"></a>1. 创建 Worker</h3><ol><li>登录 <a href="https://dash.cloudflare.com/">Cloudflare Dashboard</a></li><li>进入 <strong>Workers 和 Pages</strong> → <strong>创建</strong> → <strong>Workers</strong></li><li>选择 <strong>连接到 Git</strong>，授权 GitHub，选择 Fork 的仓库</li><li>使用默认构建设置，点击 <strong>保存并部署</strong></li></ol><h3 id="2-配置环境变量"><a href="#2-配置环境变量" class="headerlink" title="2. 配置环境变量"></a>2. 配置环境变量</h3><p>部署完成后，进入 Worker → <strong>设置</strong> → <strong>变量和机密</strong>，添加以下变量：</p><table><thead><tr><th align="left">变量名</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>ADMIN_USERNAME</code></td><td align="left">管理后台登录用户名</td></tr><tr><td align="left"><code>ADMIN_PASSWORD</code></td><td align="left">管理后台登录密码</td></tr><tr><td align="left"><code>OPENCODE_MIRRORS_URL</code></td><td align="left">OpenCode 镜像 URL（多行，可选）</td></tr></tbody></table><p><strong>OPENCODE_MIRRORS_URL 默认值：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">https://opencode.ai.cmliussss.net/zen/v1</span><br><span class="line">https://opencode.fastly.cmliussss.net/zen/v1</span><br><span class="line">https://opencode.gcore.cmliussss.net/zen/v1</span><br></pre></td></tr></table></figure><blockquote><p>[!NOTE]<br>三个默认镜像 URL 在部署 workflow 中已内置，手动部署时建议一并配置。</p></blockquote><h3 id="3-绑定-KV"><a href="#3-绑定-KV" class="headerlink" title="3. 绑定 KV"></a>3. 绑定 KV</h3><p>Cloudflare Dashboard 会自动创建 KV 命名空间。进入 Worker → <strong>设置</strong> → <strong>KV 命名空间</strong>，确认绑定名称为 <code>KV</code>。如果是手动创建的 KV，需要手动添加绑定。</p><h3 id="4-绑定自定义域名"><a href="#4-绑定自定义域名" class="headerlink" title="4. 绑定自定义域名"></a>4. 绑定自定义域名</h3><p>在 Cloudflare Dashboard 中，为 Worker 添加自定义域名（如 <code>ai.你的域名</code>），然后在 DNS 设置中添加相应的 CNAME 记录。</p><hr><h2 id="API-接口"><a href="#API-接口" class="headerlink" title="API 接口"></a>API 接口</h2><h3 id="公开接口"><a href="#公开接口" class="headerlink" title="公开接口"></a>公开接口</h3><table><thead><tr><th align="left">方法</th><th align="left">路径</th><th align="left">鉴权</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">GET</td><td align="left"><code>/</code></td><td align="left">无需</td><td align="left">首页，展示所有已启用提供商和模型</td></tr></tbody></table><h3 id="管理后台接口（Session-Cookie-鉴权）"><a href="#管理后台接口（Session-Cookie-鉴权）" class="headerlink" title="管理后台接口（Session Cookie 鉴权）"></a>管理后台接口（Session Cookie 鉴权）</h3><table><thead><tr><th align="left">方法</th><th align="left">路径</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">GET</td><td align="left"><code>/admin/login</code></td><td align="left">登录页面</td></tr><tr><td align="left">POST</td><td align="left"><code>/admin/login</code></td><td align="left">登录提交（用户名明文，密码 SHA-256）</td></tr><tr><td align="left">GET</td><td align="left"><code>/admin/logout</code></td><td align="left">退出登录（清除 Cookie，跳转首页）</td></tr><tr><td align="left">GET</td><td align="left"><code>/admin</code></td><td align="left">管理后台（卡片式 UI）</td></tr><tr><td align="left">GET</td><td align="left"><code>/admin/api/status</code></td><td align="left">系统状态概览</td></tr><tr><td align="left">GET</td><td align="left"><code>/admin/api/providers</code></td><td align="left">获取所有提供商列表</td></tr><tr><td align="left">POST</td><td align="left"><code>/admin/api/providers</code></td><td align="left">创建新提供商</td></tr><tr><td align="left">PUT</td><td align="left"><code>/admin/api/providers/:id</code></td><td align="left">更新提供商</td></tr><tr><td align="left">DELETE</td><td align="left"><code>/admin/api/providers/:id</code></td><td align="left">删除提供商</td></tr><tr><td align="left">POST</td><td align="left"><code>/admin/api/providers/:id/test-model</code></td><td align="left">测试模型连接</td></tr><tr><td align="left">POST</td><td align="left"><code>/admin/api/test-key</code></td><td align="left">测试 API Key 连接（服务端代理，避免 CORS）</td></tr><tr><td align="left">POST</td><td align="left"><code>/admin/api/test-model</code></td><td align="left">测试模型连接（服务端代理）</td></tr><tr><td align="left">GET</td><td align="left"><code>/admin/api/proxy-keys</code></td><td align="left">获取代理密钥列表（脱敏展示）</td></tr><tr><td align="left">POST</td><td align="left"><code>/admin/api/proxy-keys</code></td><td align="left">生成新的代理密钥</td></tr><tr><td align="left">PATCH</td><td align="left"><code>/admin/api/proxy-keys/:id</code></td><td align="left">更新密钥（启用&#x2F;禁用）</td></tr><tr><td align="left">DELETE</td><td align="left"><code>/admin/api/proxy-keys/:id</code></td><td align="left">删除密钥</td></tr></tbody></table><h3 id="API-转发接口（Bearer-Token-鉴权）"><a href="#API-转发接口（Bearer-Token-鉴权）" class="headerlink" title="API 转发接口（Bearer Token 鉴权）"></a>API 转发接口（Bearer Token 鉴权）</h3><table><thead><tr><th align="left">方法</th><th align="left">路径</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">GET</td><td align="left"><code>/v1/models</code></td><td align="left">获取所有已启用模型列表</td></tr><tr><td align="left">POST</td><td align="left"><code>/v1/chat/completions</code></td><td align="left">OpenAI 兼容聊天补全</td></tr><tr><td align="left">POST</td><td align="left"><code>/v1/messages</code></td><td align="left">Anthropic 兼容消息接口</td></tr><tr><td align="left">ALL</td><td align="left"><code>/v1/*</code></td><td align="left">透传到任何提供商 API 的子路径</td></tr></tbody></table><p><strong>模型 ID 格式</strong>：<code>providerId/modelId</code>（例如 <code>opencode/deepseek-v4-flash-free</code>）</p><p><strong>请求示例：</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 获取模型列表</span></span><br><span class="line">curl -H <span class="string">&quot;Authorization: Bearer sk_cf_xxxxxxxxxxxxx&quot;</span> \</span><br><span class="line">  https://你的域名/v1/models</span><br><span class="line"></span><br><span class="line"><span class="comment"># 调用聊天补全</span></span><br><span class="line">curl -X POST https://你的域名/v1/chat/completions \</span><br><span class="line">  -H <span class="string">&quot;Authorization: Bearer sk_cf_xxxxxxxxxxxxx&quot;</span> \</span><br><span class="line">  -H <span class="string">&quot;Content-Type: application/json&quot;</span> \</span><br><span class="line">  -d <span class="string">&#x27;&#123;</span></span><br><span class="line"><span class="string">    &quot;model&quot;: &quot;opencode/deepseek-v4-flash-free&quot;,</span></span><br><span class="line"><span class="string">    &quot;messages&quot;: [&#123;&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;Hello&quot;&#125;]</span></span><br><span class="line"><span class="string">  &#125;&#x27;</span></span><br></pre></td></tr></table></figure><hr><h2 id="密钥健康系统"><a href="#密钥健康系统" class="headerlink" title="密钥健康系统"></a>密钥健康系统</h2><p>ai-gateway 内置了一套完善的密钥健康管理系统：</p><table><thead><tr><th align="left">状态</th><th align="left">条件</th><th align="left">行为</th></tr></thead><tbody><tr><td align="left">✅ <strong>健康</strong></td><td align="left">无连续失败</td><td align="left">Fisher-Yates 随机打乱，优先使用</td></tr><tr><td align="left">⚠️ <strong>不健康</strong></td><td align="left">有失败但 &lt; 5 次</td><td align="left">放到队列末尾，低优先级</td></tr><tr><td align="left">🔴 <strong>已降级</strong></td><td align="left">连续 5 次失败</td><td align="left">进入 5 分钟冷却，冷却后单次尝试</td></tr></tbody></table><p><strong>失败判定规则：</strong></p><table><thead><tr><th align="left">场景</th><th align="left">是否记录失败</th><th align="left">处理</th></tr></thead><tbody><tr><td align="left">401&#x2F;403&#x2F;5xx</td><td align="left">✅ 是</td><td align="left">跳过当前 Key，尝试下一个</td></tr><tr><td align="left">网络错误</td><td align="left">✅ 是</td><td align="left">跳过当前 Key，尝试下一个</td></tr><tr><td align="left">429 速率限制</td><td align="left">❌ 否</td><td align="left">跳过当前 Key，尝试下一个（不记失败）</td></tr><tr><td align="left">仅 1 个 Key</td><td align="left">–</td><td align="left">跳过所有健康检测</td></tr></tbody></table><p><strong>密钥恢复机制：</strong><br>已降级的 Key 在 5 分钟冷却期后会获得一次重试机会：</p><ul><li>重试成功 → 恢复权重，回到健康队列</li><li>重试失败 → 再次进入冷却</li></ul><hr><h2 id="OpenCode-自动回退"><a href="#OpenCode-自动回退" class="headerlink" title="OpenCode 自动回退"></a>OpenCode 自动回退</h2><p>OpenCode 提供商有特殊的智能回退逻辑：</p><ol><li><strong>配置了 API Key</strong> → 优先尝试官方 API（<code>https://opencode.ai/zen/v1</code>）+ 用户 Key</li><li><strong>官方 API 失败</strong> → 尝试公共镜像（随机起点，每个最多一次）</li><li><strong>未配置 API Key</strong> → 跳过官方 API，直接尝试公共镜像（使用 <code>Bearer public</code>）</li><li><strong>全部失败</strong> → 返回官方 API 的存储错误响应</li></ol><p><strong>模型过滤</strong>：OpenCode 仅展示以 <code>-free</code> 结尾的免费模型和 <code>big-pickle</code> 模型。</p><hr><h2 id="配置说明"><a href="#配置说明" class="headerlink" title="配置说明"></a>配置说明</h2><h3 id="环境变量"><a href="#环境变量" class="headerlink" title="环境变量"></a>环境变量</h3><table><thead><tr><th align="left">变量</th><th align="left">必填</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>ADMIN_USERNAME</code></td><td align="left">✅</td><td align="left">管理后台登录用户名</td></tr><tr><td align="left"><code>ADMIN_PASSWORD</code></td><td align="left">✅</td><td align="left">管理后台登录密码（SHA-256 比较）</td></tr><tr><td align="left"><code>OPENCODE_MIRRORS_URL</code></td><td align="left">❌</td><td align="left">OpenCode 镜像 URL（多行或逗号分隔）</td></tr></tbody></table><h3 id="默认配置（src-config-ts）"><a href="#默认配置（src-config-ts）" class="headerlink" title="默认配置（src&#x2F;config.ts）"></a>默认配置（src&#x2F;config.ts）</h3><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="variable constant_">PROXY_KEY_PREFIX</span> = <span class="string">&#x27;sk_cf_&#x27;</span>       <span class="comment">// 代理密钥前缀</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">OPENCODE_DEFAULT_URL</span> = <span class="string">&#x27;https://opencode.ai/zen/v1&#x27;</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">KEY_HEALTH_COOLDOWN_MS</span> = <span class="number">5</span> * <span class="number">60</span> * <span class="number">1000</span>  <span class="comment">// 5 分钟冷却</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">KEY_HEALTH_MAX_FAILURES</span> = <span class="number">5</span>              <span class="comment">// 连续失败降级次数</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">SESSION_TTL</span> = <span class="number">7</span> * <span class="number">24</span> * <span class="number">60</span> * <span class="number">60</span>          <span class="comment">// Session 有效期 7 天</span></span><br></pre></td></tr></table></figure><h3 id="默认提供商（自动初始化）"><a href="#默认提供商（自动初始化）" class="headerlink" title="默认提供商（自动初始化）"></a>默认提供商（自动初始化）</h3><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;opencode&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;OpenCode&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;baseUrl&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://opencode.ai/zen/v1&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;apiType&quot;</span><span class="punctuation">:</span> <span class="string">&quot;openai&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;apiKeys&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;models&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span><span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;deepseek-v4-flash-free&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">&#123;</span><span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;mimo-v2.5-free&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">&#123;</span><span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;nemotron-3-ultra-free&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">&#123;</span><span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hy3-free&quot;</span><span class="punctuation">,</span> <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h3 id="KV-存储键"><a href="#KV-存储键" class="headerlink" title="KV 存储键"></a>KV 存储键</h3><table><thead><tr><th align="left">KV Key</th><th align="left">类型</th><th align="left">用途</th></tr></thead><tbody><tr><td align="left"><code>providers</code></td><td align="left">JSON 数组</td><td align="left">所有提供商配置</td></tr><tr><td align="left"><code>proxy:keys</code></td><td align="left">JSON 数组</td><td align="left">所有代理 API 密钥</td></tr><tr><td align="left"><code>admin:session:{sessionId}</code></td><td align="left">JSON</td><td align="left">管理后台 Session（TTL 控制）</td></tr><tr><td align="left"><code>key:health:{providerId}</code></td><td align="left">JSON 对象</td><td align="left">每个提供商的密钥健康状态</td></tr><tr><td align="left"><code>migration:opencode-default:v1</code></td><td align="left">字符串</td><td align="left">迁移标记（防止重复初始化）</td></tr></tbody></table><hr><h2 id="管理后台"><a href="#管理后台" class="headerlink" title="管理后台"></a>管理后台</h2><p>管理后台访问路径为 <code>https://你的域名/admin</code>，登录后可以：</p><h3 id="提供商管理"><a href="#提供商管理" class="headerlink" title="提供商管理"></a>提供商管理</h3><ul><li>查看所有提供商（OpenCode、自定义 OpenAI&#x2F;Anthropic 兼容提供商）</li><li>添加新提供商（填写 ID、名称、API 地址、API 类型）</li><li>编辑提供商配置（API Key、模型列表、启用&#x2F;禁用）</li><li>删除不再使用的提供商</li></ul><h3 id="代理密钥管理"><a href="#代理密钥管理" class="headerlink" title="代理密钥管理"></a>代理密钥管理</h3><ul><li>生成新的 <code>sk_cf_*</code> 格式 API 密钥</li><li>查看密钥列表（密钥值脱敏展示）</li><li>启用&#x2F;禁用特定密钥</li><li>删除密钥</li></ul><h3 id="模型测试"><a href="#模型测试" class="headerlink" title="模型测试"></a>模型测试</h3><ul><li>测试某个 API Key 是否可以连接</li><li>测试某个模型是否可以正常调用</li><li>所有测试通过服务端代理完成，避免跨域问题</li></ul><hr><h2 id="本地开发"><a href="#本地开发" class="headerlink" title="本地开发"></a>本地开发</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 克隆仓库</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/your-username/ai-gateway</span><br><span class="line"><span class="built_in">cd</span> ai-gateway</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装依赖</span></span><br><span class="line">npm install</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建 .dev.vars 文件（已 gitignore）</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;ADMIN_USERNAME=admin&quot;</span> &gt;&gt; .dev.vars</span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;ADMIN_PASSWORD=your-password&quot;</span> &gt;&gt; .dev.vars</span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;OPENCODE_MIRRORS_URL=https://opencode.ai.cmliussss.net/zen/v1&quot;</span> &gt;&gt; .dev.vars</span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动本地开发</span></span><br><span class="line">npm run dev</span><br><span class="line"></span><br><span class="line"><span class="comment"># 部署</span></span><br><span class="line">npm run deploy</span><br></pre></td></tr></table></figure><p><strong>npm 脚本：</strong></p><table><thead><tr><th align="left">脚本</th><th align="left">命令</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>npm run dev</code></td><td align="left"><code>wrangler dev</code></td><td align="left">本地开发服务器</td></tr><tr><td align="left"><code>npm run build</code></td><td align="left"><code>wrangler deploy --dry-run</code></td><td align="left">构建检查（干运行）</td></tr><tr><td align="left"><code>npm run deploy</code></td><td align="left"><code>wrangler deploy</code></td><td align="left">部署到 Cloudflare</td></tr></tbody></table><hr><h2 id="设计系统"><a href="#设计系统" class="headerlink" title="设计系统"></a>设计系统</h2><p>项目使用 Hono 服务端渲染，设计系统遵循：</p><table><thead><tr><th align="left">项目</th><th align="left">规范</th></tr></thead><tbody><tr><td align="left">风格</td><td align="left">现代极简风、冷静基础设施 UI</td></tr><tr><td align="left">主题色</td><td align="left">钴蓝 <code>oklch(52% 0.205 256)</code></td></tr><tr><td align="left">显示字体</td><td align="left">Space Grotesk（500-600 字重）</td></tr><tr><td align="left">正文字体</td><td align="left">Inter（400-600 字重）</td></tr><tr><td align="left">等宽字体</td><td align="left">JetBrains Mono（400-600 字重）</td></tr><tr><td align="left">响应式断点</td><td align="left">320px、375px、414px、768px</td></tr><tr><td align="left">动画时长</td><td align="left">交互 160ms，面板 260ms</td></tr><tr><td align="left">动效曲线</td><td align="left"><code>cubic-bezier(0.16, 1, 0.3, 1)</code></td></tr><tr><td align="left">布局</td><td align="left">桌面端侧边导航栏，移动端顶部紧凑导航</td></tr></tbody></table><hr><h2 id="错误响应格式"><a href="#错误响应格式" class="headerlink" title="错误响应格式"></a>错误响应格式</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;error&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;message&quot;</span><span class="punctuation">:</span> <span class="string">&quot;错误描述信息&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;错误类型&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><strong>错误类型</strong>：<code>authentication_error</code>、<code>invalid_request_error</code>、<code>provider_disabled</code>、<code>model_disabled</code>、<code>configuration_error</code>、<code>key_exhausted</code>、<code>proxy_error</code>、<code>server_error</code>、<code>not_found</code></p><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="部署后首页空白或报错？"><a href="#部署后首页空白或报错？" class="headerlink" title="部署后首页空白或报错？"></a>部署后首页空白或报错？</h3><p>检查 KV 命名空间是否正确绑定。进入 Cloudflare Worker → <strong>设置</strong> → <strong>KV 命名空间</strong>，确认绑定名称为 <code>KV</code>。</p><h3 id="管理后台无法登录？"><a href="#管理后台无法登录？" class="headerlink" title="管理后台无法登录？"></a>管理后台无法登录？</h3><p>确认环境变量 <code>ADMIN_USERNAME</code> 和 <code>ADMIN_PASSWORD</code> 已正确设置。密码使用 SHA-256 比较，确保密码没有多余空格。</p><h3 id="OpenCode-模型无法调用？"><a href="#OpenCode-模型无法调用？" class="headerlink" title="OpenCode 模型无法调用？"></a>OpenCode 模型无法调用？</h3><ol><li>检查 <code>OPENCODE_MIRRORS_URL</code> 环境变量是否配置</li><li>确认 Cloudflare 网络可以访问镜像地址</li><li>检查模型是否处于启用状态</li></ol><h3 id="自定义提供商模型-ID-格式？"><a href="#自定义提供商模型-ID-格式？" class="headerlink" title="自定义提供商模型 ID 格式？"></a>自定义提供商模型 ID 格式？</h3><p>模型 ID 格式为 <code>providerId/modelId</code>。例如添加了名为 <code>my-api</code> 的提供商，模型 ID 为 <code>gpt-4o</code>，则调用时使用 <code>my-api/gpt-4o</code>。</p><h3 id="代理密钥-sk-cf-忘记了怎么办？"><a href="#代理密钥-sk-cf-忘记了怎么办？" class="headerlink" title="代理密钥 sk_cf_* 忘记了怎么办？"></a>代理密钥 sk_cf_* 忘记了怎么办？</h3><p>代理密钥在创建时只显示一次。如果忘记了，可以在管理后台的「代理密钥」页面重新生成一个新的。</p><h3 id="不支持哪些部署平台？"><a href="#不支持哪些部署平台？" class="headerlink" title="不支持哪些部署平台？"></a>不支持哪些部署平台？</h3><p>不推荐部署到：</p><ul><li><strong>Vercel</strong> — SSE 连接会超时</li><li><strong>Netlify</strong> — 不支持 SSE 透传</li><li><strong>Render</strong> — 冷启动延迟 5-10 秒</li></ul><h3 id="如何添加自定义-OpenCode-镜像？"><a href="#如何添加自定义-OpenCode-镜像？" class="headerlink" title="如何添加自定义 OpenCode 镜像？"></a>如何添加自定义 OpenCode 镜像？</h3><p>在 GitHub Actions 的 <code>OPENCODE_MIRRORS_URL</code> 变量中追加你的镜像 URL，或使用 Dashboard 手动配置环境变量。</p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://github.com/yutian81/ai-gateway">ai-gateway GitHub 仓库</a></li><li><a href="https://hono.dev/">Hono 框架官网</a></li><li><a href="https://developers.cloudflare.com/workers/">Cloudflare Workers 文档</a></li><li><a href="https://developers.cloudflare.com/kv/">Cloudflare KV 文档</a></li><li><a href="https://developers.cloudflare.com/workers/wrangler/">Wrangler CLI 文档</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/28/ai-gateway-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/08/28/ai-gateway-deployment-tutorial/"/>
    <published>2026-08-28T09:00:00.000Z</published>
    <summary>ai-gateway 是一个基于 Cloudflare Workers + Hono 的 AI 提供商 API 代理网关，实现一个 API 调用所有模型的聚合能力，支持多密钥轮询、健康检测、自动故障转移、管理后台等功能，本文将详细介绍从零开始部署的完整流程。</summary>
    <title>AI Gateway 部署教程：Cloudflare Workers 搭建 AI 聚合网关，统一多模型 API</title>
    <updated>2026-08-28T05:31:47.559Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="Cloudflare Pages" scheme="https://blog.ztmss.com/tags/Cloudflare-Pages/"/>
    <category term="KV" scheme="https://blog.ztmss.com/tags/KV/"/>
    <category term="部署教程" scheme="https://blog.ztmss.com/tags/%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/"/>
    <category term="UFO" scheme="https://blog.ztmss.com/tags/UFO/"/>
    <category term="管理后台" scheme="https://blog.ztmss.com/tags/%E7%AE%A1%E7%90%86%E5%90%8E%E5%8F%B0/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p><strong>UFO-zh-kg</strong> 是一个基于 <strong>Cloudflare Pages + KV 存储</strong> 构建的宇宙奥秘科普内容站，前端采用纯 HTML&#x2F;CSS&#x2F;JS（零依赖），后端通过 Cloudflare Pages Functions 提供边缘 API，文章数据存储在 Cloudflare KV 中。整个项目开箱即用，支持在线文章管理后台、暗色&#x2F;亮色主题切换、分类和标签筛选等功能。</p><ul><li><strong>演示站</strong>：<a href="https://ufo.zh.kg/">https://ufo.zh.kg/</a></li><li><strong>项目地址</strong>：<a href="https://github.com/love-ztm/ufo-zh-kg">https://github.com/love-ztm/ufo-zh-kg</a></li><li><strong>开源协议</strong>：MIT</li></ul><hr><h2 id="功能特点"><a href="#功能特点" class="headerlink" title="功能特点"></a>功能特点</h2><table><thead><tr><th align="left">功能</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">🛸 <strong>纯前端零依赖</strong></td><td align="left">HTML&#x2F;CSS&#x2F;JS 原生开发，无需构建步骤，部署即运行</td></tr><tr><td align="left">🌐 <strong>边缘 API</strong></td><td align="left">Cloudflare Pages Functions 提供全球边缘节点 API</td></tr><tr><td align="left">💾 <strong>KV 存储</strong></td><td align="left">Cloudflare KV 存储文章数据和网站配置</td></tr><tr><td align="left">📚 <strong>分类浏览</strong></td><td align="left">支持按分类和标签筛选文章</td></tr><tr><td align="left">🌙 <strong>主题切换</strong></td><td align="left">暗色&#x2F;亮色双主题，偏好自动保存到 localStorage</td></tr><tr><td align="left">🔐 <strong>管理后台</strong></td><td align="left">带密码鉴权的管理界面，支持文章 CRUD</td></tr><tr><td align="left">🔑 <strong>Session 鉴权</strong></td><td align="left">Token 鉴权机制，24 小时有效期</td></tr><tr><td align="left">📦 <strong>种子数据</strong></td><td align="left">一键初始化预置文章数据到 KV</td></tr><tr><td align="left">⚡ <strong>GitHub Actions</strong></td><td align="left">推送 main 分支自动部署到 Cloudflare Pages</td></tr><tr><td align="left">📱 <strong>响应式设计</strong></td><td align="left">适配桌面端和移动端</td></tr><tr><td align="left">🎨 <strong>SEO 友好</strong></td><td align="left">Open Graph 元数据，社交分享友好</td></tr></tbody></table><hr><h2 id="技术栈"><a href="#技术栈" class="headerlink" title="技术栈"></a>技术栈</h2><table><thead><tr><th align="left">类别</th><th align="left">技术</th></tr></thead><tbody><tr><td align="left">前端</td><td align="left">纯 HTML &#x2F; CSS &#x2F; JavaScript（零依赖）</td></tr><tr><td align="left">后端</td><td align="left">Cloudflare Pages Functions（边缘计算）</td></tr><tr><td align="left">数据存储</td><td align="left">Cloudflare KV（键值存储）</td></tr><tr><td align="left">部署</td><td align="left">GitHub Actions → Cloudflare Pages（自动部署）</td></tr><tr><td align="left">开发工具</td><td align="left">Wrangler CLI（本地开发调试）</td></tr></tbody></table><hr><h2 id="项目结构"><a href="#项目结构" class="headerlink" title="项目结构"></a>项目结构</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">ufo-zh-kg/</span><br><span class="line">├── public/                        # 静态文件</span><br><span class="line">│   ├── index.html                 # 首页（文章列表）</span><br><span class="line">│   ├── article.html               # 文章详情页</span><br><span class="line">│   ├── admin.html                 # 管理后台</span><br><span class="line">│   ├── favicon.ico                # 图标</span><br><span class="line">│   ├── favicon.png</span><br><span class="line">│   ├── favicon-32x32.png</span><br><span class="line">│   └── favicon.svg</span><br><span class="line">├── functions/                     # Cloudflare Pages Functions</span><br><span class="line">│   ├── _data/</span><br><span class="line">│   │   └── articles.js            # 文章种子数据</span><br><span class="line">│   └── api/</span><br><span class="line">│       ├── articles.js            # GET /api/articles（文章列表）</span><br><span class="line">│       ├── articles/[id].js       # GET /api/articles/:id（文章详情）</span><br><span class="line">│       ├── seed.js                # POST /api/seed（初始化数据）</span><br><span class="line">│       ├── settings.js            # GET /api/settings（公开配置）</span><br><span class="line">│       └── admin/</span><br><span class="line">│           ├── login.js           # POST /api/admin/login（登录）</span><br><span class="line">│           ├── check.js           # GET /api/admin/check（登录状态）</span><br><span class="line">│           ├── list.js            # GET /api/admin/list（管理文章列表）</span><br><span class="line">│           ├── article.js         # POST/PUT/DELETE /api/admin/article（CRUD）</span><br><span class="line">│           ├── settings.js        # GET/POST /api/admin/settings（网站配置）</span><br><span class="line">│           └── change-password.js # POST /api/admin/change-password（改密码）</span><br><span class="line">├── wrangler.toml                  # Cloudflare 配置</span><br><span class="line">├── package.json</span><br><span class="line">└── .github/</span><br><span class="line">    └── workflows/</span><br><span class="line">        └── deploy.yml             # GitHub Actions 自动部署</span><br></pre></td></tr></table></figure><hr><h2 id="部署步骤"><a href="#部署步骤" class="headerlink" title="部署步骤"></a>部署步骤</h2><h3 id="1-准备工作"><a href="#1-准备工作" class="headerlink" title="1. 准备工作"></a>1. 准备工作</h3><p>开始之前，需要准备以下内容：</p><ol><li><strong>Cloudflare 账号</strong> — 注册 <a href="https://dash.cloudflare.com/">Cloudflare</a> 并绑定一个域名</li><li><strong>GitHub 账号</strong> — 用于 Fork 仓库</li><li><strong>API Token</strong> — 需要具有 Pages 部署权限的 API Token</li></ol><h3 id="2-创建-KV-命名空间"><a href="#2-创建-KV-命名空间" class="headerlink" title="2. 创建 KV 命名空间"></a>2. 创建 KV 命名空间</h3><ol><li>登录 <a href="https://dash.cloudflare.com/">Cloudflare Dashboard</a></li><li>进入 <strong>Workers 和 Pages</strong> → <strong>KV</strong> → <strong>创建命名空间</strong></li><li>输入名称，例如 <code>UFO_ARTICLES</code>，点击创建</li><li>创建后右侧会显示一串字符，这就是 <strong>KV namespace ID</strong>，请保存下来备用</li></ol><blockquote><p>示例 KV ID：<code>28733a27837f4aef9be0b8d6f7b58cac</code></p></blockquote><h3 id="3-Fork-项目仓库"><a href="#3-Fork-项目仓库" class="headerlink" title="3. Fork 项目仓库"></a>3. Fork 项目仓库</h3><p>访问 <a href="https://github.com/love-ztm/ufo-zh-kg">UFO-zh-kg 项目</a>，先给项目点个 ⭐，然后点击右上角 <strong>Fork</strong>，将仓库克隆到你的 GitHub 账号下。</p><h3 id="4-配置-wrangler-toml"><a href="#4-配置-wrangler-toml" class="headerlink" title="4. 配置 wrangler.toml"></a>4. 配置 wrangler.toml</h3><p>打开 <code>wrangler.toml</code>，将 KV ID 填入：</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name</span> = <span class="string">&quot;ufo-zh-kg&quot;</span></span><br><span class="line"><span class="attr">compatibility_date</span> = <span class="string">&quot;2024-01-01&quot;</span></span><br><span class="line"><span class="attr">pages_build_output_dir</span> = <span class="string">&quot;./public&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[kv_namespaces]]</span></span><br><span class="line"><span class="attr">binding</span> = <span class="string">&quot;ARTICLES&quot;</span></span><br><span class="line"><span class="attr">id</span> = <span class="string">&quot;你的KV_NAMESPACE_ID&quot;</span>  <span class="comment"># 替换为你的 KV ID</span></span><br></pre></td></tr></table></figure><h3 id="5-配置-GitHub-Secrets"><a href="#5-配置-GitHub-Secrets" class="headerlink" title="5. 配置 GitHub Secrets"></a>5. 配置 GitHub Secrets</h3><p>在 Fork 的仓库中，按以下步骤设置：</p><ol><li>进入仓库 <strong>Settings</strong> → <strong>Secrets and variables</strong> → <strong>Actions</strong></li><li>点击 <strong>New repository secret</strong>，添加以下 secrets：</li></ol><table><thead><tr><th align="left">Secret 名称</th><th align="left">说明</th><th align="left">必填</th></tr></thead><tbody><tr><td align="left"><code>CLOUDFLARE_ACCOUNT_ID</code></td><td align="left">Cloudflare 账户 ID（不是邮箱）</td><td align="left">✅</td></tr><tr><td align="left"><code>CLOUDFLARE_API_TOKEN</code></td><td align="left">API Token（需 Pages 部署权限）</td><td align="left">✅</td></tr></tbody></table><blockquote><p>⚠️ API Token 需要具有 <strong>Pages 部署</strong> 的权限，否则部署会失败。</p></blockquote><p><strong>如何获取 Cloudflare 账户 ID：</strong><br>登录 Cloudflare Dashboard，在右上角头像下拉菜单中可以看到账户 ID，或者从 URL 中提取：<code>https://dash.cloudflare.com/ACCOUNT_ID/...</code></p><h3 id="6-推送部署"><a href="#6-推送部署" class="headerlink" title="6. 推送部署"></a>6. 推送部署</h3><p>在 Fork 的仓库中，将修改推送到 <code>main</code> 分支：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git add .</span><br><span class="line">git commit -m <span class="string">&quot;init: 配置KV和部署&quot;</span></span><br><span class="line">git push origin main</span><br></pre></td></tr></table></figure><p>推送后，GitHub Actions 会自动触发部署流程，将 <code>public/</code> 目录部署到 Cloudflare Pages。部署完成后会生成一个 Pages 项目链接（如 <code>ufo-zh-kg.pages.dev</code>）。</p><blockquote><p>[!TIP]<br>你也可以绑定自定义域名：在 Cloudflare Pages 项目设置中添加自定义域（如 <code>ufo.你的域名</code>），然后在 Cloudflare DNS 中添加相应的 CNAME 记录。</p></blockquote><h3 id="7-初始化数据（Seed）"><a href="#7-初始化数据（Seed）" class="headerlink" title="7. 初始化数据（Seed）"></a>7. 初始化数据（Seed）</h3><p>部署完成后，需要调用 seed 接口将文章数据写入 KV 存储：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -X POST https://ufo.zh.kg/api/seed?key=ufo-zh-kg-seed-2024</span><br></pre></td></tr></table></figure><p>首次执行后，种子数据会被写入 KV。如果需要强制重新写入（覆盖已有数据），添加 <code>force=1</code> 参数：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -X POST https://ufo.zh.kg/api/seed?key=ufo-zh-kg-seed-2024&amp;force=1</span><br></pre></td></tr></table></figure><blockquote><p>[!NOTE]<br>seed 密钥 <code>ufo-zh-kg-seed-2024</code> 硬编码在 <code>functions/api/seed.js</code> 中，出于安全考虑，建议在生产环境中修改为自己的密钥。</p></blockquote><hr><h2 id="API-接口"><a href="#API-接口" class="headerlink" title="API 接口"></a>API 接口</h2><table><thead><tr><th align="left">方法</th><th align="left">路径</th><th align="left">说明</th><th align="left">鉴权</th></tr></thead><tbody><tr><td align="left">GET</td><td align="left"><code>/api/articles</code></td><td align="left">获取文章列表（支持 <code>?category=xxx</code> 和 <code>?tag=xxx</code> 筛选）</td><td align="left">公开</td></tr><tr><td align="left">GET</td><td align="left"><code>/api/articles/:id</code></td><td align="left">获取单篇文章详情</td><td align="left">公开</td></tr><tr><td align="left">POST</td><td align="left"><code>/api/seed</code></td><td align="left">初始化 KV 数据（需密钥）</td><td align="left">密钥验证</td></tr><tr><td align="left">GET</td><td align="left"><code>/api/settings</code></td><td align="left">获取网站公开配置</td><td align="left">公开</td></tr><tr><td align="left">POST</td><td align="left"><code>/api/admin/login</code></td><td align="left">管理员登录</td><td align="left">密码验证</td></tr><tr><td align="left">GET</td><td align="left"><code>/api/admin/check</code></td><td align="left">检查登录状态</td><td align="left">Token 鉴权</td></tr><tr><td align="left">GET</td><td align="left"><code>/api/admin/list</code></td><td align="left">获取管理文章列表</td><td align="left">Token 鉴权</td></tr><tr><td align="left">POST</td><td align="left"><code>/api/admin/article</code></td><td align="left">新建文章</td><td align="left">Token 鉴权</td></tr><tr><td align="left">PUT</td><td align="left"><code>/api/admin/article?id=xxx</code></td><td align="left">更新文章</td><td align="left">Token 鉴权</td></tr><tr><td align="left">DELETE</td><td align="left"><code>/api/admin/article?id=xxx</code></td><td align="left">删除文章</td><td align="left">Token 鉴权</td></tr><tr><td align="left">GET</td><td align="left"><code>/api/admin/settings</code></td><td align="left">读取网站配置</td><td align="left">Token 鉴权</td></tr><tr><td align="left">POST</td><td align="left"><code>/api/admin/settings</code></td><td align="left">保存网站配置</td><td align="left">Token 鉴权</td></tr><tr><td align="left">POST</td><td align="left"><code>/api/admin/change-password</code></td><td align="left">修改管理密码</td><td align="left">Token 鉴权</td></tr></tbody></table><h3 id="文章列表接口"><a href="#文章列表接口" class="headerlink" title="文章列表接口"></a>文章列表接口</h3><p><code>GET /api/articles</code> 支持通过查询参数筛选：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">GET /api/articles                 # 获取全部文章</span><br><span class="line">GET /api/articles?category=经典案例  # 按分类筛选</span><br><span class="line">GET /api/articles?tag=UFO        # 按标签筛选</span><br></pre></td></tr></table></figure><p>返回结构：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;articles&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;roswell-incident&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;title&quot;</span><span class="punctuation">:</span> <span class="string">&quot;罗斯威尔事件：最著名的UFO坠毁案&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;category&quot;</span><span class="punctuation">:</span> <span class="string">&quot;经典案例&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;tags&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;经典案例&quot;</span><span class="punctuation">,</span> <span class="string">&quot;UFO&quot;</span><span class="punctuation">,</span> <span class="string">&quot;政府档案&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;summary&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1947年，美国新墨西哥州罗斯威尔发生了一起震惊世界的事件……&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;image&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://images.unsplash.com/photo-xxx?w=800&amp;h=600&amp;fit=crop&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;date&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1947-07-08&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;total&quot;</span><span class="punctuation">:</span> <span class="number">1</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h3 id="文章详情接口"><a href="#文章详情接口" class="headerlink" title="文章详情接口"></a>文章详情接口</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET /api/articles/roswell-incident</span><br></pre></td></tr></table></figure><p>返回完整的文章内容（含 <code>content</code> 字段，HTML 格式）。</p><hr><h2 id="管理后台"><a href="#管理后台" class="headerlink" title="管理后台"></a>管理后台</h2><p>管理后台页面在 <code>https://ufo.zh.kg/admin.html</code>，首次部署后默认密码为：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ufo-admin-2024</span><br></pre></td></tr></table></figure><blockquote><p>⚠️ <strong>强烈建议</strong>：部署成功后，第一时间在管理后台修改默认密码！</p></blockquote><h3 id="管理后台功能"><a href="#管理后台功能" class="headerlink" title="管理后台功能"></a>管理后台功能</h3><table><thead><tr><th align="left">功能</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">文章列表</td><td align="left">查看所有文章，支持搜索</td></tr><tr><td align="left">新建文章</td><td align="left">填写标题、分类、标签、摘要、图片、内容等</td></tr><tr><td align="left">编辑文章</td><td align="left">修改已有文章内容</td></tr><tr><td align="left">删除文章</td><td align="left">删除不再需要的文章</td></tr><tr><td align="left">网站配置</td><td align="left">修改站名、副标题、导航、分类、主题、背景图等</td></tr><tr><td align="left">修改密码</td><td align="left">修改管理后台登录密码</td></tr></tbody></table><h3 id="网站配置项"><a href="#网站配置项" class="headerlink" title="网站配置项"></a>网站配置项</h3><table><thead><tr><th align="left">配置项</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>title</code></td><td align="left">网站标题</td></tr><tr><td align="left"><code>subtitle</code></td><td align="left">网站副标题</td></tr><tr><td align="left"><code>subtitleUrl</code></td><td align="left">副标题链接</td></tr><tr><td align="left"><code>categories</code></td><td align="left">文章分类列表</td></tr><tr><td align="left"><code>nav</code></td><td align="left">导航栏配置（支持按分类筛选）</td></tr><tr><td align="left"><code>theme</code></td><td align="left">默认主题（<code>dark</code> &#x2F; <code>light</code>）</td></tr><tr><td align="left"><code>bgImage</code></td><td align="left">暗色主题背景图</td></tr><tr><td align="left"><code>bgImageLight</code></td><td align="left">亮色主题背景图</td></tr></tbody></table><hr><h2 id="前端页面"><a href="#前端页面" class="headerlink" title="前端页面"></a>前端页面</h2><h3 id="首页（index-html）"><a href="#首页（index-html）" class="headerlink" title="首页（index.html）"></a>首页（index.html）</h3><ul><li>顶部导航栏：Logo + 导航菜单 + 主题切换</li><li>文章列表卡片：缩略图 + 标题 + 摘要 + 标签</li><li>分类&#x2F;标签筛选：点击导航或筛选按钮过滤文章</li><li>暗色&#x2F;亮色主题：点击月亮&#x2F;太阳图标切换，偏好保存到 <code>localStorage</code></li></ul><h3 id="文章详情页（article-html）"><a href="#文章详情页（article-html）" class="headerlink" title="文章详情页（article.html）"></a>文章详情页（article.html）</h3><ul><li>大图展示：文章封面图</li><li>文章内容：HTML 格式渲染</li><li>分类&#x2F;标签：文章分类和标签展示</li><li>暗色&#x2F;亮色主题：与首页保持一致</li></ul><hr><h2 id="本地开发"><a href="#本地开发" class="headerlink" title="本地开发"></a>本地开发</h2><p>如果你想在本地调试和开发，可以使用 Wrangler CLI：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装 Wrangler</span></span><br><span class="line">npm install -g wrangler</span><br><span class="line"></span><br><span class="line"><span class="comment"># 登录 Cloudflare</span></span><br><span class="line">wrangler login</span><br><span class="line"></span><br><span class="line"><span class="comment"># 本地开发（会自动模拟 KV）</span></span><br><span class="line">wrangler pages dev public --kv=ARTICLES</span><br><span class="line"></span><br><span class="line"><span class="comment"># 部署</span></span><br><span class="line">wrangler pages deploy public</span><br></pre></td></tr></table></figure><p>本地开发时，KV 数据会在本地模拟，无需真实 KV 环境即可调试。</p><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="部署后文章列表为空？"><a href="#部署后文章列表为空？" class="headerlink" title="部署后文章列表为空？"></a>部署后文章列表为空？</h3><p>这是正常现象，KV 是空的。需要调用 seed 接口初始化数据：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -X POST https://你的域名/api/seed?key=ufo-zh-kg-seed-2024</span><br></pre></td></tr></table></figure><h3 id="首页显示「加载中」但不消失？"><a href="#首页显示「加载中」但不消失？" class="headerlink" title="首页显示「加载中」但不消失？"></a>首页显示「加载中」但不消失？</h3><p>检查 Cloudflare Pages 项目的 <strong>KV 绑定</strong> 是否正确：</p><ol><li>进入 Cloudflare Pages 项目</li><li>点击 <strong>设置</strong> → <strong>变量和机密</strong></li><li>确认 KV 绑定名称为 <code>ARTICLES</code>，且 KV ID 正确</li></ol><h3 id="管理后台登录失败？"><a href="#管理后台登录失败？" class="headerlink" title="管理后台登录失败？"></a>管理后台登录失败？</h3><p>确认密码是否正确。默认密码为 <code>ufo-admin-2024</code>。如果之前修改过密码但忘记了，需要在 Cloudflare KV 中删除 <code>admin_password</code> 键即可恢复默认密码：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 通过 Wrangler CLI</span></span><br><span class="line">wrangler kv:namespace list   <span class="comment"># 找到 namespace ID</span></span><br><span class="line">wrangler kv:key delete admin_password --namespace-id=YOUR_KV_ID</span><br></pre></td></tr></table></figure><h3 id="如何修改-seed-密钥？"><a href="#如何修改-seed-密钥？" class="headerlink" title="如何修改 seed 密钥？"></a>如何修改 seed 密钥？</h3><p>编辑 <code>functions/api/seed.js</code> 中的 <code>SEED_SECRET</code> 常量：</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="variable constant_">SEED_SECRET</span> = <span class="string">&quot;ufo-zh-kg-seed-2024&quot;</span>;  <span class="comment">// 改成你自己的密钥</span></span><br></pre></td></tr></table></figure><h3 id="如何添加新的预置文章？"><a href="#如何添加新的预置文章？" class="headerlink" title="如何添加新的预置文章？"></a>如何添加新的预置文章？</h3><p>编辑 <code>functions/_data/articles.js</code>，按照现有格式添加新文章对象，然后重新运行 seed 接口（带 <code>?force=1</code>）。</p><h3 id="图片-404-或加载失败？"><a href="#图片-404-或加载失败？" class="headerlink" title="图片 404 或加载失败？"></a>图片 404 或加载失败？</h3><p>文章中的图片使用 Unsplash 和 Picsum 的图床服务，访问可能需要稳定的网络环境。你也可以替换为自己的图床 URL。</p><hr><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><ul><li><a href="https://github.com/love-ztm/ufo-zh-kg">UFO-zh-kg GitHub 仓库</a></li><li><a href="https://ufo.zh.kg/">演示站 ufo.zh.kg</a></li><li><a href="https://developers.cloudflare.com/pages/">Cloudflare Pages 文档</a></li><li><a href="https://developers.cloudflare.com/workers/">Cloudflare Workers 文档</a></li><li><a href="https://developers.cloudflare.com/kv/">Cloudflare KV 文档</a></li><li><a href="https://developers.cloudflare.com/workers/wrangler/">Wrangler CLI 文档</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/28/ufo-zh-kg-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/08/28/ufo-zh-kg-deployment-tutorial/"/>
    <published>2026-08-28T08:00:00.000Z</published>
    <summary>UFO-zh-kg 是一个基于 Cloudflare Pages Functions 和 KV 存储构建的宇宙奥秘科普内容站，支持文章管理后台、多分类浏览、暗色主题切换等特性，本文将详细介绍从零开始部署的完整流程。</summary>
    <title>UFO部署教程：Cloudflare Pages + KV 搭建宇宙奥秘科普站，带管理后台和主题切换</title>
    <updated>2026-08-28T04:56:06.468Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="IPv6" scheme="https://blog.ztmss.com/tags/IPv6/"/>
    <category term="隧道" scheme="https://blog.ztmss.com/tags/%E9%9A%A7%E9%81%93/"/>
    <category term="TunnelBroker" scheme="https://blog.ztmss.com/tags/TunnelBroker/"/>
    <category term="Hurricane Electric" scheme="https://blog.ztmss.com/tags/Hurricane-Electric/"/>
    <category term="6in4" scheme="https://blog.ztmss.com/tags/6in4/"/>
    <category term="网络配置" scheme="https://blog.ztmss.com/tags/%E7%BD%91%E7%BB%9C%E9%85%8D%E7%BD%AE/"/>
    <content>
      <![CDATA[<h1 id="IPv6-隧道部署教程：Hurricane-Electric-TunnelBroker-6in4-完整配置指南"><a href="#IPv6-隧道部署教程：Hurricane-Electric-TunnelBroker-6in4-完整配置指南" class="headerlink" title="IPv6 隧道部署教程：Hurricane Electric (TunnelBroker) 6in4 完整配置指南"></a>IPv6 隧道部署教程：Hurricane Electric (TunnelBroker) 6in4 完整配置指南</h1><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>现在很多宽带运营商（尤其国内）还没有普及 IPv6，导致我们访问 IPv6-only 资源、测试 IPv6 应用时非常不方便。<strong>Hurricane Electric（HE，飓风电讯）</strong> 提供的 <strong>免费 IPv6 隧道服务（Tunnel Broker）</strong> 就是解决这个问题的利器：它通过现有 IPv4 网络把 IPv6 数据包”隧道”到 HE 的 IPv6 骨干网，让你的设备立刻获得 IPv6 连接。</p><ul><li><strong>官网</strong>：<a href="https://tunnelbroker.net/">https://tunnelbroker.net</a></li><li><strong>费用</strong>：完全免费，注册即用</li><li><strong>定位</strong>：面向开发者和实验者，提供稳定的隧道平台</li><li><strong>服务商</strong>：HE 是一家运营 24×7 的商业 ISP，拥有国际骨干网络，稳定性有保障</li></ul><h2 id="服务特点"><a href="#服务特点" class="headerlink" title="服务特点"></a>服务特点</h2><table><thead><tr><th align="left">特点</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">🆓 <strong>完全免费</strong></td><td align="left">无需信用卡，注册即可创建隧道</td></tr><tr><td align="left">🌐 <strong>全球节点</strong></td><td align="left">隧道服务器遍布全球 30+ 城市（阿什本、芝加哥、洛杉矶、西雅图、法兰克福、伦敦、巴黎、香港、新加坡等），可选离你最近的节点</td></tr><tr><td align="left">🏠 <strong>&#x2F;48 前缀</strong></td><td align="left">隧道启用后可以申请自己的 <strong>&#x2F;48 IPv6 前缀</strong>，可细分大量子网</td></tr><tr><td align="left">⚡ <strong>即开即用</strong></td><td align="left">简单注册后不到一分钟即可创建隧道</td></tr><tr><td align="left">🔧 <strong>多平台支持</strong></td><td align="left">Linux &#x2F; Windows &#x2F; macOS &#x2F; 路由器（OpenWRT 等）均有配置方案</td></tr></tbody></table><h2 id="技术原理：什么是-6in4-隧道"><a href="#技术原理：什么是-6in4-隧道" class="headerlink" title="技术原理：什么是 6in4 隧道"></a>技术原理：什么是 6in4 隧道</h2><p><strong>6in4</strong>（IPv6-in-IPv4）是最常见的隧道协议：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">┌──────────┐   IPv6数据包   ┌───────────┐   IPv6数据包   ┌─────────────┐</span><br><span class="line">│ 你的设备  │ ─────────────▶ │ HE隧道服务器 │ ─────────────▶ │ IPv6 互联网 │</span><br><span class="line">│ (IPv4接入)│  IPv4封装(协议41)│ (全球骨干)  │  解封装转发    │   IPv6 全网  │</span><br><span class="line">└──────────┘                └───────────┘                └─────────────┘</span><br></pre></td></tr></table></figure><ul><li>你的设备把 <strong>IPv6 数据包封装进 IPv4 报文</strong>（IP 协议号 <strong>41</strong>），通过现有 IPv4 网络发送</li><li>HE 的隧道服务器解封装后，把 IPv6 数据包接入 HE 的 IPv6 骨干网</li><li>回程流量同样经过隧道返回你的设备</li></ul><p>这样，你不需要任何硬件改造，只要有一台能上 IPv4 网络的设备，就能获得 IPv6 地址并访问 IPv6 互联网。</p><h2 id="第一步：注册账号"><a href="#第一步：注册账号" class="headerlink" title="第一步：注册账号"></a>第一步：注册账号</h2><ol><li>打开 <a href="https://tunnelbroker.net/">tunnelbroker.net</a></li><li>点击 <strong>Register</strong>（注册），填写邮箱和密码</li><li>登录后进入控制台</li></ol><blockquote><p>💡 HE 还提供免费 DNS、BGP Toolkit、Looking Glass 等网络工具，注册一个账号可以全部使用。</p></blockquote><h2 id="第二步：创建隧道"><a href="#第二步：创建隧道" class="headerlink" title="第二步：创建隧道"></a>第二步：创建隧道</h2><ol><li>登录后点击 <strong>Create Regular Tunnel</strong>（创建普通隧道）</li><li>在 <strong>IPv4 Endpoint (Your side)</strong> 输入你当前设备的<strong>公网 IPv4 地址</strong>（就是你出口的公网 IP）</li><li>系统会根据你的 IP 自动推荐<strong>离你最近的隧道服务器</strong>，也可以手动选择（Available Tunnel Servers 列表里选）</li><li>点击 <strong>Create Tunnel</strong> 创建</li></ol><p>创建成功后进入 <strong>Tunnel Details（隧道详情）</strong> 页面，记录以下关键信息：</p><table><thead><tr><th align="left">字段</th><th align="left">说明</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left"><strong>Server IPv4 Address</strong></td><td align="left">HE 隧道服务器的 IPv4 地址</td><td align="left"><code>216.66.80.30</code></td></tr><tr><td align="left"><strong>Server IPv6 Address</strong></td><td align="left">HE 隧道服务器的 IPv6 地址</td><td align="left"><code>2001:470:1f0b:xxx::1</code></td></tr><tr><td align="left"><strong>Client IPv6 Address</strong></td><td align="left">分配给你的设备的 IPv6 地址</td><td align="left"><code>2001:470:1f0b:xxx::2</code></td></tr><tr><td align="left"><strong>Routed &#x2F;64</strong></td><td align="left">路由给你的 &#x2F;64 子网</td><td align="left"><code>2001:470:xxxx:xxx::/64</code></td></tr><tr><td align="left"><strong>Routed &#x2F;48</strong></td><td align="left">可选，申请后可获得 &#x2F;48 大段前缀</td><td align="left"><code>2001:470:xxxx::/48</code></td></tr></tbody></table><blockquote><p>⚠️ 页面下方还有 <strong>Example Configurations</strong>（示例配置），会针对你的系统自动生成完整命令，可以直接参考。</p></blockquote><h2 id="第三步：Linux-配置（iproute2）"><a href="#第三步：Linux-配置（iproute2）" class="headerlink" title="第三步：Linux 配置（iproute2）"></a>第三步：Linux 配置（iproute2）</h2><p>以下命令适用于 Debian &#x2F; Ubuntu &#x2F; CentOS 等主流 Linux 发行版，把示例值替换成你隧道详情页里的真实值：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 创建隧道接口（he-ipv6）</span></span><br><span class="line"><span class="comment">#    remote = Server IPv4 Address，local = 本机公网 IPv4</span></span><br><span class="line"><span class="built_in">sudo</span> ip tunnel add he-ipv6 mode sit remote 216.66.80.30 <span class="built_in">local</span> 你的公网IP ttl 255</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 启用隧道接口</span></span><br><span class="line"><span class="built_in">sudo</span> ip <span class="built_in">link</span> <span class="built_in">set</span> he-ipv6 up</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 配置客户端 IPv6 地址（Client IPv6 Address）</span></span><br><span class="line"><span class="built_in">sudo</span> ip addr add 2001:470:1f0b:xxxx::2/64 dev he-ipv6</span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 添加默认 IPv6 路由（流量全部走隧道）</span></span><br><span class="line"><span class="built_in">sudo</span> ip -6 route add default dev he-ipv6</span><br></pre></td></tr></table></figure><p><strong>验证配置：</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ip tunnel list            <span class="comment"># 查看隧道状态（应显示 he-ipv6 up）</span></span><br><span class="line">ip -6 addr show he-ipv6   <span class="comment"># 查看 IPv6 地址</span></span><br><span class="line">ip -6 route show          <span class="comment"># 查看 IPv6 路由</span></span><br></pre></td></tr></table></figure><p><strong>测试 IPv6 连通性：</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ping Google 的 IPv6 DNS（2001:4860:4860::8888）</span></span><br><span class="line">ping6 2001:4860:4860::8888</span><br><span class="line"></span><br><span class="line"><span class="comment"># 或使用 curl 测试</span></span><br><span class="line">curl -6 https://ipv6.google.com</span><br></pre></td></tr></table></figure><h3 id="开机自启（systemd）"><a href="#开机自启（systemd）" class="headerlink" title="开机自启（systemd）"></a>开机自启（systemd）</h3><p>隧道配置重启后会丢失，建议写成 systemd 服务：</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># /etc/systemd/system/he-ipv6.service</span></span><br><span class="line"><span class="section">[Unit]</span></span><br><span class="line"><span class="attr">Description</span>=HE <span class="number">6</span>in4 IPv6 Tunnel</span><br><span class="line"><span class="attr">After</span>=network.target</span><br><span class="line"></span><br><span class="line"><span class="section">[Service]</span></span><br><span class="line"><span class="attr">Type</span>=<span class="literal">on</span>eshot</span><br><span class="line"><span class="attr">ExecStart</span>=/usr/sbin/ip tunnel add he-ipv6 mode sit remote <span class="number">216.66</span>.<span class="number">80.30</span> local 你的公网IP ttl <span class="number">255</span></span><br><span class="line"><span class="attr">ExecStart</span>=/usr/sbin/ip link set he-ipv6 up</span><br><span class="line"><span class="attr">ExecStart</span>=/usr/sbin/ip addr add <span class="number">2001</span>:<span class="number">470</span>:<span class="number">1</span>f0b:xxxx::<span class="number">2</span>/<span class="number">64</span> dev he-ipv6</span><br><span class="line"><span class="attr">ExecStart</span>=/usr/sbin/ip -<span class="number">6</span> route add default dev he-ipv6</span><br><span class="line"><span class="attr">ExecStop</span>=/usr/sbin/ip link set he-ipv6 down</span><br><span class="line"><span class="attr">ExecStop</span>=/usr/sbin/ip tunnel del he-ipv6</span><br><span class="line"></span><br><span class="line"><span class="section">[Install]</span></span><br><span class="line"><span class="attr">WantedBy</span>=multi-user.target</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> systemctl daemon-reload</span><br><span class="line"><span class="built_in">sudo</span> systemctl <span class="built_in">enable</span> he-ipv6</span><br><span class="line"><span class="built_in">sudo</span> systemctl start he-ipv6</span><br></pre></td></tr></table></figure><h2 id="第四步：Windows-配置（netsh）"><a href="#第四步：Windows-配置（netsh）" class="headerlink" title="第四步：Windows 配置（netsh）"></a>第四步：Windows 配置（netsh）</h2><p>以管理员身份打开 PowerShell 或 CMD：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 创建 6in4 隧道</span></span><br><span class="line">netsh interface ipv6 add v6v4tunnel <span class="string">&quot;he-ipv6&quot;</span> <span class="number">216.66</span>.<span class="number">80.30</span> 你的公网IP</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 设置客户端 IPv6 地址</span></span><br><span class="line">netsh interface ipv6 add address <span class="string">&quot;he-ipv6&quot;</span> <span class="number">2001</span>:<span class="number">470</span>:<span class="number">1</span>f0b:xxxx::<span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 添加默认 IPv6 路由</span></span><br><span class="line">netsh interface ipv6 add route ::/<span class="number">0</span> <span class="string">&quot;he-ipv6&quot;</span> <span class="number">2001</span>:<span class="number">470</span>:<span class="number">1</span>f0b:xxxx::<span class="number">1</span></span><br></pre></td></tr></table></figure><blockquote><p>💡 如果你使用的系统无法直接用 netsh，也可以在 <a href="https://www.tunnelbroker.net/">下载页面</a> 找到 HE 提供的隧道客户端工具，图形化配置更简单。</p></blockquote><h2 id="第五步：申请-48-前缀（可选，进阶）"><a href="#第五步：申请-48-前缀（可选，进阶）" class="headerlink" title="第五步：申请 &#x2F;48 前缀（可选，进阶）"></a>第五步：申请 &#x2F;48 前缀（可选，进阶）</h2><p>隧道启用并稳定运行后，可以在隧道详情页找到 <strong>Assign &#x2F;48</strong>（分配 &#x2F;48 前缀）的入口，申请一个完整的 <code>/48</code> 地址段。拿到 &#x2F;48 后，你可以把它路由到局域网，给家里的所有设备都分配 IPv6 地址：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 开启 IPv6 转发（路由器/网关设备上）</span></span><br><span class="line"><span class="built_in">sudo</span> sysctl -w net.ipv6.conf.all.forwarding=1</span><br><span class="line"></span><br><span class="line"><span class="comment"># 把 /48 路由到隧道接口</span></span><br><span class="line"><span class="built_in">sudo</span> ip -6 route add 2001:470:xxxx::/48 dev he-ipv6</span><br></pre></td></tr></table></figure><p>然后在内网接口配置一个 &#x2F;48 内的地址，并用 radvd &#x2F; dnsmasq &#x2F; 路由器固件做 <strong>IPv6 地址下发（RA）</strong>，局域网设备就能自动获得 IPv6 地址了。</p><blockquote><p>⚠️ &#x2F;48 申请前请确认你在 HE 的隧道已经持续可用；滥用会导致隧道被回收。</p></blockquote><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><p><strong>Q：为什么隧道创建后 ping 不通？</strong><br>A：常见原因：</p><ol><li>防火墙没有放行 <strong>协议 41（IPv6-in-IPv4）</strong> 的出入流量</li><li>路由器&#x2F;运营商做了 NAT 且不支持协议 41 转发（家庭宽带尤其常见）</li><li>隧道服务器选得太远，时延高导致连接不稳定</li></ol><p><strong>Q：我家里是 NAT 环境，能用吗？</strong><br>A：如果你的出口是 NAT（绝大多数家庭宽带），需要在<strong>光猫&#x2F;路由器上把协议 41 转发</strong>到内网这台设备，或者给这台设备配置公网 IP。最省事的办法是直接在<strong>有公网 IP 的 VPS 服务器</strong>上配置隧道。</p><p><strong>Q：隧道重启后就没了？</strong><br>A：6in4 隧道默认是临时的，重启后需要重新执行配置命令。Linux 建议写成 systemd 服务（见上文），Windows 建议使用计划任务或隧道客户端工具。</p><p><strong>Q：隧道有流量限制吗？</strong><br>A：HE 隧道对个人使用没有明确流量上限，但明确<strong>禁止用于商业转售</strong>，大量滥用流量（如 BT 下载）可能导致隧道被限制或回收。</p><p><strong>Q：IPv6 速度怎么样？</strong><br>A：由于所有流量都要经过 HE 隧道服务器中转，速度取决于你到 HE 节点（及回程）的线路质量，通常比原生 IPv6 稍慢。国内用户建议选择最近的节点（香港、新加坡等）或使用其他方案（如 VPS 中转）。</p><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>用 HE 免费隧道获得 IPv6，核心就三步：</p><ol><li><strong>注册</strong> tunnelbroker.net 账号，创建 6in4 隧道，拿到 Server IPv4 和 Client IPv6 地址</li><li><strong>配置</strong>：Linux 用 <code>ip tunnel add</code>（或 systemd 持久化），Windows 用 <code>netsh</code>，一分钟搞定</li><li><strong>验证</strong>：<code>ping6 2001:4860:4860::8888</code> 通，即可正常访问 IPv6 互联网</li></ol><p>隧道稳定后别忘了去申请 <strong>&#x2F;48 前缀</strong>，把它路由到局域网，让家里所有设备都能享受 IPv6。这套方案完全免费，是测试 IPv6、搭建 IPv6-only 服务的最佳入门选择。</p><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://tunnelbroker.net/">Hurricane Electric 免费 IPv6 隧道服务</a></li><li><a href="https://tunnelbroker.net/tunnel_status.php">HE 隧道服务状态与服务器列表</a></li><li><a href="https://test-ipv6.com/">test-ipv6.com 在线 IPv6 测试</a></li><li><a href="https://ipv6-test.com/">ipv6-test.com 在线测试</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/15/ipv6-tunnel-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/08/15/ipv6-tunnel-deployment-tutorial/"/>
    <published>2026-08-15T02:00:00.000Z</published>
    <summary>使用 Hurricane Electric 免费 IPv6 隧道服务 (tunnelbroker.net)，在纯 IPv4 网络上一分钟开通 IPv6 连接。本文从注册、创建隧道到 Linux / Windows 双平台配置与测试，完整讲解 6in4 隧道部署流程，隧道启用后还可申请 /48 前缀。</summary>
    <title>IPv6隧道部署教程：Hurricane Electric (TunnelBroker) 免费 6in4 隧道完整配置指南</title>
    <updated>2026-08-17T07:58:22.402Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="Cloudflare" scheme="https://blog.ztmss.com/tags/Cloudflare/"/>
    <category term="异地组网" scheme="https://blog.ztmss.com/tags/%E5%BC%82%E5%9C%B0%E7%BB%84%E7%BD%91/"/>
    <category term="ZeroTier" scheme="https://blog.ztmss.com/tags/ZeroTier/"/>
    <category term="Tailscale" scheme="https://blog.ztmss.com/tags/Tailscale/"/>
    <category term="内网穿透" scheme="https://blog.ztmss.com/tags/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/"/>
    <category term="虚拟局域网" scheme="https://blog.ztmss.com/tags/%E8%99%9A%E6%8B%9F%E5%B1%80%E5%9F%9F%E7%BD%91/"/>
    <category term="VPN" scheme="https://blog.ztmss.com/tags/VPN/"/>
    <content>
      <![CDATA[<h1 id="异地组网全攻略：ZeroTier-Tailscale-Cloudflare-三大方案"><a href="#异地组网全攻略：ZeroTier-Tailscale-Cloudflare-三大方案" class="headerlink" title="异地组网全攻略：ZeroTier &#x2F; Tailscale &#x2F; Cloudflare 三大方案"></a>异地组网全攻略：ZeroTier &#x2F; Tailscale &#x2F; Cloudflare 三大方案</h1><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>你有没有遇到过这些问题？</p><ul><li>人在公司或出差，想访问<strong>家里 NAS</strong> 里的文件、看监控，却要先折腾路由器端口映射；</li><li>想远程连接<strong>家里的电脑</strong>、内网里的打印机、摄像头，被公网 IP 和 NAT 卡住；</li><li>买了 <strong>VPS &#x2F; 云服务器</strong>，想和家里的设备组成一个”局域网”，互相随意访问。</li></ul><p><strong>异地组网</strong>（也叫虚拟局域网、Mesh 组网 &#x2F; VPN overlay）就是解决这些问题的钥匙：它把分散在不同地区、不同运营商网络里的设备，通过加密隧道”拉”进同一个虚拟局域网。之后你用家里的 IP（如 <code>192.168.2.8</code>）就能直接访问，不用再记一串公网 IP，也不用开放端口。</p><p>目前最主流的是三大方案：</p><table><thead><tr><th align="left">方案</th><th align="left">技术</th><th align="left">适合人群</th></tr></thead><tbody><tr><td align="left"><strong>ZeroTier</strong></td><td align="left">自研 VL2 二层虚拟以太网</td><td align="left">想自建网络、设备跨平台、免费额度大</td></tr><tr><td align="left"><strong>Tailscale</strong></td><td align="left">基于 WireGuard 的现代组网</td><td align="left">个人&#x2F;小团队、追求简单零配置、免费设备不限</td></tr><tr><td align="left"><strong>Cloudflare</strong></td><td align="left">企业级零信任 + Tunnel 内网穿透</td><td align="left">已有 Cloudflare 账号、想把内网服务发布到公网</td></tr></tbody></table><p>下面分别介绍原理、免费额度、以及最详细的实操步骤。</p><hr><h2 id="方案一：ZeroTier（全球可达的虚拟以太网）"><a href="#方案一：ZeroTier（全球可达的虚拟以太网）" class="headerlink" title="方案一：ZeroTier（全球可达的虚拟以太网）"></a>方案一：ZeroTier（全球可达的虚拟以太网）</h2><h3 id="简介与原理"><a href="#简介与原理" class="headerlink" title="简介与原理"></a>简介与原理</h3><p>ZeroTier 通过自研协议在公网上构建一个 <strong>Layer-2 虚拟以太网</strong>（overlay network），所有节点宛如连接在同一台交换机上。它核心的 P2P 架构没有”集中式瓶颈”——控制面用平台的协调服务器（my.zerotier.com）管理网络，数据面设备之间尽量直连（打洞穿透 NAT），打洞失败时自动走中继。</p><ul><li>每个网络有一个 <strong>16 位十六进制 Network ID</strong>（如 <code>8056c2e21c000001</code>）</li><li>每个设备加入后会获得一个 <strong>V4&#x2F;V6 虚拟地址</strong>，网络内可自由互ping、互访端口</li><li>支持 Windows &#x2F; macOS &#x2F; Linux &#x2F; Android &#x2F; iOS &#x2F; Docker &#x2F; FreeBSD &#x2F; OpenWRT 等几乎所有平台</li><li>官网：<a href="https://www.zerotier.com/">https://www.zerotier.com</a></li></ul><h3 id="免费额度"><a href="#免费额度" class="headerlink" title="免费额度"></a>免费额度</h3><ul><li>个人免费版：<strong>无限网络</strong>、每个网络最多 <strong>25 台设备</strong>，适合大多数个人家庭场景</li><li>更高需求走付费计划（$179&#x2F;月起的商业版等）</li></ul><h3 id="完整操作教程"><a href="#完整操作教程" class="headerlink" title="完整操作教程"></a>完整操作教程</h3><p><strong>第一步：注册并在网页创建网络</strong></p><ol><li>打开 <a href="https://my.zerotier.com/">my.zerotier.com</a>，用邮箱&#x2F;Google&#x2F;GitHub 登录</li><li>点击 <strong>Create A Network</strong>（创建一个网络）</li><li>创建成功后，页面会显示一个 <strong>16 位 Network ID</strong>，复制保存备用</li><li>记下这个网络默认的 IP 段（如 <code>10.244.x.x</code>），这就是你虚拟局域网段的起点</li></ol><p><strong>第二步：在各类设备上安装客户端并加入网络</strong></p><p><strong>Linux（Debian&#x2F;Ubuntu&#x2F;CentOS 等）</strong>，一行脚本安装：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 加载 ZeroTier 官方源并安装（纯静态编译，装完即用）</span></span><br><span class="line">curl -s https://install.zerotier.com | <span class="built_in">sudo</span> bash</span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动服务并设置开机自启</span></span><br><span class="line"><span class="built_in">sudo</span> systemctl <span class="built_in">enable</span> zerotier-one</span><br><span class="line"><span class="built_in">sudo</span> systemctl start zerotier-one</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看节点状态（拿到 10 位 Node ID 地址）</span></span><br><span class="line"><span class="built_in">sudo</span> zerotier-cli status</span><br><span class="line"></span><br><span class="line"><span class="comment"># 加入你的网络（换成你的 16 位 Network ID）</span></span><br><span class="line"><span class="built_in">sudo</span> zerotier-cli <span class="built_in">join</span> 8056c2e21c000001</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看已加入的网络和分配的虚拟 IP</span></span><br><span class="line"><span class="built_in">sudo</span> zerotier-cli listnetworks</span><br></pre></td></tr></table></figure><p><strong>Windows &#x2F; macOS</strong>：到 <a href="https://www.zerotier.com/download/">下载页面</a> 下载安装包，装好后在系统托盘找到 ZeroTier 图标 → <strong>Join Network</strong> → 粘贴 16 位 Network ID 即可。</p><p><strong>手机（Android&#x2F;iOS）</strong>：应用商店安装 ZeroTier One，打开后点右上角 <strong>+</strong>，输入 Network ID 加入。加入后记得把系统的 <strong>VPN 开关</strong>打开，让隧道真正生效。</p><p><strong>第三步：在后台授权（关键步骤，容易漏）</strong></p><ol><li>回到 <a href="https://my.zerotier.com/">my.zerotier.com</a> 你的网络</li><li>在 <strong>Members（成员）</strong> 列表里，找到刚加入的设备</li><li>点击该成员行的 <strong>Auth</strong> 复选框（勾选变绿，即”通过认证”）</li><li>系统会自动给该设备分配一个虚拟 IP（如 <code>10.244.x.x</code>）</li></ol><blockquote><p>⚠️ 新设备加入网络默认是<strong>未授权</strong>状态，没有授权之前无法与网络内其他节点通信。<strong>必须手动勾选 Auth</strong>。这是 ZeroTier 新手最容易踩的坑。</p></blockquote><p><strong>第四步：验证连通</strong></p><p>在某台设备上 ping 另一台的虚拟 IP，或直接 <code>ssh zt用户@10.244.x.x</code> 远程登录：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ping 10.244.2.10        <span class="comment"># 通说明组网成功</span></span><br></pre></td></tr></table></figure><p>到这里，家里的 NAS、电脑、服务器的互相访问就打通了。</p><h3 id="实用技巧"><a href="#实用技巧" class="headerlink" title="实用技巧"></a>实用技巧</h3><ul><li><strong>跨网段访问</strong>：如果想在虚拟网里直接访问真实局域网（如用 <code>192.168.2.x</code> 访问家里所有设备），需要在某台 Linux 设备上开启 <strong>IPTables 转发 + NAT</strong> 并设置为路由设备，较复杂，家庭一般用虚拟 IP 直接访问即可。</li><li><strong>网络隔离</strong>：可以给不同成员设置流控规则（Traffic Rules），实现只允许特定节点互通，保护内网安全。</li></ul><hr><h2 id="方案二：Tailscale（基于-WireGuard，简单到极致）"><a href="#方案二：Tailscale（基于-WireGuard，简单到极致）" class="headerlink" title="方案二：Tailscale（基于 WireGuard，简单到极致）"></a>方案二：Tailscale（基于 WireGuard，简单到极致）</h2><h3 id="简介与原理-1"><a href="#简介与原理-1" class="headerlink" title="简介与原理"></a>简介与原理</h3><p>Tailscale 基于开源的 <strong>WireGuard®</strong> 协议构建，但把最难的配置都自动化了：你在网页&#x2F;后台做一次授权，客户端就用 <strong>密钥管理 + NAT 打洞（TURN&#x2F;STUN）+ DERP 中继</strong> 自动建立 P2P 加密连接。设备之间的连接几乎总是直连，速度快、时延低。</p><ul><li>设备就是你的”设备”（电脑、手机、服务器、NAS）</li><li>默认启用 <strong>MagicDNS</strong>：加入的设备自动获得 <code>主机名.你的tailnet.ts.net</code> 这样的域名，不用记 IP</li><li>支持 Windows &#x2F; macOS &#x2F; Linux &#x2F; Android &#x2F; iOS &#x2F; 路由器（openwrt、Synology、OPNsense 等）</li><li>官网：<a href="https://tailscale.com/">https://tailscale.com</a></li></ul><h3 id="免费额度-1"><a href="#免费额度-1" class="headerlink" title="免费额度"></a>免费额度</h3><p>Personal（个人免费版，<strong>非商业用途</strong>，永久免费）：</p><ul><li><strong>设备数量无限</strong></li><li>最多 <strong>3 个网络&#x2F;账号（tailnet）</strong>，每个最多 <strong>6 个用户</strong></li><li>标记资源（服务器、子网路由等）50 个</li><li>用 Google &#x2F; GitHub &#x2F; 个人自定义域名注册即可，免费开箱即用</li></ul><h3 id="完整操作教程-1"><a href="#完整操作教程-1" class="headerlink" title="完整操作教程"></a>完整操作教程</h3><p><strong>第一步：注册并创建账号</strong></p><p>打开 <a href="https://tailscale.com/login">tailscale.com&#x2F;login</a>，用你的 Google &#x2F; GitHub &#x2F; Microsoft 等账号登录。首次登录会自动创建一个 <strong>tailnet</strong>（相当于你的私有组网空间），并分配一个子域名（如 <code>my-xxx.ts.net</code>）。</p><p><strong>第二步：在设备上安装并登录</strong></p><p><strong>Linux</strong>：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装</span></span><br><span class="line">curl -fsSL https://tailscale.com/install.sh | sh</span><br><span class="line"></span><br><span class="line"><span class="comment"># 登录（会打印一个 auth URL）</span></span><br><span class="line"><span class="built_in">sudo</span> tailscale up</span><br></pre></td></tr></table></figure><p>执行 <code>tailscale up</code> 后终端会显示一个链接，<strong>用手机或电脑浏览器打开</strong>，登录你的账号并确认授权，回终端就会提示登录成功。</p><p><strong>Windows &#x2F; macOS</strong>：到 <a href="https://tailscale.com/download">tailscale.com&#x2F;download</a> 下载安装，运行 App 后用账号登录即可。</p><p><strong>手机</strong>：应用商店安装 Tailscale，登录同一账号，开启 VPN 开关。</p><p><strong>第三步：查看设备与分配 IP</strong></p><p>再次执行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tailscale status</span><br></pre></td></tr></table></figure><p>会看到类似输出，其中就包含每台设备的 <strong>100.x.y.z IP</strong> 和 <strong>MagicDNS 名称</strong>：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># Health check:</span><br><span class="line">#     - Nickname may default to a .ts.net name from the machine hostname</span><br><span class="line">100.101.102.1   nas                user@ your-nas.ts.net  linux   -</span><br><span class="line">100.101.102.2   laptop             user@ your-laptop.ts.net linux  -</span><br><span class="line">100.101.102.3   phone              user@ your-phone.ts.net  ios    -</span><br></pre></td></tr></table></figure><p>网上随便找一台设备 ping <code>你的主机名.ts.net</code> 域名或 <code>100.x</code> IP，通了就成功。</p><h3 id="实用技巧-1"><a href="#实用技巧-1" class="headerlink" title="实用技巧"></a>实用技巧</h3><p><strong>① 子网路由（把整个家庭内网暴露给 Tailscale 网）</strong></p><p>在 NAS &#x2F; 路由器等 Linux 设备上，把家里局域网（如 <code>192.168.2.0/24</code>）”广播”给整个组网，这样你在外面直接用 <code>192.168.2.8</code> 访问家里所有设备：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> tailscale up --advertise-routes=192.168.2.0/24</span><br></pre></td></tr></table></figure><p>然后在后台 <a href="https://login.tailscale.com/admin">login.tailscale.com&#x2F;admin</a> → <strong>Machines</strong> → 找到这台设备 → <strong>Edit route settings</strong> → 勾选对应网段 → <strong>Save</strong>，宣告生效。</p><p><strong>② 出口节点（Exit Node，全流量走它翻&#x2F;统一出口）</strong></p><p>把某台设备设为出口节点，手机上所有流量都经过它出去：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> tailscale up --advertise-exit-node</span><br></pre></td></tr></table></figure><p>然后在手机 Tailscale App 里开启 <strong>Use exit node</strong> 选择该设备即可。</p><p><strong>③ Tailscale SSH</strong>：<code>tailscale ssh 主机名</code> 免密登录，由 Tailscale 统一管理身份。</p><hr><h2 id="方案三：Cloudflare（企业级零信任-Tunnel-内网穿透）"><a href="#方案三：Cloudflare（企业级零信任-Tunnel-内网穿透）" class="headerlink" title="方案三：Cloudflare（企业级零信任 + Tunnel 内网穿透）"></a>方案三：Cloudflare（企业级零信任 + Tunnel 内网穿透）</h2><h3 id="简介与原理-2"><a href="#简介与原理-2" class="headerlink" title="简介与原理"></a>简介与原理</h3><p>严格说，Cloudflare 和上面两个侧重点不完全一样。它提供一套 <strong>企业级零信任（Cloudflare Zero Trust）</strong> 体系，核心是 <strong>Cloudflare Tunnel（cloudflared）</strong>：</p><ul><li>在你的内网设备&#x2F;服务器上跑一个轻量的 <strong><code>cloudflared</code></strong> 守护进程</li><li>它主动向 Cloudflare 全球网络发起 <strong>出站（outbound-only）连接</strong>，无需公网 IP、不用在路由器开端口映射、不会被 NAT&#x2F;防火墙阻挡</li><li>Cloudflare 边缘节点再把请求”隧道”转发到你的内网服务</li><li>配合 <strong>Access 策略</strong>，实现”每个请求都需要身份验证”的零信任访问</li><li>官网：<a href="https://developers.cloudflare.com/cloudflare-one/">https://developers.cloudflare.com/cloudflare-one/</a></li></ul><p>一句话对比：<strong>ZeroTier &#x2F; Tailscale 偏重于”设备之间互联”（像 VPN），Cloudflare 更偏重于”把内网服务安全地发布给特定的人访问”（像内网穿透 + 访问控制）</strong>。</p><h3 id="免费额度-2"><a href="#免费额度-2" class="headerlink" title="免费额度"></a>免费额度</h3><ul><li>Cloudflare Zero Trust 免费版：<strong>最多 50 个用户</strong></li><li>可创建多个 Tunnel，流量走 Cloudflare 免费 CDN</li><li>需要先有一个 Cloudflare 账号（可免费注册）并绑定一个域名做接入</li></ul><h3 id="完整操作教程（用-Tunnel-把内网服务发布出去）"><a href="#完整操作教程（用-Tunnel-把内网服务发布出去）" class="headerlink" title="完整操作教程（用 Tunnel 把内网服务发布出去）"></a>完整操作教程（用 Tunnel 把内网服务发布出去）</h3><p><strong>第一步：注册 Cloudflare 并准备</strong></p><ol><li>打开 <a href="https://dash.cloudflare.com/">dash.cloudflare.com</a>，注册账号</li><li>把一个域名接入 Cloudflare（在 Cloudflare 添加站点、改 NS 到 Cloudflare）</li><li>登录后左侧选你的站点，进入 <strong>Zero Trust</strong>（会引导你创建一个”团队域名”，如 <code>myteam.cloudflareaccess.com</code>，记住了以后访问用它）</li></ol><p>实际上 Zero Trust 也可以不绑定域名直接开始试用，但要用 <strong>自定义域名</strong> 访问就必须先接入该域名。</p><p><strong>第二步：安装 cloudflared 并创建隧道</strong></p><p>在需要发布服务的内网 Linux 机器上：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Linux 安装 cloudflared</span></span><br><span class="line"><span class="comment"># Debian/Ubuntu:</span></span><br><span class="line">curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb</span><br><span class="line"><span class="built_in">sudo</span> dpkg -i cloudflared.deb</span><br><span class="line"></span><br><span class="line"><span class="comment"># 登录（会打开一个 Cloudflare 网页确认）</span></span><br><span class="line">cloudflared tunnel login</span><br></pre></td></tr></table></figure><p>登录成功后，自动把凭据写入到 <code>~/.cloudflared/cert.pem</code>。</p><p><strong>第三步：创建隧道并配置</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 创建一条隧道，比如名字叫 home-elk</span></span><br><span class="line">cloudflared tunnel create home-elk</span><br><span class="line"><span class="comment"># 会输出一条 Tunnel ID（类似 uuid）</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 为隧道写配置文件 ~/.cloudflared/config.yml</span></span><br></pre></td></tr></table></figure><p>编辑 <code>~/.cloudflared/config.yml</code>：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">tunnel:</span> <span class="string">&lt;你的Tunnel-ID&gt;</span></span><br><span class="line"><span class="attr">credentials-file:</span> <span class="string">/root/.cloudflared/&lt;你的Tunnel-ID&gt;.json</span></span><br><span class="line"></span><br><span class="line"><span class="attr">ingress:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">hostname:</span> <span class="string">nas.你的域名.com</span>      <span class="comment"># 你想通过哪个域名访问</span></span><br><span class="line">    <span class="attr">service:</span> <span class="string">http://localhost:3000</span>  <span class="comment"># 转发到本机 3000 端口的服务</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">hostname:</span> <span class="string">router.你的域名.com</span></span><br><span class="line">    <span class="attr">service:</span> <span class="string">http://192.168.2.1</span>   <span class="comment"># 也可以转发到内网其他设备</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">service:</span> <span class="string">http_status:404</span>      <span class="comment"># 兜底规则，必须存在</span></span><br></pre></td></tr></table></figure><p><strong>第四步：运行隧道并绑定 DNS</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 后台运行（生产建议用 systemd 托管开机自启）</span></span><br><span class="line">cloudflared tunnel run home-elk</span><br></pre></td></tr></table></figure><p>然后在 Cloudflare 后台给每个 <code>hostname</code> 加上一条 <strong>CNAME 记录</strong>：指向 <code>&lt;Tunnel-ID&gt;.cfargotunnel.com</code>（也可以用 <code>cloudflared tunnel route dns home-elk nas.你的域名.com</code> 一条命令自动添加）。</p><p><strong>第五步：配置 Access 权限（零信任核心）</strong></p><ol><li>进入 <strong>Zero Trust → Access → Applications</strong>，添加一个 <strong>Self-hosted</strong> 应用</li><li>域名填 <code>nas.你的域名.com</code></li><li>在 <strong>Policies</strong> 里设置哪些身份可以访问（Gmail 邮箱、One-time PIN 邮箱、或 Allowlist 组织成员）</li><li>保存后，任何人访问 <code>nas.你的域名.com</code> 都要先过 Cloudflare 的登录验证，验证通过才把请求隧道到你的内网服务</li></ol><p>至此，你在公网任何地方，用浏览器登录 Cloudflare Access 后，就能安全访问家里 NAS 的 Web 界面了。</p><hr><h2 id="三方案对比速览"><a href="#三方案对比速览" class="headerlink" title="三方案对比速览"></a>三方案对比速览</h2><table><thead><tr><th align="left">维度</th><th align="left">ZeroTier</th><th align="left">Tailscale</th><th align="left">Cloudflare Tunnel</th></tr></thead><tbody><tr><td align="left">定位</td><td align="left">虚拟以太网 &#x2F; Mesh VPN</td><td align="left">现代 Mesh VPN（WireGuard）</td><td align="left">内网穿透 + 零信任访问控制</td></tr><tr><td align="left">免费额度</td><td align="left">每网 25 设备</td><td align="left">设备无限、6 用户</td><td align="left">最多 50 用户</td></tr><tr><td align="left">数据层协议</td><td align="left">自研 ZeroTier 协议</td><td align="left">WireGuard</td><td align="left">cloudflared 加密隧道</td></tr><tr><td align="left">是否要公网 IP</td><td align="left">否（打洞&#x2F;中继）</td><td align="left">否（打洞&#x2F;DERP）</td><td align="left">否（纯出站连接）</td></tr><tr><td align="left">是否需要绑定域名</td><td align="left">不需要</td><td align="left">不需要（有 ts.net 域名）</td><td align="left">需要（绑定后走自定义域名）</td></tr><tr><td align="left">最擅长的场景</td><td align="left">设备间互联互通</td><td align="left">设备互联 + 子网路由 + 出口</td><td align="left">把内网 Web 服务安全发布</td></tr><tr><td align="left">上手难度</td><td align="left">中（需后台授权）</td><td align="left">低（最简单）</td><td align="left">中高（多一步 DNS&#x2F;域名）</td></tr><tr><td align="left">平台覆盖</td><td align="left">极广（含 OpenWRT&#x2F;Docker）</td><td align="left">广</td><td align="left">客户端为 cloudflared + WARP</td></tr></tbody></table><p><strong>怎么选？</strong></p><ul><li>就想<strong>把自己的多台设备连在一起互相访问</strong>：首选 <strong>Tailscale</strong>，免费、几乎零配置、体验最好。</li><li>想<strong>自建网络、深度控制、设备类型特别多（含路由器&#x2F;NAS 老设备）</strong>：用 <strong>ZeroTier</strong>。</li><li>想把 <strong>NAS &#x2F; 建站服务 &#x2F; 内网 Web 应用暴露给信任的人访问</strong>，又要安全和管控：用 <strong>Cloudflare Tunnel + Access</strong>。</li></ul><p>三者也<strong>可以混用</strong>：比如家里用 Tailscale 打通设备，再把其中的某台当作 Cloudflare 隧道入口发布给外部人员。</p><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><p><strong>Q：组网后速度慢是为什么？</strong><br>A：多为 NAT 打洞失败走了中继（DERP &#x2F; ZeroTier 中继）。开启 UDP 端口、减少设备前面的对称 NAT，通常能切回 P2P 直连，速度大幅提升。</p><p><strong>Q：免费方案数据安全吗？</strong><br>A：隧道都用现代加密（Tailscale 是 WireGuard，ZeroTier 是 VL2+加密），数据在传输中被加密。但要留意免费层通常是”控制面在厂商”——私网流量本身不经过厂商，只是打洞&#x2F;中继的协调。</p><p><strong>Q：在没网的环境（纯内网、无外网）能用吗？</strong><br>A：不能直接用于完全离线环境；Tailscale&#x2F;ZeroTier 首次握手依赖协调服务器，离线环境可用本地部署方案（Tailscale 有 self-hosted coordination 选项，Cloudflare 属云端）。普通有外网的家庭&#x2F;办公场景无此问题。</p><p><strong>Q：云服务器（VPS）也能加入组网吗？</strong><br>A：完全可以。VPS 装客户端加入后，就成为虚拟局域网的一员，家里可以直接访问 VPS，反之 VPS 也能访问家里设备，方便做反向方向的服务。</p><p><strong>Q：异地组网能代替公网 IP 吗？</strong><br>A：对”设备间访问”（SSH、文件共享、远程桌面、访问 NAS Web）可以很好代替；对有严格公网入向要求的场景（比如给第三方发内网地址）则相对复杂，建议用 Cloudflare Tunnel 或纯公网。</p><hr><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://www.zerotier.com/">ZeroTier 官网</a></li><li><a href="https://www.zerotier.com/download/">ZeroTier 下载（安装命令）</a></li><li><a href="https://tailscale.com/">Tailscale 定价（免费额度）</a></li><li><a href="https://tailscale.com/kb/1017/install">Tailscale Linux 安装</a></li><li><a href="https://tailscale.com/kb/1019/subnets">Tailscale 子网路由文档</a></li><li><a href="https://developers.cloudflare.com/cloudflare-one/">Cloudflare Zero Trust 文档</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/13/remote-networking-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/08/13/remote-networking-tutorial/"/>
    <published>2026-08-13T02:00:00.000Z</published>
    <summary>异地组网指的是把分散在不同地区、不同网络（家里、公司、服务器、出差设备）的终端安全地连接成一个虚拟局域网。本文对比 ZeroTier、Tailscale、Cloudflare 三大主流方案，并提供从零开始的详细操作教程，帮助你零成本打通家中设备、远程访问 NAS 和内部服务。</summary>
    <title>异地组网全攻略：ZeroTier / Tailscale / Cloudflare 三大方案对比与实操教程</title>
    <updated>2026-08-17T07:58:22.428Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="Cloudflare Pages" scheme="https://blog.ztmss.com/tags/Cloudflare-Pages/"/>
    <category term="domain-showcase" scheme="https://blog.ztmss.com/tags/domain-showcase/"/>
    <category term="KV" scheme="https://blog.ztmss.com/tags/KV/"/>
    <category term="Docker" scheme="https://blog.ztmss.com/tags/Docker/"/>
    <category term="域名展示" scheme="https://blog.ztmss.com/tags/%E5%9F%9F%E5%90%8D%E5%B1%95%E7%A4%BA/"/>
    <category term="部署教程" scheme="https://blog.ztmss.com/tags/%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/"/>
    <content>
      <![CDATA[<h1 id="domain-showcase-部署教程：赛博朋克域名展示站"><a href="#domain-showcase-部署教程：赛博朋克域名展示站" class="headerlink" title="domain-showcase 部署教程：赛博朋克域名展示站"></a>domain-showcase 部署教程：赛博朋克域名展示站</h1><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>domain-showcase 是一个<strong>赛博朋克风格的个人域名展示主页</strong>，自带可视化后台管理系统，支持在线编辑站点内容。它同时提供了 <strong>Cloudflare Pages 和 Docker</strong> 两套部署方案，前者完全免费（Pages 配额 + KV 免费额度），后者适合已有 VPS 的用户。</p><ul><li><strong>项目地址</strong>：<a href="https://github.com/love-ztm/domain-showcase">https://github.com/love-ztm/domain-showcase</a></li><li><strong>开源协议</strong>：ISC</li><li><strong>演示域名</strong>：<code>oooooooooooo.cc.cd</code>（CC 免费域名，来自 DNSHE）</li></ul><hr><h2 id="功能特点"><a href="#功能特点" class="headerlink" title="功能特点"></a>功能特点</h2><table><thead><tr><th align="left">功能</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">🌃 <strong>赛博朋克首屏</strong></td><td align="left">粒子动画背景 + 荧光配色（<code>#00f0ff</code> 青 &#x2F; <code>#7b2fff</code> 紫），终端打字效果</td></tr><tr><td align="left">⚙️ <strong>后台可视化编辑</strong></td><td align="left"><code>/admin.html</code> 分板块编辑：首屏、关于、技能、项目、链接、页脚、主题</td></tr><tr><td align="left">📝 <strong>JSON 直编</strong></td><td align="left">后台提供原始 JSON 编辑，全部数据一键导出&#x2F;导入</td></tr><tr><td align="left">📊 <strong>技能进度条</strong></td><td align="left">每一项技能可配置名称、熟练度百分比、emoji 图标</td></tr><tr><td align="left">🗂️ <strong>项目展示</strong></td><td align="left">项目标题、描述、技术标签、链接卡片</td></tr><tr><td align="left">🔗 <strong>社交链接</strong></td><td align="left">GitHub &#x2F; Twitter &#x2F; LinkedIn &#x2F; 邮箱 等链接配置</td></tr><tr><td align="left">🕐 <strong>页脚实时时钟</strong></td><td align="left">可开关的实时时间显示</td></tr><tr><td align="left">🎨 <strong>主题自定义</strong></td><td align="left">主色调、强调色、背景风格（dark&#x2F;light）即时切换</td></tr><tr><td align="left">☁️ <strong>双轨部署</strong></td><td align="left">Cloudflare Pages（Functions + KV）或 Docker（Express + JSON 文件存储）</td></tr><tr><td align="left">🌐 <strong>CORS 支持</strong></td><td align="left">API 允许跨域访问，数据层与展示层解耦</td></tr></tbody></table><hr><h2 id="技术栈"><a href="#技术栈" class="headerlink" title="技术栈"></a>技术栈</h2><table><thead><tr><th align="left">类别</th><th align="left">Cloudflare Pages 方案</th><th align="left">Docker 方案</th></tr></thead><tbody><tr><td align="left">运行平台</td><td align="left">Cloudflare Pages + Functions</td><td align="left">Node.js + Express</td></tr><tr><td align="left">数据存储</td><td align="left">Cloudflare KV（key: <code>content</code>）</td><td align="left"><code>data/content.json</code> 文件</td></tr><tr><td align="left">前端</td><td align="left">原生 HTML&#x2F;CSS&#x2F;JS（无构建步骤）</td><td align="left">同左</td></tr><tr><td align="left">本地开发</td><td align="left"><code>wrangler pages dev</code></td><td align="left"><code>npm run dev</code></td></tr></tbody></table><hr><h2 id="项目结构"><a href="#项目结构" class="headerlink" title="项目结构"></a>项目结构</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">domain-showcase/</span><br><span class="line">├── public/                 # 前端静态资源（部署目录）</span><br><span class="line">│   ├── index.html          # 主页</span><br><span class="line">│   ├── admin.html          # 管理后台</span><br><span class="line">│   ├── css/                # 样式</span><br><span class="line">│   └── js/                 # 脚本</span><br><span class="line">├── functions/api/          # Cloudflare Pages Functions</span><br><span class="line">│   └── content.js          # API: GET / PUT / PATCH /api/content</span><br><span class="line">├── data/content.json       # 本地开发 / Docker 数据存储</span><br><span class="line">├── server.js               # Express 服务器（Docker 用）</span><br><span class="line">├── wrangler.toml           # Cloudflare 配置（含 KV 绑定）</span><br><span class="line">├── Dockerfile              # Docker 构建文件</span><br><span class="line">└── package.json</span><br></pre></td></tr></table></figure><p>核心思路：<strong>前端和 API 共用一套</strong>。Cloudflare Pages 方案由 <code>functions/api/content.js</code> 读写 KV，Docker 方案由 <code>server.js</code> 读写 <code>content.json</code>，两端 API 接口完全一致（<code>GET/PUT/PATCH /api/content</code>），所以前端零改动即可切换部署方式。</p><hr><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><ol><li><strong>GitHub 账号</strong> — 用于托管项目代码，并接入 Cloudflare Pages</li><li><strong>Cloudflare 账号</strong> — <a href="https://dash.cloudflare.com/">Dash Cloudflare</a>，绑定或托管一个域名</li><li><strong>Node.js 环境</strong>（可选）— 仅在创建 KV、本地调试时需要</li></ol><hr><h2 id="部署方式一：GitHub-Cloudflare-Pages（免费）"><a href="#部署方式一：GitHub-Cloudflare-Pages（免费）" class="headerlink" title="部署方式一：GitHub + Cloudflare Pages（免费）"></a>部署方式一：GitHub + Cloudflare Pages（免费）</h2><p>整体流程：推代码到 GitHub → 创建 KV 命名空间 → Cloudflare Pages 连接仓库 → 绑定 KV → 部署完成。</p><h3 id="1-推送项目到-GitHub"><a href="#1-推送项目到-GitHub" class="headerlink" title="1. 推送项目到 GitHub"></a>1. 推送项目到 GitHub</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> domain-showcase</span><br><span class="line">git init</span><br><span class="line">git add .</span><br><span class="line">git commit -m <span class="string">&quot;init: domain showcase&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 在 GitHub 创建同名仓库后：</span></span><br><span class="line">git remote add origin https://github.com/你的用户名/domain-showcase.git</span><br><span class="line">git branch -M main</span><br><span class="line">git push -u origin main</span><br></pre></td></tr></table></figure><h3 id="2-创建-KV-命名空间"><a href="#2-创建-KV-命名空间" class="headerlink" title="2. 创建 KV 命名空间"></a>2. 创建 KV 命名空间</h3><p>安装 wrangler CLI 并登录 Cloudflare：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">npm install -g wrangler</span><br><span class="line">wrangler login</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建 KV 命名空间</span></span><br><span class="line">npx wrangler kv namespace create SITE_CONTENT</span><br></pre></td></tr></table></figure><p>执行后会输出：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;binding = <span class="string">&quot;SITE_CONTENT&quot;</span>, <span class="built_in">id</span> = <span class="string">&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;</span>&#125;</span><br></pre></td></tr></table></figure><p>记下这串 <strong>KV ID</strong>。</p><h3 id="3-确认-wrangler-toml-中的-KV-ID"><a href="#3-确认-wrangler-toml-中的-KV-ID" class="headerlink" title="3. 确认 wrangler.toml 中的 KV ID"></a>3. 确认 wrangler.toml 中的 KV ID</h3><p>打开 <code>wrangler.toml</code>，确认 <code>kv_namespaces</code> 绑定的是你刚创建的 ID：</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name</span> = <span class="string">&quot;domain-showcase&quot;</span></span><br><span class="line"><span class="attr">compatibility_date</span> = <span class="string">&quot;2024-09-23&quot;</span></span><br><span class="line"><span class="attr">pages_build_output_dir</span> = <span class="string">&quot;public&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[kv_namespaces]]</span></span><br><span class="line"><span class="attr">binding</span> = <span class="string">&quot;SITE_CONTENT&quot;</span></span><br><span class="line"><span class="attr">id</span> = <span class="string">&quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;</span></span><br></pre></td></tr></table></figure><blockquote><p>💡 仓库里默认带了一个 KV ID，直接部署也能跑；但建议换成自己的命名空间，数据隔离更清晰、管理更方便。</p></blockquote><h3 id="4-连接-Cloudflare-Pages"><a href="#4-连接-Cloudflare-Pages" class="headerlink" title="4. 连接 Cloudflare Pages"></a>4. 连接 Cloudflare Pages</h3><ol><li>登录 <a href="https://dash.cloudflare.com/">Cloudflare Dashboard</a></li><li>进入 <strong>Workers 和 Pages</strong> → <strong>Create application</strong> → <strong>Pages</strong> → <strong>Connect to Git</strong></li><li>授权并选择你的 GitHub 仓库</li><li>配置构建设置：<ul><li><strong>Production branch</strong>：<code>main</code></li><li><strong>Build command</strong>：留空（纯静态站，无需构建）</li><li><strong>Build output directory</strong>：<code>public</code></li></ul></li><li>点击 <strong>Save and Deploy</strong></li></ol><h3 id="5-绑定-KV-到-Pages-项目"><a href="#5-绑定-KV-到-Pages-项目" class="headerlink" title="5. 绑定 KV 到 Pages 项目"></a>5. 绑定 KV 到 Pages 项目</h3><ol><li>进入刚才创建的 Pages 项目 → <strong>Settings</strong> → <strong>Functions</strong> → <strong>KV namespace bindings</strong></li><li>添加绑定：<ul><li><strong>Variable name</strong>：<code>SITE_CONTENT</code>（必须和代码里的绑定名一致）</li><li><strong>KV namespace</strong>：选择第 2 步创建的 <code>SITE_CONTENT</code></li></ul></li><li>保存后项目会自动重新部署（或手动再部署一次）</li></ol><p>查看部署：<strong>Deployments</strong> 里确认最新部署状态为 <strong>Success</strong>，域名下的 <strong>Functions</strong> 部分能看到 <code>functions/api/content</code>。</p><h3 id="6-绑定自定义域名"><a href="#6-绑定自定义域名" class="headerlink" title="6. 绑定自定义域名"></a>6. 绑定自定义域名</h3><ol><li>进入项目 <strong>Settings</strong> → <strong>Custom domains</strong> → <strong>Set up a custom domain</strong></li><li>输入你的域名（例如 <code>oooooooooooo.cc.cd</code>）</li><li>如果域名在 Cloudflare DNS 托管，会<strong>自动添加 DNS 记录</strong>；否则按提示手动添加 CNAME 指向 <code>xxx.pages.dev</code></li></ol><h3 id="7-验证部署"><a href="#7-验证部署" class="headerlink" title="7. 验证部署"></a>7. 验证部署</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># API 是否正常读出内容</span></span><br><span class="line">curl https://你的域名/api/content</span><br><span class="line"></span><br><span class="line"><span class="comment"># 页面是否正常</span></span><br><span class="line">curl -I https://你的域名/</span><br></pre></td></tr></table></figure><p>返回 <code>{ &quot;ok&quot;: true, &quot;data&quot;: {...} }</code> 即表示 KV 绑定成功。</p><hr><h2 id="部署方式二：Docker（VPS-部署）"><a href="#部署方式二：Docker（VPS-部署）" class="headerlink" title="部署方式二：Docker（VPS 部署）"></a>部署方式二：Docker（VPS 部署）</h2><p>适合已经有 VPS（如国内&#x2F;海外小鸡）的用户，数据直接存在服务器的 <code>content.json</code> 文件里。</p><h3 id="1-上传项目到服务器"><a href="#1-上传项目到服务器" class="headerlink" title="1. 上传项目到服务器"></a>1. 上传项目到服务器</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 方式 A：通过 Git 拉取</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/你的用户名/domain-showcase.git</span><br><span class="line"></span><br><span class="line"><span class="comment"># 方式 B：scp 上传</span></span><br><span class="line">scp -r domain-showcase/ root@你的服务器IP:/opt/</span><br></pre></td></tr></table></figure><h3 id="2-构建并运行"><a href="#2-构建并运行" class="headerlink" title="2. 构建并运行"></a>2. 构建并运行</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> /opt/domain-showcase</span><br><span class="line"></span><br><span class="line"><span class="comment"># 构建镜像</span></span><br><span class="line">docker build -t domain-showcase .</span><br><span class="line"></span><br><span class="line"><span class="comment"># 运行容器（挂载 data 目录，避免重建容器丢数据）</span></span><br><span class="line">docker run -d \</span><br><span class="line">  --name domain-showcase \</span><br><span class="line">  --restart always \</span><br><span class="line">  -p 3000:3000 \</span><br><span class="line">  -v /opt/domain-showcase/data:/app/data \</span><br><span class="line">  domain-showcase</span><br></pre></td></tr></table></figure><blockquote><p>⚠️ 记得挂载 <code>-v ...:/app/data</code> 数据卷！后台编辑的内容写入 <code>data/content.json</code>，不挂载的话容器重建后修改会丢失。</p></blockquote><h3 id="3-验证"><a href="#3-验证" class="headerlink" title="3. 验证"></a>3. 验证</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看容器状态 / 日志</span></span><br><span class="line">docker ps</span><br><span class="line">docker logs domain-showcase</span><br><span class="line"></span><br><span class="line"><span class="comment"># 测试 API（应返回 ok:true 和默认内容）</span></span><br><span class="line">curl http://localhost:3000/api/content</span><br><span class="line"></span><br><span class="line"><span class="comment"># 访问页面</span></span><br><span class="line">curl -I http://localhost:3000/</span><br></pre></td></tr></table></figure><h3 id="4-Nginx-反向代理（可选）"><a href="#4-Nginx-反向代理（可选）" class="headerlink" title="4. Nginx 反向代理（可选）"></a>4. Nginx 反向代理（可选）</h3><p>通过域名访问时，在 Nginx 里反代到 3000 端口：</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line">    <span class="attribute">server_name</span> oooooooooooo.cc.cd;</span><br><span class="line"></span><br><span class="line">    <span class="section">location</span> / &#123;</span><br><span class="line">        <span class="attribute">proxy_pass</span> http://127.0.0.1:3000;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Forwarded-Proto <span class="variable">$scheme</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="5-配置-HTTPS（可选）"><a href="#5-配置-HTTPS（可选）" class="headerlink" title="5. 配置 HTTPS（可选）"></a>5. 配置 HTTPS（可选）</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">apt install certbot python3-certbot-nginx</span><br><span class="line">certbot --nginx -d oooooooooooo.cc.cd</span><br></pre></td></tr></table></figure><hr><h2 id="API-接口说明"><a href="#API-接口说明" class="headerlink" title="API 接口说明"></a>API 接口说明</h2><table><thead><tr><th align="left">方法</th><th align="left">路径</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>GET</code></td><td align="left"><code>/api/content</code></td><td align="left">读取全部站点内容（KV&#x2F;文件无数据时返回内置默认内容兜底）</td></tr><tr><td align="left"><code>PUT</code></td><td align="left"><code>/api/content</code></td><td align="left">整份覆盖保存内容（后台「保存」时调用）</td></tr><tr><td align="left"><code>PATCH</code></td><td align="left"><code>/api/content/:section</code></td><td align="left">只更新单个板块（hero &#x2F; about &#x2F; skills &#x2F; projects &#x2F; links &#x2F; footer &#x2F; theme）</td></tr><tr><td align="left"><code>OPTIONS</code></td><td align="left"><code>/api/content</code></td><td align="left">CORS 预检，允许跨域</td></tr></tbody></table><p>Cloudflare 方案中，<code>functions/api/content.js</code> 内置了 <code>DEFAULT_CONTENT</code>：<strong>KV 里没有任何数据时，自动返回默认内容</strong>，所以首次部署页面不会空，修改前访问后台都是默认展示效果。</p><hr><h2 id="管理后台使用"><a href="#管理后台使用" class="headerlink" title="管理后台使用"></a>管理后台使用</h2><p>部署完成后访问 <code>/admin.html</code> 即进入后台，左侧按板块切换编辑：</p><table><thead><tr><th align="left">板块</th><th align="left">可编辑内容</th></tr></thead><tbody><tr><td align="left">首屏</td><td align="left">域名标题、副标题、描述、粒子动画开关</td></tr><tr><td align="left">关于</td><td align="left">个人简介、头像、统计数字（经验&#x2F;项目&#x2F;客户）</td></tr><tr><td align="left">技能</td><td align="left">技能名称、熟练度（0-100）、emoji 图标</td></tr><tr><td align="left">项目</td><td align="left">项目标题、描述、技术标签、链接</td></tr><tr><td align="left">链接</td><td align="left">GitHub &#x2F; Twitter &#x2F; LinkedIn &#x2F; Email 等</td></tr><tr><td align="left">页脚</td><td align="left">页脚文字、实时时钟开关</td></tr><tr><td align="left">主题</td><td align="left">主色调、强调色、背景风格</td></tr><tr><td align="left">JSON 编辑</td><td align="left">直接编辑完整 JSON，适合批量修改&#x2F;格式化数据</td></tr></tbody></table><p>编辑完点击 <strong>保存</strong>，会调用 <code>PUT /api/content</code> 写入 KV（或 <code>content.json</code>），页面顶端出现「已保存 ✓」提示，刷新主页即可看到效果。</p><blockquote><p>🔒 <strong>安全提醒</strong>：当前版本后台没有登录鉴权，任何能访问 <code>/admin.html</code> 的人都能改内容。公开部署建议在 Cloudflare 给 <code>/admin*</code> 路径加上 <strong>Cloudflare Access</strong> 保护，或用 Vercel&#x2F;CF 等平台的访问密码功能兜底。</p></blockquote><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><p><strong>Q：KV 绑定了但 API 还是返回默认内容？</strong><br>A：这是正常的——KV 里还没有数据时会用内置 <code>DEFAULT_CONTENT</code> 兜底。去后台改一下任意板块点保存，就会写入 KV 了。</p><p><strong>Q：后台保存后主页没变化？</strong><br>A：确认保存提示「已保存 ✓」出现；Cloudflare 方案保存的是 KV，主页通过 <code>GET /api/content</code> 读取，无缓存问题。如果没变化，检查浏览器控制台是否有 CORS &#x2F; 404 报错。</p><p><strong>Q：Pages 构建失败？</strong><br>A：这是纯静态站，<strong>Build command 必须留空</strong>，输出目录填 <code>public</code>。如果填了 <code>npm run build</code> 之类会直接失败。</p><p><strong>Q：KV 绑定名需要注意什么？</strong><br>A：绑定名必须严格是 <code>SITE_CONTENT</code>，与 <code>functions/api/content.js</code> 里的 <code>env.SITE_CONTENT</code> 一致，大小写也要一致。</p><p><strong>Q：Docker 重启容器后后台改的内容没了？</strong><br>A：没挂载数据卷。启动命令里加上 <code>-v /opt/domain-showcase/data:/app/data</code>，内容持久化在服务器的 <code>content.json</code> 中。</p><p><strong>Q：怎么把 Cloudflare 方案改成 Docker 方案？</strong><br>A：前端和 API 接口完全一致，把 <code>functions/api</code> 换成 <code>server.js</code> 跑起来即可，前端代码零改动；数据从 KV 迁到 <code>content.json</code> 即可。</p><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>domain-showcase 的核心亮点是<strong>一套前端双轨部署</strong>：</p><ul><li>☁️ <strong>Cloudflare Pages + KV</strong>：免服务器、免备案、全球 CDN，适合个人展示页，成本为零</li><li>🐳 <strong>Docker + Express</strong>：数据落在自己 VPS 的 JSON 文件里，适合已有服务器、想完全掌控数据的场景</li></ul><p>配合免费的 CC 域名（<code>.cc.cd</code> 等）和 Cloudflare 免费套餐，一个赛博朋克风格的域名展示站十分钟就能上线。部署中遇到问题欢迎在评论区交流～</p><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/12/domain-showcase-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/08/12/domain-showcase-deployment-tutorial/"/>
    <published>2026-08-12T06:00:00.000Z</published>
    <summary>domain-showcase 是一个赛博朋克风格的个人域名展示主页，带可视化后台管理系统，支持 Cloudflare Pages（Functions + KV）与 Docker（Express）双轨部署。本文从零开始讲解完整的部署流程、后台使用与常见问题。</summary>
    <title>domain-showcase部署教程：赛博朋克域名展示站，Cloudflare Pages / Docker 双轨部署</title>
    <updated>2026-08-17T07:58:22.412Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="免费域名" scheme="https://blog.ztmss.com/tags/%E5%85%8D%E8%B4%B9%E5%9F%9F%E5%90%8D/"/>
    <category term="域名解析" scheme="https://blog.ztmss.com/tags/%E5%9F%9F%E5%90%8D%E8%A7%A3%E6%9E%90/"/>
    <category term="Vercel" scheme="https://blog.ztmss.com/tags/Vercel/"/>
    <category term="DNSHE" scheme="https://blog.ztmss.com/tags/DNSHE/"/>
    <category term="根域名" scheme="https://blog.ztmss.com/tags/%E6%A0%B9%E5%9F%9F%E5%90%8D/"/>
    <category term="教程" scheme="https://blog.ztmss.com/tags/%E6%95%99%E7%A8%8B/"/>
    <content>
      <![CDATA[<h1 id="DNSHE-免费域名-Vercel-根域名绑定完整教程"><a href="#DNSHE-免费域名-Vercel-根域名绑定完整教程" class="headerlink" title="DNSHE 免费域名 + Vercel 根域名绑定完整教程"></a>DNSHE 免费域名 + Vercel 根域名绑定完整教程</h1><blockquote><p>📹 视频作者：luoriyingcangqiong（洛璃）</p><p>视频演示在文章末尾，建议先看文字步骤，再对照视频操作。</p></blockquote><h2 id="什么是-DNSHE？"><a href="#什么是-DNSHE？" class="headerlink" title="什么是 DNSHE？"></a>什么是 DNSHE？</h2><p><a href="https://www.dnshe.com/">DNSHE</a> 是一个<strong>永久免费的域名注册与 DNS 解析平台</strong>：</p><ul><li>提供 <code>.l.cd</code>、<code>.ccwu.cc</code>、<code>.ddns.ge</code>、<code>.de5.net</code>、<code>.cn.mt</code>、<code>.bbroot.com</code>、<code>.bot.cd</code>、<code>.cc.cd</code>、<code>.us.ci</code> 等免费域名后缀</li><li>无需信用卡、无隐藏费用，注册即用</li><li>支持 A、AAAA、CNAME、MX、TXT、NS、SRV、CAA 全类型 DNS 记录</li><li>内置 DNSSEC 支持，自带基础 DNS 防护</li><li>提供 REST API，可编程管理域名与解析记录</li></ul><p>配合 Vercel、Cloudflare Pages 等免费托管平台，可以零成本搭建自己的博客、API、状态页。</p><h2 id="整体流程（5-步）"><a href="#整体流程（5-步）" class="headerlink" title="整体流程（5 步）"></a>整体流程（5 步）</h2><table><thead><tr><th>步骤</th><th>平台</th><th>操作</th></tr></thead><tbody><tr><td>①</td><td>Vercel</td><td>左侧 Domain 添加根域名，复制验证信息</td></tr><tr><td>②</td><td>DNSHE</td><td>免费域名 → 功能中心 → 根域名验证 → 粘贴信息 → 验证</td></tr><tr><td>③</td><td>Vercel</td><td>点击确认，验证成功</td></tr><tr><td>④</td><td>DNSHE</td><td>验证完成后删除验证记录</td></tr><tr><td>⑤</td><td>两边配合</td><td>Vercel 添加域名 → DNSHE 加 CNAME → Vercel 刷新 → 成功</td></tr></tbody></table><hr><h2 id="第一步：Vercel-添加根域名"><a href="#第一步：Vercel-添加根域名" class="headerlink" title="第一步：Vercel 添加根域名"></a>第一步：Vercel 添加根域名</h2><ol><li>打开 Vercel，<strong>不需要进入项目</strong></li><li>直接点击左侧菜单 <strong>Domains</strong></li><li>输入你的<strong>根域名</strong>（裸域名，例如 <code>de5.net</code>）</li><li>点击 <strong>添加（Add）</strong></li><li>页面会给出<strong>验证信息</strong>（TXT 记录值），<strong>复制保存</strong>备用</li></ol><h2 id="第二步：DNSHE-平台根域名验证"><a href="#第二步：DNSHE-平台根域名验证" class="headerlink" title="第二步：DNSHE 平台根域名验证"></a>第二步：DNSHE 平台根域名验证</h2><ol><li>登录 <a href="https://www.dnshe.com/">DNSHE</a></li><li>进入<strong>免费域名</strong></li><li>进入<strong>功能中心</strong></li><li>点击<strong>根域名验证</strong></li><li>选择你的<strong>子域名</strong>（也就是你要绑定的域名）</li><li>平台类型选择 <strong>Vercel</strong></li><li>把第一步复制的验证信息<strong>粘贴</strong>到内容框</li><li>点击<strong>验证</strong></li></ol><h2 id="第三步：回到-Vercel-确认"><a href="#第三步：回到-Vercel-确认" class="headerlink" title="第三步：回到 Vercel 确认"></a>第三步：回到 Vercel 确认</h2><ol><li>回到 Vercel 的 Domain 页面</li><li>点击<strong>确认（Verify）</strong></li><li>域名验证状态变为<strong>验证成功</strong> ✅</li></ol><h2 id="第四步：DNSHE-删除验证记录"><a href="#第四步：DNSHE-删除验证记录" class="headerlink" title="第四步：DNSHE 删除验证记录"></a>第四步：DNSHE 删除验证记录</h2><ol><li>回到 DNSHE 功能中心</li><li>找到刚才添加的验证记录</li><li>点击<strong>验证完成</strong>，<strong>删除该记录</strong>（验证已通过，这条记录不需要再保留）</li></ol><h2 id="第五步：Vercel-添加域名-DNSHE-添加-CNAME"><a href="#第五步：Vercel-添加域名-DNSHE-添加-CNAME" class="headerlink" title="第五步：Vercel 添加域名 + DNSHE 添加 CNAME"></a>第五步：Vercel 添加域名 + DNSHE 添加 CNAME</h2><ol><li>在 <strong>Vercel 项目里添加域名</strong>（正式把域名绑到项目上）</li><li>把 Vercel 给出的<strong>记录内容</strong>复制</li><li>到 <strong>DNSHE 你的域名下添加 CNAME 记录</strong>（粘贴刚才复制的内容）</li><li>回到 <strong>Vercel 点击刷新</strong></li><li>域名状态显示 ✅ <strong>成功</strong>，绑定完成！</li></ol><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><p><strong>Q：根域名验证为什么还要删记录？</strong><br>A：验证记录只在验证阶段需要，验证通过后删除可以保持解析干净，避免记录冗余冲突。</p><p><strong>Q：CNAME 记录填什么？</strong><br>A：以 Vercel 添加域名时页面给出的提示为准，一般是把 <code>www</code> 或根域名 CNAME 指向 <code>cname.vercel-dns.com</code>。</p><p><strong>Q：验证信息粘贴时要注意什么？</strong><br>A：整段复制完整，别漏字符，别带多余空格或换行。</p><p><strong>Q：DNSHE 免费域名能长期用吗？</strong><br>A：DNSHE 承诺基础域名服务永久免费，但需按平台规则活跃使用&#x2F;续期，建议定期登录后台确认状态。</p><p><strong>Q：可以同时绑定 Cloudflare Pages &#x2F; GitHub Pages 吗？</strong><br>A：可以，流程类似，只是平台类型选择和验证值不同。</p><h2 id="📺-视频教程"><a href="#📺-视频教程" class="headerlink" title="📺 视频教程"></a>📺 视频教程</h2><iframe width="100%" height="400" src="https://www.youtube.com/embed/q2D6SC07YpM" title="DNSHE Vercel 根域名绑定教程" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe><p>原视频：<a href="https://youtu.be/q2D6SC07YpM">YouTube - vercel dnshe验证根域名解析域名</a></p><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p><strong>5 步核心流程</strong>：Vercel 拿验证信息 → DNSHE 功能中心根域名验证 → Vercel 确认 → 删除验证记录 → 添加 CNAME 完成解析。</p><p>免费域名 + Vercel 免费托管，零成本拥有自己的线上服务。跟着教程一步步来，基本一次就能通过。</p><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/12/vercel-root-domain-verification-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/08/12/vercel-root-domain-verification-tutorial/"/>
    <published>2026-08-12T03:00:00.000Z</published>
    <summary>使用 DNSHE 免费域名（de5.net、l.cd 等）绑定 Vercel 根域名的完整教程，5 步搞定：Vercel 添加域名拿验证信息 → DNSHE 功能中心根域名验证 → Vercel 确认 → 删除记录 → 添加域名与 CNAME 解析，附视频演示。</summary>
    <title>DNSHE 免费域名 + Vercel 根域名绑定完整教程（附视频）</title>
    <updated>2026-08-17T07:58:22.406Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="教程" scheme="https://blog.ztmss.com/categories/%E6%95%99%E7%A8%8B/"/>
    <category term="Cloudflare Workers" scheme="https://blog.ztmss.com/tags/Cloudflare-Workers/"/>
    <category term="D1" scheme="https://blog.ztmss.com/tags/D1/"/>
    <category term="Cloudflare" scheme="https://blog.ztmss.com/tags/Cloudflare/"/>
    <category term="R2" scheme="https://blog.ztmss.com/tags/R2/"/>
    <category term="笔记" scheme="https://blog.ztmss.com/tags/%E7%AC%94%E8%AE%B0/"/>
    <category term="端到端加密" scheme="https://blog.ztmss.com/tags/%E7%AB%AF%E5%88%B0%E7%AB%AF%E5%8A%A0%E5%AF%86/"/>
    <category term="PWA" scheme="https://blog.ztmss.com/tags/PWA/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>每天写的笔记都放在哪里？Notion 太慢？Obsidian 要配置？有道云笔记收费？</p><p>今天推荐一个完全免费、零运行成本、<strong>真正的端到端加密</strong>私人笔记应用——<strong>Edge Notes</strong>。</p><p>它部署在 Cloudflare 的全球边缘网络上，数据存于 Cloudflare D1 数据库，图片存于 R2 对象存储——所有组件都是 Cloudflare 免费额度内，<strong>完全没有额外费用</strong>。更重要的是，笔记在浏览器本地加密后上传，服务端只存储密文，<strong>连云平台本身都无法读取你的内容</strong>。</p><ul><li><strong>项目地址</strong>：<a href="https://github.com/love-ztm/cf-edge-notes">https://github.com/love-ztm/cf-edge-notes</a></li><li><strong>开源协议</strong>：MIT</li></ul><hr><h2 id="功能一览"><a href="#功能一览" class="headerlink" title="功能一览"></a>功能一览</h2><p>Edge Notes 的功能之丰富，远超一个”简单笔记”的范畴：</p><h3 id="核心功能"><a href="#核心功能" class="headerlink" title="核心功能"></a>核心功能</h3><table><thead><tr><th align="left">功能</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">🔒 <strong>端到端加密</strong></td><td align="left">浏览器本地 AES-GCM + PBKDF2 加密，服务端只存密文</td></tr><tr><td align="left">🗂️ <strong>多密码多 vault 隔离</strong></td><td align="left">不同密码登录，进入独立数据仓库，彼此完全隔离</td></tr><tr><td align="left">🔍 <strong>全文搜索</strong></td><td align="left">支持标题和正文关键词实时搜索</td></tr><tr><td align="left">📌 <strong>笔记置顶</strong></td><td align="left">重要笔记一键置顶，始终显示在最前</td></tr><tr><td align="left">🏷️ <strong>标签管理</strong></td><td align="left">创建自定义标签并设置颜色，侧边栏按标签筛选</td></tr><tr><td align="left">🖼️ <strong>图片上传</strong></td><td align="left">编辑器内粘贴、拖拽上传图片，加密存储到 R2</td></tr><tr><td align="left">🔗 <strong>笔记分享</strong></td><td align="left">生成公开分享链接，支持设置过期时间，随时撤销</td></tr><tr><td align="left">📤 <strong>导出</strong></td><td align="left">单条导出 Markdown，全部导出 JSON 或 Markdown</td></tr></tbody></table><h3 id="WebDAV-备份与恢复"><a href="#WebDAV-备份与恢复" class="headerlink" title="WebDAV 备份与恢复"></a>WebDAV 备份与恢复</h3><table><thead><tr><th align="left">功能</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">☁️ <strong>WebDAV 备份</strong></td><td align="left">一键备份到 WebDAV 服务器</td></tr><tr><td align="left">🔄 <strong>定时自动备份</strong></td><td align="left">可设置 1h &#x2F; 6h &#x2F; 12h &#x2F; 24h 备份间隔</td></tr><tr><td align="left">📂 <strong>备份文件管理</strong></td><td align="left">按日期命名，支持保留份数设置</td></tr><tr><td align="left">⬇️ <strong>从备份恢复</strong></td><td align="left">浏览并选择历史备份进行恢复</td></tr><tr><td align="left">📥 <strong>本地导入</strong></td><td align="left">支持从本地文件导入备份</td></tr></tbody></table><h3 id="其他功能"><a href="#其他功能" class="headerlink" title="其他功能"></a>其他功能</h3><ul><li>🗑️ <strong>回收站</strong> — 删除笔记进入回收站，可恢复，支持永久删除和定时清理</li><li>🌙 <strong>深色&#x2F;浅色主题</strong> — 一键切换，自动跟随系统偏好</li><li>📱 <strong>PWA 支持</strong> — 手机可添加到主屏幕，像原生应用一样使用</li><li>⚡ <strong>全球边缘加速</strong> — 基于 Cloudflare Workers，全球节点就近响应</li></ul><hr><h2 id="技术架构"><a href="#技术架构" class="headerlink" title="技术架构"></a>技术架构</h2><p>Edge Notes 的技术栈非常现代和轻量：</p><table><thead><tr><th align="left">层级</th><th align="left">技术</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><strong>运行时</strong></td><td align="left">Cloudflare Workers (V8 Isolates)</td><td align="left">全球 300+ 节点边缘执行</td></tr><tr><td align="left"><strong>数据库</strong></td><td align="left">Cloudflare D1 (SQLite)</td><td align="left">免费 5GB 存储空间</td></tr><tr><td align="left"><strong>对象存储</strong></td><td align="left">Cloudflare R2</td><td align="left">免费 10GB 图片存储，无出口流量费</td></tr><tr><td align="left"><strong>加密</strong></td><td align="left">Web Crypto API (AES-GCM + PBKDF2)</td><td align="left">浏览器端原生加密</td></tr><tr><td align="left"><strong>前端</strong></td><td align="left">原生 HTML&#x2F;CSS&#x2F;JS</td><td align="left">无框架依赖，极小体积</td></tr><tr><td align="left"><strong>定时任务</strong></td><td align="left">Cloudflare Cron Triggers</td><td align="left">每日凌晨定时清理</td></tr></tbody></table><p>整个项目由 TypeScript 编写，采用<strong>纯前端 + 无框架</strong>的开发方式——Worker 直接返回 HTML 单页应用，没有 SSR，没有构建步骤，部署就是代码本身。</p><hr><h2 id="部署方式一：一键部署（推荐）"><a href="#部署方式一：一键部署（推荐）" class="headerlink" title="部署方式一：一键部署（推荐）"></a>部署方式一：一键部署（推荐）</h2><p>最简单的方式是通过 Cloudflare 的一键部署按钮：</p><p><a href="https://deploy.workers.cloudflare.com/?url=https://github.com/love-ztm/cf-edge-notes"><img src="https://deploy.workers.cloudflare.com/button" alt="Deploy to Cloudflare"></a></p><p>点击按钮后：</p><ol><li>授权 Cloudflare 访问你的 GitHub</li><li>选择你的 Cloudflare 账号</li><li>Cloudflare 会自动创建 D1 数据库并部署 Worker</li></ol><h3 id="⚠️-部署后必须配置-R2-Bucket"><a href="#⚠️-部署后必须配置-R2-Bucket" class="headerlink" title="⚠️ 部署后必须配置 R2 Bucket"></a>⚠️ 部署后必须配置 R2 Bucket</h3><p>一键部署后，还需要在 Workers 设置中手动添加 R2 Bucket 绑定：</p><ol><li>进入 Cloudflare Dashboard → <strong>Workers &amp; Pages</strong></li><li>选择刚部署的 <code>cf-notes</code> Worker</li><li>进入 <strong>设置</strong> → <strong>变量</strong></li><li>添加 <strong>R2 Bucket 绑定</strong>：<ul><li><strong>绑定名称</strong>：<code>IMAGES</code></li><li><strong>Bucket</strong>：选择一个已创建的 R2 Bucket（如果没有，先在 R2 创建一个）</li></ul></li></ol><h3 id="⚠️-必须设置安全密钥"><a href="#⚠️-必须设置安全密钥" class="headerlink" title="⚠️ 必须设置安全密钥"></a>⚠️ 必须设置安全密钥</h3><p>进入 <strong>变量</strong> → <strong>Secrets</strong> → <strong>添加</strong>：</p><table><thead><tr><th align="left">Secret 名称</th><th align="left">值</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left"><code>APP_PASSWORD</code></td><td align="left">你的密码</td><td align="left">默认 vault 密码，<strong>生产环境务必修改</strong></td></tr><tr><td align="left"><code>COOKIE_SECRET</code></td><td align="left">32位以上随机字符串</td><td align="left">会话签名密钥，不要泄露</td></tr></tbody></table><p>可以通过 <code>openssl rand -base64 32</code> 生成随机密钥。</p><hr><h2 id="部署方式二：手动部署（完整控制）"><a href="#部署方式二：手动部署（完整控制）" class="headerlink" title="部署方式二：手动部署（完整控制）"></a>部署方式二：手动部署（完整控制）</h2><p>如果你需要更多控制权，或者想让部署流程完全透明，手动部署是更好的选择。</p><h3 id="前提条件"><a href="#前提条件" class="headerlink" title="前提条件"></a>前提条件</h3><ul><li>已安装 <strong>Node.js</strong> (≥18)</li><li>已安装 <strong>Wrangler CLI</strong>：<code>npm install -g wrangler</code></li><li>已登录 Cloudflare：<code>npx wrangler login</code></li></ul><h3 id="第-1-步：Fork-项目并安装依赖"><a href="#第-1-步：Fork-项目并安装依赖" class="headerlink" title="第 1 步：Fork 项目并安装依赖"></a>第 1 步：Fork 项目并安装依赖</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 先 Fork 到 GitHub，然后克隆到本地</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/love-ztm/cf-edge-notes.git</span><br><span class="line"><span class="built_in">cd</span> cf-edge-notes</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装依赖</span></span><br><span class="line">npm install</span><br></pre></td></tr></table></figure><h3 id="第-2-步：创建-D1-数据库"><a href="#第-2-步：创建-D1-数据库" class="headerlink" title="第 2 步：创建 D1 数据库"></a>第 2 步：创建 D1 数据库</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx wrangler d1 create private-notes-db</span><br></pre></td></tr></table></figure><p>执行后会返回一个 <code>database_id</code>（UUID 格式），记住它，下一步需要用到。</p><h3 id="第-3-步：创建-R2-Bucket"><a href="#第-3-步：创建-R2-Bucket" class="headerlink" title="第 3 步：创建 R2 Bucket"></a>第 3 步：创建 R2 Bucket</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx wrangler r2 bucket create cf-notes-images</span><br></pre></td></tr></table></figure><h3 id="第-4-步：配置-wrangler-jsonc"><a href="#第-4-步：配置-wrangler-jsonc" class="headerlink" title="第 4 步：配置 wrangler.jsonc"></a>第 4 步：配置 wrangler.jsonc</h3><p>打开 <code>wrangler.jsonc</code>，修改以下字段：</p><figure class="highlight jsonc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;cf-notes&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;main&quot;</span><span class="punctuation">:</span> <span class="string">&quot;src/index.ts&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;compatibility_date&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2026-04-14&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;d1_databases&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;binding&quot;</span><span class="punctuation">:</span> <span class="string">&quot;DB&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;database_name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;private-notes-db&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;database_id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;你上面创建的 database_id&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;r2_buckets&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;binding&quot;</span><span class="punctuation">:</span> <span class="string">&quot;IMAGES&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;bucket_name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;cf-notes-images&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;triggers&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;crons&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;0 3 * * *&quot;</span><span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h3 id="第-5-步：执行数据库迁移"><a href="#第-5-步：执行数据库迁移" class="headerlink" title="第 5 步：执行数据库迁移"></a>第 5 步：执行数据库迁移</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx wrangler d1 migrations apply DB --remote</span><br></pre></td></tr></table></figure><p>这会在 D1 中创建所有必要的表结构（notes、note_shares、tags、trash 等 10 个迁移文件）。</p><h3 id="第-6-步：设置环境变量（Secrets）"><a href="#第-6-步：设置环境变量（Secrets）" class="headerlink" title="第 6 步：设置环境变量（Secrets）"></a>第 6 步：设置环境变量（Secrets）</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 默认 vault 密码</span></span><br><span class="line">npx wrangler secret put APP_PASSWORD</span><br><span class="line"></span><br><span class="line"><span class="comment"># 会话签名密钥（建议 32 字符以上随机字符串）</span></span><br><span class="line">npx wrangler secret put COOKIE_SECRET</span><br><span class="line"></span><br><span class="line"><span class="comment"># 可选：多数据仓库密码</span></span><br><span class="line"><span class="comment"># 格式：vault_id=password,guest=another-password</span></span><br><span class="line">npx wrangler secret put APP_PASSWORDS</span><br></pre></td></tr></table></figure><table><thead><tr><th align="left">变量</th><th align="left">说明</th><th align="left">是否必须</th></tr></thead><tbody><tr><td align="left"><code>APP_PASSWORD</code></td><td align="left">默认 vault 密码</td><td align="left">✅ 必须</td></tr><tr><td align="left"><code>COOKIE_SECRET</code></td><td align="left">会话签名密钥</td><td align="left">✅ 必须</td></tr><tr><td align="left"><code>APP_PASSWORDS</code></td><td align="left">额外隔离 vault 密码，格式 <code>id=password,id2=password2</code></td><td align="left">可选</td></tr></tbody></table><h3 id="第-7-步：部署"><a href="#第-7-步：部署" class="headerlink" title="第 7 步：部署"></a>第 7 步：部署</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm run deploy</span><br></pre></td></tr></table></figure><p>这会自动执行数据库迁移并部署 Worker。部署成功后，你会得到一个 <code>*.workers.dev</code> 地址，直接访问即可。</p><hr><h2 id="部署方式三：GitHub-自动部署"><a href="#部署方式三：GitHub-自动部署" class="headerlink" title="部署方式三：GitHub 自动部署"></a>部署方式三：GitHub 自动部署</h2><p>如果你想让代码更新自动触发部署，可以配置 GitHub 自动部署：</p><ol><li>进入 <strong>Cloudflare Dashboard</strong> → <strong>Workers &amp; Pages</strong></li><li>点击 <strong>连接到 Git</strong></li><li>授权 Cloudflare 访问你的 GitHub</li><li>选择 Fork 的 <code>cf-edge-notes</code> 仓库</li><li>配置构建信息：<ul><li><strong>框架预设</strong>：None</li><li><strong>构建命令</strong>：<code>npm run deploy</code></li><li><strong>构建输出目录</strong>：<code>dist</code></li></ul></li><li>点击 <strong>保存并部署</strong></li></ol><p>以后每次 <code>git push</code> 到 main 分支，Cloudflare 会自动重新部署。</p><hr><h2 id="本地开发"><a href="#本地开发" class="headerlink" title="本地开发"></a>本地开发</h2><p>如果需要本地调试，可以这样配置：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 复制开发配置模板</span></span><br><span class="line"><span class="built_in">cp</span> .dev.vars.example .dev.vars</span><br></pre></td></tr></table></figure><p>编辑 <code>.dev.vars</code>，设置本地密码：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">APP_PASSWORD=facker668</span><br><span class="line">COOKIE_SECRET=change-this-to-a-long-random-string</span><br></pre></td></tr></table></figure><p>然后启动本地开发服务器：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx wrangler dev</span><br></pre></td></tr></table></figure><hr><h2 id="项目结构"><a href="#项目结构" class="headerlink" title="项目结构"></a>项目结构</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">cf-edge-notes/</span><br><span class="line">├── src/</span><br><span class="line">│   ├── index.ts          # Worker 入口 / API 路由 / 分享页面</span><br><span class="line">│   ├── homeHtml.ts       # 前端单页应用（HTML + CSS + JS）</span><br><span class="line">│   └── auth.ts           # 认证与会话管理</span><br><span class="line">├── migrations/</span><br><span class="line">│   ├── 0001_init.sql            # notes 表初始化</span><br><span class="line">│   ├── 0002_notes_fts.sql       # 全文搜索索引</span><br><span class="line">│   ├── 0003_app_meta.sql        # 应用元数据表</span><br><span class="line">│   ├── 0004_auth_rate_limits.sql # 登录频率限制</span><br><span class="line">│   ├── 0005_note_vaults.sql     # 多 vault 支持</span><br><span class="line">│   ├── 0006_add_is_pinned.sql   # 笔记置顶</span><br><span class="line">│   ├── 0007_add_tags.sql        # 标签系统</span><br><span class="line">│   ├── 0008_add_trash.sql       # 回收站</span><br><span class="line">│   ├── 0009_add_images.sql      # 图片上传</span><br><span class="line">│   └── 0010_add_sharing.sql     # 笔记分享</span><br><span class="line">├── wrangler.jsonc         # Cloudflare Workers 配置</span><br><span class="line">├── .dev.vars.example      # 本地开发环境变量模板</span><br><span class="line">└── package.json</span><br></pre></td></tr></table></figure><p>可以看到，整个项目极其精简——核心代码只有 3 个 TypeScript 文件，前端是纯 HTML&#x2F;CSS&#x2F;JS，没有任何前端框架依赖。</p><hr><h2 id="安全机制详解"><a href="#安全机制详解" class="headerlink" title="安全机制详解"></a>安全机制详解</h2><p>Edge Notes 的安全性是其最大的亮点，它采用了<strong>三层防护</strong>：</p><h3 id="1-浏览器端加密（第一层）"><a href="#1-浏览器端加密（第一层）" class="headerlink" title="1. 浏览器端加密（第一层）"></a>1. 浏览器端加密（第一层）</h3><p>笔记在<strong>浏览器本地</strong>使用 AES-GCM + PBKDF2 加密后，才通过 HTTPS 上传到服务器。服务端只存储<strong>密文</strong>，无法读取任何内容。即使 Cloudflare 的运维人员也无法查看你的笔记内容。</p><h3 id="2-认证与会话管理（第二层）"><a href="#2-认证与会话管理（第二层）" class="headerlink" title="2. 认证与会话管理（第二层）"></a>2. 认证与会话管理（第二层）</h3><ul><li><strong>Session Cookie</strong> 使用 HttpOnly + Secure + SameSite&#x3D;Strict，防止 XSS 窃取</li><li><strong>登录频率限制</strong>：5 次失败登录尝试后锁定 15 分钟</li><li><strong>HMAC 签名</strong>：会话使用 HMAC-SHA256 签名，防止篡改</li><li><strong>会话有效期</strong>：30 天，超时自动过期</li></ul><h3 id="3-多-Vault-隔离（第三层）"><a href="#3-多-Vault-隔离（第三层）" class="headerlink" title="3. 多 Vault 隔离（第三层）"></a>3. 多 Vault 隔离（第三层）</h3><p>不同密码登录，进入<strong>完全不同的数据仓库</strong>——数据在数据库层面也是物理隔离的（<code>vault_id</code> 字段），不同 vault 之间的数据互不可见。</p><h3 id="为什么安全？"><a href="#为什么安全？" class="headerlink" title="为什么安全？"></a>为什么安全？</h3><ul><li>密码<strong>不离开浏览器</strong>，云端只知道密码的 PBKDF2 哈希</li><li>笔记内容在浏览器端<strong>用 AES-GCM 加密</strong>，使用密码派生的密钥</li><li>即使数据库被泄露，攻击者拿到的也只是<strong>无法解密的密文</strong></li><li>服务端没有能力解密任何内容——<strong>设计上就不可能</strong></li></ul><hr><h2 id="手机端使用"><a href="#手机端使用" class="headerlink" title="手机端使用"></a>手机端使用</h2><h3 id="iPhone-Safari"><a href="#iPhone-Safari" class="headerlink" title="iPhone (Safari)"></a>iPhone (Safari)</h3><ol><li>用 Safari 打开你的 Edge Notes 站点并登录</li><li>点击底部的<strong>分享按钮</strong> → <strong>添加到主屏幕</strong></li><li>点击<strong>添加</strong>，即可在桌面上找到 Edge Notes</li></ol><h3 id="Android-Chrome"><a href="#Android-Chrome" class="headerlink" title="Android (Chrome)"></a>Android (Chrome)</h3><ol><li>用 Chrome 打开站点并登录</li><li>点击右上角<strong>菜单</strong>（三个点）</li><li>选择<strong>添加到主屏幕</strong> &#x2F; <strong>安装应用</strong></li><li>确认安装，即可在桌面使用</li></ol><p>添加到主屏幕后，Edge Notes 会以<strong>全屏 PWA 应用</strong>的形式运行，体验与原生应用无异。</p><hr><h2 id="使用技巧"><a href="#使用技巧" class="headerlink" title="使用技巧"></a>使用技巧</h2><h3 id="多-Vault-的玩法"><a href="#多-Vault-的玩法" class="headerlink" title="多 Vault 的玩法"></a>多 Vault 的玩法</h3><p>Edge Notes 的<strong>多密码多 vault 隔离</strong>是一个非常有意思的功能：</p><ul><li><strong>工作密码</strong> → 工作笔记（代码片段、技术文档）</li><li><strong>生活密码</strong> → 个人笔记（日记、想法、购物清单）</li><li><strong>密码本</strong> → 可以专门存密码（但建议用 Bitwarden，更安全）</li></ul><p>每个 vault 之间的数据完全隔离，即使你忘了某个工作密码，也不影响生活笔记的使用。</p><h3 id="笔记分享的正确姿势"><a href="#笔记分享的正确姿势" class="headerlink" title="笔记分享的正确姿势"></a>笔记分享的正确姿势</h3><p>当需要和朋友分享一段笔记时：</p><ol><li>打开笔记 → 点击<strong>分享</strong>按钮</li><li>系统会生成一个公开链接（格式：<code>https://你的域名/share/xxx</code>）</li><li>可以设置<strong>过期时间</strong>（1天、1周、1个月等）</li><li>分享后<strong>随时可以撤销</strong>——撤销后链接立即失效</li></ol><h3 id="WebDAV-备份推荐配置"><a href="#WebDAV-备份推荐配置" class="headerlink" title="WebDAV 备份推荐配置"></a>WebDAV 备份推荐配置</h3><p>建议使用 Nextcloud 或 Seafile 的 WebDAV 服务作为备份目标：</p><ul><li><strong>备份间隔</strong>：24h（日常足够）</li><li><strong>保留份数</strong>：7 份（一周历史）</li><li>配合 Cloudflare Cron Triggers（每日凌晨 3 点自动执行清理任务）</li></ul><h3 id="标签系统的用法"><a href="#标签系统的用法" class="headerlink" title="标签系统的用法"></a>标签系统的用法</h3><p>标签系统非常适合做知识分类：</p><ul><li><code>#代码片段</code> — 存放代码片段</li><li><code>#读书笔记</code> — 读书笔记和摘抄</li><li><code>#灵感</code> — 灵感和想法</li><li><code>#待办</code> — 待办事项</li></ul><p>在侧边栏按标签筛选，可以快速定位到特定类别的笔记。</p><hr><h2 id="免费额度说明"><a href="#免费额度说明" class="headerlink" title="免费额度说明"></a>免费额度说明</h2><p>Cloudflare Workers 免费额度：</p><table><thead><tr><th align="left">资源</th><th align="left">免费额度</th><th align="left">Edge Notes 消耗</th></tr></thead><tbody><tr><td align="left">Workers 请求</td><td align="left">10 万次&#x2F;天</td><td align="left">笔记操作极少，<strong>绰绰有余</strong></td></tr><tr><td align="left">D1 数据库</td><td align="left">5GB</td><td align="left">纯文本笔记，<strong>存几万字也才几 KB</strong></td></tr><tr><td align="left">R2 存储</td><td align="left">10GB</td><td align="left">图片附件，<strong>够存几千张</strong></td></tr><tr><td align="left">R2 出口流量</td><td align="left">10GB&#x2F;月</td><td align="left">图片读取，<strong>个人使用完全足够</strong></td></tr></tbody></table><p>对于个人笔记用户来说，<strong>Cloudflare 的免费额度几乎不会用完</strong>。即使你每天写 10 条笔记、上传 20 张图片，一年的总消耗也远低于免费额度。</p><hr><h2 id="与竞品对比"><a href="#与竞品对比" class="headerlink" title="与竞品对比"></a>与竞品对比</h2><table><thead><tr><th align="left">功能</th><th align="left">Edge Notes</th><th align="left">有道云笔记</th><th align="left">Notion</th><th align="left">Obsidian</th></tr></thead><tbody><tr><td align="left"><strong>免费使用</strong></td><td align="left">✅</td><td align="left">⚠️ 容量限制</td><td align="left">✅ 个人免费</td><td align="left">✅</td></tr><tr><td align="left"><strong>端到端加密</strong></td><td align="left">✅</td><td align="left">❌</td><td align="left">❌</td><td align="left">✅</td></tr><tr><td align="left"><strong>零成本运行</strong></td><td align="left">✅</td><td align="left">❌</td><td align="left">❌</td><td align="left">❌</td></tr><tr><td align="left"><strong>数据私有</strong></td><td align="left">✅ 自有</td><td align="left">❌ 第三方</td><td align="left">❌ 第三方</td><td align="left">✅ 本地</td></tr><tr><td align="left"><strong>图片上传</strong></td><td align="left">✅</td><td align="left">✅</td><td align="left">✅</td><td align="left">✅</td></tr><tr><td align="left"><strong>PWA 支持</strong></td><td align="left">✅</td><td align="left">❌</td><td align="left">❌</td><td align="left">❌</td></tr><tr><td align="left"><strong>笔记分享</strong></td><td align="left">✅</td><td align="left">❌</td><td align="left">❌</td><td align="left">❌</td></tr><tr><td align="left"><strong>WebDAV 备份</strong></td><td align="left">✅</td><td align="left">❌</td><td align="left">❌</td><td align="left">❌</td></tr><tr><td align="left"><strong>全文搜索</strong></td><td align="left">✅</td><td align="left">✅</td><td align="left">✅</td><td align="left">✅</td></tr><tr><td align="left"><strong>标签系统</strong></td><td align="left">✅</td><td align="left">✅</td><td align="left">✅</td><td align="left">✅</td></tr></tbody></table><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>Edge Notes 是一个被严重低估的项目——它用 Cloudflare 的免费基础设施，搭建了一个功能丰富、安全性极高的私人笔记应用。</p><p><strong>它的核心价值在于</strong>：</p><ol><li><strong>真正的端到端加密</strong>——不是”数据安全”的承诺，而是代码层面的保证</li><li><strong>零成本运行</strong>——Cloudflare 免费额度对个人使用绰绰有余</li><li><strong>数据完全私有</strong>——不依赖任何第三方服务</li><li><strong>功能远超预期</strong>——标签、分享、备份、PWA，该有的都有</li></ol><p>如果你需要一个<strong>安全、免费、可控</strong>的私人笔记应用，Edge Notes 值得尝试。</p><p><a href="https://github.com/love-ztm/cf-edge-notes">👉 立即访问 GitHub 项目</a></p><hr><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://github.com/love-ztm/cf-edge-notes">Edge Notes GitHub 仓库</a></li><li><a href="https://developers.cloudflare.com/workers/">Cloudflare Workers 文档</a></li><li><a href="https://developers.cloudflare.com/d1/">Cloudflare D1 文档</a></li><li><a href="https://developers.cloudflare.com/r2/">Cloudflare R2 文档</a></li><li><a href="https://developers.cloudflare.com/workers/wrangler/">Wrangler CLI 文档</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/05/edge-notes-deployment-tutorial/</id>
    <link href="https://blog.ztmss.com/2026/08/05/edge-notes-deployment-tutorial/"/>
    <published>2026-08-05T06:00:00.000Z</published>
    <summary>Edge Notes 是一个部署在 Cloudflare Workers + D1 + R2 上的免费端到端加密私人笔记应用。支持浏览器端 AES-GCM 加密、多密码多数据仓库隔离、PWA 支持、全文搜索、标签管理、图片上传、笔记分享、WebDAV 备份恢复等丰富功能。本文将详细介绍从一键部署到手动部署的完整流程。</summary>
    <title>Edge Notes 部署教程：免费搭建端到端加密私人笔记，Cloudflare Workers + D1 + R2 一键部署</title>
    <updated>2026-08-17T07:58:22.400Z</updated>
  </entry>
  <entry>
    <author>
      <name>luoli</name>
    </author>
    <category term="技术学习" scheme="https://blog.ztmss.com/categories/%E6%8A%80%E6%9C%AF%E5%AD%A6%E4%B9%A0/"/>
    <category term="Cloudflare" scheme="https://blog.ztmss.com/categories/Cloudflare/"/>
    <category term="AI Agent" scheme="https://blog.ztmss.com/tags/AI-Agent/"/>
    <category term="Cloudflare" scheme="https://blog.ztmss.com/tags/Cloudflare/"/>
    <category term="Cloudflare Wallets" scheme="https://blog.ztmss.com/tags/Cloudflare-Wallets/"/>
    <category term="Web3" scheme="https://blog.ztmss.com/tags/Web3/"/>
    <category term="加密货币" scheme="https://blog.ztmss.com/tags/%E5%8A%A0%E5%AF%86%E8%B4%A7%E5%B8%81/"/>
    <category term="支付" scheme="https://blog.ztmss.com/tags/%E6%94%AF%E4%BB%98/"/>
    <category term="Monetization Gateway" scheme="https://blog.ztmss.com/tags/Monetization-Gateway/"/>
    <content>
      <![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>2026年8月4日，Cloudflare发布了一项引人注目的新产品——<strong>Cloudflare Wallets</strong>。</p><p>这不是一款普通的加密货币钱包，而是<strong>专为AI Agent设计的可编程钱包</strong>。它的核心理念非常清晰：让AI代理在网络上拥有自己的”身份”和”支付方式”，从而真正融入商业生态。</p><p>如果你已经在使用Cloudflare的Workers、AI推理服务，或者你对Web3支付和AI Agent商业化感兴趣，这篇博文非常重要。</p><p><strong>现在即可访问 <a href="https://cloudflare.pay/">https://cloudflare.pay</a> 认领你的钱包句柄，抢先体验。</strong></p><hr><h2 id="Cloudflare-Wallets-是什么？"><a href="#Cloudflare-Wallets-是什么？" class="headerlink" title="Cloudflare Wallets 是什么？"></a>Cloudflare Wallets 是什么？</h2><p>Cloudflare Wallets 的定位可以概括为一句话：</p><blockquote><p><strong>“Cloudflare Wallets will provide AI agents with native payments and verifiable identity on the web.”</strong></p></blockquote><p>Cloudflare Wallets 将为AI代理提供网络上的原生支付和可验证身份。</p><h3 id="为什么需要这个产品？"><a href="#为什么需要这个产品？" class="headerlink" title="为什么需要这个产品？"></a>为什么需要这个产品？</h3><p>Cloudflare在博客中明确指出：<strong>AI代理在网络上存在根本性的支付和身份障碍</strong>。</p><ul><li><strong>缺乏稳定标识符</strong>：AI代理没有固定的身份来注册、验证和交互。</li><li><strong>没有原生支付方式</strong>：代理无法独立完成付费操作，导致商业任务经常被”踢回”给人类处理。</li><li><strong>限制了代理商业的增长</strong>：没有支付和身份，AI代理就无法真正成为独立的商业参与者。</li></ul><p>Cloudflare Wallets 就是要解决这三个问题。</p><hr><h2 id="两种钱包模式"><a href="#两种钱包模式" class="headerlink" title="两种钱包模式"></a>两种钱包模式</h2><p>Cloudflare Wallets 提供两种截然不同的钱包类型，分别面向人类和AI代理：</p><h3 id="1-账户钱包（Account-Wallets）"><a href="#1-账户钱包（Account-Wallets）" class="headerlink" title="1. 账户钱包（Account Wallets）"></a>1. 账户钱包（Account Wallets）</h3><p>面向<strong>人类用户</strong>，是最传统意义上的”数字钱包”。</p><table><thead><tr><th align="left">功能</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">💰 <strong>充值</strong></td><td align="left">符合条件的用户可以自行向账户充值</td></tr><tr><td align="left">📤 <strong>委托支出</strong></td><td align="left">人类可以授权AI代理代为支出</td></tr><tr><td align="left">💸 <strong>提取资金</strong></td><td align="left">支持提现操作</td></tr><tr><td align="left">🪙 <strong>存储稳定币</strong></td><td align="left">以稳定币形式存储资金</td></tr></tbody></table><h3 id="2-虚拟钱包（Virtual-Wallets）"><a href="#2-虚拟钱包（Virtual-Wallets）" class="headerlink" title="2. 虚拟钱包（Virtual Wallets）"></a>2. 虚拟钱包（Virtual Wallets）</h3><p>专为<strong>AI代理</strong>设计，通过<strong>API密钥</strong>运作。</p><table><thead><tr><th align="left">功能</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">🔑 <strong>API密钥驱动</strong></td><td align="left">通过API密钥控制，无需传统登录</td></tr><tr><td align="left">🛡️ <strong>支出上限</strong></td><td align="left">人类可设定代理的最高消费额度</td></tr><tr><td align="left">✅ <strong>允许列表</strong></td><td align="left">限制代理只能向特定收款方付款</td></tr><tr><td align="left">💵 <strong>最大交易金额</strong></td><td align="left">单笔交易金额上限，防止失控</td></tr><tr><td align="left">🤖 <strong>自主探索</strong></td><td align="left">在安全范围内，代理可自主消费</td></tr></tbody></table><blockquote><p><strong>“You will be able to define guardrails for your Virtual Wallets.”</strong><br>你可以为自己的虚拟钱包设定护栏。</p></blockquote><p>这套护栏系统的设计哲学非常清晰：<strong>让人类放心地放手，让AI代理在安全范围内自主行动</strong>。</p><hr><h2 id="Monetization-Gateway：HTTP请求附带的微支付"><a href="#Monetization-Gateway：HTTP请求附带的微支付" class="headerlink" title="Monetization Gateway：HTTP请求附带的微支付"></a>Monetization Gateway：HTTP请求附带的微支付</h2><p>这是Cloudflare Wallets最具技术深度的部分。</p><p><strong>Monetization Gateway</strong> 允许网站运营者直接<strong>通过HTTP请求收取费用</strong>——支付不需要跳转到第三方支付页面，而是<strong>附带在HTTP请求中</strong>完成。</p><h3 id="x402-微支付协议"><a href="#x402-微支付协议" class="headerlink" title="x402 微支付协议"></a>x402 微支付协议</h3><p>Monetization Gateway 基于 <strong>x402协议</strong>实现微支付：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">HTTP 请求 + x402 支付头 = 自动计费</span><br></pre></td></tr></table></figure><p><strong>典型应用场景：</strong></p><table><thead><tr><th align="left">场景</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">🤖 <strong>AI推理付费</strong></td><td align="left">每次调用AI模型自动扣费</td></tr><tr><td align="left">📊 <strong>数据访问付费</strong></td><td align="left">查询付费数据集时自动结算</td></tr><tr><td align="left">📝 <strong>内容购买付费</strong></td><td align="left">付费阅读文章时按次计费</td></tr><tr><td align="left">🔍 <strong>API调用付费</strong></td><td align="left">按调用次数计费，无需订阅制</td></tr></tbody></table><blockquote><p><strong>“Payments can be attached to HTTP requests for uses ranging from AI inference to data to content.”</strong><br>支付可附加到HTTP请求中，涵盖AI推理、数据和内容等场景。</p></blockquote><p>这种模式的意义在于：<strong>它把”付费”变成了像”发送HTTP请求”一样自然的操作</strong>，彻底消除了传统支付流程中的跳转、确认、登录等摩擦。</p><hr><h2 id="身份验证：Turnstile-Web-Bot-Auth"><a href="#身份验证：Turnstile-Web-Bot-Auth" class="headerlink" title="身份验证：Turnstile + Web Bot Auth"></a>身份验证：Turnstile + Web Bot Auth</h2><p>支付解决了，身份怎么办？Cloudflare给出了自己的答案。</p><h3 id="Web-Bot-Auth"><a href="#Web-Bot-Auth" class="headerlink" title="Web Bot Auth"></a>Web Bot Auth</h3><p>Web Bot Auth 允许AI代理通过<strong>密钥对</strong>在网络上注册和声明身份：</p><ul><li>钱包ID附属于Cloudflare Wallets，使密钥对变成”人类可读”的身份标识。</li><li>代理可以通过 <strong>cloudflare.pay</strong> 句柄来声明自己的身份（例如使用某个组织名下的句柄）。</li></ul><h3 id="Turnstile-整合"><a href="#Turnstile-整合" class="headerlink" title="Turnstile 整合"></a>Turnstile 整合</h3><p>Cloudflare的 <strong>Turnstile</strong>（无感验证）和 <strong>Bot Management</strong> 也被整合进来：</p><ul><li><strong>检测机器人</strong>：区分真实人类和AI代理</li><li><strong>身份认证</strong>：确保接入的代理是可信的</li><li><strong>防滥用</strong>：配合虚拟钱包的护栏系统，构建多层安全防护</li></ul><h3 id="句柄（Handle）"><a href="#句柄（Handle）" class="headerlink" title="句柄（Handle）"></a>句柄（Handle）</h3><p>从<strong>今天起</strong>，你可以认领一个Cloudflare Wallet句柄：</p><ul><li>访问 <strong><a href="https://cloudflare.pay/">https://cloudflare.pay</a></strong></li><li>为你的账户认领一个独特的句柄</li><li>这个句柄将成为你的AI代理在Web上的身份标识</li></ul><hr><h2 id="与-Cloudflare-产品生态的整合"><a href="#与-Cloudflare-产品生态的整合" class="headerlink" title="与 Cloudflare 产品生态的整合"></a>与 Cloudflare 产品生态的整合</h2><p>Cloudflare Wallets 并非孤立产品，而是深度整合到Cloudflare的现有生态中：</p><table><thead><tr><th align="left">产品</th><th align="left">整合方式</th></tr></thead><tbody><tr><td align="left"><strong>Agents SDK</strong></td><td align="left">Wallets将成为Cloudflare Agents SDK的新工具</td></tr><tr><td align="left"><strong>Workers</strong></td><td align="left">通过API密钥直接调用钱包功能</td></tr><tr><td align="left"><strong>Pages</strong></td><td align="left">网站可直接通过Monetization Gateway收费</td></tr><tr><td align="left"><strong>Turnstile</strong></td><td align="left">提供Bot检测与身份验证</td></tr><tr><td align="left"><strong>Bot Management</strong></td><td align="left">多层安全防护</td></tr><tr><td align="left"><strong>AI推理服务</strong></td><td align="left">钱包可直接为AI调用付费</td></tr></tbody></table><p>Cloudflare的策略非常清晰：<strong>构建一个完整的”无头市场”（Headless Market）</strong>，让AI代理能够像人类一样在网络上消费、付费、识别和被识别。</p><hr><h2 id="安全性设计"><a href="#安全性设计" class="headerlink" title="安全性设计"></a>安全性设计</h2><p>作为一个涉及资金的产品，安全性自然是重中之重。Cloudflare Wallets采用了多层安全机制：</p><h3 id="1-护栏系统"><a href="#1-护栏系统" class="headerlink" title="1. 护栏系统"></a>1. 护栏系统</h3><p>人类可以为AI代理的虚拟钱包设定：</p><ul><li><strong>预算上限</strong>：代理的总消费额度</li><li><strong>允许列表</strong>：代理只能向特定收款方付款</li><li><strong>最大交易金额</strong>：单笔交易上限</li></ul><h3 id="2-异常审核"><a href="#2-异常审核" class="headerlink" title="2. 异常审核"></a>2. 异常审核</h3><p>当代理的消费行为超出预设范围时，系统会<strong>自动拦截并通知人类</strong>，需要人工审核确认后才能继续。</p><blockquote><p><strong>“Spending caps on Virtual Wallets are designed so that humans can let agents explore autonomously.”</strong><br>虚拟钱包的支出上限设计，是为了让人类可以放心地让AI代理自主探索。</p></blockquote><h3 id="3-Cloudflare基础设施安全"><a href="#3-Cloudflare基础设施安全" class="headerlink" title="3. Cloudflare基础设施安全"></a>3. Cloudflare基础设施安全</h3><p>作为建立在Cloudflare全球网络之上的产品，Wallets继承了Cloudflare在DDoS防护、DDoS缓解和网络安全方面的能力。</p><hr><h2 id="开发者如何使用？"><a href="#开发者如何使用？" class="headerlink" title="开发者如何使用？"></a>开发者如何使用？</h2><h3 id="当前阶段（2026年8月4日）"><a href="#当前阶段（2026年8月4日）" class="headerlink" title="当前阶段（2026年8月4日）"></a>当前阶段（2026年8月4日）</h3><ul><li>✅ <strong>认领句柄</strong>：访问 <a href="https://cloudflare.pay/">https://cloudflare.pay</a> 即可开始</li><li>🔜 <strong>钱包功能</strong>：即将上线，届时可通过API密钥操作</li><li>🔜 <strong>Agents SDK集成</strong>：钱包将作为新工具加入Cloudflare Agents SDK</li></ul><h3 id="未来阶段"><a href="#未来阶段" class="headerlink" title="未来阶段"></a>未来阶段</h3><ul><li><strong>x402基金会标准采纳</strong>：Cloudflare表示未来将采纳x402基金会的标准</li><li><strong>无头市场建设</strong>：Cloudflare明确表示”我们不试图定义特定的schema”，而是构建开放的基础设施</li></ul><hr><h2 id="这意味着什么？"><a href="#这意味着什么？" class="headerlink" title="这意味着什么？"></a>这意味着什么？</h2><p>Cloudflare Wallets 的发布，标志着<strong>AI代理商业化</strong>进入了新阶段：</p><ol><li><strong>AI代理真正拥有了”身份”</strong>——不再只是后台代码，而是网络上的可识别实体。</li><li><strong>AI代理可以独立付费</strong>——不再需要人类每次都要”替代理付钱”。</li><li><strong>微支付让API经济成为可能</strong>——按调用计费，无需订阅，AI推理服务将迎来革命性的定价模式。</li><li><strong>Cloudflare生态闭环形成</strong>——从计算（Workers）、AI（推理）、到支付（Wallets），Cloudflare正在构建AI时代的基础设施全栈。</li></ol><hr><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>Cloudflare Wallets 是Cloudflare向AI时代迈出的一大步。它解决的不仅是”如何付钱”的问题，更是”AI如何在网络上作为独立商业主体存在”的根本问题。</p><p>对于开发者而言，现在的行动建议是：</p><ol><li><strong>立即访问</strong> <a href="https://cloudflare.pay/">https://cloudflare.pay</a> <strong>认领你的句柄</strong>——先到先得，独特性不可重复。</li><li><strong>关注Agents SDK更新</strong>——钱包功能即将上线，届时即可开始集成。</li><li><strong>思考你的产品如何接入微支付</strong>——x402协议可能彻底改变你的API定价策略。</li></ol><p>Cloudflare的野心很大：<strong>构建一个AI Agent可以自由消费、付费、识别和被识别的网络</strong>。而这一切，从今天开始。</p><hr><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://blog.cloudflare.com/wallets/">Cloudflare官方博客 - Announcing Cloudflare Wallets</a></li><li><a href="https://cloudflare.pay/">Cloudflare Wallets 官方入口</a></li><li><a href="https://developers.cloudflare.com/workers/">Cloudflare Workers 文档</a></li><li><a href="https://www.x402.org/">x402 微支付协议</a></li></ul><h2 id="推荐链接"><a href="#推荐链接" class="headerlink" title="推荐链接"></a>推荐链接</h2><ul><li><a href="https://blog.cmliussss.com/">大佬CM博客</a></li><li><a href="https://blog.zrf.me/">大佬周润发博客</a></li><li><a href="https://blog.811520.xyz/">大佬青云志博客</a></li></ul>]]>
    </content>
    <id>https://blog.ztmss.com/2026/08/04/cloudflare-wallets-release/</id>
    <link href="https://blog.ztmss.com/2026/08/04/cloudflare-wallets-release/"/>
    <published>2026-08-04T09:00:00.000Z</published>
    <summary>2026年8月4日，Cloudflare正式发布Wallets——一款专为AI Agent设计的可编程钱包。支持账户钱包和虚拟钱包双模式，整合Monetization Gateway实现基于x402协议的网络微支付，并提供Turnstile身份验证。现已开放句柄认领，支持稳定币充值和自主支出控制。</summary>
    <title>Cloudflare Wallets 来了：AI Agent 的原生钱包与支付，2026年8月4日重磅发布</title>
    <updated>2026-08-17T07:58:22.398Z</updated>
  </entry>
</feed>
