{
  "id": "ZY-PROJ-002",
  "name": "语言保护罩 · ZY-SVR-006 智库节点部署",
  "guardian": "铸渊 · ICE-GL-ZY001",
  "copyright": "国作登字-2026-A-00037559",
  "background": {
    "bingshuo_requirement": "ZY-SVR-006是智能小说系统的宿主·在部署小说系统之前先要有防护层·不然一上线就被扫烂了",
    "zhuyuan_understanding": "三层IP隐身架构·L1出站代理池·L2蜜罐·L3 fail2ban自动封禁·nginx防护配置·冰朔称其为语言保护罩"
  },
  "architecture": {
    "layers": [
      "L1 出站代理池: 爬取下载时用代理·不暴露本机IP",
      "L2 蜜罐入口: 扫描者看到自己的镜像·心理威慑+信息收集",
      "L3 fail2ban自动封禁: 路径扫描/高频请求/SSH暴力破解→TARPIT耗尽资源"
    ],
    "nginx_config": "server/nginx/novel-mirror-shield.conf",
    "fail2ban_jails": [
      "novel-nginx-limit-req: 5分钟10次429→ban 6小时",
      "novel-path-scan: 5分钟3次路径扫描→ban 24小时",
      "novel-sshd: 10分钟3次SSH失败→ban 12小时",
      "novel-nginx-404: 10分钟5次40x→ban 1小时"
    ],
    "why": "ZY-SVR-006是新加坡节点·公网暴露·没有防护层直接部署小说系统必然遭暴力扫描"
  },
  "phases": [
    {
      "id": "ZY-PROJ-002-PHASE-1",
      "name": "防护配置文件准备",
      "status": "completed",
      "completed_at": "2026-04-16",
      "content": [
        "novel-mirror-shield.conf: Nginx防护配置（蜜罐+速率限制）",
        "fail2ban-novel.conf: 4个jail配置（nginx+ssh）",
        "fail2ban-filter-novel-scan.conf: 路径扫描正则过滤规则",
        "fail2ban-action-ban-log.conf: 封禁日志动作",
        "deploy-novel-mirror-shield.yml: 4动作部署workflow"
      ],
      "verified": "配置文件语法正确·workflow可触发"
    },
    {
      "id": "ZY-PROJ-002-PHASE-2",
      "name": "服务器实际部署 + SSL证书 + Phase 2 三大引擎",
      "status": "code_complete",
      "blocked_reason": null,
      "started_at": "2026-04-16",
      "content": [
        "服务器基础环境: nginx + fail2ban + certbot",
        "nginx防护配置上线（SSL鸡蛋问题已修复：创建占位文件引导→certonly --webroot申请真实证书）",
        "fail2ban jail启动（4个jail: nginx-limit-req/path-scan/sshd/4xx）",
        "SSL证书申请（Let's Encrypt · webroot方式）",
        "Phase 2 三大引擎后端 API 已完成:",
        "  - 下载引擎: /api/zhiku/download/* (5端点·任务创建/列表/状态/书籍/统计)",
        "  - 智能分章: /api/zhiku/chapter/* (5端点·分章/列表/详情/章节内容/统计)",
        "  - 在线阅读器: /api/zhiku/reader/* (9端点·书架/进度/偏好/统计)",
        "  - 综合统计: /api/zhiku/stats",
        "前端 zhiku.html 已联动全部 API (搜索/下载/自动分章/在线阅读/进度存储)",
        "",
        "Phase 3 团队书库 + 成员Agent 后端 API 已完成:",
        "  - 团队书库: /api/zhiku/library/* (7端点·列表/添加/详情/评分/评论/分类/统计)",
        "  - 成员Agent: /api/zhiku/agent/* (10端点·注册/详情/对话/记忆/笔记/统计)",
        "前端 zhiku.html Phase 3 已联动 (团队书库分区筛选+Agent对话面板)"
      ],
      "next_step": "合并PR后触发 deploy-novel-mirror-shield.yml 的 deploy 动作"
    },
    {
      "id": "ZY-PROJ-002-PHASE-3",
      "name": "验证防护效果 + 健康监控",
      "status": "pending",
      "content": [
        "触发health动作验证三层防护正常运行",
        "测试fail2ban封禁是否生效",
        "确认/var/log/novel-shield-bans.log有写入",
        "确认HTTPS正常"
      ]
    }
  ],
  "fixes": [
    {
      "id": "ZY-PROJ-002-FIX-1",
      "date": "2026-04-16",
      "problem": "certbot --nginx申请证书失败·全新服务器上/etc/letsencrypt/options-ssl-nginx.conf不存在",
      "root_cause": "novel-mirror-shield.conf在ssl server块中引用了letsencrypt的nginx配置文件·这些文件只有certbot成功运行一次后才存在·但certbot运行前需要nginx配置有效·循环依赖",
      "fix": "已实现：1)在启用站点步骤中·检查letsencrypt文件是否存在·若不存在则创建临时占位文件(options-ssl-nginx.conf + ssl-dhparams.pem + 自签名证书)让nginx -t通过并启动nginx 2)certbot申请步骤改用certonly --webroot方式·不依赖nginx插件·不触发nginx -t 3)certbot申请成功后真实证书替换占位文件·nginx reload激活 4)setup-ssl独立动作同样改为certonly --webroot",
      "files_changed": [".github/workflows/deploy-novel-mirror-shield.yml"],
      "result": "implemented"
    },
    {
      "id": "ZY-PROJ-002-FIX-2",
      "date": "2026-04-16",
      "problem": "fail2ban novel-nginx-404 jail使用了错误的filter·nginx-http-auth只匹配401认证失败·不匹配400/403/404",
      "root_cause": "Sonnet开发时直接引用了内置filter名nginx-http-auth·该filter的failregex只匹配HTTP Basic Auth失败(401)·不匹配通用40x状态码",
      "fix": "新建fail2ban-filter-novel-4xx.conf·匹配400/403/404/405状态码·同时忽略favicon和robots正常请求·jail名改为novel-nginx-4xx·部署workflow添加上传该filter文件的scp步骤",
      "files_changed": [
        "server/novel-db/security/fail2ban-filter-novel-4xx.conf",
        "server/novel-db/security/fail2ban-novel.conf",
        ".github/workflows/deploy-novel-mirror-shield.yml"
      ],
      "result": "implemented"
    },
    {
      "id": "ZY-PROJ-002-FIX-3",
      "date": "2026-04-16",
      "problem": "nginx蜜罐块重复定义ACME challenge路径·root路径不一致(/var/www/html vs /var/www/certbot)",
      "root_cause": "蜜罐server块(default_server)和novel.guanghuyaoming.com server块都定义了/.well-known/acme-challenge/·root路径不同·如果蜜罐块先被匹配则certbot验证失败",
      "fix": "删除蜜罐块中的重复ACME location·只保留novel.guanghuyaoming.com块中的定义(root /var/www/certbot)·因为certbot只对指定域名验证",
      "files_changed": ["server/nginx/novel-mirror-shield.conf"],
      "result": "implemented"
    },
    {
      "id": "ZY-PROJ-002-FIX-4",
      "date": "2026-04-16",
      "problem": "setup-ssl job 运行 certbot 时 nginx -t 失败·/etc/letsencrypt/options-ssl-nginx.conf 不存在",
      "root_cause": "setup-ssl job 安装了 python3-certbot-nginx 后 certbot 自动尝试 nginx 插件验证·触发 nginx -t·但 SSL 占位文件只在 deploy job 中创建·setup-ssl 单独运行时无占位文件。deploy job 从未成功执行(push 触发时 paths 不匹配·workflow_dispatch 只选了 setup-ssl)。",
      "fix": "1) setup-ssl job 增加与 deploy job 相同的 SSL 占位文件创建逻辑 2) 改为只安装 certbot 不安装 python3-certbot-nginx 避免 nginx 插件干扰 3) 添加 --preferred-challenges http 强制 HTTP-01 验证 4) deploy job 的 certbot 步骤同样添加 --preferred-challenges http 5) setup-ssl 添加自动续期 cron",
      "files_changed": [".github/workflows/deploy-novel-mirror-shield.yml"],
      "result": "implemented"
    }
  ],
    "server/nginx/novel-mirror-shield.conf",
    "server/novel-db/security/fail2ban-novel.conf",
    "server/novel-db/security/fail2ban-filter-novel-scan.conf",
    "server/novel-db/security/fail2ban-filter-novel-4xx.conf",
    "server/novel-db/security/fail2ban-action-ban-log.conf",
    ".github/workflows/deploy-novel-mirror-shield.yml"
  ],
  "next_step": "合并PR后→冰朔在GitHub Actions页面手动触发 deploy-novel-mirror-shield.yml(action=deploy)→部署完成后再触发setup-ssl→最后触发health验证。注意：合并PR不会自动触发deploy(paths不匹配)，必须手动workflow_dispatch",
  "status": "in_progress",
  "current_phase": "ZY-PROJ-002-PHASE-2"
}
