Files
vue-driven-cloud-storage/UPDATE_SUMMARY_v1.1.0.md

7.6 KiB
Raw Blame History

玩玩云 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 等反向代理

安全日志

[防爆破] 拦截登录尝试 - IP: xxx.xxx.xxx.xxx, 原因: IP被封锁
[防爆破] 封锁Key: login:username:admin, 失败次数: 5, 封锁时长: 30分钟
[防爆破清理] 已清理 12 个过期尝试记录, 3 个过期封锁记录

2. 🔧 部署优化 - 上传工具修复

问题描述

更新脚本执行 git pull 时会删除 upload-tool 目录,但由于 .gitignore 排除了 dist/*.exe,导致更新后上传工具丢失。

解决方案

install.sh 更新流程中添加检查逻辑:

# 检查并重新下载上传工具(如果需要)
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. 防爆破保护测试

登录限流测试:

# 连续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}

分享密码限流测试:

# 连续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. 上传工具修复测试

# 1. 备份当前上传工具
mv upload-tool/dist/玩玩云上传工具.exe /tmp/backup.exe

# 2. 执行更新
./install.sh
# 选择选项 7: 更新系统

# 3. 验证上传工具已自动恢复
ls -lh upload-tool/dist/玩玩云上传工具.exe
# 应显示文件大小约 43MB

3. 反向代理测试

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

方法一: 使用安装脚本(推荐)

cd /opt/vue-driven-cloud-storage
./install.sh
# 选择选项 7: 更新系统

脚本会自动:

  1. 停止现有服务
  2. 拉取最新代码
  3. 检测并重新下载上传工具(如需要)
  4. 更新依赖
  5. 重启服务

方法二: 手动更新

# 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 实现原理

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);
  }
}

中间件应用

// 登录接口
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({...});
  }
);

🐛 已知问题

无已知问题。


📧 反馈与支持

如遇到问题,请通过以下方式反馈:


感谢使用玩玩云! 🎉