# License Management System 一个基于 Go 和 Web 前端的许可证管理系统。 ## 功能特性 - 🔐 用户认证(管理员登录) - 📱 设备管理(创建、更新、列表查询) - 📜 License 签发和验证(ECDSA 签名) - 🔄 自动续期和手动审批 - 🎨 现代化 Web 前端界面 ## 快速开始 ### 1. 编译项目 ```bash go build -o licensing-cotton cmd/server/main.go ``` ### 2. 启动服务 ```bash ./licensing-cotton ``` 服务将监听在 `0.0.0.0:8895` 端口。 ### 3. 访问前端界面 打开浏览器访问:`http://localhost:8895` 默认管理员账号: - 用户名:`admin` - 密码:`admin123` ## 前端界面使用 ### 登录 - 访问首页会自动显示登录界面 - 输入管理员账号密码登录 ### 设备管理 - **设备列表**:查看所有设备及其到期状态 - **创建/更新设备**:添加新设备或修改已有设备的到期时间 ### 签发 License - 输入设备 ID 签发 License - 系统会自动生成签名并返回完整的 License JSON ### 续期审批 - 查看所有待审批的续期请求 - 点击"批准"或"拒绝"按钮处理申请 - 批准时自动设置续期时间为 1 年后 ### 系统设置 - **自动续期开关**:开启后所有设备可以自动续期 1 小时 - 关闭后需要管理员手动审批续期请求 - **Ed25519 公钥**:查看用于验证 License 签名的公钥 ## 密钥管理 ### 自动生成密钥对 首次启动服务时,系统会自动生成 Ed25519 密钥对: - **私钥**:保存到 `keys/licensing-key`(加密保护,仅服务器可读) - **公钥**:保存到 `keys/licensing-key.pub`(可安全分发) ### 密钥说明 - **Ed25519 算法**:现代、快速、安全 - **私钥加密**:使用密码短语加密存储(默认: 2718) - **公钥公开**:前端可查看,用于验证签名 - **密钥持久化**:重启服务时自动加载已有密钥 ### 查看公钥 1. 登录管理界面 2. 进入 **"系统设置"** 标签 3. 在 **"Ed25519 公钥"** 区域查看公钥(SSH 和 Base64 两种格式) ### 密钥备份 ⚠️ **重要**:请定期备份 `keys/` 目录,丢失私钥将无法签发新 License! ```bash # 备份密钥 tar -czf keys-backup-$(date +%Y%m%d).tar.gz keys/ ``` ## 日志系统 ### 日志特性 系统已集成统一的日志管理系统: - ✅ **分级日志**:支持 `DEBUG`、`INFO`、`WARN`、`ERROR` 和 `FATAL` - ✅ **自动轮转**:当日志文件达到 10MB 时自动轮转 - ✅ **文件保留**:保留最近 5 个日志文件 - ✅ **双输出**:同时写入文件和标准输出 ### 日志文件位置 ``` logs/licensing-cotton.log # 当前日志 logs/licensing-cotton.log.1 # 上次轮转的日志 logs/licensing-cotton.log.2 # 更早的日志 ... ``` ### 日志级别 - **DEBUG**:调试信息(默认不显示) - **INFO**:一般信息(系统启动、密钥加载等) - **WARN**:警告信息(初始化失败但可继续) - **ERROR**:错误信息(查询失败、解析错误等) - **FATAL**:致命错误(程序终止) ### 查看日志 ```bash # 查看实时日志 tail -f logs/licensing-cotton.log # 查看最近的错误 grep ERROR logs/licensing-cotton.log # 搜索特定内容 grep "device_id" logs/licensing-cotton.log ``` ## API 接口 所有接口同时支持 `/api/*` 和 `/*` 两种路径(向后兼容)。 ### 认证接口 #### POST /api/login ```json { "username": "admin", "password": "admin123" } ``` 返回: ```json { "message": "登录成功", "token": "...", "role": "admin" } ``` ### 设备管理接口 #### POST /api/device/manage (需要管理员权限) ```json { "device_id": "dev-001", "expiration": "2030-01-01T00:00:00Z" } ``` #### GET /api/device/list (需要管理员权限) 返回所有设备列表 ### License 接口 #### POST /api/license/sign (需要管理员权限) ```json { "device_id": "dev-001" } ``` 返回签名的 License #### POST /api/license/verify ```json { "device_id": "dev-001", "expiration": "2030-01-01T00:00:00Z", "sign_date": "2025-01-01T00:00:00Z", "signature": "..." } ``` #### POST /api/license/renew ```json { "device_id": "dev-001", "expiration": "" } ``` #### GET /api/license/public-key 获取 Ed25519 公钥(无需认证) 返回: ```json { "ssh_format": "ssh-ed25519 AAAAC3...", "base64": "AAAAC3NzaC1l...", "algorithm": "Ed25519", "usage": "用于验证 License 签名" } ``` ### 管理接口 #### POST /api/admin/pending_requests (需要管理员权限) 查看所有待审批的续期请求 #### POST /api/admin/handle_request (需要管理员权限) ```json { "device_id": "dev-001", "expiration": "2030-01-01T00:00:00Z", "approved_by": "admin", "action": "approve" // 或 "reject" } ``` #### POST /api/admin/allow_auto_renew (需要管理员权限) ```json { "enabled": "true" } ``` ## 技术栈 **后端:** - Go 1.21+ - SQLite 数据库 - ECDSA 和 Ed25519 签名算法 - 统一的日志系统(分级、轮转) **前端:** - HTML5 + CSS3 - 原生 JavaScript (无依赖) - 响应式设计 ## 安全特性 - 密码使用 bcrypt 加密 - Token 基于 JWT - License 使用 Ed25519 签名 - 管理员权限验证 ## 目录结构 ``` licensing-cotton/ ├── cmd/ │ └── server/ │ └── main.go # 主程序入口 ├── internal/ │ ├── config/ # 配置 │ ├── database/ # 数据库操作 │ ├── handlers/ # HTTP 处理器 │ ├── logger/ # 日志系统 │ ├── models/ # 数据模型 │ └── security/ # 安全相关 ├── web/ │ └── index.html # 前端页面 ├── keys/ # 密钥目录(自动生成) │ ├── licensing-key # 私钥(加密) │ └── licensing-key.pub # 公钥 ├── logs/ # 日志目录(自动生成) │ ├── licensing-cotton.log # 当前日志 │ ├── licensing-cotton.log.1 # 历史日志 │ └── ... ├── go.mod └── README.md ``` ## 部署 ### 后台运行 ```bash nohup ./licensing-cotton > /var/log/licensing-cotton.out 2>&1 & ``` ### Systemd 服务(推荐) 创建 `/etc/systemd/system/licensing-cotton.service`: ```ini [Unit] Description=Licensing Cotton After=network.target [Service] Type=simple WorkingDirectory=/path/to/licensing-cotton ExecStart=/path/to/licensing-cotton/licensing-cotton Restart=always StandardOutput=append:/var/log/licensing-cotton.out StandardError=append:/var/log/licensing-cotton.err [Install] WantedBy=multi-user.target ``` 启动服务: ```bash sudo systemctl daemon-reload sudo systemctl enable licensing-cotton sudo systemctl start licensing-cotton ``` ## 开发 ### 运行测试 ```bash go test ./... ``` ### 代码格式 ```bash go fmt ./... ``` ## 许可证 MIT License