321 lines
7.6 KiB
Markdown
321 lines
7.6 KiB
Markdown
# 玩玩云 v1.1.0 更新总结
|
||
|
||
**发布日期**: 2025-11-13
|
||
**版本**: v1.1.0
|
||
**提交记录**: ac9f1c7
|
||
|
||
---
|
||
|
||
## 🎉 本次更新内容
|
||
|
||
### 1. 🔐 安全增强 - 防爆破保护系统
|
||
|
||
#### 登录防爆破保护
|
||
- **限制策略**: 5次失败尝试/15分钟
|
||
- **封锁时长**: 30分钟
|
||
- **保护维度**:
|
||
- IP地址维度(防止同一IP多次尝试)
|
||
- 用户名维度(防止针对特定账号的攻击)
|
||
- **技术实现**:
|
||
- 新增 `RateLimiter` 类
|
||
- 使用内存存储(TTL机制)
|
||
- 自动清理过期记录
|
||
|
||
#### 分享密码防爆破保护
|
||
- **限制策略**: 10次失败尝试/10分钟
|
||
- **封锁时长**: 20分钟
|
||
- **保护维度**: IP + 分享码组合
|
||
- **应用场景**:
|
||
- `/api/share/:code/verify` - 密码验证
|
||
- 防止暴力破解分享密码
|
||
|
||
#### 反向代理支持
|
||
- 支持读取 `X-Forwarded-For` 头
|
||
- 正确识别真实客户端IP
|
||
- 适配 Nginx/Caddy 等反向代理
|
||
|
||
#### 安全日志
|
||
```javascript
|
||
[防爆破] 拦截登录尝试 - IP: xxx.xxx.xxx.xxx, 原因: IP被封锁
|
||
[防爆破] 封锁Key: login:username:admin, 失败次数: 5, 封锁时长: 30分钟
|
||
[防爆破清理] 已清理 12 个过期尝试记录, 3 个过期封锁记录
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 🔧 部署优化 - 上传工具修复
|
||
|
||
#### 问题描述
|
||
更新脚本执行 `git pull` 时会删除 `upload-tool` 目录,但由于 `.gitignore` 排除了 `dist/*.exe`,导致更新后上传工具丢失。
|
||
|
||
#### 解决方案
|
||
在 `install.sh` 更新流程中添加检查逻辑:
|
||
|
||
```bash
|
||
# 检查并重新下载上传工具(如果需要)
|
||
if [[ ! -f "${PROJECT_DIR}/upload-tool/dist/玩玩云上传工具.exe" ]]; then
|
||
print_info "检测到上传工具丢失,正在重新下载..."
|
||
build_upload_tool
|
||
else
|
||
FILE_SIZE=$(stat -c%s "${PROJECT_DIR}/upload-tool/dist/玩玩云上传工具.exe")
|
||
if [[ $FILE_SIZE -lt 30000000 ]]; then
|
||
print_warning "上传工具文件大小异常,正在重新下载..."
|
||
build_upload_tool
|
||
fi
|
||
fi
|
||
```
|
||
|
||
#### 功能特性
|
||
- ✅ 自动检测上传工具是否存在
|
||
- ✅ 验证文件大小确保完整性(>30MB)
|
||
- ✅ 自动从直链下载:`http://a.haory.top/e/e82/玩玩云上传工具.exe`
|
||
- ✅ 最多重试3次,确保下载成功
|
||
|
||
---
|
||
|
||
### 3. 🎨 界面优化
|
||
|
||
#### 首页更新
|
||
- **版本标识**: "v1.0 生产就绪版本" → "版本号 V1.0"
|
||
- **功能描述**: 明确说明支持 SFTP 和本地存储双模式
|
||
- **统计卡片**:
|
||
- 移除 "100%开源免费"
|
||
- 移除 "Docker 一键部署"
|
||
- 新增 "双模式 - SFTP + 本地存储"
|
||
- **页脚简化**: 移除不可点击的导航链接
|
||
|
||
#### 功能说明优化
|
||
- 将 "流式下载" 更名为 "灵活下载"
|
||
- 明确说明本地存储模式不是流式中转
|
||
|
||
---
|
||
|
||
## 📊 提交记录
|
||
|
||
### Commit 1: 防爆破保护
|
||
```
|
||
commit c439966
|
||
feat: 添加登录和分享密码防爆破保护
|
||
|
||
- 新增RateLimiter类实现基于IP和用户名的限流
|
||
- 登录接口: 5次失败/15分钟后封锁30分钟
|
||
- 分享密码: 10次失败/10分钟后封锁20分钟
|
||
- 支持X-Forwarded-For反向代理
|
||
- 自动清理过期记录
|
||
- 详细的安全日志记录
|
||
```
|
||
|
||
**变更文件**:
|
||
- `backend/server.js`: +233行, -1行
|
||
|
||
### Commit 2: 上传工具修复
|
||
```
|
||
commit 72063c5
|
||
fix: 修复更新脚本导致上传工具丢失的问题
|
||
|
||
- 在更新流程中添加上传工具完整性检查
|
||
- 如果上传工具丢失或文件大小异常,自动重新下载
|
||
- 使用已有的build_upload_tool函数从直链下载
|
||
- 验证文件大小确保下载完整(>30MB)
|
||
```
|
||
|
||
**变更文件**:
|
||
- `install.sh`: +16行
|
||
|
||
### Commit 3: 版本发布
|
||
```
|
||
commit ac9f1c7
|
||
chore: 发布 v1.1.0 版本
|
||
|
||
新增功能:
|
||
- 登录和分享密码防爆破保护
|
||
- 更新脚本自动检测和修复上传工具
|
||
- 首页界面优化
|
||
```
|
||
|
||
**变更文件**:
|
||
- `VERSION.txt`: +46行, -26行
|
||
|
||
---
|
||
|
||
## 🧪 测试建议
|
||
|
||
### 1. 防爆破保护测试
|
||
|
||
**登录限流测试**:
|
||
```bash
|
||
# 连续5次错误密码登录
|
||
curl -X POST http://localhost:40001/api/login \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username":"admin","password":"wrongpass"}'
|
||
|
||
# 第6次应返回 429 状态码
|
||
# 响应: {"success":false,"message":"登录尝试过多,请在 30 分钟后重试","blocked":true}
|
||
```
|
||
|
||
**分享密码限流测试**:
|
||
```bash
|
||
# 连续10次错误密码
|
||
for i in {1..11}; do
|
||
curl -X POST http://localhost:40001/api/share/XXXXX/verify \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"password":"wrongpass"}'
|
||
echo ""
|
||
done
|
||
|
||
# 第11次应返回 429 状态码
|
||
```
|
||
|
||
### 2. 上传工具修复测试
|
||
|
||
```bash
|
||
# 1. 备份当前上传工具
|
||
mv upload-tool/dist/玩玩云上传工具.exe /tmp/backup.exe
|
||
|
||
# 2. 执行更新
|
||
./install.sh
|
||
# 选择选项 7: 更新系统
|
||
|
||
# 3. 验证上传工具已自动恢复
|
||
ls -lh upload-tool/dist/玩玩云上传工具.exe
|
||
# 应显示文件大小约 43MB
|
||
```
|
||
|
||
### 3. 反向代理测试
|
||
|
||
Nginx配置示例:
|
||
```nginx
|
||
location /api/ {
|
||
proxy_pass http://localhost:40001;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
}
|
||
```
|
||
|
||
验证日志中显示的是真实客户端IP而非代理IP。
|
||
|
||
---
|
||
|
||
## 📝 升级指南
|
||
|
||
### 从 v1.0.0 升级到 v1.1.0
|
||
|
||
#### 方法一: 使用安装脚本(推荐)
|
||
```bash
|
||
cd /opt/vue-driven-cloud-storage
|
||
./install.sh
|
||
# 选择选项 7: 更新系统
|
||
```
|
||
|
||
脚本会自动:
|
||
1. 停止现有服务
|
||
2. 拉取最新代码
|
||
3. 检测并重新下载上传工具(如需要)
|
||
4. 更新依赖
|
||
5. 重启服务
|
||
|
||
#### 方法二: 手动更新
|
||
```bash
|
||
# 1. 停止服务
|
||
pm2 stop vue-driven-cloud-storage-backend
|
||
|
||
# 2. 备份数据
|
||
cp -r backend/data /tmp/backup-data
|
||
|
||
# 3. 拉取代码
|
||
git pull origin master
|
||
|
||
# 4. 检查上传工具
|
||
ls -lh upload-tool/dist/玩玩云上传工具.exe
|
||
# 如果不存在或小于30MB,重新下载:
|
||
wget -O upload-tool/dist/玩玩云上传工具.exe \
|
||
http://a.haory.top/e/e82/玩玩云上传工具.exe
|
||
|
||
# 5. 重启服务
|
||
pm2 restart vue-driven-cloud-storage-backend
|
||
```
|
||
|
||
---
|
||
|
||
## 🔍 技术细节
|
||
|
||
### RateLimiter 实现原理
|
||
|
||
```javascript
|
||
class RateLimiter {
|
||
constructor(options) {
|
||
this.maxAttempts = options.maxAttempts || 5;
|
||
this.windowMs = options.windowMs || 15 * 60 * 1000;
|
||
this.blockDuration = options.blockDuration || 30 * 60 * 1000;
|
||
this.attempts = new Map(); // 尝试记录
|
||
this.blockedKeys = new Map(); // 封锁记录
|
||
}
|
||
|
||
recordFailure(key) {
|
||
// 检查是否已封锁
|
||
if (this.isBlocked(key)) {
|
||
return { blocked: true, ... };
|
||
}
|
||
|
||
// 记录失败尝试
|
||
let info = this.attempts.get(key) || { count: 0, windowEnd: ... };
|
||
info.count++;
|
||
|
||
// 达到阈值,进行封锁
|
||
if (info.count >= this.maxAttempts) {
|
||
this.blockedKeys.set(key, { expiresAt: ... });
|
||
return { blocked: true, ... };
|
||
}
|
||
|
||
return { blocked: false, remainingAttempts: ... };
|
||
}
|
||
|
||
recordSuccess(key) {
|
||
// 认证成功,清除所有记录
|
||
this.attempts.delete(key);
|
||
this.blockedKeys.delete(key);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 中间件应用
|
||
|
||
```javascript
|
||
// 登录接口
|
||
app.post('/api/login',
|
||
loginRateLimitMiddleware, // 添加限流中间件
|
||
[...validators],
|
||
async (req, res) => {
|
||
// 验证失败
|
||
if (!user || !passwordCorrect) {
|
||
loginLimiter.recordFailure(req.rateLimitKeys.ipKey);
|
||
loginLimiter.recordFailure(req.rateLimitKeys.usernameKey);
|
||
return res.status(401).json({...});
|
||
}
|
||
|
||
// 验证成功
|
||
loginLimiter.recordSuccess(req.rateLimitKeys.ipKey);
|
||
loginLimiter.recordSuccess(req.rateLimitKeys.usernameKey);
|
||
return res.json({...});
|
||
}
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## 🐛 已知问题
|
||
|
||
无已知问题。
|
||
|
||
---
|
||
|
||
## 📧 反馈与支持
|
||
|
||
如遇到问题,请通过以下方式反馈:
|
||
- Gitee Issues: https://gitee.com/yu-yon/vue-driven-cloud-storage/issues
|
||
- 查看日志: `pm2 logs vue-driven-cloud-storage-backend`
|
||
|
||
---
|
||
|
||
**感谢使用玩玩云!** 🎉
|