Appearance
🌐 部署私有 WEB 解密服务
PasswordReset 提供了基于 Docker 的私有 Web 解密服务,管理员可以在内网部署一个 Web 界面,让团队成员通过安全秘钥自助查询当日密码,无需登录服务器。
架构说明
Web 解密服务是无状态的——不需要挂载配置文件,服务仅根据用户传入的安全秘钥和当天日期实时派生密码。
┌──────────────────────────────────────────────────────────┐
│ Docker 容器 (时区: Asia/Shanghai) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ PasswordReset-server (:12397) │ │
│ │ ├── /api/password → 密码查询 API (POST) │ │
│ │ ├── /api/time → 服务器时间 (GET) │ │
│ │ ├── /api/health → 健康检查 (GET) │ │
│ │ └── /* → 前端静态页面 (Vue 3 SPA) │ │
│ └─────────────────────────────────────────────────────┘ │
│ 内置: builtinKey (编译时注入,与客户端绑定) │
└──────────────────────────────────────────────────────────┘::: important 两个关键要求
- builtinKey 一致:服务端和客户端的
builtinKey必须相同(由同一源码编译,或构建时传入相同的BUILTIN_KEY) - 时间一致:密码按日期生成,容器时间必须与密码重置服务器时间一致(默认北京时间) :::
- 无状态:无需挂载配置文件,开箱即用
- builtinKey 内置:编译时注入二进制,不接受运行时修改,客户端和服务端天然绑定
- 后端:Go HTTP 服务,接收安全秘钥,结合 builtinKey 和当天日期实时派生密码
- 前端:Vue 3 单页应用,密码默认脱敏显示,点击复制按钮获取完整密码
- 安全:服务端日志不记录密码,前端不缓存密码明文
密码生成原理
用户输入安全秘钥 (userKey)
↓
SHA256(builtinKey + ":" + userKey + ":" + 当天日期)
↓
base64 编码 → 最终密码- builtinKey:编译时注入,客户端和服务端相同
- userKey:每用户独立的安全密钥,添加用户时设置
- 日期:当天 YYYYMMDD(确保每天密码不同)
- 日期参与 SHA256 运算,不是拼接在密码后面,保证每天密码完全不同
快速部署
公共查询平台
如果不需要私有部署,可以直接使用官方公共查询平台:https://encrypt.liumou.site/
公共平台已内置与官方预编译客户端一致的 builtinKey,直接输入安全秘钥即可查询当日密码,无需任何部署。
TIP
公共平台适合临时查询或小规模使用。如需在内网部署、限制访问来源或自定义时区,请参考下方私有部署方式。
使用公共镜像(推荐)
公共镜像已内置与官方预编译客户端一致的 builtinKey,开箱即用:
bash
docker run -d \
--name passwordreset-server \
--restart unless-stopped \
-p 12397:12397 \
-e TZ=Asia/Shanghai \
ccr.ccs.tencentyun.com/passwordreset/server:latest| 参数 | 说明 |
|---|---|
-p 12397:12397 | 宿主机端口:容器端口,可修改左侧宿主机端口 |
-e TZ | 容器时区,默认 Asia/Shanghai,影响密码按日生成 |
| 无数据库、无配置文件,纯无状态服务 |
Docker Compose 部署
完整的 Docker Compose 配置见根目录 docker-compose.yml,同目录下 env.sh 文件可直接导入环境变量:
bash
# env.sh
# ===========================================
# PasswordReset Web 解密服务 - 环境变量配置
# ===========================================
# 时区(默认: Asia/Shanghai)
TZ="Asia/Shanghai"yaml
# =============================================================================
# PasswordReset Web 解密服务
# 访问端口: 12397 (Web 界面 + API)
# 功能: 用户通过安全秘钥自助查询当日密码
# 说明: 无状态服务,无需挂载配置文件,无需数据库
# 使用方式:
# docker compose up -d
# 环境变量:
# TZ 时区(默认: Asia/Shanghai),影响密码生成日期
# =============================================================================
services:
passwordreset: # Web 解密服务(前端 SPA + 后端 API)
image: ccr.ccs.tencentyun.com/passwordreset/server:latest # 公共镜像
container_name: passwordreset-server # 容器名称
network_mode: bridge # 桥接网络
ports:
- "12397:12397" # 宿主机端口:容器端口
environment:
- TZ=${TZ:-Asia/Shanghai} # 时区设置,影响密码按日生成
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:12397/api/health"]
interval: 30s # 健康检查间隔
timeout: 10s # 检查超时
retries: 3 # 重试次数
start_period: 10s # 启动宽限期
restart: unless-stopped # 容器退出策略部署管理命令
bash
# 启动服务
docker compose up -d
# 查看运行状态
docker compose ps
# 查看实时日志
docker compose logs -f
# 重启服务
docker compose restart
# 停止服务
docker compose down
# 更新到最新镜像
docker compose pull && docker compose up -d自行构建镜像
如果使用自行编译的客户端(非官方预编译版本),需要使用相同的 BUILTIN_KEY 构建 Web 服务镜像:
bash
# 克隆仓库
git clone https://gitee.com/liumou_site/PasswordReset.git
cd PasswordReset
# 方式1:通过构建参数传入 builtinKey(与客户端编译时相同)
docker build \
--build-arg BUILTIN_KEY="你的builtinKey-hex字符串" \
-t passwordreset-server .
# 方式2:通过 builtin.key 文件传入
echo -n "你的builtinKey-hex字符串" > builtin.key
docker build -t passwordreset-server .
# 运行
docker run -d \
--name passwordreset-server \
--restart unless-stopped \
-p 12397:12397 \
passwordreset-serverWARNING
builtinKey 在编译时注入二进制,客户端和服务端必须使用相同的值才能生成一致的密码。如果使用官方预编译客户端,直接使用公共镜像即可;如果自行编译客户端,构建镜像时必须传入相同的 BUILTIN_KEY。
使用方式
- 浏览器访问
http://<服务器IP>:12397 - 输入安全秘钥(即添加用户时设置的 userKey)
- 点击"查询今日密码"
- 密码默认脱敏显示(如
20****25),点击 👁 眼睛图标可切换明文/脱敏 - 点击"复制密码"按钮获取完整密码到剪贴板
生产环境建议
HTTPS 反向代理
建议在生产环境中使用 Nginx 反向代理并启用 HTTPS:
nginx
server {
listen 443 ssl;
server_name password.example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
location / {
proxy_pass http://127.0.0.1:12397;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}安全建议
| 措施 | 说明 |
|---|---|
| 内网部署 | 仅在内网开放,不暴露到公网 |
| HTTPS | 防止秘钥和密码在传输中被窃听 |
| 访问控制 | 通过 Nginx 或防火墙限制来源 IP |
| 日志脱敏 | 服务端日志不记录密码明文 |
| 前端脱敏 | 密码默认遮罩显示,需主动点击才可查看明文 |
| 时间同步 | 确保容器与密码重置服务器时间一致(默认北京时间) |
健康检查
服务提供 /api/health 健康检查端点:
bash
curl http://localhost:12397/api/health
# 返回: {"status":"ok"}API 参考
POST /api/password
查询当日密码。
请求:
json
{
"key": "用户安全秘钥"
}成功响应:
json
{
"password": "base64编码的SHA256哈希值",
"date": "2026-05-26"
}错误响应:
json
{
"error": "缺少 key 参数"
}GET /api/time
获取服务器时间。
响应:
json
{
"timezone": "CST",
"date": "2026-05-26",
"time": "14:30:00",
"unix": 1748238600,
"display_name": "2026-05-26 14:30:00"
}GET /api/health
健康检查端点。
响应:
json
{
"status": "ok"
}常见问题
Q: 为什么不需要在运行时传入密钥?
A: builtinKey 在编译时已注入二进制文件中,不需要运行时注入。公共镜像的 builtinKey 与官方预编译客户端一致,直接使用即可。只有自行编译客户端时,才需要在构建镜像时传入相同的 BUILTIN_KEY。
Q: 时区不一致会怎样?
A: 密码基于日期参与 SHA256 运算生成(SHA256(builtinKey:userKey:YYYYMMDD))。如果容器时区与密码重置服务器不同,可能导致跨日时查询到的密码不匹配。例如服务器在北京时间 5 月 26 日 00:30 重置了密码,但 UTC 时区的容器仍认为是 5 月 25 日,查询结果就会错误。公共镜像默认设置为北京时间(Asia/Shanghai),一般无需修改。
Q: 忘记安全秘钥怎么办?
A: 安全秘钥即添加用户时设置的 userKey。如果遗忘,无法通过系统恢复,需要重新添加用户并设置新的密钥。
Q: 多人使用是否安全?
A: 每个用户使用各自的安全密钥(userKey)查询对应的密码,不同密钥查询不同用户的密码结果。一个用户的密钥泄露不影响其他用户。建议在内网部署并通过 HTTPS + IP 白名单加强安全性。