98 lines
7.2 KiB
Markdown
98 lines
7.2 KiB
Markdown
# 22 · 服务域名迁移:dsh.alotbuy.com → alotbuy.com
|
||||
|
|
|
|||
|
|
- 日期:2026-09-10
|
|||
|
|
- 触发:用户裁定「服务域名改为 alotbuy.com」,并在两条路径中选定 **路径 ②:走 Cloudflare 代理(橙云,零 DNS 改动)**
|
|||
|
|
- 结论一句话:**已完成迁移** —— 门户 = `https://alotbuy.com`,用户实例 = `https://<用户名>.alotbuy.com`;旧域名 `dsh.alotbuy.com` 全部 **301** 到新域名(含用户名映射);证书 `alotbuy.com + *.alotbuy.com` 已签发且**续期演练参数已加固**。
|
|||
|
|
- 状态:**已上线**;遗留:CF SSL 模式建议人工确认 Full (Strict)、全员需重新登录
|
|||
|
|
|
|||
|
|
> **TL;DR**|**结论**:域名迁移完成:门户 **`alotbuy.com`**、用户实例 **`<用户名>.alotbuy.com`**;旧域 `dsh.alotbuy.com` 全部 **301**(含用户名映射)。
|
|||
|
|
> **关键**:走 Cloudflare 代理(橙云、零 DNS 改动);签 `alotbuy.com + *.alotbuy.com` 通配证书(**DNS-01 传播必须 60 s**)+ CF 真实 IP 还原。
|
|||
|
|
> **状态**:✅ 已上线(含回滚步骤)
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、决策与前置侦察(实测)
|
|||
|
|
|
|||
|
|
| 项 | 结果 |
|
|||
|
|
|---|---|
|
|||
|
|
| `alotbuy.com` A 记录 | **已指向本机** `47.77.182.89`,经 **Cloudflare 代理(橙云)** |
|
|||
|
|
| `alotbuy.com` 当时内容 | **nginx 404(空站)** → 根域未被占用,接管无冲突 ✅ |
|
|||
|
|
| `*.alotbuy.com` | **通配记录已存在**(橙云)→ 用户子域天然可解析 ✅ |
|
|||
|
|
| 同域其它记录 | `gao`/`mao`→154.40.35.3、`www`→apex、`work`→apex、`alimail/smtp`→mxhichina、MX/TXT(SPF) → **迁移不触碰这些** |
|
|||
|
|
| CF token 权限 | **仅 DNS(Zone:DNS:Edit)**:能改记录、能签 DNS-01 证书;**不能读写 zone 设置**(SSL 模式需人工确认) |
|
|||
|
|
| CF 回源端口(实测 `ss`) | 全部 **443**,无 80 连接 → CF 处于 Full(或 Strict)模式,**CF→源站已加密**,无明文风险 ✅ |
|
|||
|
|
| 备案 | alotbuy.com 已在阿里云备案(否则子域无法访问)✅ |
|
|||
|
|
|
|||
|
|
## 二、执行步骤(含踩坑)
|
|||
|
|
|
|||
|
|
### 1. 签发通配证书(DNS-01)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare.ini \
|
|||
|
|
--dns-cloudflare-propagation-seconds 60 --non-interactive --agree-tos \
|
|||
|
|
--cert-name alotbuy.com -d alotbuy.com -d '*.alotbuy.com'
|
|||
|
|
```
|
|||
|
|
产物:`/etc/letsencrypt/live/alotbuy.com/{fullchain,privkey}.pem`(有效期至 2026-12-09,已配置自动续期)。
|
|||
|
|
|
|||
|
|
> ⚠️ **踩坑 1(重要)**:首次签发**失败**(`No TXT record found at _acme-challenge.alotbuy.com`)。certbot 日志显示 TXT 记录**创建成功**,只是**默认只等 10 秒传播**(CF 上实测 ~10 s 才可见,正好卡边界)。写临时 TXT 探测证实记录可被 Google/CF 解析到(无通配 CNAME 劫持),**把传播等待改为 60 s 后即成功**。
|
|||
|
|
> ⚠️ **踩坑 2(续期)**:`certbot` 只把该参数写进**新证书**的 renewal conf;**旧证书(dsh.alotbuy.com)仍是默认 10 s** → 会在 ~60 天后续期失败。已给两个 renewal conf 都补上 `dns_cloudflare_propagation_seconds = 60`。
|
|||
|
|
|
|||
|
|
### 2. nginx vhost(新域名)
|
|||
|
|
|
|||
|
|
- 新增 `/www/server/panel/vhost/nginx/alotbuy.com.conf`:`server_name alotbuy.com www.alotbuy.com *.alotbuy.com`,80 段**代理**(不 301,兼容 CF 任一模式),443 段用新证书;
|
|||
|
|
- 继承 dsh 站点的三项优化:`proxy_buffering off`(流式)、`gzip_proxied any`(930 KB bundle 压缩)、`/assets/` 长缓存;
|
|||
|
|
- **CF 真实 IP 还原**:`set_real_ip_from <CF 全部回源段>` + `real_ip_header CF-Connecting-IP`(写在 server 块内,避免全局生效;否则日志/风控里全是 CF 机房 IP)。
|
|||
|
|
> 踩坑 3:`set_real_ip_from` 写在 vhost 文件顶层会落到 **http 上下文作用于全局**,务必放进 server 块。
|
|||
|
|
|
|||
|
|
### 3. 切换域名配置(drain + 重启)
|
|||
|
|
|
|||
|
|
脚本:`/opt/dsh/switch-domain-alotbuy.sh`(幂等、带备份、**drain 用按 pid 结束而非 `pkill -f`**——后者会杀掉自身 ssh 会话,档案 20 已踩过)
|
|||
|
|
```
|
|||
|
|
env: DSHS_BASE_DOMAIN=alotbuy.com
|
|||
|
|
DSHS_COOKIE_DOMAIN=.alotbuy.com (备份 /etc/dshs.env.bak-20260910-2332)
|
|||
|
|
停服务 → 结束残留 dsh 子进程/scope → 起服务(残留实例数 = 0)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 旧域名 301(保留用户名映射)
|
|||
|
|
|
|||
|
|
`dsh.alotbuy.com.conf` 改为纯跳转,使用 **map + 通配 server_name**(正则 server_name 实测**不匹配**,踩坑 4):
|
|||
|
|
```nginx
|
|||
|
|
map $host $alotbuy_new_host {
|
|||
|
|
default alotbuy.com;
|
|||
|
|
~^(?<label>[^.]+)\.dsh\.alotbuy\.com$ $label.alotbuy.com;
|
|||
|
|
}
|
|||
|
|
server { listen 80; server_name dsh.alotbuy.com *.dsh.alotbuy.com; return 301 https://$alotbuy_new_host$request_uri; }
|
|||
|
|
server { listen 443 ssl; server_name dsh.alotbuy.com *.dsh.alotbuy.com; ssl_certificate …dsh.alotbuy.com…; return 301 https://$alotbuy_new_host$request_uri; }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 三、验证结果
|
|||
|
|
|
|||
|
|
| 检查 | 结果 |
|
|||
|
|
|---|---|
|
|||
|
|
| 门户(经 CF) | `https://alotbuy.com/login.html` → **200** |
|
|||
|
|
| 用户子域(经 CF,未登录) | `https://admin.alotbuy.com/` → **401**(正常:需登录)✅ 说明编排器已把该 Host 识别为用户子域 |
|
|||
|
|
| 旧域名跳转 | `dsh.alotbuy.com/...` → **301 → https://alotbuy.com/...**;`admin.dsh.alotbuy.com` → **301 → https://admin.alotbuy.com/**;`x.dsh.*` → `x.alotbuy.com`(通用映射) |
|
|||
|
|
| 源站证书校验 | `ssl_verify_result=0`(链有效,CF Full (Strict) 亦可通过) |
|
|||
|
|
| 服务状态 | `active`/`enabled`,编排器正常,残留实例 0(用户重新进入时按需拉起) |
|
|||
|
|
| 自动续期 | 两个证书 renewal conf 均含 `dns_cloudflare_propagation_seconds = 60` |
|
|||
|
|
|
|||
|
|
## 四、回滚
|
|||
|
|
|
|||
|
|
| 项 | 回滚 |
|
|||
|
|
|---|---|
|
|||
|
|
| 域名配置 | `cp /etc/dshs.env.bak-20260910-2332 /etc/dshs.env` → 跑 drain(停服务→清实例→起服务) |
|
|||
|
|
| nginx | `cp /www/server/panel/vhost/nginx/{dsh.alotbuy.com.conf.bak-*-pre-redirect,alotbuy.com.conf}` 还原/删除 → `nginx -t && nginx -s reload` |
|
|||
|
|
| 证书 | 保留(不影响) |
|
|||
|
|
|
|||
|
|
## 五、遗留与注意事项
|
|||
|
|
|
|||
|
|
1. **CF SSL 模式建议人工确认为 Full (Strict)**:token 无 zone 设置权限,只能由用户在 Cloudflare 面板确认(当前实测回源走 443,已是 Full 级别;Strict 仅多一层源站证书校验,而我们的证书有效,可直接切换)。同时建议开启 **Always Use HTTPS**。
|
|||
|
|
2. **全员需重新登录**:`COOKIE_DOMAIN` 由 `.dsh.alotbuy.com` 变为 `.alotbuy.com`,旧 Cookie 失效。
|
|||
|
|
3. **Cookie 覆盖面扩大**:`.alotbuy.com` 意味着该 Cookie 会随请求发往 `alotbuy.com` 下**所有子域**(含 `gao`/`mao`/`work`/`www`)。若日后希望收窄,需改为在 `<用户名>.alotbuy.com` 上设置 host-only Cookie(涉及代码改动)。
|
|||
|
|
4. **宝塔面板会重写 vhost**:在面板里保存站点配置可能抹掉 `proxy_buffering off` / `gzip_proxied any` / `real_ip` 等自定义指令 → 流式或真实 IP 异常时先回来检查。
|
|||
|
|
5. 未完成项(独立跟踪):档案 21 §三 的 **A1 禁用 HMR**、**A2 catch-all 默认站点**。
|
|||
|
|
|
|||
|
|
## 六、红线遵守
|
|||
|
|
|
|||
|
|
- 未触碰 R1(不升级 dsh)与 R2(不改官方 dsh 主程序);仅改 nginx 站点配置、编排器环境变量与 DNS/证书。
|
|||
|
|
- 全程保留可回滚副本(env / vhost / renewal conf 各有 `*.bak-*`)。
|
|||
|
|
- 未改动 alotbuy.com 的 MX/邮件/TXT 记录与 `gao`/`mao`/`work` 等既有子域记录。
|