# 玩玩云 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` --- **感谢使用玩玩云!** 🎉