Databasus v3.63.1 安全加固指南

以 v3.63.1 实测逐层验证 Databasus 三层安全模型:secret.key 主密钥机制、凭据 enc: 加密落库与 API 不回显、备份产物 PGRSUS01 封装与独立盐/IV、只读三层预检、2FA 与实例级注册开关、审计日志实证、传输与存储加固,并给出 P0-P2 加固核查清单。

Databasus备份恢复PostgreSQLMySQL 中间件2026/10/24

Databasus v3.63.1 安全加固指南

目标:以 v3.63.1 实测为准,把 Databasus 的安全机制逐层拆开验证,并给出可直接落地的加固清单。Databasus 是备份工具,天然持有数据库凭据与全量数据副本,一旦失守就是「攻击者拿到所有钥匙」——因此本文围绕官方三层安全模型(敏感数据加密、备份加密、只读访问)逐项实测印证,再补齐实例级账户安全、审计、网络暴露面与供应链工程,最后汇总成核查清单。部署过程与备份实测见《Databasus v3.63.1 Docker Compose 部署指南》,组件定位与选型背景见《Databasus v3.63.1 介绍与选型指南》。

一、环境信息与威胁模型

  • 实测日期:2026-10-24;实测版本:v3.63.1(GET /api/v1/system/version 返回 {"version":"3.63.1"});
  • 部署形态:Docker Compose 单体服务(内嵌 PostgreSQL 元数据库),Web 控制台映射宿主 8142 → 容器 4005;数据目录 databasus-data/;
  • 接入目标:PostgreSQL 16 逻辑(backup_ro 角色)、PostgreSQL 17 物理(appuser 走复制协议)、MySQL 8.0 逻辑(backup_ro 角色),三路加密备份均已跑通并完成恢复验证。

威胁模型按数据流向梳理,Databasus 在每一环都持有敏感资产:

环节持有的敏感资产失守后果
元数据库全部数据库连接凭据、存储目的地凭据、通知渠道 secret攻击者可连到所有受管数据库
数据目录secret.key 加密主密钥、备份产物、应用与审计日志主密钥+备份同时失守则加密失效
云存储目的地加密备份文件的副本离线暴力破解风险
Web 控制台管理员会话、下载令牌可触发备份、下载任意备份文件

对应的官方设计原则有四条:敏感数据永不以明文暴露(落库前加密,且永不通过 API/UI 回显);备份必须加密(即使云存储泄露也不可读);Databasus 对业务数据库只读(绝不持有写权限);所有动作可审计。下文逐层实测验证这四条是否落地,再给加固项。

二、三层安全模型总览(官方设计 + 实测印证)

官方文档《Security》将安全强制点分为三层,实测逐一印证如下:

层官方声明本文实测证据(v3.63.1)结论
L1 敏感数据加密凭据以 AES-256-GCM 加密落库,密钥存本地文件不入库postgresql_logical_databases.password 值以 enc: 前缀存储(见第四章);secret_keys 表 0 行,主密钥只在文件✅ 落地
L2 备份加密备份生成时流式加密,每备份独立派生密钥产物文件头为 PGRSUS01 魔数+密文;metadata 含独立 encryptionSalt/encryptionIV(见第五章)✅ 落地
L3 数据库只读三层预检拒绝写权限凭据只读预检拒绝拥有写权限用户的接入,backup_ro 角色通过(见第六章)✅ 落地

三层是纵深防御而非互备:即便服务器被入侵、secret.key 被窃、凭据被解密,L3 仍保证攻击者无法通过 Databasus 的数据库连接写坏业务数据——这是备份工具与普通密码管理器最大的差异点。

三、加密主密钥(secret.key)防护加固

主密钥是全部加密的根,实测属性:

$ ls -la /databasus-data/secret.key
-rw------- 1 databasus databasus 72 Oct 24 09:10 /databasus-data/secret.key
$ wc -c < /databasus-data/secret.key
72

三个关键事实:① 密钥为 72 字节随机数据(首字节 a2 73 67 39…,非可读文本);② 文件权限 600、属主为运行用户 databasus——进程内其他用户不可读;③ 库内 secret_keys 表为空(0 行),主密钥只存在于文件系统,不存在于数据库,因此拖库得不到主密钥。

加固项:

  1. 备份主密钥并与备份文件隔离存放。secret.key 丢失 = 全部历史加密备份永久不可解密(官方无任何恢复手段)。建议:把 72 字节密钥抄录进密码保险库或打印离线保存,不要与备份文件放在同一存储目的地——否则「偷到备份的人」同时偷到钥匙;
  2. 数据目录整体限权。Compose 部署中 databasus-data/ 挂载自宿主,宿主侧执行 chmod 700 databasus-data && chmod 600 databasus-data/secret.key,避免宿主其他账户读取;
  3. 禁止把数据目录打进镜像或提交进代码仓。.gitignore 与 CI 扫描(gitleaks 类)双保险;
  4. 不要为了「方便迁移」把 secret.key 上传到备份目的地。迁移场景正确做法是:备份 databasus-data/ 整体(含 pgdata 与 secret.key)到受控位置,或按官方 FAQ 用实例级备份功能。

四、凭据存储加密与脱敏验证(L1 实测)

4.1 enc: 密文格式实证

接入备份目标时填写的数据库密码,落库后不是明文。直接查询内嵌库(DSN 位于容器内 /dev/shm/databasus-database-dsn):

$ psql "$(cat /dev/shm/databasus-database-dsn)" -tAc \
  "SELECT left(password,30) FROM postgresql_logical_databases LIMIT 2"
enc:hQQlGzQwu4R2OZey:zeOseOu+J

密文格式为 enc:<盐>:<密文> 两段结构。加密算法为官方声明的 AES-256-GCM(认证加密:篡改密文会在解密时报错而非返回错误数据)。同类敏感字段还有 ssh_password、ssh_private_key_passphrase,存储目的地(S3 AccessKey、Google Drive token)与通知渠道(webhook secret、Slack token)同属此列。

4.2 API/UI 不回显验证

官方声明「加密之外,这些值也从不通过 API 或 UI 暴露」。实测:GET /api/v1/databases 系列接口返回的连接对象中密码字段恒为空串或省略,编辑连接时控制台密码框必须重新输入——接口层没有「读取明文凭据」的通道,拖库+抓 API 双路径都拿不到原密码。

4.3 加固项

  1. 轮换即重录:凭据在数据库侧轮换后,务必同步更新 Databasus 中的连接配置;旧密文无法「原地改盐」,直接编辑重存即可;
  2. 凭据最小化:连接账号用专用最小权限角色(见第六章),不用超级用户凭据——加密保护的是「存储侧」,权限控制保护的是「使用侧」,两者叠加;
  3. SSH 隧道场景:私钥口令同样以 enc: 存储,但私钥文件本身建议放在 Databasus 可读的专用路径并限权 600,不要复用运维人员的日常私钥。

五、备份产物加密与完整性(L2 实测)

5.1 产物非明文验证

本地存储目的地下的备份产物(无扩展名文件 + .metadata):

$ head -c 20 pg16-appdb-20261024-092106-a981d549-… | od -c | head -2
0000000   P   G   R   S   U   S   0   1 323   B 205   t 220 236  \v 302
0000020 207 231 201 033

前 8 字节是 Databasus 自有封装格式的魔数 PGRSUS01(区别于原生 pg_dump custom 格式的 PGDMP),第 9 字节起即密文。文件在任何编辑器/对象存储预览中都不可读。

5.2 每备份独立密钥派生实证

.metadata 文件是明文 JSON,记录加密参数:

{"backupId":"a981d549-1aa1-4348-9f5d-d2cfb1367993",
 "encryptionSalt":"00KFdJCeC8KHmYEb59tYJWcL1hVWDND7s1EsWuPRcFI=",
 "encryptionIV":"cL+JI0HcE05G0iia",
 "encryption":"ENCRYPTED"}

与官方声明完全对应:每个备份的加密密钥由「主密钥(secret.key)+ 备份 ID + 随机盐」派生,盐与 IV 每备份唯一——即使两个备份内容完全相同,密文也不同,无法通过密文对比推断内容。加密在备份流水线中位于压缩之后:pg_dump → 压缩 → 加密 → 上传存储,因此存储端(含 S3/Google Drive 等云目的地)收到的永远是密文。

实测压缩与加密叠加收益:200 行 customers + 1000 行 orders 的测试库,pg_dump 原始逻辑备份约 0.18MB,加密产物仅 0.013MB(约 14 倍压缩),加密未破坏压缩收益。

5.3 加固项

  1. metadata 文件与产物一同保存:解密需要盐与 IV,.metadata 丢失则该备份不可恢复——按备份 ID 一一对应存放;
  2. 云目的地泄露演练:定期从存储目的地拉一份备份,在无 secret.key 的机器上验证确实解不开、在持有 secret.key 的机器上验证能通过恢复流程解开(恢复验证机制见《Databasus v3.63.1 配置参数详解》第七章);
  3. 完整性:AES-GCM 自带认证标签,解密时篡改会直接报错——不必额外维护 SHA256 清单,但建议在下载令牌分发环节核对文件大小(下载令牌审计见第八章)。

六、数据库访问最小权限(L3 实测)

6.1 三层只读预检

Databasus 在接受数据库凭据前做三层预检,任何一层发现写权限即告警拒绝:

层检查内容实测行为
角色级不是 superuser、不能 CREATE ROLE/DATABASE用超级用户接入被拒
库级无 CREATE、无 TEMP 权限授予 CREATE 后被拒
表级零写权限(INSERT/UPDATE/DELETE/TRUNCATE 等)缺 SEQUENCE SELECT 也会被拒(只读要求连序列都可读,见下)

实测中最有价值的一条:为 PG16 目标建 backup_ro 角色时,仅授予了表 SELECT,预检报错——pg_dump 导出自定义格式还需要序列上的 SELECT 权限。补齐后通过:

GRANT SELECT ON ALL TABLES IN SCHEMA public TO backup_ro;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO backup_ro;  -- 这条不能漏
GRANT USAGE ON SCHEMA public TO backup_ro;                    -- 只有 USAGE,无 CREATE
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO backup_ro;

MySQL 侧对应:GRANT SELECT, SHOW VIEW, PROCESS, LOCK TABLES ON appdb.* TO 'backup_ro'@'%'(mysqldump 需要 LOCK TABLES 与 PROCESS)。

6.2 为什么「只读」是备份工具的安全底线

官方原话的推演:即使 Databasus 被攻破、服务器被入侵、secret.key 被偷、凭据被解密——四层全破——攻击者拿到的数据库账号依然写不了业务库。备份链路不可能是攻击链。这也是官方提供「代建只读用户」功能的原因:一键创建满足上述全部约束的角色(全表 SELECT、schema USAGE、显式 REVOKE 全部写权限、含未来新表)。

6.3 物理备份的权限特例

PostgreSQL 物理备份走复制协议,账号需要 REPLICATION 属性(实测用 appuser 通过 pg_basebackup 完成,LSN 0/3000028 → 0/3000120)。REPLICATION 角色可以读到全库 WAL 流,但依然不能执行 SQL 写操作,最小权限原则在此降级为「复制专用账号 + pg_hba 白名单」:实测的 pg_hba.conf 仅放行 Databasus 网段访问 replication 数据库(host replication appuser 10.89.67.0/24 scram-sha-256),并强制 scram-sha-256 而非 trust/md5。

6.4 加固项

  1. 永远不用超级用户接入:预检会拦,但不要为绕过预检而降级安全;
  2. 新表默认可读:ALTER DEFAULT PRIVILEGES 保证未来建的表自动对 backup_ro 可见,否则增量业务的新表会静默漏备;
  3. 复制账号独立:物理备份账号与逻辑备份账号分开建,pg_hba 按网段+用户双约束。

七、登录与账户安全(2FA 与实例开关)

7.1 双因子认证机制

官方《Security》文档与密码页均描述了 2FA:管理员开启后,密码登录需再输入发送到邮箱的六位验证码。实测库内对应结构:

users_settings 字段:is_two_factor_auth_required(当前值 f)
独立表:two_factor_codes(当前 0 行)

机制细节(官方文档口径):验证码 10 分钟过期、错 5 次作废、重发替换旧码;开启只影响之后的密码登录,已建立会话不受影响;仅覆盖密码登录,Google/GitHub OAuth 登录直接发 token(依赖提供商自身的多因子);开启前置条件是实例已配邮件服务器且全部在职管理员有真实邮箱——防止把自己锁在门外;邮件服务器故障时密码登录整体失效是有意设计——不允许因投递故障静默降级回单因子。

7.2 应急关闭通道

邮箱通道整体失效时的兜底是服务器上的 shell 命令:

docker exec -it databasus ./main --disable-2fa

命令会报告改了什么,并记录进审计日志——之后审计里能看到「2FA 被谁在何时关掉」,防止有人悄悄降级认证。

7.3 实例级注册与邀请开关

users_settings 另有三个账户面开关,实测默认值均为 t:

字段含义加固建议
is_allow_external_registrations允许外部自主注册公网实例改 f,改为管理员邀请制
is_allow_member_invitations允许成员发邀请按需收紧
is_member_allowed_to_create_workspaces成员可自建工作区多租户场景按需关闭

实测过程中验证了注册端点可用(产生了 MEMBER 角色测试账号),公网部署时这三个开关是第一优先收敛项。工作区隔离(workspace)本身也是安全边界:备份目标、存储、通知、API 令牌都挂在工作区下,成员只可见所属工作区。

八、审计日志实测

审计落库在 audit_logs 表(id / user_id / workspace_id / message / created_at),实测样例:

Download token generated for backup of database: pg16-appdb   2026-10-24 09:24:03
Backup manually initiated for database: pg16-appdb            2026-10-24 09:17:17

实测覆盖的两类事件:手动触发备份、生成备份下载令牌——后者恰是最敏感动作(谁把哪个备份下载走了)。官方口径中审计还覆盖:--disable-2fa 应急关闭、登录行为等。日志同时写入 databasus-data/databasus.log 文件(应用日志与审计并存),文件级留存的优点是即便元数据库被清也能追查。

加固项:

  1. 定期导出:审计表在内嵌库中,实例级备份会一并带走;合规场景建议外部周期拉取 audit_logs 增量;
  2. 关注下载令牌事件:任何非预期时间的 Download token generated 都应核查;
  3. 时钟同步:审计价值依赖时间戳可信,宿主开启 NTP。

九、传输与网络暴露面加固

实测部署中控制台为 HTTP 明文(容器 4005 端口),这是默认形态而非缺陷——备份凭据在落库前已经过 TLS 之外的独立加密,但浏览器到控制台之间的会话(含登录密码、验证码、下载令牌)不受保护。加固序列:

  1. 反代加 TLS:生产环境前置 Nginx/Caddy/Traefik 终结 HTTPS,控制台端口只绑定 127.0.0.1 或内网;恢复验证代理启动参数中的 --allow-insecure-http 仅限测试环境使用,生产一律走 TLS;
  2. 收敛端口暴露:Compose 中控制台端口映射绑定 127.0.0.1:8142:4005 而非 8142:4005;备份目标数据库(pg16/pg17/mysql80)的端口不应映射到宿主——实测栈为验证方便做了映射,生产仅保留 Databasus 容器到目标库的内网通路;
  3. 防火墙白名单:宿主防火墙仅放行办公网/VPN 网段访问控制台端口;
  4. 数据库侧白名单:受管数据库的 pg_hba / MySQL 账号主机限制,只放行 Databasus 所在网段(实测 10.89.67.0/24),拒绝全网段。

十、存储目的地与通知渠道安全

  • 存储凭据同受 L1 保护:S3 AccessKey/SecretKey、Google Drive token、FTP/SFTP 密码均以 enc: 密文落库,API 不回显;
  • 目的地最小权限:S3 bucket 策略建议只授予目标前缀的 PutObject/GetObject/ListBucket,禁 DeleteObject——即使 Databasus 凭据泄露,攻击者也无法删除云上备份(勒索对抗的关键一环);本地存储目的地同理,备份目录对运行用户只写不删;
  • 保留策略即安全机制:FOREVER 档保留可对抗「攻击者删掉备份再加密勒索」;各保留档位取值见《Databasus v3.63.1 配置参数详解》第四章;
  • 通知渠道的 secret 同样加密:Webhook URL 带 token、Slack/Telegram/Mattermost token 均走 enc:;通知内容只含「数据库名+状态+时长」等元信息,不含备份数据本身,泄露通知渠道不泄露数据;
  • 下载令牌:备份下载走一次性令牌而非会话,令牌生成计入审计(第八章实测),分发给第三方时按需设置过期。

十一、供应链与 CI 安全工程

官方以整节篇幅披露了安全工程投入(《Security》🛡️ 一节),要点转述:

  • 静态分析:CodeQL 全库扫描;每个 PR 跑 gitleaks(防密钥泄漏)与 semgrep(安全规则);Dockerfile 与 CI workflow 有独立规则集(pin 住 action 引用、最小权限、可疑基础镜像);另有 OpenAI Codex Security 定期做全库深度审计,覆盖 PR 级扫描漏掉的架构性/横切面问题;
  • 依赖管理:Dependabot 对接 GitHub Advisory Database,CVE 公告后分钟级呈现;更新引入冷却期(新版本先观察再采纳,防供应链投毒);Dependency Review Action 直接阻断引入 HIGH/CRITICAL CVE 的 PR;
  • 容器与 CI 加固:每次构建跑 Trivy 镜像扫描 + Dockerfile 专项扫描;全部 GitHub Actions 钉死到完整 commit SHA(@v4/@main 浮动标签是 2025 年的活跃攻击向量);workflow 默认最小权限、逐 job 按需提权;
  • 恢复即测试:每个 PR 对全部支持的引擎与主版本跑真实数据库容器的「备份→恢复」端到端循环——备份工具最重要的正确性指标是「备了能恢复」而非「备份成功」。

漏洞报告走 GitHub Security tab(SECURITY.md),官方声明安全报告为最高优先级工作队列。

十二、安全加固核查清单

按优先级汇总,可逐项勾选执行:

#优先级加固项依据章节
1P0secret.key 离线备份并与备份文件隔离存放三
2P0关闭外部自主注册(is_allow_external_registrations=f),改邀请制七
3P0控制台前置 TLS,端口绑定 127.0.0.1 或内网九
4P0数据库接入一律用专用只读角色,禁超级用户六
5P1开启管理员 2FA(先确保邮件服务器可用)七
6P1备份目标库端口不映射宿主,pg_hba 按网段白名单 + scram-sha-256六/九
7P1云存储目的地禁 DeleteObject,保留策略设长档位十
8P1数据目录宿主侧 700/600 限权三
9P2审计日志外部周期导出,关注下载令牌事件八
10P2周期执行「无钥解不开、有钥能恢复」演练五
11P2序列 SELECT 权限纳入只读角色基线(防静默漏备)六
12P2跟进上游版本升级(供应链修复随版本发布)十一

十三、常见问题

Q1:secret.key 丢了还能恢复备份吗? 不能。AES-256-GCM 下没有后门,官方不提供任何恢复手段。所以第 1 项加固是「离线备份主密钥」——这是全部安全机制中唯一不可补救的单点。

Q2:metadata 文件明文含盐和 IV,会不会削弱加密? 不会。盐与 IV 的安全前提就是「可以公开」——密钥派生需要主密钥参与,仅有盐/IV 无法反推密钥。metadata 必须与产物一起保存,否则解密缺参数。

Q3:为什么只读预检连 SEQUENCE 权限都要求? 实测踩坑:pg_dump custom 格式导出时会读序列(sequence)元数据,缺 SELECT 会导出失败。Databasus 把「能完整备份」作为只读判定的标准,宁可拒绝也不接受半残账号——这是正确的失败方向。

Q4:2FA 开启后邮件服务器坏了,全员锁死怎么办? 官方有意不让认证静默降级:密码登录会持续失败直到邮件恢复,或由有 shell 权限的运维执行 --disable-2fa(该动作本身进审计日志)。这保证「锁死」是显式、可追溯的,而非悄悄变回单因子。

Q5:内嵌 PostgreSQL 的超级密码在 DSN 里,算不算暴露面? DSN 只存在于容器内 /dev/shm/databasus-database-dsn(tmpfs,重启即消失),内嵌库只监听容器内部。暴露面收敛点是控制台端口而非内嵌库——把 8142 这类映射管好即可。

十四、参考链接