NovaBot
GitHub

附录 C 安全须知与资源占用

正文讲怎么把它用起来,这一本附录讲两件容易被略过的事:哪些地方不设防会出事, 以及机器要备多少资源。两节都不长,装好之后通读一遍即可。 完整的安全说明在仓库的 SECURITY.md, 这里挑使用者必须知道的几条。

部署时必做的几件

配置界面默认只监听本机回环地址并要求访问令牌。要从外网访问,请走 SSH 隧道, 不要直接把端口暴露到公网:

ssh -L 7827:127.0.0.1:7827 用户名@服务器地址

推送接口有口令鉴权与来源 IP 白名单,默认只放行本机。 若确需从其他机器调用, 同时做到三点:给 novabot.adapter.onebot.senders 下的每个推送平台配强随机的 api-token、把来源地址加进 novabot.adapter.onebot.security.allow-ips、在防火墙上限制来源。

cookies.json 等同于哔哩哔哩账号的完整控制权,默认加密存储,密钥在 cookies.key。 两个文件都要妥善保管,也都不要提交到任何仓库;权限定期核对仍是 600。 向他人求助时,最稳妥的做法是只发日志,不发整个工作目录。非发目录不可时,先删掉这些—— 工作目录里的:

  • application.yml 与它保存时留下的备份(application.yml.yyyyMMdd-HHmmss.bak 这类名字):里面有控制台访问令牌、两步验证密钥、OneBot 与推送接口的令牌、邮件授权码这类凭据
  • cookies.json、cookies.key 与 cookies.json.plain.bak(明文凭据迁移为加密存储时留下的备份)
  • datasource.json:写着推送到哪些群、哪些 QQ

以及数据目录里的(没挪过数据目录的话,它与工作目录是同一个):

  • state.json:群成员的 QQ 号与其绑定的哔哩哔哩 uid
  • data.json 与 sessions.jsonl:观众 uid 与昵称、按场的观众名单
  • timeline/:事件时间线,含主播名与推送目标的群号/QQ 号
  • details/:每场的弹幕原文与发言人、排行名单、大航海名单,含观众 uid 与昵称

上面这些文件旁边,名字后面多了 .bad- 加时间或 .tmp 的同名件,内容和原件一样,也要一并删掉。

novabot.core.exec 能执行任意程序,默认关闭。 打开前请确认清楚要跑的是什么; 命令以参数数组执行而非交给 shell,因此昵称、弹幕内容逃不出参数去 (写法见附录 B)。

用小号登录哔哩哔哩。 程序默认开着「自动关注被监听的主播」,会主动用登录账号执行关注操作, 凭据一旦泄露,攻击者即取得该账号的完整控制权。QQ 那一侧同理:发消息的是 OneBot 实现登录的那个号,别拿主号用。

自动关注被 B 站明确拒绝(如对方隐私设置不让关注)时,每天再试一次;网络出错照旧下一小时再试。

OneBot 实现(NapCat 等)那一侧的端口要自己管住。 安装脚本不会、也无法替你配置它。 NapCat 一般开三个监听,三个都要绑回环并各自设令牌——尤其是 6099 的 WebUI, 拿到它就等于拿到这个 QQ 号(能换登录、能往任意群发消息、能读历史):

端口(默认)是什么风险
3000OneBot HTTP能借机器人发消息
3001OneBot WebSocket同上
6099WebUI等同于这个 QQ 号的完整控制权

装完自己核一遍,每一行都应是 127.0.0.1 而不是 0.0.0.0:

ss -tlnp | grep -E ':(3000|3001|6099)\b'

需要远程用 WebUI 扫码时建端口转发过去(ssh -L 6099:127.0.0.1:6099 用户名@服务器地址), 不要把 6099 放开。

配置界面若要开到公网,必须启用密码登录。 放开 novabot.core.config-ui.allow-ips 而不设密码, 等于把「改推送目标、看运行数据」的权限对全网敞开。 设了密码之后:二次验证默认要求,密钥必须明文存放在配置里(所以 application.yml 的权限要收紧到 600);必须走 https;忘记密码或验证器丢了,把 novabot.core.config-ui.auth.operator-token 改成 true 重启,用启动日志里的地址进去改完再改回 false。 这个启动令牌等同于密码加验证器,而且走地址栏、会进反向代理的访问日志,平日里不要开着。

启动日志里的地址按 INFO 级别输出。日志只看错误或已关闭时,先把 novabot.core.log.console 或 novabot.core.log.file 临时改为 INFO 后重启, 用完把日志设置改回原值,并把 novabot.core.config-ui.auth.operator-token 改回 false。

观众数据与金额

程序会按用户记录直播间内的互动量(弹幕条数、礼物价值等),用于排行榜, 以及下播报告里按人出的那几块(弹幕排行、流水排行、醒目留言名单、大航海名单等),并缓存观众头像地址。 这些都是直播间里本就公开可见的信息,不涉及私聊内容或好友关系。 两点仍值得注意:

  • 账号绑定已停用:没有接口能证明某个 QQ 号与某个哔哩哔哩账号属于同一人,绑定只核对昵称防打错。5.1.0 起绑定与个人数据查询的命令一并撤掉,控制台也不再显示这一块。互动量仍按人记着,只供给上面说的排行榜和报告,不再按 QQ 号去查某一个人
  • state.json 里的历史绑定仍可以反推出人,换机器、发日志、交接部署时按上面说的处理

金额是另一回事。 直播收益、每位观众送了多少钱,属于主播的经营信息与观众的消费记录。 4.2.0 起「谁能看到金额」是会话自己的属性,默认私聊显示、群聊隐藏,且只能在控制台改—— 若允许群里的人自己把它打开,这道设置就形同虚设。

设置页的「直播间原始消息调试日志」与「动态接口原始响应调试日志」会把原始消息完整写进 日志,不需要时保持关闭;排障用的 EventDebug/ 也含观众昵称与 uid,用完记得关掉 (见第 14 章)。

在反向代理之后

若在 Nginx 之后部署,需显式开启 trust-proxy,否则来源 IP 始终是代理的地址:

novabot:
  adapter:
    onebot:
      security:
        trust-proxy: true

反代还要把浏览器发来的 Host 原样送下来,不然控制台的登录或保存会被拒(「请求来源不正确」), 写法见 SECURITY.md 的「关于反向代理」一节。

只有在请求确实全部经过可信代理时才可开启——直接暴露的服务开这一项, 等于让 IP 白名单可以被一个请求头绕过。开启后取的是 X-Forwarded-For 里 最右侧的那一段(最左侧完全由客户端说了算)。本仓库的反代模板不让客户端自带的该头送下来, 自己写 Nginx 时用 proxy_set_header X-Forwarded-For $remote_addr; 覆写,改它之前请先读 SECURITY.md 的 「关于反向代理」一节。

让代理服务使用控制台会话

代理可用 GET /config/api/session-check 检查会话是否有效;该接口接受所有有效角色。 管理后端应使用 GET /config/api/admin-session-check,仅已启用的管理员返回 204。 两者成功时均无响应体;未登录、会话过期、账号待授权或已停用时返回 401, 管理员检查遇到成员时返回 403。尚未完成使用协议确认时也返回 403。 本地口令、统一登录的管理员和启动令牌通道均可使用管理员检查。 使用原有检查地址后,本次运行会记一条日志提醒,并在管理员网页控制台的各页顶部显示接入提醒。 改好管理后端的代理检查地址并重启 NovaBot,且不再使用原有检查地址后,提醒不再出现。

Nginx 接入管理后端的示例(端口与后端地址按实际部署填写):

location = /config/_admin-check {
    internal;
    proxy_pass http://127.0.0.1:7827/config/api/admin-session-check;
    proxy_method GET;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header Host $http_host;
    proxy_set_header Cookie $http_cookie;
}

location /config/admin/ {
    auth_request /config/_admin-check;
    proxy_pass http://127.0.0.1:9000/;
}

被代理服务的浏览器访问路径也应位于 /config/ 下,会话 Cookie 才会随请求发送。 若配置了 server.servlet.context-path,上述对外路径、检查地址与 auth_request 地址均加上该前缀。 检查请求同样沿用来源 IP 白名单与会话活跃时间刷新约定。后端仍需执行自身的登录与角色检查。

挂在路径前缀下

要把控制台挂在某个路径前缀下(例如 https://example.com/novabot/config), 把 Spring 的 server.servlet.context-path 设成那个前缀:

server:
  servlet:
    context-path: /novabot
  • 反代原样转发路径,不剥前缀:/novabot/ 下的请求照原路径转给 NovaBot。页面、接口、登录 Cookie 都按这个前缀写,地址对不上时登录后会又回到登录页。
  • NapCat WebUI 那条反代规则跟着带前缀,写成 /novabot/config/napcat/(即「前缀 + /config/napcat/」)。
  • 反代剥掉前缀再转发、靠 X-Forwarded-Prefix 告诉 NovaBot 前缀的那种部署不支持: NovaBot 只认自己配置里的前缀,不认请求头里的。

资源占用

一句话:按带负载的稳态峰值(约 896 MB)规划机器内存。这个数是测过的那个场景里的峰值,不是上界;约 476 MB 只是同条件下较短时段的稳态常驻,按它去备会不够。512 MB 的机器不够用; 1 GB 的机器要把 -Xmx 与 systemd 的 MemoryHigh / MemoryMax 一起往下调,只压其中一个 会让进程被内核直接杀掉或被节流拖慢;MemoryHigh / MemoryMax 用覆盖设置放在模板单元上, 别直接改单元文件(升级会被模板重写)。实测条件、数字与调法都在 附录 A。

CPU 占用主要来自直播间长连接的心跳与动态轮询,监听的主播多时属正常。

报告漏洞与使用立场

安全问题不要走公开渠道发。请用仓库的 Security → Report a vulnerability (私密漏洞报告)描述问题与复现步骤,收到后会尽快处理。

本项目面向中小型公会、个人势主播及其运营人员,用于自有或已获授权的直播间数据采集、 通知与运营分析。不做风控对抗:不伪造浏览器指纹、不伪造观看行为数据, 连接行为按「礼貌客户端」设计(指数退避、全局连接节流、不高频轮询、遵守平台限流反馈)。 任何「提高采集速度或密度」的需求都要先过这条线,大规模采集场景下不保证账号安全与数据完整性。

两件本项目无法根治、只能让它不静默发生的事:NapCat 等 OneBot 实现属于非官方 QQ 协议 实现,存在账号被封禁的风险;QQ 登录态可能在无预兆的情况下失效(服务端或 NapCat 重启后 有一定概率提示登录态已失效),需要重新扫码。OneBot 连接中断会触发健康告警, 配上不经过机器人链路的通道(Webhook / Bark 一类)才能在 QQ 那一侧已经停摆时把消息送出来。