# 管理端 mTLS 部署 `account.osglab.com` 在同一个 TLS `server` 中同时承载移动端 API 和管理端。 由于 TLS 握手发生在 HTTP 路径匹配之前,配置必须使用 server 级 `ssl_verify_client optional`:普通客户端不提供证书时仍可正常访问,只有 `/admin`、`/admin/`、`/v1/admin` 和其子路径要求验证成功。 ## CA 与证书 1. 为管理客户端创建独立私有 CA,不要复用公网服务端证书 CA 或其他内部 CA。 2. CA 私钥离线保存;不要放入仓库、OpenResty 主机或容器镜像。 3. 管理客户端证书使用短有效期和唯一密钥,并限制为 TLS Client Authentication (`clientAuth`) 用途。 4. 仅将 CA 证书链(不含任何私钥)部署到: `/www/server/openresty/conf/mtls/admin-client-ca.pem` 5. CA 文件由 OpenResty 运行用户只读,目录不可由应用进程或非特权用户写入。 6. 更新 CA 文件后先运行 `openresty -t`,成功后再平滑重载。若需要立即吊销证书, 应另外配置并维护 `ssl_crl`;当前配置只依据证书链和有效期验证。 不要把客户端证书、客户端私钥、CA 私钥或生产证书标识提交到仓库。 计划轮换与紧急处置步骤见 [ROTATION.md](ROTATION.md)。 ## 上游信任边界 OpenResty 仅在管理路径且 `$ssl_client_verify = SUCCESS` 时向 Ktor 设置固定头: ```text X-OSG-mTLS-Verified: SUCCESS ``` 客户端传入的同名头会被覆盖;其他路径会删除该头。Ktor 只能把这个头作为“边缘已验证” 信号,不能信任客户端提供的证书相关头,也不能用 DN、CN 或证书正文做隐式授权。 后端端口必须继续只监听 `127.0.0.1:18080`,否则攻击者可绕过边缘伪造该头。 mTLS 只证明客户端持有受信证书,管理接口仍应执行应用层身份认证、授权和审计。 ## 一次性管理员 Bootstrap 首次部署前运行 `./gradlew generateAdminCredentials`,将生成的 runtime 文件仅临时写入 1Panel/Compose 环境,并同时设置: ```text ADMIN_ENABLED=true ADMIN_BOOTSTRAP_ENABLED=true ``` 确认初始管理员已创建且可以登录后,必须将 `ADMIN_BOOTSTRAP_ENABLED` 改回 `false`, 并从 1Panel、Compose 环境和部署文件中永久删除 `ADMIN_BOOTSTRAP_OPERATOR_ID`、`ADMIN_BOOTSTRAP_USERNAME`、 `ADMIN_BOOTSTRAP_PASSWORD_HASH`、`ADMIN_BOOTSTRAP_TOTP_SECRET_BASE32`。 日常运行只保留 `ADMIN_ENABLED=true`。重启后再次验证登录,确保服务不再依赖 Bootstrap 秘密。 ## 验证 将测试域名解析到目标边缘后执行: ```sh # 无证书:管理路径必须是 404。 curl -i https://account.osglab.com/admin curl -i https://account.osglab.com/v1/admin # 有效管理证书:请求应到达 Ktor,状态码由管理接口决定。 curl -i --cert admin-client.pem --key admin-client-key.pem \ https://account.osglab.com/v1/admin # 无证书的普通移动端 API:响应应与变更前一致。 curl -i https://account.osglab.com/health # 即使客户端伪造信任头,无证书访问管理路径仍必须是 404。 curl -i -H 'X-OSG-mTLS-Verified: SUCCESS' \ https://account.osglab.com/v1/admin ``` 还应使用由非管理 CA 签发或已过期的客户端证书确认返回 404,并在 Ktor 测试端点确认: 管理请求只收到固定值 `SUCCESS`,普通 API 不收到 `X-OSG-mTLS-Verified`。 部署后可在受信设备运行不含登录凭据的自动验收: ```sh ADMIN_CLIENT_CERT=/secure/path/admin-client.pem \ ADMIN_CLIENT_KEY=/secure/path/admin-client-key.pem \ bash deploy/verify-admin.sh ``` 脚本验证公开健康检查、无证书隐藏、伪造边缘头拦截、有效证书访问,以及 HSTS/CSP 安全响应头;它不会读取或传输管理员密码和 TOTP 密钥。