设备授权服务器
| .idea | ||
| cmd/server | ||
| internal | ||
| web | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| QUICKSTART.md | ||
| README.md | ||
License Management System
一个基于 Go 和 Web 前端的许可证管理系统。
功能特性
- 🔐 用户认证(管理员登录)
- 📱 设备管理(创建、更新、列表查询)
- 📜 License 签发和验证(ECDSA 签名)
- 🔄 自动续期和手动审批
- 🎨 现代化 Web 前端界面
快速开始
1. 编译项目
go build -o licensing-cotton cmd/server/main.go
2. 启动服务
./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)
- 公钥公开:前端可查看,用于验证签名
- 密钥持久化:重启服务时自动加载已有密钥
查看公钥
- 登录管理界面
- 进入 "系统设置" 标签
- 在 "Ed25519 公钥" 区域查看公钥(SSH 和 Base64 两种格式)
密钥备份
⚠️ 重要:请定期备份 keys/ 目录,丢失私钥将无法签发新 License!
# 备份密钥
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:致命错误(程序终止)
查看日志
# 查看实时日志
tail -f logs/licensing-cotton.log
# 查看最近的错误
grep ERROR logs/licensing-cotton.log
# 搜索特定内容
grep "device_id" logs/licensing-cotton.log
API 接口
所有接口同时支持 /api/* 和 /* 两种路径(向后兼容)。
认证接口
POST /api/login
{
"username": "admin",
"password": "admin123"
}
返回:
{
"message": "登录成功",
"token": "...",
"role": "admin"
}
设备管理接口
POST /api/device/manage (需要管理员权限)
{
"device_id": "dev-001",
"expiration": "2030-01-01T00:00:00Z"
}
GET /api/device/list (需要管理员权限)
返回所有设备列表
License 接口
POST /api/license/sign (需要管理员权限)
{
"device_id": "dev-001"
}
返回签名的 License
POST /api/license/verify
{
"device_id": "dev-001",
"expiration": "2030-01-01T00:00:00Z",
"sign_date": "2025-01-01T00:00:00Z",
"signature": "..."
}
POST /api/license/renew
{
"device_id": "dev-001",
"expiration": ""
}
GET /api/license/public-key
获取 Ed25519 公钥(无需认证)
返回:
{
"ssh_format": "ssh-ed25519 AAAAC3...",
"base64": "AAAAC3NzaC1l...",
"algorithm": "Ed25519",
"usage": "用于验证 License 签名"
}
管理接口
POST /api/admin/pending_requests (需要管理员权限)
查看所有待审批的续期请求
POST /api/admin/handle_request (需要管理员权限)
{
"device_id": "dev-001",
"expiration": "2030-01-01T00:00:00Z",
"approved_by": "admin",
"action": "approve" // 或 "reject"
}
POST /api/admin/allow_auto_renew (需要管理员权限)
{
"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
部署
后台运行
nohup ./licensing-cotton > /var/log/licensing-cotton.out 2>&1 &
Systemd 服务(推荐)
创建 /etc/systemd/system/licensing-cotton.service:
[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
启动服务:
sudo systemctl daemon-reload
sudo systemctl enable licensing-cotton
sudo systemctl start licensing-cotton
开发
运行测试
go test ./...
代码格式
go fmt ./...
许可证
MIT License