跳到主要内容

管理后台紧急登录说明

本文面向实施维护人员,说明如何配置、使用和验证 ONES 管理后台的紧急登录。

紧急登录只用于 IDS 不可用、但必须进入管理后台处理问题的场景。正常情况下请优先使用 IDS 登录。

1. 使用前提

紧急登录需要提前配置,未配置时页面会提示:

当前环境未配置紧急帐号或入口已关闭。

紧急登录账号必须绑定一个已有的管理后台管理员身份。也就是说,对应用户应已经在管理后台 访问名单 中,并且状态为启用。

2. 进入操作容器

生产环境在部署机执行:

./ones-ai-k8s.sh

进入容器后切到部署目录:

cd /data/ones/ones-ai-k8s

3. 准备管理员身份信息

如果已经知道管理员的组织和用户 UUID,可直接使用。

如果不知道,可以查询当前访问名单:

MYSQL_PWD="$(sed -n 's/^mysqlPassword:[[:space:]]*//p' config/private.yaml | head -1)"

kubectl -n ones exec mysql-cluster-mysql-0 -c mysql -- \
env MYSQL_PWD="$MYSQL_PWD" \
mysql -uones -N ones_admin -e \
"SELECT org_uuid, region_uuid, org_user_uuid, auth_user_uuid, display_name_snapshot, email_snapshot, status FROM admin_access_grant WHERE deleted_at_ms=0;"

选择一条 statusactive 的记录。

4. 生成密码 Hash

紧急登录密码不要明文写入配置文件,需要写入 bcrypt hash。

可以用支持 bcrypt 的工具生成,例如:

python3 - <<'PY'
import bcrypt
password = input("Emergency password: ").encode()
print(bcrypt.hashpw(password, bcrypt.gensalt(rounds=12)).decode())
PY

请只临时记录明文密码,验证完成后从聊天记录、命令历史、临时文件中清理。

5. 修改配置

先备份:

cp config/private.yaml config/private.yaml.bak-$(date +%Y%m%d-%H%M%S)

编辑:

vi config/private.yaml

增加或修改以下配置:

onesAdminEmergencyUsername: <紧急登录用户名>
onesAdminEmergencyPasswordHash: '<bcrypt hash>'
onesAdminEmergencyExpiresAt: '2026-06-23T12:00:00Z'
onesAdminEmergencyAllowedCIDRs: <允许登录的来源CIDR>
onesAdminEmergencyOrgUUID: <org_uuid>
onesAdminEmergencyRegionUUID: <region_uuid>
onesAdminEmergencyOrgUserUUID: <org_user_uuid>
onesAdminEmergencyAuthUserUUID: <auth_user_uuid>
onesAdminEmergencyDisplayName: <显示名称>
onesAdminEmergencyEmail: <邮箱>
onesAdminEmergencyOperatorNote: <运维说明>

配置要点:

  • onesAdminEmergencyExpiresAt 必须是 RFC3339 UTC 时间,例如 2026-06-23T12:00:00Z
  • onesAdminEmergencyAllowedCIDRs 建议只填写堡垒机、VPN 出口或本次验证来源,不要长期使用 0.0.0.0/0
  • 如果经过 NodePort、负载均衡或反向代理,后端看到的来源 IP 可能是代理地址,需要按实际来源调整 CIDR。
  • onesAdminEmergencyPasswordHash 只写 bcrypt hash,不要写明文密码。

6. 应用配置

执行:

make setup-installer-api
kubectl -n ones-installer rollout restart deploy/installer-api
kubectl -n ones-installer rollout status deploy/installer-api

确认渲染结果:

kubectl -n ones-installer exec deploy/installer-api -- \
sed -n '34,54p' /data/ones/ones-ai-k8s/submodules/ones-admin/api/conf/config.yaml

应能看到 auth.emergency 下的用户名、过期时间、CIDR 和用户身份信息。

7. 在容器内验证

按要求,验证建议在 installer-api 容器内完成。

进入容器:

kubectl -n ones-installer exec -it deploy/installer-api -- bash

检查是否已启用:

curl -sS http://127.0.0.1:8080/ones-admin/api/auth/emergency/status

期望看到:

{"configured":true,"expired":false}

验证登录:

COOKIE=/tmp/ones-admin-emergency.cookie

curl -sS -c "$COOKIE" \
-H 'Content-Type: application/json' \
-X POST http://127.0.0.1:8080/ones-admin/api/auth/emergency/login \
--data '{"username":"<紧急登录用户名>","password":"<明文密码>","reason":"紧急登录验证"}'

再验证 session:

curl -sS -b "$COOKIE" \
http://127.0.0.1:8080/ones-admin/api/auth/session

返回内容中应包含:

"login_type":"emergency"

验证登出:

curl -sS -o /dev/null -w "%{http_code}\n" -b "$COOKIE" -c "$COOKIE" \
-X POST http://127.0.0.1:8080/ones-admin/api/auth/logout

返回 204 表示登出成功。

8. 页面使用方式

浏览器打开:

http://<管理后台访问地址>/ones-admin/

在登录页点击 紧急登录入口,填写:

  • 用户名
  • 密码
  • 操作原因

登录成功后即可进入管理后台。所有紧急登录行为都会记录审计日志。

9. 使用后关闭

紧急登录使用完毕后,建议立即关闭。

做法是清空以下配置,或把 onesAdminEmergencyExpiresAt 改成已过期时间:

onesAdminEmergencyUsername: ""
onesAdminEmergencyPasswordHash: ""
onesAdminEmergencyExpiresAt: ""

然后重新执行:

make setup-installer-api
kubectl -n ones-installer rollout restart deploy/installer-api
kubectl -n ones-installer rollout status deploy/installer-api

再次检查:

kubectl -n ones-installer exec deploy/installer-api -- \
curl -sS http://127.0.0.1:8080/ones-admin/api/auth/emergency/status

返回 configured:false 表示已关闭。

10. 常见问题

提示未配置紧急帐号

检查 onesAdminEmergencyUsernameonesAdminEmergencyPasswordHashonesAdminEmergencyOrgUUIDonesAdminEmergencyOrgUserUUIDonesAdminEmergencyAuthUserUUID 是否都已配置,并确认已重启 installer-api

提示紧急帐号已过期

检查 onesAdminEmergencyExpiresAt 是否已经早于当前 UTC 时间。

提示来源 IP 不允许

检查 onesAdminEmergencyAllowedCIDRs。如果通过代理访问,需要填写后端实际看到的代理来源 IP。

密码错误

确认输入的是明文密码,不是 bcrypt hash。配置文件中保存的是 hash,登录页面输入的是明文密码。

登录后仍然无权限

检查绑定的 org_user_uuid 是否在 admin_access_grant 中,并且状态为 active