首页 / 技术分享 / 网站安全漏洞 /
创建网站安全漏洞扫描工具

创建网站安全漏洞扫描工具

码不停提

2026-02-04
18 次浏览
0 条评论

用 Python 搭建一个网站安全漏洞扫码工具,覆盖全部安全漏洞类型,但是因为有些漏洞通过直接扫描不能完确定,所以在扫描时会将可疑的点标记为 suspect.*,后续需要手动确认。本项目开发耗时 5天。

网站安全漏洞
Python
网站安全扫描
分享:

Cyber Walker 系统功能与后台操作流程

目标:把“它能做什么、后台怎么用、一次扫描在系统里怎么跑完”讲清楚。

适用读者:使用控制台的管理员(admin)/审计只读(reader)、开发/运维。

1. 系统是什么

Cyber Walker 是一个“面向授权资产的安全扫描与证据留存平台”。它把一次扫描拆成多个阶段(Recon → URL 发现 → 证据采集 → 规则分析 → 产出 Findings/RunLog),并通过 Scope 门禁Safe/Authorized 模式Verify 手动验证门禁 来控制风险。

与传统“一键跑完所有漏洞验证”的扫描器不同:

  • 自动扫描会产出两类结果:
    • 已验证/确定性较强的 Findings(数量较少,偏基线/低风险主动探测)
    • *候选/提示型 Findings(`suspect.`)**:用于提示“可能存在风险,需要人工 Verify/复核”,不是最终漏洞结论
  • 高风险、可能造成副作用的验证,通过 Verify(手动触发) 执行,并有预算/强度/授权门禁。

2. 组件与数据流(高层架构)

flowchart LR
  U[用户/管理员] -->|浏览器| C[Console 控制台]
  C -->|JWT Bearer| API[FastAPI API]

  API --> DB[MySQL]
  API -->|投递任务| Q[Celery Broker 通常为 Redis]
  W[Celery Worker] -->|取任务| Q

  W -->|HTTP/Playwright| T[目标站点/资产]
  W -->|写入| DB

  API -->|只读查询/列表| DB
  C -->|查看结果/下载报告| API

要点:

  • API 负责鉴权/配置/查询;扫描执行在 Celery Worker
  • Worker 会把扫描过程产生的 URL、请求响应证据、运行日志、Findings 全部落到 MySQL。
  • 代码变更后:uvicorn --reload 会自动重载,但 Celery Worker 不会热重载,需要重启 Worker 才能生效。

3. 核心对象(你在后台会操作什么)

  • Target:你要扫的资产入口 + Scope(合规边界)
  • Scope:硬性门禁(域名/协议/端口/路径前缀等),所有扫描请求必须命中 scope
  • Login Profile:登录态(cookie/token/form_login),用于访问受保护资源
  • Scan:一次扫描任务(状态机 + 配置快照 + 绑定 Target/Profile)
  • Url:扫描过程中发现/归一化的 URL(含来源)
  • HttpExchange / EvidenceBody:每笔请求响应的元数据与响应体(FULL/SUMMARY)
  • Finding:规则分析输出(含自动类与 suspect.* 候选类)
  • RunLog:扫描运行日志(阶段计数、跳过原因、门禁触发信息)
  • ReconRun / OpenPort / DnsRecord:Recon 结果(DNS/端口探测)
  • EnumRun / EnumPathResult:目录/路径枚举结果(独立表,不作为 Findings)

4. 后台操作流程(从 0 到一次可复现扫描)

4.1 角色与权限

  • reader:只读查看(Targets/Scans/Findings/Exchanges 等)
  • admin:可写操作(创建/修改 Target、Profile、创建/克隆 Scan、触发 Verify 等)

4.2 推荐的“标准工作流”(最常用)

flowchart TD
  A[1. 创建 Target
设置 entry_url] --> B[2. 配置 Scope
allowed_hosts/schemes/ports/path_prefix]
  B --> C{需要登录态?}
  C -- 否 --> E[4. 创建 Scan
选择 Target + Safe/Authorized]
  C -- 是 --> D[3. 创建 Login Profile
cookie/token/form_login]
  D --> E
  E --> F[5. 运行 Scan
(后台 Worker 执行)]
  F --> G[6. 查看结果
RunLog/Urls/Exchanges/Findings/Recon/Enum]
  G --> H{需要高风险确认?}
  H -- 否 --> I[结束:输出报告/复盘]
  H -- 是 --> J[7. 选择 URL/Exchange
发起 Verify(手动)]
  J --> K[8. Verify 结果落库
生成 verify.* Findings + 证据]
  K --> I

操作要点:

  • “可复现”= Scan 配置快照 + 证据留存 + RunLog。建议每次重要变更都通过 Clone Scan 形成新 Scan,而不是直接改老 Scan。
  • Safe/Authorized:
    • Safe:默认启用低风险阶段(基线、少量探测、Recon safe 等)
    • Authorized:用于在已授权前提下执行更主动的验证(并要求审计字段/门禁满足条件)

4.3 Clone Scan(推荐的配置编辑方式)

系统倾向于把 Scan 当作“不可变的一次执行记录”。当你想调整配置(比如动态发现预算、是否启用枚举、recon ports 等),推荐做法是:

  1. 找到一个已有 Scan(成功/接近成功的)
  2. 点击 Clone Scan(或通过 API 克隆)
  3. 在新 Scan 上修改配置并运行

收益:

  • 老 Scan 的证据链/审计链保持稳定
  • 新旧 Scan 易于对比:同一 Target、不同配置

4.4 控制台视角 SOP(按页面走一遍)

这一节用“从哪些页面进入、点什么、看什么”来描述后台操作流程,适合给运维/安全同学当操作手册。

4.4.1 Targets 页面(创建资产 + Scope 护栏)

  1. 新建 Target:填写 entry_url
  2. 配置 Scope(强烈建议至少配置):
    • allowed_hosts:把域名白名单收紧到你确定拥有授权的域名/子域
    • allowed_schemes:通常仅允许 http/https
    • allowed_ports:建议明确列出目标服务端口(例如 80/443/8080
    • path_prefixes:当只允许扫某个路径空间时使用(例如 /app
  3. 保存后建议做一次最小 Safe Scan 验证 scope 是否配置正确

4.4.2 Login Profiles 页面(登录态)

当扫描需要登录态才能覆盖更多页面/接口时:

  • cookie 注入:
    • 适合存在验证码/OTP 的站点(人工完成登录后复制 Cookie)
    • 风险控制:Cookie 应尽量短期有效;泄露风险由组织内部流程控制
  • token 注入:
    • 适合 API Token、Bearer Token 或自定义 Header
  • form_login(Playwright):
    • 适合标准表单登录;验证码/OTP 不在 MVP
    • 建议优先在测试环境验证稳定性

4.4.3 Scans 页面(创建 / Clone / 运行 / 对比)

推荐路径:

  1. 选择 Target → 创建 Scan(或从一个“接近你想要的配置”的 Scan 进行 Clone)
  2. 配置项(常见):
    • mode: safe/authorized(授权模式通常伴随更严格审计)
    • dynamic discovery:是否启用 Playwright 网络监听;是否允许交互
    • enum:是否启用路径枚举与预算
    • recon:是否提供显式 ports(并理解会被 scope.allowed_ports 取交集)
  3. 运行 Scan
  4. 对比:同一 Target 下,通过不同 Scan 的 RunLog/Findings/Urls/Exchanges 对照差异

4.4.4 Urls / Exchanges / Findings 页面(结果三件套)

  • Urls:回答“系统发现了哪些 URL、来源是什么、是否在 scope 内”
  • Exchanges:回答“系统对哪些 URL 发出了请求、返回了什么、是否留存了响应体”
  • Findings:回答“基于证据做了哪些规则判断(包括候选 suspect.* 与 verify 结论)”

4.4.5 Verify 操作入口(手动确认)

常见入口是从 Urls/Exchanges/Findings 选中目标后发起 Verify(具体 UI 入口随控制台实现而定)。

执行前建议:

  • 先看 Evidence(响应体/headers)与 RunLog
  • 明确这是“确认型验证”还是“排错型探测”
  • 选择合适的 Verify strength(conservative/normal/aggressive)

4.5 典型配置示例(Safe 扫描 vs 动态发现交互)

下面给两个“容易理解、便于复用”的思路,实际字段请以控制台表单/Scan config schema 为准。

4.5.1 最小 Safe 扫描(适合先打通链路)

  • 目标:确认 scope 正确、能产生 Exchanges/Evidence、基础 Findings 与 RunLog
  • 建议:先关闭动态交互与高预算扩展

4.5.2 动态发现 + 交互探索(需要显式确认)

  • 目标:覆盖更多 JS 驱动页面/XHR 接口
  • 必要条件:
    • dynamic_discovery_enabled=true
    • confirm_interaction=true
    • 仅当确实需要提交表单时,再打开 enable_post_form_submit=true
  • 建议:逐步增加预算(click/forms/url capture),并优先在测试环境验证

5. 扫描执行流程(Worker 内部流水线)

下面是“一次 Scan 在 Worker 里”典型会经历的阶段。具体启用与否由 Scan 配置与门禁共同决定(例如 scope、预算、dynamic discovery 开关等)。

flowchart TD
  S[Scan 入队/开始] --> L[加载 Scan + Target + Profile
生成 effective_config 快照]

  L --> G{Scope 门禁校验
entry_url 是否可扫}
  G -- 不通过 --> X[Scan 失败/取消
RunLog 记录原因]
  G -- 通过 --> R1

  subgraph Recon[Recon(信息收集)]
    R1[DNS 解析] --> R2[端口探测(safe)]
  end

  R2 --> D1

  subgraph Discovery[URL 发现(Discovery)]
    D1[静态提链
HTML/headers 解析] --> D2{动态发现 enable?}
    D2 -- 否 --> D5[得到 URL 集合]
    D2 -- 是 --> D3[Playwright 网络监听
抓取 XHR/fetch/document]
    D3 --> D4{允许交互?
confirm_interaction=true}
    D4 -- 否 --> D5
    D4 -- 是 --> D6[交互探索
click/forms(受预算限制)]
    D6 --> D5
  end

  D5 --> E1

  subgraph Evidence[证据采集(Evidence)]
    E1[抓取 URL
写入 HttpExchange] --> E2[写入 EvidenceBody
FULL/SUMMARY + hash/snippet]
  end

  E2 --> A1

  subgraph Analysis[规则分析(Findings)]
    A1[基线/低风险规则
输出 Findings] --> A2[候选规则
输出 suspect.*]
  end

  A2 --> O[写入 RunLog/统计]
  O --> DONE[Scan 完成
succeeded/failed]

5.1 关键门禁与“为什么会跳过”

系统会尽量把“跳过原因”写进 RunLog,便于排查。

常见门禁:

  • Scope:不在 allowed_hosts / allowed_schemes / allowed_ports / path_prefix 范围内 → 请求被拒绝或阶段被跳过
  • Recon ports:端口探测只允许显式端口列表,并与 target.scope.allowed_ports 取交集;交集为空时 Recon 端口探测会跳过
  • Dynamic discovery 交互
    • dynamic_discovery_enabled=true 才会启用 Playwright 网络监听
    • 交互探索必须 confirm_interaction=true
    • POST 表单提交还需要 enable_post_form_submit=true
  • 预算/硬上限:URL 数、深度、枚举 budget、dynamic discovery 捕获数量等超过上限会停止继续扩展

5.2 Recon(DNS/端口)策略说明

  • Recon 的端口探测是 TCP connect,不发送应用层 payload。
  • 端口集合来源:
    1. scan.config.recon.safe.ports(显式端口列表)
    2. 若未配置显式端口,则使用 safe 默认端口集合(仍会被 scope.allowed_ports 进一步收敛)
  • 合规边界:最终端口集合 = normalize_ports(config)target.scope.allowed_ports

设计原则:不做“扫描全部 scope 端口”的隐式兜底;端口探测必须是可预期、可解释、可审计的。

5.3 Enum(目录/路径枚举)与 Findings 的关系

路径枚举是“信息收集/扩展 URL”能力:

  • 结果落库到 enum_runs / enum_path_results(Recon 风格表)
  • 不直接生成 Findings(避免把“枚举到的路径”误当作漏洞)
  • 后续可基于 Enum 结果进一步选择 URL 进行 Verify/复核

5.4 一次扫描的时序图(Admin → API → Worker → DB)

这张图用于解释“你点了运行后,到底发生了什么”,也方便排查问题落在哪一段。

sequenceDiagram
  autonumber
  actor Admin as Admin/Reader
  participant Console as Console
  participant API as FastAPI API
  participant DB as MySQL
  participant Q as Celery Broker
  participant Worker as Celery Worker
  participant Target as Target Site

  Admin->>Console: 创建/克隆 Scan(填写配置)
  Console->>API: POST /api/scans
  API->>DB: 写入 Scan + config 快照
  API-->>Console: 返回 scan_id

  Admin->>Console: 点击运行
  Console->>API: POST /api/scans/{id}/run
  API->>Q: enqueue scan task
  API->>DB: 写入 RunLog(开始)
  API-->>Console: 200

  Worker->>Q: 获取 scan task
  Worker->>DB: 读取 Scan/Target/Profile
  Worker->>Target: Recon/抓取/动态发现(受门禁)
  Worker->>DB: 写 HttpExchange/EvidenceBody/Urls
  Worker->>DB: 写 Findings(含 suspect.*)
  Worker->>DB: 写 RunLog(统计/skip 原因)
  Worker->>DB: 更新 Scan 状态

  Console->>API: GET /api/scans/{id}
  API->>DB: 查询 Scan/聚合计数
  API-->>Console: 状态 + 结果索引

5.5 “哪些东西会落库”与“从哪看”(结果索引表)

这部分把数据落库与控制台视图对齐,方便你定位“我该去哪里看”。

  • Recon:recon_runs / dns_records / open_ports → Scan 详情的 Recon 区块
  • URL 发现:urls → Urls 页面(或 Scan 详情的 URL 列表)
  • 证据索引:http_exchanges → Exchanges 页面
  • 响应体与摘要:evidence_bodies → Exchange 详情的 Evidence 预览
  • Findings:findings → Findings 页面
  • 运行日志:run_logs → Scan 详情的 RunLog
  • 枚举:enum_runs / enum_path_results → 枚举结果页面/Scan 详情的 Enum 区块

6. Verify(手动验证)流程

Verify 用来做“高风险、可能造成副作用、但确认价值更高”的验证。它不随普通扫描自动批量执行,而是由 admin 明确触发。

flowchart TD
  A[选择目标 URL/Exchange] --> B[选择 Verify 规则/规则模板]
  B --> C[门禁校验
角色=admin + 授权/预算/强度]
  C -- 不通过 --> X[拒绝执行
返回原因]
  C -- 通过 --> D[Worker 执行 Verify
HTTP/Playwright 探测]
  D --> E[产出证据 + verify.* Findings]
  E --> F[控制台查看/导出]

Verify 的关键点:

  • 强度(strength) 与预算控制,避免误操作造成大量流量
  • 规则目录按风险分层(例如极高风险规则默认关闭,需要显式开关)
  • 支持去重(同一 url + rule 在 TTL 内可复用结果,减少重复请求)

6.1 Verify 什么时候用、怎么选强度

建议把 Verify 当作“最终确认工具”,而不是“把所有主动攻击都塞进自动扫描”。

常见场景:

  • 扫描发现 suspect.* 候选:需要把“提示”变成“可复现的结论”
  • 你在 Evidence/Headers/DOM 里看到明显迹象:需要用规则化手段给出确认与证据
  • 你需要控制副作用:通过强度/预算/并发把影响降到可控范围

强度选择建议:

  • conservative:排查优先、流量最小、适合生产/敏感环境
  • normal:日常测试环境验证
  • aggressive:只在明确授权、且目标对流量更耐受时使用

7. 后台常见操作清单(按页面/模块)

下面用“你在控制台里经常会做的事”来组织。

7.1 Targets(资产)

  • 新增 Target:填写 entry_url
  • 配 Scope:建议最少配置 allowed_hostsallowed_schemes,并按需要配置 allowed_portspath_prefixes
  • 资产复用:同一系统的不同环境建议分 Target(测试/预发/生产)

7.2 Login Profiles(登录态)

  • cookie 注入:适合验证码/OTP 场景(人工拿 cookie)
  • token 注入:适合 API Token/自定义 header
  • form_login:适合标准表单登录(Playwright 自动化);验证码/OTP 不在 MVP

7.3 Scans(扫描任务)

  • 创建/克隆 Scan:绑定 Target(可选 profile)
  • 调整配置:建议通过 Clone Scan 修改(保留历史可审计)
  • 观察执行:RunLog(阶段计数/跳过原因/预算耗尽)

7.4 Urls / Exchanges / Evidence(证据)

  • Urls:看系统“发现了什么 URL、来源是什么”
  • Exchanges:看每次请求/响应的元信息(状态码、headers、耗时、错误)
  • EvidenceBody:看响应体 FULL/SUMMARY、hash/snippet、是否被截断

7.5 Findings(结果)

  • 自动 Findings:较确定的结论(数量少)
  • suspect.*:候选提示,建议结合证据与业务上下文再决定是否 Verify
  • verify.*:手动验证后的确认型结果(更适合作为最终结论)

7.6 Recon / Enum(信息收集)

  • Recon:DNS、端口开放情况(受 scope + 显式端口策略约束)
  • Enum:目录/路径枚举结果(独立表,不当作漏洞)

7.7 Audit Logs(审计)

  • admin 操作(创建/修改、授权相关操作、Verify 等)会写入审计日志,便于追责与合规。

8. 排查与运维提示

  • Worker 未生效:修改后端扫描相关代码后要重启 Celery Worker
  • 某阶段“没跑”:优先看 RunLog(通常会记录门禁/预算/skip 原因)
  • 动态发现没抓到 URL:
    • 检查是否启用 dynamic_discovery_enabled
    • 若依赖点击/表单触发,必须 confirm_interaction=true
    • POST 表单提交还要 enable_post_form_submit=true
  • Recon 没有端口结果:
    • 检查 target.scope.allowed_ports 是否包含目标端口
    • 检查 scan.config.recon.safe.ports 是否为空或被 scope 交集后为空

8.1 排查 Runbook(按优先级从快到慢)

  • 先看 Scan 状态与 RunLog:是否已入队、是否被取消、是否有明确 skip 原因
  • 若 Scan 长时间 running:看 Worker 日志是否卡住;确认是否开启 dynamic discovery(Playwright 阶段更耗时)
  • “发现 URL 太少”:检查 Scope 是否过窄;确认是否启用了 dynamic discovery/交互确认
  • “Exchanges 有,但 EvidenceBody 为空/很短”:确认是否写入 SUMMARY;查看 Exchanges 的 error_text/超时信息
  • “Recon 结果为空”:检查 scope.allowed_ports 与 recon ports 交集;端口必须同时被 scope 与 scan config 显式允许
  • “Verify 触发失败”:确认是 admin;是否命中规则门禁;是否超过 verify 预算(批量/并发/estimated_requests)

9. 进一步阅读

10. 部署拓扑与运维说明

这一节更偏运维视角:如何部署组件、如何理解任务队列、如何配置 .env,以及上线后怎么排查。

10.1 部署拓扑(单机最小可用)

适合:PoC/测试环境/单机演示。

flowchart TB
  subgraph Host[一台服务器/一台开发机]
    N[Nginx/反向代理-可选]
    API[FastAPI :uvicorn/gunicorn]
    W[Celery Worker]
    R[(Redis
Celery broker/backend)]
    DB[MySQL]
  end

  User[用户浏览器] -->|HTTPS/HTTP| N
  N -->|/api/*| API
  N -->|/ console 静态资源 可选:后端同源托管| API

  API --> DB
  API --> R
  W --> R
  W --> DB
  W --> Target[目标站点/资产]

说明:

  • 控制台(console)在生产可以构建为静态文件并由后端同源托管;开发期通常由 Vite dev server 提供并代理 /api
  • CELERY_ENABLED=false 时,API 会用 FastAPI BackgroundTasks 在 API 进程里跑扫描(仅适合 dev/回归,不建议生产)。

10.2 部署拓扑(推荐:组件分离)

适合:正式测试环境/多人使用/需要更稳定的 worker 执行。

flowchart TB
  User[用户浏览器] -->|HTTPS| N[Nginx/Ingress]
  N -->|/| Static[console 静态站点 可由 Nginx 托管]
  N -->|/api/*| API[FastAPI API 可水平扩容]

  API --> DB[MySQL]
  API --> R[Redis broker/backend]

  W1[Worker 1] --> R
  W2[Worker 2] --> R
  W1 --> DB
  W2 --> DB
  W1 --> Target[目标站点/资产]
  W2 --> Target

  W1 --> OSS[OSS 可选 快照/证据对象存储]

要点:

  • API 建议无状态(状态都在 DB),便于扩容。
  • Worker 可以按压力横向扩容;并发受 Celery -c 以及 verify/爬虫预算共同约束。
  • Redis/DB 建议用托管/高可用方案;否则它们是整体稳定性的瓶颈。

10.3 进程职责与启停顺序

推荐启停顺序:

  1. MySQL(必须)
  2. Redis(如果启用 Celery)
  3. API(FastAPI)
  4. Worker(Celery)
  5. Nginx/Ingress(可选)

常用启动命令(示例):

  • API(开发期):cd server && ./.venv/bin/python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
  • Worker:cd server && ./.venv/bin/python -m celery -A app.celery_app worker -l info -n cw@%h -c 2

注意:Worker 不会热重载;任何扫描/验证相关代码改动都需要重启 Worker。

10.4 任务队列(Celery)与可靠性语义

系统对 Celery 做了偏“至少一次投递”的配置(at-least-once):

  • task_acks_late=true:任务执行完成后才 ack
  • task_reject_on_worker_lost=true:worker 崩溃时任务可被 broker 重新投递
  • worker_prefetch_multiplier=1:减少未开始但已预取的任务堆积
  • CELERY_VISIBILITY_TIMEOUT_SECONDS(Redis broker):控制“未 ack 任务”的重投递时间窗口

运维含义:

  • 发生 worker 异常/重启时,任务可能被重跑。因此扫描逻辑需要尽量幂等(本项目倾向以 Scan 状态机 + RunLog 来保证可解释性)。
  • 在 dev/回归可把 visibility timeout 调小以验证重投递;生产建议保持更大值,避免长任务被误判“超时重投”。

10.5 .env 配置项说明(按类别)

后端默认读取 server/.env(示例见 server/.env.example),完整项可参考 server/app/core/config.py

10.5.1 必需项(最小可跑)

  • DATABASE_URL:MySQL 连接串(格式:mysql+pymysql://user:pass@host:port/db
  • JWT_SECRET_KEY:JWT 签名密钥(务必改为随机值)

10.5.2 推荐安全项

  • APP_SECRET_KEY:应用级加密/签名用途(后续里程碑会更依赖)
  • APP_ENVdev/prod,影响部分错误返回细节
  • LOG_LEVEL:日志级别

10.5.3 Celery/Redis(异步扫描执行,推荐生产启用)

  • CELERY_ENABLED:是否启用 Celery 入队
  • CELERY_BROKER_URL:Redis broker
  • CELERY_RESULT_BACKEND:结果后端(通常同 Redis)
  • CELERY_VISIBILITY_TIMEOUT_SECONDS:未 ack 任务的可见性超时(重投递窗口)

10.5.4 证据与页面快照(可选)

  • EVIDENCE_BODY_LIMIT_BYTES / EVIDENCE_SNIPPET_BYTES:响应体 FULL/SUMMARY 阈值与摘要片段大小
  • SNAPSHOT_STORAGE_BACKENDdboss
  • SNAPSHOT_OSS_STRICT:strict 时 OSS 上传失败会导致快照生成失败(并在 Exchanges 里记录 error)
  • OSS_ENDPOINT / OSS_BUCKET / OSS_ACCESS_KEY_ID / OSS_ACCESS_KEY_SECRET / OSS_PREFIX
  • OSS_PUBLIC_BASE_URL / OSS_STORE_URL_ENABLED

10.5.5 Verify(手动验证)安全预算

  • VERIFY_MAX_*:批量验证的硬上限
  • VERIFY_DEDUPE_TTL_SECONDS:重复验证去重窗口
  • VERIFY_STRENGTH_*:不同强度档位的预算/超时/并发

10.5.6 扫描/爬虫影响控制(Guardrails)

  • CRAWL_MAX_URLS_HARD_LIMIT / CRAWL_MAX_DEPTH_HARD_LIMIT
  • CRAWL_MIN_REQUEST_INTERVAL_MS / CRAWL_REQUEST_TIMEOUT_SECONDS

动态发现/枚举/出站代理等也有对应配置项(例如 dynamic discovery 的预算与交互确认默认值、出站代理与 UA 池),建议以 server/app/core/config.py 为准。

10.6 Playwright 运维注意事项

使用动态发现(Playwright)或表单登录(form_login)时:

  • 必须在“运行 worker 的同一个 Python 环境”安装浏览器:python -m playwright install chromium
  • Linux 生产环境通常需要系统依赖;可用 python -m playwright install --with-deps chromium(取决于发行版/权限策略)
  • Worker 主机需要能访问目标站点(网络策略/代理/防火墙)

10.7 上线检查清单(Checklist)

  • GET /api/health 返回正常
  • MySQL 连接正常,且已执行 server/scripts/init_db.sql(或对应迁移)
  • 若启用 Celery:Redis 可连通,Worker 正常消费队列(可用一个最小 Scan 验证)
  • Worker 与 API 使用同一 venv/依赖版本(避免“API 新代码 + Worker 旧代码”)
  • .env 中的 JWT_SECRET_KEY / APP_SECRET_KEY 已替换为随机值
  • 若启用 OSS:确认 bucket/凭据/权限正确;strict 模式下要特别关注失败告警

10.8 运行期排查(从外到内)

  • 访问异常:先看 Nginx/Ingress,再看 API 日志(有 X-Request-Id/X-Trace-Id
  • 扫描不执行:确认 CELERY_ENABLED=true 且 broker 配置正确;确认 Worker 在线且无报错
  • 扫描执行但结果异常:优先看 Scan RunLog,其次看 Exchanges 的 error_text 与 Evidence

10.9 Ubuntu 生产部署示例(systemd)

这一节给出可直接复制的模板。假设代码部署在:/opt/cyber-walker

10.9.1 推荐目录结构

/opt/cyber-walker/
  console/
    dist/                 # 可选:前端 build 产物
  server/
    .venv/
    .env
    app/
    scripts/

10.9.2 创建运行用户(示例)

sudo adduser --system --group --home /opt/cyber-walker --shell /usr/sbin/nologin cyberwalker
sudo chown -R cyberwalker:cyberwalker /opt/cyber-walker

也可以沿用你现有的部署用户;关键是 API/Worker 不要以 root 运行。

10.9.3 systemd:API 服务单元

创建 /etc/systemd/system/cyber-walker-api.service

[Unit]
Description=Cyber Walker API (FastAPI)
After=network.target

[Service]
Type=simple
User=cyberwalker
Group=cyberwalker
WorkingDirectory=/opt/cyber-walker/server
EnvironmentFile=/opt/cyber-walker/server/.env

# 生产建议用多个 worker,并交给 Nginx 反代
ExecStart=/opt/cyber-walker/server/.venv/bin/python -m uvicorn app.main:app \
  --host 127.0.0.1 --port 8000 --workers 2

Restart=always
RestartSec=2

# 让日志进入 journald
StandardOutput=journal
StandardError=journal

# 基础安全加固(可按需调整)
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target

启用并启动:

sudo systemctl daemon-reload
sudo systemctl enable --now cyber-walker-api
sudo systemctl status cyber-walker-api --no-pager

10.9.4 systemd:Celery Worker 服务单元

创建 /etc/systemd/system/cyber-walker-worker.service

[Unit]
Description=Cyber Walker Worker (Celery)
After=network.target

[Service]
Type=simple
User=cyberwalker
Group=cyberwalker
WorkingDirectory=/opt/cyber-walker/server
EnvironmentFile=/opt/cyber-walker/server/.env

# -c 并发建议结合机器资源与扫描预算调优
ExecStart=/opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app worker \
  -l info -n cw@%H -c 2

Restart=always
RestartSec=2

StandardOutput=journal
StandardError=journal

NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target

启用并启动:

sudo systemctl daemon-reload
sudo systemctl enable --now cyber-walker-worker
sudo systemctl status cyber-walker-worker --no-pager

常用排查命令:

sudo journalctl -u cyber-walker-api -f
sudo journalctl -u cyber-walker-worker -f

10.9.5 Redis / MySQL(说明)

  • Redis/MySQL 推荐使用托管或独立服务;如果你在同机部署,务必做好持久化与备份。
  • 若启用 Celery,确保 CELERY_ENABLED=trueCELERY_BROKER_URL/CELERY_RESULT_BACKEND 指向可达的 Redis。

10.10 Ubuntu Nginx 反代与静态托管示例

两种常见方式:

  1. Nginx 托管 console/dist 静态文件(推荐)+ /api 反代到后端
  2. 不单独托管静态文件,直接把 //api 都反代到后端(后端检测到 console/dist 时会同源托管)

10.10.1 方式 A:Nginx 托管静态 + 反代 /api

创建(或修改)/etc/nginx/sites-available/cyber-walker.conf

server {
  listen 80;
  server_name _;

  # 静态站点(console build 输出)
  root /opt/cyber-walker/console/dist;
  index index.html;

  # SPA history fallback
  location / {
    try_files $uri $uri/ /index.html;
  }

  # API 反代
  location /api/ {
    proxy_pass http://127.0.0.1:8000/api/;
    proxy_http_version 1.1;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # 可选:超时按环境调整(动态发现/大响应可能更慢)
    proxy_connect_timeout 30s;
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;
  }
}

启用配置并 reload:

sudo ln -sf /etc/nginx/sites-available/cyber-walker.conf /etc/nginx/sites-enabled/cyber-walker.conf
sudo nginx -t
sudo systemctl reload nginx

10.10.2 方式 B:全部反代到后端(后端同源托管 console/dist)

如果你不想让 Nginx 直接接触静态目录,可以这样做:

server {
  listen 80;
  server_name _;

  location / {
    proxy_pass http://127.0.0.1:8000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
}

前提:你已经在服务器上 cd console && pnpm build,保证 /opt/cyber-walker/console/dist 存在。

10.11 Ubuntu 防火墙(UFW)与端口暴露建议

目标:只暴露对外必需端口,把内部服务端口(例如 8000)限制在本机。

推荐策略:

  • 对外只开放:22(SSH)、80/443(HTTP/HTTPS)
  • FastAPI 内部监听:127.0.0.1:8000,不对公网开放
  • Redis/MySQL:只允许内网或本机访问(生产建议独立网段/安全组控制)

UFW 示例(按需调整):

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw enable
sudo ufw status verbose

如果你的 API 不是只监听 127.0.0.1(不推荐),务必额外限制 8000 端口来源。

10.12 Ubuntu HTTPS(Let’s Encrypt / certbot)快速落地

建议优先做 HTTPS:控制台登录与 JWT 传输需要 TLS 保护(尤其在非内网环境)。

步骤概览:

  1. 确保域名解析到服务器公网 IP(A/AAAA 记录)
  2. Nginx 已按 10.10 配好站点并可访问 HTTP
  3. 用 certbot 自动签发并写入 Nginx SSL 配置

示例命令(Ubuntu 常用):

sudo apt update
sudo apt install -y certbot python3-certbot-nginx

# 替换成你的域名与邮箱
sudo certbot --nginx -d your.domain.example \
  --non-interactive --agree-tos -m you@example.com

sudo nginx -t
sudo systemctl reload nginx

续期检查:

sudo certbot renew --dry-run

10.13 滚动更新与回滚(Ubuntu 操作手册)

目标:更新代码/依赖/配置时,尽量避免“任务执行中途被打断”与“API/Worker 版本不一致”。

10.13.1 更新前检查

  • 确认数据库备份可用(至少有最近一次备份)
  • 观察当前是否有长时间运行中的 Scan/Verify(避免更新期间打断)
  • 记录当前版本(git commit hash / tag)便于回滚

10.13.2 推荐更新顺序(先停 Worker,后停 API)

# 1) 停止 worker(避免新任务继续执行)
sudo systemctl stop cyber-walker-worker

# 2) 更新代码(示例:git pull;实际可用你们的发布流程)
cd /opt/cyber-walker
sudo -u cyberwalker git pull

# 3) 更新后端依赖(如 requirements 有变化)
cd /opt/cyber-walker/server
sudo -u cyberwalker ./.venv/bin/python -m pip install -r requirements.txt

# 4) 如有 DB 升级:执行 init_db.sql 或对应 migrate 脚本(按发布说明)
#    注意:这一步属于“有风险操作”,请确保备份与变更评审。

# 5) 重启 API
sudo systemctl restart cyber-walker-api

# 6) 健康检查
curl -sS http://127.0.0.1:8000/api/health

# 7) 启动 worker
sudo systemctl start cyber-walker-worker

# 8) 观察日志
sudo journalctl -u cyber-walker-api -n 50 --no-pager
sudo journalctl -u cyber-walker-worker -n 50 --no-pager

10.13.3 回滚思路(最小化损失)

  • 回滚代码到上一个已知可用版本(tag/commit)
  • 重新安装依赖(如果依赖有变化)
  • 重启 API 与 Worker
  • 如果涉及 DB 迁移:优先使用“向前兼容”的迁移策略;若必须回滚 DB,需要严格的备份/恢复演练

10.14 配置与密钥管理建议

  • server/.env 权限建议:仅部署用户可读(例如 chmod 600 /opt/cyber-walker/server/.env
  • JWT_SECRET_KEY / APP_SECRET_KEY 必须替换为随机值,并避免提交到代码库
  • 若使用 OSS/TOTP 等外部服务:密钥建议放入专用的 Secret 管理系统(Vault/KMS/CI Secret),再由 systemd 注入

10.15 备份与监控(最低要求)

最低要求(建议按组织规范增强):

  • MySQL:定期全量备份 + 保留策略(至少能恢复到最近 7 天)
  • Redis:如果仅作 broker 可容忍丢失(取决于业务要求);生产仍建议持久化与监控
  • 日志:journald 或集中式日志(至少保留 API/worker 的关键错误日志)
  • 基础监控:CPU/内存/磁盘、MySQL 连接数、Redis 内存、API 5xx 比例、队列堆积(worker backlog)

10.16 Celery 队列观测(Flower)

当你需要快速回答这些问题时,Flower 很有用:

  • 现在有哪些 worker 在线?并发/心跳是否正常?
  • 队列里有没有积压(reserved/active)?
  • 单个任务运行多久、是否失败重试?

注意:Flower 属于可选组件,默认不随依赖安装。

10.16.1 安装(可选)

在运行 Worker 的同一个 venv 中安装(推荐):

cd /opt/cyber-walker/server
sudo -u cyberwalker ./.venv/bin/python -m pip install flower

10.16.2 运行(开发/临时排查)

绑定本机回环地址,避免直接暴露到公网:

cd /opt/cyber-walker/server

# 确保 server/.env 中已经配置 CELERY_BROKER_URL
sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery \
  -A app.celery_app flower --address=127.0.0.1 --port=5555

访问方式(推荐二选一):

  • SSH 隧道:ssh -L 5555:127.0.0.1:5555 your_server 然后本地打开 http://127.0.0.1:5555
  • Nginx 反代 + Basic Auth(仅内网/受控网络环境):把 Flower 挂在一个受保护路径下

10.16.3 Nginx 反代 Flower(/flower/ + Basic Auth)

强烈建议:Flower 只监听 127.0.0.1:5555,不要直接对公网暴露;外部访问通过 Nginx 受控反代。

  1. 安装 htpasswd 工具并创建账号:
sudo apt update
sudo apt install -y apache2-utils

sudo htpasswd -c /etc/nginx/.htpasswd_flower admin
  1. 在你的 Nginx server 块中加入一个 location(示例挂在 /flower/):
# Flower (Celery monitoring)
location /flower/ {
  # 基本认证
  auth_basic "Flower";
  auth_basic_user_file /etc/nginx/.htpasswd_flower;

  # 可选:再加一层 IP 白名单(推荐内网)
  # allow 10.0.0.0/8;
  # allow 192.168.0.0/16;
  # deny all;

  # 反代到本机 Flower
  proxy_pass http://127.0.0.1:5555/;
  proxy_http_version 1.1;

  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;

  # WebSocket 支持(部分页面/功能可能用到)
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";

  proxy_read_timeout 300s;
}
  1. 检查并 reload:
sudo nginx -t
sudo systemctl reload nginx

访问:https://your.domain.example/flower/(会弹 Basic Auth)。

10.16.4 systemd(长期运行)

创建 /etc/systemd/system/cyber-walker-flower.service

[Unit]
Description=Cyber Walker Flower (Celery Monitoring)
After=network.target

[Service]
Type=simple
User=cyberwalker
Group=cyberwalker
WorkingDirectory=/opt/cyber-walker/server
EnvironmentFile=/opt/cyber-walker/server/.env

# 强烈建议只监听 127.0.0.1,再通过 SSH tunnel 或 Nginx 受控反代访问
ExecStart=/opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app flower \
  --address=127.0.0.1 --port=5555

Restart=always
RestartSec=2

StandardOutput=journal
StandardError=journal

NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true

[Install]
WantedBy=multi-user.target

启用并启动:

sudo systemctl daemon-reload
sudo systemctl enable --now cyber-walker-flower
sudo systemctl status cyber-walker-flower --no-pager

10.16.5 无 Flower 的替代观测(零额外依赖)

如果你不想安装 Flower,也可以用 Celery 自带 inspect 做快速排查:

cd /opt/cyber-walker/server

sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app status
sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app inspect active
sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app inspect reserved
sudo -u cyberwalker /opt/cyber-walker/server/.venv/bin/python -m celery -A app.celery_app inspect stats

一般判断思路:

  • status 看 worker 是否在线
  • active 看是否有卡住的长任务
  • reserved 看是否有明显队列堆积

评论区 (0)

你需要先 登录 后才能发表评论。
还没有人评论,赶快成为第一个吧。