Files
opsx d584b64813 feat(security): 默认账号随机初始密码(不再硬编码 admin123)
参考 lokistack 的实现:

1. 首次启动生成 16 位随机密码(大小写+数字,排除 0/O/1/l/I 易混淆字符)
   - 4 个默认账号共用:admin / dba / auditor / developer
   - 写入数据目录 initial-admin-password.txt(0600)
   - 打印到启动日志(含账号列表、密码、文件路径、docker/kubectl 获取命令)

2. 支持 ADMIN_INIT_PASSWORD 环境变量覆盖(自动化部署 / 需要固定密码时)

3. 生成失败直接 log.Fatalf 退出,不降级到公开默认口令

4. 批量导入用户 BatchImportUsers:空密码不再默认 admin123,
   改为随机 14 位(新增 genPassword),保证每个导入用户密码不可预测

5. 幂等:已存在的账号不重建、不改密码;只有缺失的账号才创建

6. imagePullPolicy: IfNotPresent → Always
   原因:latest tag 配 IfNotPresent 会导致节点一直复用缓存的旧镜像,
        新 push 的镜像不生效(本次实测踩到:Pod imageID 仍是旧 digest)

7. 文档
   - README 新增「首次部署获取默认账号密码」章节(含 4 账号角色表 + 3 种获取方式)
   - docker-compose.yml 加 ADMIN_INIT_PASSWORD 环境变量
   - kubernetes/deployment.yaml 加 env 注释

验证(清空 DB 后全新 seed):
  镜像 sha256:eaf0affd8d93
  /app/data/initial-admin-password.txt  199B  权限 0600
  内容含 "适用账号: [admin dba auditor developer]" + 随机密码
  启动日志完整打印获取方式
  登录实测:admin / dba / developer 用新密码均返回 access_token;
           admin123 登录失败(已失效)
  二进制 strings:admin123 命中 0
2026-10-26 17:37:21 +00:00

242 lines
7.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OpsxSQL — SQL 审核与数据变更审批平台
<p align="center">
<strong>安全、高效的企业级数据库自助查询 + 数据变更审批平台</strong>
</p>
---
## 项目简介
OpsxSQL 是一个面向 DBA 和开发人员的数据库管理平台,核心定位:
- **自助查询** — 支持 MySQL / PostgreSQL / Redis / MongoDB 多类型数据库的在线查询
- **数据变更审批流** — SQL 变更工单提交 → 审核 → 执行的完整审批流程
- **SQL 审核** — 内置 26+ 条审核规则,覆盖语法、性能、安全、命名规范等维度
- **实例管理** — 统一管理多种数据库实例,支持分组和标签
## 技术栈
| 层级 | 技术 |
|------|------|
| 后端 | Go 1.26 + Gin + GORM + SQLite |
| 前端 | React 19 + TypeScript + Vite + Tailwind CSS + shadcn/ui |
| 认证 | JWT + LDAP 集成 |
| 数据库 | SQLite(零依赖,开箱即用) |
## 功能模块
### 🗄️ 实例管理
- MySQL / PostgreSQL / Redis / MongoDB 实例注册与连接测试
- 实例分组管理
- 库表结构浏览(字段、索引详情)
### 📝 自助查询
- 在线 SQL 编辑器(CodeMirror)
- 语法高亮 + 自动补全
- 查询历史记录(上限 500 条/用户)
- 慢查询日志分析
### ✅ 工单审批
- SQL 变更工单创建(支持 DDL / DML)
- 多级审批流程(developer → dba → admin)
- 工单状态追踪与通知
- 执行结果确认
### 🔍 SQL 审核
- 26 条内置审核规则(MySQL 11 / PostgreSQL 7 / Redis 4 / MongoDB 4)
- 规则类型:syntax / performance / safety / security / naming / DDL / DML / DQL / DCL
- 规则启用/禁用 + 自定义配置
### 👥 用户与权限
- 四级角色:admin / dba / developer / auditor
- LDAP 集成登录
- 基于角色的数据隔离
### 🔔 通知渠道
- 飞书 Webhook 通知
- 钉钉 Webhook 通知
- 工单状态变更自动推送
### 📊 其他
- Dashboard 运营数据总览
- 审计日志
- 公告管理
- 系统设置
## 项目结构
```
sql-platform/
├── backend/ # Go 后端
│ ├── cmd/server/ # 入口 + seed
│ │ ├── main.go # 启动入口
│ │ └── seed.go # 默认数据初始化
│ ├── internal/
│ │ ├── handler/ # 请求处理器
│ │ ├── middleware/ # 中间件(认证/权限/日志)
│ │ ├── model/ # 数据模型
│ │ └── service/ # 业务逻辑
│ ├── config/ # 配置管理
│ └── router/ # 路由注册
├── frontend/ # React 前端
│ └── src/
│ ├── api/ # API 请求封装
│ ├── components/ # 通用组件
│ │ └── ui/ # shadcn/ui 组件
│ ├── pages/ # 页面组件(27 个)
│ └── lib/ # 工具函数
├── tests/ # 集成测试
├── run.sh # 启动/停止脚本
├── docker-compose.yml # Docker Compose 部署(单镜像)
├── Dockerfile # 单镜像多阶段构建(前端+后端+gh-ost)
└── kubernetes/ # K8s 部署(install.sh 一键 + 清单)
```
## 快速开始
### 前置要求
- Go 1.26+
- Node.js 18+
- npm 或 yarn
### 方式一:Docker Compose(推荐,单镜像前后端同源)
```bash
git clone https://gitee.com/opsx-tools/opsxsql.git
cd opsxsql
# 生成密钥(必填;SECRET_KEY 部署后不可更换,否则已加密的实例/LDAP 密码无法解密)
export SECRET_KEY=$(openssl rand -hex 32)
# 可选;不设则生产模式自动生成随机 JWT 密钥并持久化到数据卷
export JWT_SECRET=$(openssl rand -hex 32)
docker compose up -d --build
```
访问 **http://localhost:9000**(单镜像,Gin 同时托管前端静态资源与 API)。
自定义端口:`OPSXSQL_PORT=18000 docker compose up -d`。
安全基线:非 root 运行、no-new-privileges、cap_drop ALL、/health 健康检查、资源限额、日志轮转。
### 方式二:Kubernetes 一键部署
```bash
# 默认部署(镜像 opsxsql:latest)
bash kubernetes/install.sh
# 指定镜像 + 入口
IMAGE=registry.example.com/opsxsql:v1.0.0 bash kubernetes/install.sh --nodeport
IMAGE=registry.example.com/opsxsql:v1.1.0 bash kubernetes/install.sh --ingress opsxsql.example.com
```
install.sh 幂等:自动建命名空间/生成并复用密钥/应用 PVC+Deployment+Service,等待就绪后打印访问方式。
注意:SQLite 单写者,Deployment 固定 **单副本 + Recreate**(脚本已内置);详见 `kubernetes/README.md`。
### 方式三:本地开发
```bash
./run.sh start # 后端 9000 + 前端 5173
```
后端 **http://localhost:9000**,前端 dev server **http://localhost:5173**(vite 代理 /api)。
### 默认账号
首次启动自动初始化以下账号(密码均为 `admin123`):
| 用户名 | 角色 | 说明 |
|--------|------|------|
| admin | admin | 超级管理员 |
| dba | dba | 数据库管理员 |
| auditor | auditor | 审计员(只读) |
| developer | developer | 开发者 |
### 测试
```bash
# 后端集成测试
cd tests
pip install pytest pytest-asyncio httpx
pytest -v
# 前端类型检查
cd frontend
npx tsc --noEmit
```
## 首次部署获取默认账号密码
首次启动会生成 **16 位随机密码**(不再固定 `admin123`),以下默认账号**共用该密码**:
| 账号 | 角色 | 说明 |
|------|------|------|
| `admin` | 超级管理员 | 全权限 |
| `dba` | DBA管理员 | 数据库实例与变更 |
| `auditor` | 审计员 | 审核工单 |
| `developer` | 开发者 | 提交 SQL 工单 |
密码同时:
- 打印到**启动日志**(仅首次,日志轮转后就没了)
- 写入数据目录 `initial-admin-password.txt`(权限 `0600`)
### 获取方式(推荐第 1 种)
```bash
# Docker Compose
docker compose exec <服务名> cat /app/data/initial-admin-password.txt
docker compose logs <服务名> | grep -A8 "已创建默认账号"
docker cp <容器名>:/app/data/initial-admin-password.txt ./
# Kubernetes
kubectl -n sql exec deploy/opsxsql -- cat /app/data/initial-admin-password.txt
kubectl -n sql logs deploy/opsxsql | grep -A8 "已创建默认账号"
kubectl -n sql cp <pod>:/app/data/initial-admin-password.txt ./
```
### 自定义密码(跳过随机生成)
```bash
# Docker Compose:部署前设置
export ADMIN_INIT_PASSWORD='your-strong-password'
docker compose up -d
# Kubernetes:在 deployment env 中加 ADMIN_INIT_PASSWORD(或用 Secret 注入)
```
### 说明
| 项 | 说明 |
|----|------|
| 幂等 | 已存在同名账号时**不重建、不改密码**;只有缺失的账号才创建 |
| 生成失败 | 随机密码生成失败时**直接退出**,不降级到公开默认口令 |
| 轮转 | 本平台暂无自助改密接口;改密请用管理员 `POST /api/v1/users/:id/reset-password` |
| 清理 | 确认所有账号改密后可删除 `initial-admin-password.txt` |
## 版本历史
| 版本 | 说明 |
|------|------|
| v0.4.0 | 弹框架构重构 + 审核规则 API + LDAP 配置 + 全量 seed |
| v0.3.2 | 通知渠道对接 + TicketCreatePage 重写 + 默认用户初始化 |
| v0.3.1 | Go 后端迁移 + 工单审批流程 + 实例管理 |
| v0.2.0 | 前端 UI 重构 + shadcn/ui 组件化 |
| v0.1.0 | 项目初始化 + 基础 CRUD |
## 代码统计
- 后端 Go:29 文件,8,000+ 行
- 前端 TypeScript:131 文件,27,000+ 行
- 集成测试:21 文件,1,100+ 行
- **总计 36,000+ 行**
## 许可证
MIT License
---
<p align="center">
<a href="https://gitee.com/opsx-tools/opsxsql">Gitee 仓库</a>
</p>