feat(deploy): zd-host.sh 支持部署时轮换管理/同步令牌

渗透报告证明旧 NAVI_ADMIN_TOKEN / NAVI_SYNC_TOKEN 已在公网泄露
(/api/sync-info 曾明文回显 syncToken)。但本脚本只从旧容器继承 env,
轮换没有落地入口。

新增 NAVI_ROTATE_ADMIN_TOKEN / NAVI_ROTATE_SYNC_TOKEN:传入后覆盖
env 文件里的旧值,只打印长度不回显内容,最短 32 字符。
This commit is contained in:
HomeDash
2026-10-22 14:09:28 +08:00
parent dea722f51c
commit 19b4238cb1

View File

@ -104,7 +104,9 @@ echo "== 2/3 上传 =="
echo "== 3/3 远端切换(接受数秒闪断,失败自动回滚)=="
"${SSH[@]}" "TAG='$TAG' VER='$VER' STAMP='$STAMP' REMOTE_TAR='$REMOTE_TAR' \
DATA_DIR='$DATA_DIR' CERT_DIR='$CERT_DIR' \
NAVI_COOKIE_DOMAIN='${NAVI_COOKIE_DOMAIN:-}' NAVI_HOME_URL='${NAVI_HOME_URL:-}' bash -s" <<'REMOTE'
NAVI_COOKIE_DOMAIN='${NAVI_COOKIE_DOMAIN:-}' NAVI_HOME_URL='${NAVI_HOME_URL:-}' \
NAVI_ROTATE_ADMIN_TOKEN='${NAVI_ROTATE_ADMIN_TOKEN:-}' \
NAVI_ROTATE_SYNC_TOKEN='${NAVI_ROTATE_SYNC_TOKEN:-}' bash -s" <<'REMOTE'
set -euo pipefail
# 前置检查:必须已经是 host 模式的单容器入口,否则用错脚本会出事
@ -126,9 +128,36 @@ chmod 600 "/tmp/navi-host-${STAMP}.env"
CLEAN_PORTAL_PW=0
if grep -q '^PORTAL_PASSWORD=' "/tmp/navi-host-${STAMP}.env"; then
grep -v '^PORTAL_PASSWORD=' "/tmp/navi-host-${STAMP}.env" > "/tmp/navi-host-${STAMP}.env.new" && mv "/tmp/navi-host-${STAMP}.env.new" "/tmp/navi-host-${STAMP}.env"
CLEAN_PORTAL_PW=1
CLEAN_PORTAL_PW=1
fi
# ③ 令牌轮换:渗透报告证明旧 NAVI_ADMIN_TOKEN / NAVI_SYNC_TOKEN 已泄露
# (/api/sync-info 在公网明文回显过 syncToken),必须支持在部署时换新值。
# 以前本脚本只从旧容器继承 env,导致轮换无处落地。
# 用法:NAVI_ROTATE_ADMIN_TOKEN=<新值> NAVI_ROTATE_SYNC_TOKEN=<新值> bash deploy/zd-host.sh <ver>
# 只打印长度,不打印值。
if [ -n "${NAVI_ROTATE_ADMIN_TOKEN:-}" ]; then
if [ "${#NAVI_ROTATE_ADMIN_TOKEN}" -lt 32 ]; then
echo "!! NAVI_ROTATE_ADMIN_TOKEN 太短(${#NAVI_ROTATE_ADMIN_TOKEN} 字符),至少 32" >&2
exit 2
fi
grep -v '^NAVI_ADMIN_TOKEN=' "/tmp/navi-host-${STAMP}.env" > "/tmp/navi-host-${STAMP}.env.t" || true
echo "NAVI_ADMIN_TOKEN=${NAVI_ROTATE_ADMIN_TOKEN}" >> "/tmp/navi-host-${STAMP}.env.t"
mv "/tmp/navi-host-${STAMP}.env.t" "/tmp/navi-host-${STAMP}.env"
echo " 已轮换 NAVI_ADMIN_TOKEN(新值长度 ${#NAVI_ROTATE_ADMIN_TOKEN})"
fi
if [ -n "${NAVI_ROTATE_SYNC_TOKEN:-}" ]; then
if [ "${#NAVI_ROTATE_SYNC_TOKEN}" -lt 32 ]; then
echo "!! NAVI_ROTATE_SYNC_TOKEN 太短(${#NAVI_ROTATE_SYNC_TOKEN} 字符),至少 32" >&2
exit 2
fi
grep -v '^NAVI_SYNC_TOKEN=' "/tmp/navi-host-${STAMP}.env" > "/tmp/navi-host-${STAMP}.env.t" || true
echo "NAVI_SYNC_TOKEN=${NAVI_ROTATE_SYNC_TOKEN}" >> "/tmp/navi-host-${STAMP}.env.t"
mv "/tmp/navi-host-${STAMP}.env.t" "/tmp/navi-host-${STAMP}.env"
echo " 已轮换 NAVI_SYNC_TOKEN(新值长度 ${#NAVI_ROTATE_SYNC_TOKEN})"
fi
chmod 600 "/tmp/navi-host-${STAMP}.env"
# ② 跨子域单点登录所需变量:新版已移除代码里的写死默认值,
# 不显式提供的话登录 cookie 会退化成 host-only(登录后换子域就掉线)。
if ! grep -q '^PORTAL_COOKIE_DOMAIN=' "/tmp/navi-host-${STAMP}.env"; then