# 管理后台紧急登录说明

URL: https://docs.ones.cn/deploy/configure/ones-admin/ones-admin-emergency-login

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

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

## 1. 使用前提

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

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

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

## 2. 进入操作容器

生产环境在部署机执行：

```sh
./ones-ai-k8s.sh
```

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

```sh
cd /data/ones/ones-ai-k8s
```

## 3. 准备管理员身份信息

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

如果不知道，可以查询当前访问名单：

```sh
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;"
```

选择一条 `status` 为 `active` 的记录。

## 4. 生成密码 Hash

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

可以用支持 bcrypt 的工具生成，例如：

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

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

## 5. 修改配置

先备份：

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

编辑：

```sh
vi config/private.yaml
```

增加或修改以下配置：

```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. 应用配置

执行：

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

确认渲染结果：

```sh
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` 容器内完成。

进入容器：

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

检查是否已启用：

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

期望看到：

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

验证登录：

```sh
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：

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

返回内容中应包含：

```json
"login_type":"emergency"
```

验证登出：

```sh
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. 页面使用方式

浏览器打开：

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

在登录页点击 `紧急登录入口` ，填写：

- 用户名
- 密码
- 操作原因
登录成功后即可进入管理后台。所有紧急登录行为都会记录审计日志。

## 9. 使用后关闭

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

做法是清空以下配置，或把 `onesAdminEmergencyExpiresAt` 改成已过期时间：

```yaml
onesAdminEmergencyUsername: ""
onesAdminEmergencyPasswordHash: ""
onesAdminEmergencyExpiresAt: ""
```

然后重新执行：

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

再次检查：

```sh
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. 常见问题

### 提示未配置紧急帐号

检查 `onesAdminEmergencyUsername` 、 `onesAdminEmergencyPasswordHash` 、 `onesAdminEmergencyOrgUUID` 、 `onesAdminEmergencyOrgUserUUID` 、 `onesAdminEmergencyAuthUserUUID` 是否都已配置，并确认已重启 `installer-api` 。

### 提示紧急帐号已过期

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

### 提示来源 IP 不允许

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

### 密码错误

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

### 登录后仍然无权限

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