fix(security): retire default-credential surface (yanxue-20260914-cma-defaultcred-code-fix)
- Login.vue: no prefilled default creds; no anonymous entity enumeration on mount - deploy.sh: readiness polling (0.5s/30s cap) replaces fixed sleep 3; login smoke reads same-source 600 secret file, missing file = explicit abort - 19 verify/check/gen_report scripts: shared _admin_creds() loader (CMA_ADMIN_ENV -> ops .secrets -> profile copy); no hardcoded creds - tests: single TEST_USER_PASSWORD fixture constant; docs: pointer to 600 secret file; removed 4 legacy .bak + pycache residue
This commit is contained in:
@@ -59,7 +59,22 @@ echo " ✓ 服务重启完成"
|
||||
# ── 部署后冒烟测试 ──
|
||||
echo ""
|
||||
echo "===== 冒烟测试 ====="
|
||||
sleep 3
|
||||
# 就绪轮询(2026-09-14 cma-defaultcred-code-fix):journalctl 实测冷启动就绪间隔 2/2/3/3/5s,
|
||||
# 固定 sleep 3 会让贴边/超时的冷启动误判为冒烟红;改为每 0.5s 探一次 /health,命中即进入判据。
|
||||
# 轮询用尽仍不健康 → 下面的健康判据照常判 ❌(不静默放行)。
|
||||
# 探测上限可由 SMOKE_READY_MAX 覆盖(离线演练用短上限,生产不设即 30s)。
|
||||
SMOKE_READY_MAX="${SMOKE_READY_MAX:-30}"
|
||||
HEALTH_URL="http://127.0.0.1:8010/health"
|
||||
READY_TRIES=$(( SMOKE_READY_MAX * 2 ))
|
||||
READY_TRY=0
|
||||
READY_T0=$(date +%s)
|
||||
while [ "$READY_TRY" -lt "$READY_TRIES" ]; do
|
||||
if curl -sf "$HEALTH_URL" > /dev/null 2>&1; then break; fi
|
||||
sleep 0.5
|
||||
READY_TRY=$((READY_TRY + 1))
|
||||
done
|
||||
READY_ELAPSED=$(( $(date +%s) - READY_T0 ))
|
||||
echo " ⏱ 就绪探测: 耗时 ${READY_ELAPSED}s / 轮询 ${READY_TRY} 次(上限 ${SMOKE_READY_MAX}s,命中健康即停)"
|
||||
SMOKE_FAIL=0
|
||||
if curl -sf http://127.0.0.1:8010/health > /dev/null 2>&1; then
|
||||
echo " ✅ 后端健康检查通过"
|
||||
@@ -78,9 +93,26 @@ else
|
||||
echo " ❌ Schema不一致,请检查: cd /root/cma-management/backend && venv/bin/python3 scripts/schema_check.py"
|
||||
SMOKE_FAIL=1
|
||||
fi
|
||||
# 凭据同源(2026-09-14 cma-defaultcred-code-fix):登录冒烟不再硬编码默认账号/口令 —— 轮换后必须自动跟随。
|
||||
# 落点:$CMA_ADMIN_ENV 或 600 密钥文件(默认 wecom-ops 主副本);缺失/缺键 → 显式报错并中止,禁止静默退回默认口令。
|
||||
CMA_ADMIN_ENV_FILE="${CMA_ADMIN_ENV:-/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env}"
|
||||
if [ ! -f "$CMA_ADMIN_ENV_FILE" ]; then
|
||||
echo " ❌ 管理员凭据文件缺失: $CMA_ADMIN_ENV_FILE"
|
||||
echo " 请准备 600 权限密钥文件(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS),或用 CMA_ADMIN_ENV 指定路径"
|
||||
exit 1
|
||||
fi
|
||||
set -a
|
||||
# shellcheck disable=SC1090
|
||||
. "$CMA_ADMIN_ENV_FILE"
|
||||
set +a
|
||||
if [ -z "${CMA_ADMIN_USER:-}" ] || [ -z "${CMA_ADMIN_PASS:-}" ]; then
|
||||
echo " ❌ 凭据文件缺少 CMA_ADMIN_USER / CMA_ADMIN_PASS: $CMA_ADMIN_ENV_FILE"
|
||||
exit 1
|
||||
fi
|
||||
echo " ℹ️ 登录冒烟凭据来源: $CMA_ADMIN_ENV_FILE(账号 ${CMA_ADMIN_USER},口令不回显)"
|
||||
TOKEN=$(curl -s -X POST http://127.0.0.1:8010/api/cma/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"admin123","entity_id":1}' | python3 -c "import sys,json; print(json.load(sys.stdin).get('token',''))" 2>/dev/null)
|
||||
-d "{\"username\":\"${CMA_ADMIN_USER}\",\"password\":\"${CMA_ADMIN_PASS}\",\"entity_id\":1}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('token',''))" 2>/dev/null)
|
||||
if [ -n "$TOKEN" ]; then
|
||||
echo " ✅ 登录API通过"
|
||||
if curl -sf -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8010/api/cma/kpis > /dev/null 2>&1; then
|
||||
|
||||
Reference in New Issue
Block a user