Enforce mTLS and least-privilege runtime boundaries while adding repeatable MySQL 8.4 and Docker smoke checks that require no production secrets.
3.7 KiB
管理端 mTLS 部署
account.osglab.com 在同一个 TLS server 中同时承载移动端 API 和管理端。
由于 TLS 握手发生在 HTTP 路径匹配之前,配置必须使用 server 级
ssl_verify_client optional:普通客户端不提供证书时仍可正常访问,只有
/admin、/admin/、/v1/admin 和其子路径要求验证成功。
CA 与证书
- 为管理客户端创建独立私有 CA,不要复用公网服务端证书 CA 或其他内部 CA。
- CA 私钥离线保存;不要放入仓库、OpenResty 主机或容器镜像。
- 管理客户端证书使用短有效期和唯一密钥,并限制为 TLS Client Authentication
(
clientAuth) 用途。 - 仅将 CA 证书链(不含任何私钥)部署到:
/www/server/openresty/conf/mtls/admin-client-ca.pem - CA 文件由 OpenResty 运行用户只读,目录不可由应用进程或非特权用户写入。
- 更新 CA 文件后先运行
openresty -t,成功后再平滑重载。若需要立即吊销证书, 应另外配置并维护ssl_crl;当前配置只依据证书链和有效期验证。
不要把客户端证书、客户端私钥、CA 私钥或生产证书标识提交到仓库。 计划轮换与紧急处置步骤见 ROTATION.md。
上游信任边界
OpenResty 仅在管理路径且 $ssl_client_verify = SUCCESS 时向 Ktor 设置固定头:
X-OSG-mTLS-Verified: SUCCESS
客户端传入的同名头会被覆盖;其他路径会删除该头。Ktor 只能把这个头作为“边缘已验证”
信号,不能信任客户端提供的证书相关头,也不能用 DN、CN 或证书正文做隐式授权。
后端端口必须继续只监听 127.0.0.1:18080,否则攻击者可绕过边缘伪造该头。
mTLS 只证明客户端持有受信证书,管理接口仍应执行应用层身份认证、授权和审计。
一次性管理员 Bootstrap
首次部署前运行 ./gradlew generateAdminCredentials,将生成的 runtime 文件仅临时写入
1Panel/Compose 环境,并同时设置:
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
秘密。
验证
将测试域名解析到目标边缘后执行:
# 无证书:管理路径必须是 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。
部署后可在受信设备运行不含登录凭据的自动验收:
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 密钥。