@@@@@ /www/server/panel/vhost/nginx/alotbuy.com.conf
# alotbuy.com —— DSH 平台站点（2026-09-10 建立，档案 21 场景延伸）
# 走 Cloudflare 代理（橙云），故：
#   1) 用 set_real_ip_from + CF-Connecting-IP 还原真实客户端 IP（否则日志/风控里全是 CF 的 IP）
#   2) 80 端口「代理」而非 301：CF 若为 Flexible，源站 301 会造成 CF 侧循环；改成代理两种模式都能用
#      —— 但**必须**把 CF 的 SSL/TLS 模式设为 Full (Strict)，否则 CF→源站是明文（凭据裸奔）
#   3) 继承 dsh 站点的关键优化：proxy_buffering off（流式）、gzip_proxied any（930KB bundle 压缩）


# ---- HTTP：代理（不用 301，兼容 CF Flexible；Full (Strict) 下 80 不会被用到）----
server {
    # CF 回源 IP → 还原真实客户端 IP（仅本 server 生效）
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 104.16.0.0/13;
    set_real_ip_from 104.24.0.0/14;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 131.0.72.0/22;
    set_real_ip_from 2400:cb00::/32;
    set_real_ip_from 2606:4700::/32;
    set_real_ip_from 2803:f800::/32;
    set_real_ip_from 2405:b500::/32;
    set_real_ip_from 2405:8100::/32;
    set_real_ip_from 2a06:98c0::/29;
    set_real_ip_from 2c0f:f248::/32;
    real_ip_header CF-Connecting-IP;
    listen 80;
    server_name alotbuy.com www.alotbuy.com *.alotbuy.com;
        # 2026-09-13：3 个跳转桩页已删除（档案 80 第 7 项 / 档案 81 §四）—— 保留 301 防旧书签 404
        location = /desktop.html { return 301 /portal.html; }
        location = /plugins.html { return 301 /portal.html#/plugins; }
        location = /skills.html  { return 301 /portal.html#/skills; }
    location / {
        proxy_pass http://127.0.0.1:3080;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 3600s;
        proxy_buffering off;
        proxy_cache off;
        gzip_proxied any;
    }
    access_log /www/wwwlogs/alotbuy.com.log;
    error_log  /www/wwwlogs/alotbuy.com.error.log;
}

# ---- HTTPS：门户 + 用户实例子域 ----
server {
    # CF 回源 IP → 还原真实客户端 IP（仅本 server 生效）
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 104.16.0.0/13;
    set_real_ip_from 104.24.0.0/14;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 131.0.72.0/22;
    set_real_ip_from 2400:cb00::/32;
    set_real_ip_from 2606:4700::/32;
    set_real_ip_from 2803:f800::/32;
    set_real_ip_from 2405:b500::/32;
    set_real_ip_from 2405:8100::/32;
    set_real_ip_from 2a06:98c0::/29;
    set_real_ip_from 2c0f:f248::/32;
    real_ip_header CF-Connecting-IP;
    listen 443 ssl;
    http2 on;
    server_name alotbuy.com www.alotbuy.com *.alotbuy.com;
    ssl_certificate     /etc/letsencrypt/live/alotbuy.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/alotbuy.com/privkey.pem;

        # 2026-09-13：3 个跳转桩页已删除（档案 80 第 7 项 / 档案 81 §四）—— 保留 301 防旧书签 404
        location = /desktop.html { return 301 /portal.html; }
        location = /plugins.html { return 301 /portal.html#/plugins; }
        location = /skills.html  { return 301 /portal.html#/skills; }
    # ── DSH 覆盖网络中继（自研 relay）────────────────────────────────
    # 只在既有 443 server 块里加一个 location：不新增监听口、不新增证书、不动门户其它路径。
    # `/status` 不在此前缀下 ⇒ 不会被代理出去（relay 端也只认 RELAY_PATH 前缀）。
    location /dshs-relay {
        proxy_pass http://127.0.0.1:20080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffering off;
    }
    location / {
        proxy_pass http://127.0.0.1:3080;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 3600s;
        # 流式（dsh 回复/思考逐块下发）+ 反代压缩 + 解除缓冲
        proxy_buffering off;
        proxy_cache off;
        proxy_send_timeout 3600s;
        gzip_proxied any;
    }
    # 内容哈希命名的静态资源 → 长缓存
    location ~* ^/assets/ {
        proxy_pass http://127.0.0.1:3080;
        proxy_set_header Host              $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_buffering off;
        gzip_proxied any;
        expires 30d;
    }
    access_log /www/wwwlogs/alotbuy.com.log;
    error_log  /www/wwwlogs/alotbuy.com.error.log;
}
@@@@@ /www/server/panel/vhost/nginx/dsh.alotbuy.com.conf
# dsh.alotbuy.com —— 旧域名（2026-09-10 平台迁移到 alotbuy.com 后仅做 301 跳转）
# 用 map + 通配 server_name（比正则 server_name 更稳），保留用户名映射：
#   admin.dsh.alotbuy.com → admin.alotbuy.com
#   dsh.alotbuy.com       → alotbuy.com
# map 必须位于 http 上下文 —— 面板 vhost 文件正是被 include 在 http{} 内，故写在本文件顶层。

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     /etc/letsencrypt/live/dsh.alotbuy.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dsh.alotbuy.com/privkey.pem;
    return 301 https://$alotbuy_new_host$request_uri;
}
@@@@@ /www/server/panel/vhost/nginx/relay-direct.conf
# relay-direct.alotbuy.com —— 覆盖网络 **443/TCP 兜底入口**（序④ · L2「去门户站点 conf」）
#
# 为什么要有这个块（而不是往门户块里再加一条 location）：
#   门户块 `/www/server/panel/vhost/nginx/alotbuy.com.conf` 由宝塔面板管理 —— 面板重写配置、
#   或人工改坏它，都会**同时**打掉门户与 relay 入口（两者共用一个失败域）。
#   独立 `server_name` ⇒ 本入口与门户块**互不影响**（nginx 精确名优先于 `*.alotbuy.com` 通配）。
#
# ⛔ 零新增：不新增监听口（仍 443/TCP）、不新增证书（复用 `*.alotbuy.com` 那张）、
#   不新增域名/解析记录（`*.alotbuy.com` 泛解析天然覆盖本名）、不新增花费、不新增依赖。
# ⛔ 不碰门户 443 块、不碰 relay 进程（relay 仍是 `127.0.0.1:20080` 的纯 `ws://`，TLS 由 nginx 终结）。
# ✅ 暴露面**只收窄**：本块只承载下面两个端点，其余路径一律 404（不把门户任何路径复制过来）。
#
# 维护：`nginx -t` 通过后再 `nginx -s reload`；回滚 = 删掉本文件后同两步。
# 变更记录：2026-09-17 建立（交接单_443兜底_20260917.md §5 S1）。

server {
    listen 443 ssl;
    http2 on;                                  # ⚠️ 与门户一致；curl 验收必须带 --http1.1（否则假 404）
    server_name relay-direct.alotbuy.com;
    ssl_certificate     /etc/letsencrypt/live/alotbuy.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/alotbuy.com/privkey.pem;

    # ── 中继入口（正文与门户块 `/dshs-relay` 逐字一致，只改 server_name / 证书两处变量）──
    location /dshs-relay {
        proxy_pass http://127.0.0.1:20080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffering off;
    }

    # ── 引导目录端点（约定「引导地址 = 中继入口同源」；缺了它兜底入口拿不到签名目录）──
    # 只放行这一个路径（`=` 精确匹配）—— 目录端点只有这一个（`directory.ts` 的 DIRECTORY_PATH）。
    #
    # ⚠️ `Host` 必须改写成既有目录 origin：平台（3080）**先按 Host 做租户路由、再进路由表**，
    #    直接用兜底子域回源会命中 `404 {"error":"unknown_user"}`（实测 2026-09-17 09:00）。
    #    这是「同源」在入口层的等价翻译 —— 发的就是门户今天在发的同一个请求，**不扩大任何权限**
    #    （本 location 只放行这一个公开只读路由；本块其余路径一律 404）。
    location = /dshs-overlay/bootstrap {
        proxy_pass http://127.0.0.1:3080;
        proxy_set_header Host              alotbuy.com;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_buffering off;
    }

    # ── 兜底：本块**只**承载上面两个端点。未知路径 404（可诊断；⛔ 不 return 444，
    #    444 是「这个域名不存在」的语义，会让"路径写错"看起来像"域名没配"）──
    location / { return 404; }

    # 说明：本块**故意不复制**门户块的 `set_real_ip_from` 那一组 —— 本块只服务两个机器端点，
    # 不依赖客户端 IP（无 ACL / 无限速 / 无风控）；日志里出现 CF 回源 IP 不影响可诊断性。
    access_log /www/wwwlogs/relay-direct.log;
    error_log  /www/wwwlogs/relay-direct.error.log;
}
@@@@@ 查找 dsh 用户名映射文件
2:# 用 map + 通配 server_name（比正则 server_name 更稳），保留用户名映射：
5:# map 必须位于 http 上下文 —— 面板 vhost 文件正是被 include 在 http{} 内，故写在本文件顶层。
7:map $host $alotbuy_new_host {
@@@@@ worker/env 文件清单
-rw------- 1 root root 684 Sep 13 15:46 /etc/dshs.env
-rw------- 1 root root 529 Sep 17 08:17 /etc/dshs-worker.env
--- systemctl cat dshs-worker ---
# /etc/systemd/system/dshs-worker.service
[Unit]
Description=DSHS cluster worker agent (this host = 47, local users' instances)
After=network-online.target

[Service]
Type=simple
EnvironmentFile=/etc/dshs-worker.env
ExecStart=/usr/local/bin/node /opt/dshs/lib/cli.js worker --port 19100 --host 127.0.0.1 --host-id w-47 --instance-host 127.0.0.1 --log-level info
Restart=on-failure
RestartSec=3
KillMode=mixed

[Install]
WantedBy=multi-user.target
--- systemctl cat dshs-relay ---
# /etc/systemd/system/dshs-relay.service
[Unit]
Description=dshs relay (loopback-only WebSocket relay for the DSH overlay network)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/dsh-relay
ExecStart=/usr/local/bin/node /opt/dsh-relay/lib/net/relay/main.js --port 20080 --keys-file /etc/dshs/relay-keys.json --base 19000 --span 3000 --max-hosts 0
Restart=always
RestartSec=1
TimeoutStopSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=dshs-relay

[Install]
WantedBy=multi-user.target

# /etc/systemd/system/dshs-relay.service.d/40-content-probe.conf
# 覆盖网络 序㉔（2026-09-17）：内容面**活性自证** —— relay 侧块级内容寻址的判据落点。
#
# 背景：`OBS-17` 第三个判据要求 `local + peer` 命中 ≥ `CONTENT_TIER_HITS_MIN`(=1)。
@@@@@ 两机 SEEDS/RELAY env 命中
