Files
tamabox/outputs/domain-migration-box-shiroko-2026-09-06.md
T
tamakyi e3e59e7c69 chore: baseline snapshot before moderation-strictness feature
Repo .git was damaged (refs/ missing, index truncated, object store near-empty).
Repaired via git init (rebuilt refs), stale index preserved as .git/index.corrupt-20260910.bak,
then full worktree committed as a rollback baseline.
2026-09-10 10:56:27 +08:00

280 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# box.tama.guru → box.shiroko.one 域名迁移方案(保 Bing 排名)
> 日期:2026-09-06 | 状态:方案待批准
> 目标:在 tama.guru **不续费**(2026-12-24 到期)的约束下,把 box.tama.guru 迁移到 box.shiroko.one,最小化 Bing(及 Google)排名损失。
---
## 0. 决策记录(用户已拍板)
| 决策点 | 选择 | 影响 |
|---|---|---|
| 过渡策略 | **不续费硬过渡** | 301 窗口 ≈ 现在→2026-12-24(约 3.5 个月) |
| 新域形态 | **box.shiroko.one**(子域) | 根域 shiroko.one 留给导航页/blog 等未来用途 |
| 引擎范围 | **Bing + Google 全套** | Site Move + GSC Change of Address + 双 sitemap + IndexNow |
| umami | **一并迁走** → mami.shiroko.one | 统计不中断 |
| 站群其余子域 | **一并迁移**(blog/chat/share/status → 同名 `.shiroko.one`) | 用户 2026-09-06 追加确认;footer 链接群与 home 文案内链全部换域 |
| `/_/tamakyi` | **不保** | 从 sitemap 移除;robots 维持 `Disallow: /_/`(与 sitemap 自相矛盾的问题一并消除)。页脚/首页指向站长箱的**功能性链接保留**(用户仍可点击),只是不再提交给搜索引擎 |
> ✅ **批 1(本地代码改动)已于 2026-09-06 完成**,详见 §12。
---
## 1. 现状与硬约束(侦查取证结果)
### 1.1 资产地图
- `tama.guru` 根域 = 「狼的导航页」(Hugo 0.121.2 / CF Pages)——用户声明不保
- `box.tama.guru` = **本次迁移对象**(提问箱,生产,DNSPod 三线路 DNS:境内→EdgeOne 新加坡、境外/默认→Cloudflare SaaS+tunnel)
- `mami.tama.guru` = umami 统计(Vercel)——随迁
- `blog/status/share/chat.tama.guru` = 站群其余子域——用户未声明保,列入开放项(§11)
- `r2.337845818.best`、`337845818.best` zone = 独立域,**不受影响**(仅需在 R2 CORS 白名单追加新域)
- 注册信息:tama.guru 注册商 **DNSPod, Inc.**,**expiration 2026-12-24**,当前 active
### 1.2 box.tama.guru 的 SEO 现状(好消息)
- Bing 收录管道 = `static/sitemap.xml` 仅 **8 条 URL**:
`/`、`/explore`、`/register`、`/login`、`/_/tamakyi`、`/change-logs`、`/explore`(重复)、裸域
- `/explore` 是唯一「内容页」,排名大概率集中于此 → **索引面小、301 映射表短、信号集中,迁移成本极低**
- ⚠️ robots.txt `Disallow: /_/` 与 sitemap 提交 `/_/tamakyi` **自相矛盾**——搜索引擎以 robots 为准,该条实为无效提交;若 `/_/tamakyi` 有真实流量价值需决策(§11 开放项)
- ⚠️ 页面**无 `<link rel="canonical">`**(仅 og:url)——迁移是新站补 canonical 的好时机,对 Bing 有实际帮助
### 1.3 关键机制(Bing/Google 官方语义)
1. **301 全量逐 URL 一一对应**是唯一可靠路径:不 302、不跳首页、无链式跳转
2. Bing Site Move / GSC Change of Address 只是「加速器」;工具不可用时 301+sitemap 兜底
3. 提交 Site Move 后 **新域 6 个月内不得再次迁移**
4. 通行要求:301 保持 6–12 个月;权重转移 60–90 天;迁移期掉 10–30% 属正常
5. **约束风险**:本方案窗口 ~3.5 个月 < 6 个月通行线。缓解:① 索引面仅 3–5 个有效 URL,Bing 对小型站处理快;② 尽早切换拉满窗口;③ IndexNow 秒级通知加速新站收录
---
## 2. 目标架构
```
┌─ 境内线路 ──> EdgeOne(box.shiroko.one 加速域) ─┐
用户 → DNSPod(shiroko.one) ┤ ├→ 源站 TamaBox
(分线路) └─ 境外/默认 ─> Cloudflare SaaS + tunnel ──────┘
│
旧域 box.tama.guru(DNS 在切换日改指静态 301 载体,见 §6)
任意线路 ─> CF Pages 跳转项目 ─ 301 ─> https://box.shiroko.one/<同路径><同query>
```
- 新域 **双 CDN 架构完全照搬** box.tama.guru 现状(境内 EO / 境外 CF)
- 旧域在 12-24 前**只做 301**,不再回源 → 源站与旧域解耦,安全退役
- umami:Vercel 加 `mami.shiroko.one`,同一实例,数据不丢
---
## 3. 时间线(倒排,越早切换 301 窗口越长)
| 阶段 | 窗口 | 内容 | 责任 |
|---|---|---|---|
| **P0 准备** | 现在 – 9/20 | 代码/配置改动(§5)、域名/控制台准备(§7)、Bing/GSC 双属性验证(§8.1) | 我 + 你 |
| **P1 新站上线** | 9/20 – 9/27 | box.shiroko.one 双线打通、全功能验收、旧站并行不动 | 我 + 你 |
| **P2 切换** | 9 月底某低峰日凌晨 | 改 external_url → 源站重启 → 旧域 DNS 切 301 载体 → Site Move/CoA/IndexNow(§8) | 我 + 你 |
| **P3 过渡监控** | 10 月 – 12/24 | 每周看两站索引与流量;反链外联更新;旧域保持 301 | 我 |
| **P4 到期善后** | 12/24 后 | 旧域自然失效属计划内;确认新站独立站稳、无旧缓存依赖 | 我 |
**切换建议 ≤ 2026-10-01**,301 窗口 ≈ 85–90 天,覆盖 Bing 权重转移期(60–90 天)。
---
## 4. 保排名逻辑(为什么这样做能最小化损失)
```
旧 URL(Bing 索引中) ──301──> 新 URL ──sitemap/IndexNow──> Bing 立即重爬新址
│ │
排名信号(点击/外链/信任) 由 301 传递 ≈90% 权重 60–90 天内转移
│ │
旧域 12/24 消亡时:Bing 已把信号合并到新域 ← 目标状态
```
不这样做的代价:旧 URL 到期后全部变死链 → Bing 逐个降权删除 → 新域从零积累,等于「重新开始」。
---
## 5. 代码与配置文件改动清单(本地副本,批准后分批实施)
### P0 必改(切域前)
| # | 文件 | 改动 | 说明 |
|---|---|---|---|
| C1 | 部署侧 `conf/app.ini` | `external_url = https://box.shiroko.one` | **必填配置**;og:url 与全部邮件链接(找回密码/私信通知)一次修复。app.ini 在部署环境持有,本地副本无此文件 |
| C2 | `static/robots.txt` | `Sitemap:` 行改 `https://box.shiroko.one/sitemap.xml` | go:embed 静态文件,当前硬编码旧域 |
| C3 | `static/sitemap.xml` | 8 条 URL 域替换为 box.shiroko.one | 同上;建议顺手去掉与 robots 冲突的 `/_/tamakyi`(§11 决策) |
| C4 | `route/auth/register.go:64` | `Bloglink: "box.shiroko.one"` | 注册引导链接硬编码 |
| C5 | `internal/security/censor/text.go` | TrustedHosts:`tama.guru` → 增加/替换为 `shiroko.one` | 否则用户在新站发 shiroko.one 链接被当广告拦。实施时确认 RemoveTrustedURL 对子域是否覆盖(needle=裸域 + 边界判断) |
| C6 | `templates/base/header.html` | og:url 保留(自动跟随 ExternalURL);**新增** `<link rel="canonical" href="{{.ExternalURL}}{{.CurrentURI}}">` | 新站补 canonical,防重复收录,Bing 友好 |
| C7 | `templates/base/header.html` | umami 注入块:`s.src = "https://mami.shiroko.one/tamami.js"` | 与 umami 迁移同批(§5 D 组) |
| C8 | `templates/base/footer.html` | 链接群(blog/chat/share/status/tama.guru)按 §11 决策处理 | 到期后这些全是死链,必须在切换前定 |
| C9 | `templates/home.html` | 正文内链 `box.tama.guru` → `box.shiroko.one`;指向 blog 的文章链接按 §11 决策 | 首页是 Bing 重点页面,内链必须指向新站而非继续依赖 301 |
### 伴随迁移(D 组,与 box 同批)
| # | 位置 | 改动 |
|---|---|---|
| D1 | Vercel 控制台 | umami 项目添加自定义域 `mami.shiroko.one`(CNAME → cname.vercel-dns.com) |
| D2 | DNS(新 zone) | `mami` 记录 CNAME → Vercel 目标 |
| D3 | C7 的 header 埋点 | 指向 mami.shiroko.one(同一 data-website-id,数据连续) |
> mami.tama.guru 在 12-24 前保持在线,与新域并行无冲突(浏览器缓存自然淘汰)。
---
## 6. 301 实现方案(旧域唯一使命)
**推荐:CF Pages 静态跳转项目**(免费、一行配置、境内境外通吃)
1. Cloudflare 新建一个 Pages 项目(如 `tama-redirect`),根目录放一个 `_redirects`:
```
/* https://box.shiroko.one/:splat 301!
```
2. 把 `box.tama.guru` 添加为该 Pages 项目的自定义域(Pages 面板 → Custom domains → 按提示在 DNSPod 加 CNAME)
3. **切换日**:DNSPod 上 box.tama.guru 的三条线路(境内 EO CNAME / 境外 CF / 默认 CF)统一改 CNAME → 该 Pages 域名(或直接 CNAME 到 pages.dev 域名)
4. 原 EO 加速站点 / CF SaaS 主机名(box.tama.guru)**可停可留**——DNS 切走后自然不再产生流量,12/24 随旧域注销即可
- ✅ 保留完整路径与 query(`:splat`),无链式跳转,天然 301
- ✅ 与源站/旧 CDN 完全解耦,源站只需服务新域
- ✅ 301 响应体积极小,境内经 CF Pages 慢 ~1s 无感
- 备选 A:EO 重定向规则(境内)+ CF Worker route(境外)——需在两边控制台分别配,操作更碎
- 备选 B:源站 nginx 按 Host 301——**不推荐**:CDN 回源 Host=box.tama.guru 时会产生回源环,需同时改回源配置,风险高
---
## 7. 控制台操作清单(需你在各平台操作,我提供每一步的精确值)
### 7.1 DNS 托管决策(先行)
**推荐**:`shiroko.one` 的 NS 从 Spaceship 改到 **DNSPod**(你已在 DNSPod 管理 tama.guru,分线路 DNS 是现有双 CDN 架构的前提;Spaceship DNS 无境内/境外分线路)。
步骤:DNSPod 添加 `shiroko.one` → 获得 DNSPod 分配的 NS → Spaceship 域名面板改 NS → 等待生效(1–24h,可用 `nslookup -type=NS shiroko.one 8.8.8.8` 验证)。
### 7.2 DNSPod(shiroko.one zone)
| 主机 | 类型 | 值 | 线路 |
|---|---|---|---|
| box | CNAME | EO 分配的 CNAME 目标(控制台给,形如 `xxx.eo.dnse4.com`) | 中国境内 |
| box | CNAME | CF SaaS CNAME 目标(337845818.best zone → Custom hostnames → 形如 `<hash>.cdn.cloudflare.net`)或既有优选 CNAME | 境外 / 默认 |
| mami | CNAME | `cname.vercel-dns.com` | 默认 |
> 以上记录结构完全照搬 box.tama.guru / mami.tama.guru 现有三条线;切换日另加 box.tama.guru 的 301 线路(§6)。
### 7.3 EdgeOne(腾讯)
- 新增加速域名 **box.shiroko.one**:归属验证(TXT/CNAME,验证记录保留勿删)→ HTTPS 证书 → 回源=源站 IP:高位端口、回源 HOST=box.shiroko.one
- 规则/缓存配置照抄 box.tama.guru 现有站点
### 7.4 Cloudflare
- `337845818.best` zone → SSL/TLS → Custom hostnames(for SaaS):添加 **box.shiroko.one**(回源走既有 tunnel;cloudflared ingress 增加 box.shiroko.one 路由)
- R2 bucket CORS 白名单:追加 `https://box.shiroko.one`(**必须在 301 前完成**,否则新站图片/二维码导出被 CORS 拦)
### 7.5 Vercel
- umami 项目添加 `mami.shiroko.one`(§5 D1)
---
## 8. SEO 迁移执行序列
### 8.1 预备(P0,先于新站上线,可立即做)
1. **Bing Webmaster Tools**:添加并验证 `box.shiroko.one`(用 DNS TXT 验证,DNSPod 加记录即可,无需等站点上线);确认旧站 `box.tama.guru` 属性已存在并验证
2. **Google Search Console**:同上双属性(URL-prefix:`https://box.tama.guru/`、`https://box.shiroko.one/`)
### 8.2 切换日顺序(P2,低峰凌晨,301 是前提)
1. 确认 box.shiroko.one 在 EO(境内视角)与 CF(境外视角)全功能验收通过(§9)
2. 改 `external_url` + 重启 → 新站所有 og/canonical/sitemap/邮件全指新域
3. 旧域 DNS 切 301 载体(§6)→ `curl -I` 验证 301 与 Location 正确
4. **Bing Site Move**(旧属性 → Diagnostics & Tools → Site Move → 目标 box.shiroko.one,Scope=Domain)——若工具不可用,301+sitemap 兜底
5. **GSC Change of Address**(旧属性 → 设置 → Change of Address → 新属性)
6. 双引擎分别提交**新站 sitemap**;旧站 sitemap 保留 60–90 天(引导爬虫吃 301)
7. **IndexNow**:用 API key 提交新站全部 URL(Bing 收录最快路径)
8. 逐条验证 §9.2 的 301 映射
---
## 9. 验证与验收
### 9.1 切换前(新站验收,全部通过才允许 301)
- [ ] `https://box.shiroko.one/` 境内 EO / 境外 CF 均 200(用不同线路 DNS 查询验证)
- [ ] 登录 / 提问 / 私信 / 上传 / 投票 / 二维码导出 主链路通过(R2 CORS 已含新域)
- [ ] `curl -s https://box.shiroko.one/robots.txt` → Sitemap 行 = 新域
- [ ] `curl -s https://box.shiroko.one/sitemap.xml` → 全部 URL = 新域
- [ ] 页面含 canonical 指向自身、og:url = 新域
- [ ] 邮件模板链接 = 新域(发一封找回密码实测)
### 9.2 切换后(301 映射抽查)
```
curl -sI https://box.tama.guru/explore → 301 Location: https://box.shiroko.one/explore
curl -sI https://box.tama.guru/_/tamakyi → 301 → https://box.shiroko.one/_/tamakyi
curl -sI "https://box.tama.guru/vote/xxx?lang=en" → 301 且保留 query
curl -sI https://box.tama.guru/no-such-page → 301(不允许 404/302)
```
- [ ] 抽样 20+ URL,确认无 302、无 404、无链式跳转(一条 301 直达)
### 9.3 过渡期每周监控(P3)
- Bing/GSC:旧域 indexed 数量应**逐周下降**;新域**逐周上升**,60–90 天追平旧域基线
- 综合 Search Performance:前 2–4 周掉 10–30% 属正常;**持续 >30% 且无回升 = 异常**,立即排查
- 新域 site:box.shiroko.one 查询确认收录增长
---
## 10. 风险清单
| # | 风险 | 等级 | 缓解 |
|---|---|---|---|
| R1 | 301 窗口 3.5 个月 < 6 个月通行线,权重转移可能不完整 | 🟠 中 | 9 月底前切换拉满窗口;索引面小 + IndexNow 加速;Bing 对小型站处理快 |
| R2 | 切换瞬间旧书签/API 用户 301 到新域 → cookie 一次性失效、跨域 | 🟡 低 | 一次性,切换公告;API 调用方(若有)需跟随新域 |
| R3 | umami 迁移延误 → 12/24 后统计断 | 🟡 低 | D 组随 P1 完成,两域并行过渡 |
| R4 | DNSPod 到期政策未知:到期日是否即停解析 | 🟡 低 | 按 12-24 停摆做计划;若到期后保留解析则 301 窗口自动延长,纯赚 |
| R5 | `/_/tamakyi` robots/sitemap 矛盾未决 → 若该页真有 Bing 流量,迁移映射需特殊处理 | 🟡 低 | §11 决策后补映射 |
| R6 | footer/home 指向 blog 等将死子域 → 新站页面出现死链 | 🟡 低 | §11 决策 |
---
## 11. 开放项(2026-09-06 更新:1/2 已由用户答复)
1. ~~站群其余子域(blog/status/share/chat)是否迁~~ → **已答:一并迁**。已按 `*.shiroko.one` 同名映射改完(footer 6 条链接 + home 文案内链 + llms 三处博客链)。
⚠️ 仍需你操作:这些子域的**实际服务**也要搬(blog 的 Hugo/CF Pages、chat/share/status 各自托管),否则新域链接会是死链。若某个子域打算放弃(如 share/status),告诉我,我把 footer 对应条目删掉。
2. ~~`/_/tamakyi` 是否保~~ → **已答:不保**。已从 sitemap 移除,robots 维持 Disallow。
3. **源站回源端口/隧道细节**:EO 与 CF tunnel 的 ingress 路由是否按 hostname 区分——决定 cloudflared 配置加一条路由即可(实施时我出精确 diff)
4. 迁移公告是否要做(首页横幅提示用户更新收藏/提问链接)
5. **搜索引擎验证 token 需替换**(本次代码审查新发现):`templates/base/header.html` 的 `google-site-verification`(636 行)与 `msvalidate.01`(7 行 + 637 行重复)是**绑定域名**的,新域验证后必须替换 content 值,否则 GSC/Bing 无法验证新站 → Site Move / Change of Address 无法提交。已加注释标记。
---
## 12. 批 1 实施记录(本地改动,2026-09-06 已完成)
**备份**:`.workbuddy/backup/domain-shiroko-20260906/`(9 个文件原样)
**替换规则**:`*.tama.guru` → `*.shiroko.one`;apex `tama.guru` → `shiroko.one`
| 文件 | 改动 |
|---|---|
| `static/robots.txt` | `Sitemap:` 行 → `box.shiroko.one` |
| `static/sitemap.xml` | 5 条 URL 全部换域;**移除 `/_/tamakyi` 条目**;**去重**(原 `https://box.tama.guru` 与 `.../` 重复);`lastmod` 全量刷新为 2026-09-06 以触发重抓 |
| `static/llms.txt` | 4 条站点链接 + 2 条资源链接换域 |
| `static/llms-full.txt` | 7 处换域(主域推荐、FAQ、站点地图、blog 更新日志链) |
| `templates/base/footer.html` | 6 条链接全换域(admin/notice/chat/drive/status/nav) |
| `templates/base/header.html` | umami 注释同步为 `mami.shiroko.one`(脚本 src 已先行改为新域);验证 token 处加迁移提醒注释 |
| `templates/home.html` | 3 处换域:站长箱链接、投票/Markdown 示例链、4 条 blog 文章链、探索页链 |
| `route/auth/register.go:64` | `Bloglink` 默认值 → `box.shiroko.one` |
| `internal/security/censor/text.go` | `TrustedHosts` **新增** `"shiroko.one"`;旧域 `tama.guru` **保留**(过渡期用户分享旧链接仍需判为可信,待旧域到期后再删) |
| `conf/app.sample.ini` | 补齐**缺失的必填项** `external_url`(conf.go:36 强制校验,原模板缺失会导致照抄即启动失败),示例指向新域 |
| `dev/eo-probe-ips.py`、`eo-probe-v2.py`、`eo-scan-all.py` | EO 回源探测脚本 `--host` 默认值 → `box.shiroko.one` |
| `internal/route/route.go` | **新增 `/index-now/{key}` 路由**(IndexNow 密钥文件,见 §12.1)。文件名用 `^[0-9a-f]{32}\.txt$` 白名单校验防路径穿越;配套回归测试 `internal/route/indexnow_route_test.go` |
**验证**:sitemap XML 解析通过(5 条、无重复);`go test ./templates/`、`./internal/security/censor/`、`./internal/route/` 通过;`route/auth`、`static`、`internal/conf` 带 overlay 编译通过。
### 12.1 IndexNow 密钥文件(迁移后加速新站收录,已实现)
用户在 `static/index-now/66e5e0911b0941f2ba7dbfbbd961e9be.txt` 放了 IndexNow key,但访问被 302 到首页。
**根因(重要,以后加任何根目录静态文件都会踩)**:`internal/route/route.go:138` 的 `flamego.Static` 中间件配置了 `Prefix: "/static"`,**只接管 `/static/...`**;而 `robots.txt`、`sitemap.xml`、`llms.txt`、`llms-full.txt`、`favicon.ico` 这些根目录文件**每一个都是单独注册的 `f.Get` handler**。新加的文件没有对应路由 → 落到 `f.NotFound` → `ctx.Redirect("/")` 返回 302。embed 本身没问题。
**修复**:新增 `f.Get("/index-now/{key}")`,文件名经 `^[0-9a-f]{32}\.txt$` 白名单校验(防路径穿越)后从 embed FS 读取,返回 `text/plain` + `max-age=86400`;校验失败或文件不存在返回 404(不再是 302)。
**提交 IndexNow 时的 keyLocation 填**:
```
https://box.shiroko.one/index-now/66e5e0911b0941f2ba7dbfbbd961e9be.txt
```
⚠️ 旧域 301 上线后,旧域的该路径会被 301 重定向,而搜索引擎校验密钥文件要求 **200 直出**,因此切换后请用新域的 keyLocation 重新提交。
---
## 附:本地代码改动的执行批次建议(批准后按批落地)
- ~~**批 1(P0 代码)**:C2/C3/C4/C5/C6/C8/C9 —— 纯本地仓库改动,可先行~~ → ✅ **已完成 2026-09-06**(见 §12)
- **批 2(配置)**:C1 + D 组 —— 需部署环境 app.ini + Vercel 控制台配合
- **批 3(切换)**:§6 301 载体 + §7 DNS/CDN 控制台操作 + §8 SEO 提交