这是本节的多页打印视图。 .
安全合规
数据库通常是信息系统中最敏感的组件:它保存着最有价值的数据,也因此是攻击与故障后果最严重的地方。 数据库安全并不是某个可以一键开启的功能,而是一系列问题的答案之和:谁能连进来?连进来能做什么?流量会不会被窃听?操作有没有留痕?数据坏了、丢了、被删了,还能不能恢复?
Pigsty 把这些问题的答案沉淀为一套 开箱即用的安全基线,并用 声明式配置 的方式加以管理: HBA 规则、角色与权限、证书与加密、备份与审计策略,全部以 参数 的形式在 配置清单 中声明,由幂等剧本渲染落地。
这种 安全即代码(Security as Code)的做法本身就是一项重要的安全实践:安全策略可以被版本控制、评审与回溯,配置清单为多实例环境提供统一基线。 当审计者问“谁能访问这个数据库”时,可以先从一份可读的 YAML 声明出发,再用实际生成的 HBA 与数据库授权验证它是否已经生效。
安全即代码
在传统运维中,安全配置散落在各个角落:某台服务器上的 pg_hba.conf,某位 DBA 手工执行过的 GRANT 语句,某次应急时临时放开的防火墙规则。
时间一长,文档与实际状态容易出现偏差,也很难快速确认各实例正在使用哪一版规则。
Pigsty 的做法不同:安全策略是集群定义的一部分,与集群的其他属性写在一起。
用户、权限、HBA 规则以声明的方式描述,剧本负责把它们幂等地应用到集群的每个实例上:
新加入的实例可以沿用同一套策略,git 提交历史也可以记录安全配置的变更。手工执行的 GRANT、运行时参数修改和节点文件变更仍可能造成漂移,因此生产环境还需要定期核对实际状态。
默认安全基线
合理的默认值可以减少遗漏。以下能力在 Pigsty 默认配置下即处于启用状态:
| 能力 | 默认行为 | 相关参数 |
|---|---|---|
| 密码哈希 | 新设置或更新的 PostgreSQL 口令使用 SCRAM-SHA-256 | pg_pwd_enc |
| 数据校验和 | 集群初始化时启用页级校验和,捕获静默数据损坏 | pg_checksum |
| 服务端 TLS | PostgreSQL 服务器证书就位并启用 ssl,可以接受 TLS 连接 |
- |
| 本地 CA | 自动创建自签名 CA,为受管组件签发证书 | ca_create |
| etcd 加密认证 | 客户端与对等通信 TLS,RBAC 密码认证 | etcd_root_password |
| MINIO 对象存储 HTTPS | Silo 备份流量默认走 HTTPS | minio_https |
| Nginx HTTPS | Web 入口默认同时监听 80、443 | nginx_sslmode |
| HBA 规则集 | 分层放行:本地 ident,内网口令,公网管理员强制 SSL | pg_default_hba_rules |
| 角色与权限 | 四层角色模型与默认权限模板,提供最小权限基线 | pg_default_roles |
| 备份恢复 | pgBackRest 默认启用,本地仓库保留两份全量备份 | pgbackrest_enabled |
| 防火墙 | zone 模式:信任内网网段,公网仅放行必要端口 | node_firewall_mode |
| 受限 sudo | 数据库系统用户的 sudo 被限制在必要命令集内 | pg_dbsu_sudo |
有所取舍的加固项
默认配置面向运行在受信内网中的部署,一部分安全能力需要显式启用 —— 它们或有性能与兼容性代价,或需要用户提供额外的决策:
- 默认配置与示例模板包含 文档公开的默认密码,方便快速上手与本地测试。生产部署应先用
./configure -g随机化其支持的凭据,再检查 pgBackRest 加密口令、ha/safe中的 Silo 用户和自定义值。 - Patroni REST API 与 PgBouncer 的 TLS 默认未启用(
patroni_ssl_enabled、pgbouncer_sslmode),可以使用已经签发的证书显式开启。 - 密码强度检查(
passwordcheck)与 审计扩展(pgaudit)默认未启用;使用前应确认软件包可用,再完成预加载与策略配置。 - SELinux 默认处于
permissive模式;演示配置的防火墙额外放行了5432端口,生产环境应当移除。 - 本地备份仓库默认 不加密;远程
minio仓库预设默认启用 AES-256 加密,但需要修改默认加密口令。
安全加固模板 ha/safe 将 TLS、证书认证、密码检查和备份加密等配置组合在一起,
并配合面向一致性优先业务的 CRIT 参数模板 给出一份可直接修改的示例。模板中的公开凭据、审计扩展与故障模型仍需逐项确认。
完整的升级路径见 安全模型。
本章内容
| 章节 | 回答的问题 |
|---|---|
| 安全模型 | 信任的根在哪里?防线有几道?如何从默认基线逐步加固? |
| 身份认证 | 谁能连进来?如何证明身份?HBA 规则如何声明与生效? |
| 访问控制 | 连进来之后能做什么?最小权限如何成为默认行为? |
| 加密通信 | 流量如何加密?证书由谁签发、如何分发与轮换? |
| 数据安全 | 数据如何保证完整、可恢复、保密、可追溯? |
| 合规实践 | 如何把安全能力映射到等保与 SOC 2 的控制要求? |
相关话题
概念层之外,以下页面提供操作层面的安全内容:
- 🔰 安全建议:单机快速上手场景的最小加固动作
- 🛡️ 安全考量:生产部署的安全加固检查清单
- 📄
ha/safe模板:安全加固配置模板完整参考 - 🔑 HBA 规则:PGSQL 模块 HBA 配置详解
- 👤 访问控制:角色与权限参数参考
- ♾️ 高可用:业务连续性保障
- ⏰ 时间点恢复:PITR 原理与灾难恢复;操作见 PGSQL 备份恢复
1 - 安全模型
在讨论具体的安全特性之前,值得先回答两个更基本的问题:信任的根在哪里,以及 防线有几道。 前者决定了你应该重点保护什么,后者决定了当某一道防线失守时,你还剩下什么。
信任边界
Pigsty 是一套基于 Ansible 的声明式部署系统,它的信任模型与其他控制平面系统类似:管理节点 就是控制平面,也是整个部署中最需要保护的节点。
| 角色 | 掌握的资产与权限 |
|---|---|
| 管理节点(Admin Node) | 配置清单 pigsty.yml(通常包含系统与业务凭据)、CA 私钥、对所有节点的 SSH 管理权限 |
| INFRA 节点 | 监控告警、DNS、Nginx 入口、软件仓库 |
| 数据库节点 | 数据库实例、本地 dbsu、受限 sudo |
| 客户端 | 数据库凭据或客户端证书,经服务端口、HBA 与认证进入 |
这些角色掌握的能力不同,并不是简单的线性等级。其中三份资产尤其关键:
- 配置清单
pigsty.yml:包含所有组件的密码与凭证。应当严格控制管理节点与配置仓库(如果使用 git 管理)的访问权限。 - CA 私钥
files/pki/ca/ca.key:整个部署的信任锚点,持有它就可以签发任意受信证书。文件权限为0600,存放于0700的目录中,建议离线备份。 - 管理用户的 SSH 私钥:管理节点通过 SSH 免密 sudo 管理所有纳管节点,这份私钥等价于所有节点的 root 权限。
Pigsty 的 安全策略 对此有明确表述:需要管理节点访问权限、或已持有 pigsty.yml 与 CA 私钥才能实施的攻击,不被视作安全漏洞 ——
这些是设计上的高信任控制面,必须以相应的等级加以保护。
七道防线
纵深防御不依赖某一项机制独立解决所有问题,而是让不同控制相互补充。 Pigsty 的安全能力可以归纳为七道防线:
| # | 防线 | 机制 | 详见 |
|---|---|---|---|
| 1 | 网络边界 | 防火墙分区、监听地址收敛、统一入口 | 本页下文 |
| 2 | 传输加密 | 本地 CA、组件间 TLS | 加密通信 |
| 3 | 身份认证 | HBA 规则集、SCRAM 密码、客户端证书 | 身份认证 |
| 4 | 访问控制 | 角色体系、默认权限、数据库隔离 | 访问控制 |
| 5 | 主机安全 | SELinux、受限 sudo、专用系统用户 | 本页下文 |
| 6 | 数据安全 | 校验和、备份与加密、PITR、防误删 | 数据安全 |
| 7 | 审计追溯 | DDL 与连接日志、审计扩展、集中日志 | 数据安全 |
其中第 2、3、4、6、7 道防线各有专门章节展开,这里补充说明网络与主机两道防线。
网络边界
Pigsty 在节点置备时默认启用防火墙(node_firewall_mode 默认为 zone 模式),按操作系统使用 firewalld 或 ufw 实现:
内网网段(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16,由 node_firewall_intranet 定义)加入信任区,
公网侧仅放行 node_firewall_public_port 声明的端口,默认为 22(SSH)、80、443(Web)。
默认演示配置
pigsty.yml中额外放行了5432端口以便本地体验,生产部署通常应当移除。确需直接接入数据库时,应通过安全组、防火墙与 HBA 将来源限制到明确网段。
数据库默认监听所有地址(pg_listen:0.0.0.0),实际访问范围由监听地址、防火墙与 HBA 共同决定。对于要求更严格的场景,可以将监听收敛到特定地址:
默认防火墙不会直接向公网开放 Grafana、VictoriaMetrics 等 Web 基础设施,外部访问通常经由 Nginx 门户 反向代理接入; 数据库流量则通过 HAProxy 提供的 服务 端口接入。入口越少,越容易加固,也越容易审计。
主机安全
主机层的核心原则:每个系统用户只拥有完成本职工作所需的最小权限。
- 数据库超级用户
postgres(pg_dbsu)默认 不设密码,只能通过本地ident认证登录数据库,无法远程以超级用户身份进入。 它的 sudo 权限由pg_dbsu_sudo控制,默认为limit模式:仅允许免密执行数据库相关服务的systemctl操作与日志查看,而不是完整的 root 权限。 - 管理用户(
node_admin_username,默认dba)供运维人员与剧本使用,默认拥有免密 sudo(nopass); 安全敏感的环境可通过node_admin_sudo改为all(sudo 需输入密码)或limit(限制命令集)。 - SELinux 由
node_selinux_mode控制,默认为permissive模式:记录违规行为但不阻断,为切换到enforcing强制模式积累基线。
Pigsty 不接管 SSH 服务端配置:禁用口令登录、限制 root 远程登录等操作系统级加固不在剧本管理范围内,应当纳入您自己的主机安全基线。
加固梯度
安全水位的提升不必一步到位。Pigsty 提供了一条清晰的升级路径,每一档都建立在前一档之上:
第一档:默认基线。开箱即用的安全能力包括 SCRAM 密码、数据校验和、本地 CA 与组件证书、分层 HBA、四层角色模型、默认备份和防火墙分区。 它适合受信内网中的开发、测试与验证环境;生产部署还需要继续检查凭据、网络边界和客户端验证。
第二档:随机凭证。默认密码是公开写在文档里的,任何暴露于网络的部署都必须更换。在生成配置时加上 -g 选项,可以随机化配置向导识别的内置参数和示例凭据:
该选项不会替换 pgBackRest 的 cipher_pass、ha/safe 中的全部 Silo 示例凭据,也不会处理用户自定义值。完整范围见 默认凭证清单。
第三档:策略加固(ha/safe 模板)。配置模板 conf/ha/safe.yml 将多项安全配置组合为一份可以继续定制的参考:
- TLS 与证书认证:主要 TCP HBA 规则使用
ssl,公网管理员使用客户端证书;PgBouncer 启用require,Patroni API 启用 HTTPS。本地ident与部分 localhost 口令规则仍然保留。 - 密码策略:显式预加载
passwordcheck,并为内置用户声明expire_in;模板中的示例口令仍需在部署前检查和替换。 - 攻击面收敛:监听地址收敛至
${ip},${vip},${lo},监控与管理账号从公网访问连接池被显式拒绝。 - 备份加密:pgBackRest 使用远程
minio仓库预设并启用 AES-256-CBC;pgBR.${pg_cluster}是可预测的示例值,必须替换。 - 安全扩展:安装
passwordcheck、credcheck、pgaudit、pgsodium、anonymizer等安全相关扩展;安装不等于预加载、创建或配置。
第四档:内核加固(crit.yml 参数模板)。safe 模板默认为集群指定了面向核心业务的 CRIT 参数模板,它相对通用的 oltp 模板:
- 强制启用数据校验和,不受
pg_checksum参数影响; - 启用严格同步复制(
synchronous_mode_strict),没有可用同步副本时阻塞需要同步确认的写入; - 记录连接与断开事件;PostgreSQL 18 还会区分连接接收、认证与授权阶段;
- 将 watchdog 配置为
automatic,仅在系统存在可用设备时启用。
严格同步模式以不丢失已确认事务为目标,但仍依赖 synchronous_commit、同步副本状态和故障切换条件;RPO 需要通过目标拓扑上的故障演练验证。
也可以不使用完整模板,只挑选需要的加固项,声明在集群或全局参数中:
接下来
2 - 身份认证
PostgreSQL 使用 pg_hba.conf 进行 基于主机的认证(Host-Based Authentication):谁(用户)、从哪里(来源地址)、访问什么(数据库)、需要以何种方式证明身份(认证方法)。
这套机制足够强大,但在集群环境中手工维护的成本很高:主库与从库可能需要不同规则,配置文件又分布在每个实例的数据目录中。 如果缺少统一声明和刷新流程,各实例的规则很容易发生漂移。
Pigsty 的答案与 声明式配置 一脉相承:HBA 规则是配置清单的一部分,由剧本统一渲染与下发。
HBA 即代码
集群的 HBA 规则由两组参数拼接而成:全局默认规则 pg_default_hba_rules 与集群自定义规则 pg_hba_rules;
PgBouncer 连接池 另有独立的两组对应参数(pgb_default_hba_rules 与 pgb_hba_rules)。
每条规则可以用两种形式书写。别名形式 是推荐的方式,一条规则一行,语义一目了然:
原始形式 则直接给出 pg_hba.conf 的原文,用于表达别名覆盖不了的特殊规则。
除了四要素之外,规则还有两个控制字段:
order:渲染顺序。HBA 按“先匹配先生效”的原则工作,顺序即优先级。约定0-99保留给用户的高优先级规则,100-999是默认规则集,未指定order的规则排在最后。role:实例角色过滤。common与default规则对所有实例生效;primary、replica、offline、standby、delayed规则仅在对应角色的实例上启用;role: offline的规则还会额外下发给标记了pg_offline_query的实例。同一份声明渲染到不同实例,得到的是各自角色对应的规则 —— 主从差异不再需要手工维护。
修改声明后,使用封装好的脚本应用变更,规则会被重新渲染并重载生效:
pg_hba_rules 用于追加规则,不会自动收窄范围更宽的默认规则。需要建立更严格的边界时,应同时审查 pg_default_hba_rules,并在变更后检查各实例实际生成的 pg_hba.conf。
地址与认证别名
别名形式的价值在于把常见场景抽象为语义化的词汇。addr 字段的别名展开为具体的地址块:
| 别名 | 展开为 | 含义 |
|---|---|---|
local |
Unix Socket | 仅本地套接字 |
localhost |
Unix Socket、127.0.0.1/32 与 ::1/128 |
本机 |
admin |
<admin_ip>/32 |
管理节点 |
infra |
各 INFRA 节点的 /32 地址 |
基础设施节点 |
cluster |
集群各成员的 /32 地址 |
集群内部 |
intra |
10.0.0.0/8、172.16.0.0/12、192.168.0.0/16 |
内网网段,可通过 node_firewall_intranet 定制 |
world |
0.0.0.0/0 与 ::/0 |
任意地址 |
| CIDR 地址 | 原样保留 | 自定义网段 |
auth 字段的别名决定认证方法,以及是否强制 TLS 连接:
| 别名 | 认证方法 | 说明 |
|---|---|---|
deny |
reject |
显式拒绝 |
trust |
trust |
无条件放行,慎用 |
pwd |
scram-sha-256 或 md5 |
依 pg_pwd_enc 而定,默认 SCRAM |
sha |
scram-sha-256 |
强制 SCRAM |
md5 |
md5 |
兼容旧客户端 |
ssl |
hostssl 与密码认证 |
密码认证,且必须走 TLS |
ssl-sha |
hostssl 与 scram-sha-256 |
TLS 与强制 SCRAM |
cert |
hostssl 与 cert |
客户端证书认证 |
ident、os |
ident(PgBouncer 中为 peer) |
操作系统用户映射 |
peer |
peer |
本地操作系统用户 |
用户字段支持四个占位符,渲染时替换为实际用户名:${dbsu}(超级用户)、${repl}(复制用户)、${monitor}(监控用户)、${admin}(管理用户);
+role 前缀表示匹配该角色的所有成员。
这里还要区分两件事:auth: ssl 只要求连接使用 TLS,并不要求客户端验证服务端身份。安全敏感的客户端还应使用 sslmode=verify-full 和可信 CA,详见 加密通信。
默认规则解读
Pigsty 的默认 HBA 规则集体现了一个简单的原则:来源越远,要求越严。以下是 PostgreSQL 侧的默认规则(源码原文):
逐层来看:
- 本地最受信任:超级用户
postgres只能通过本地 Unix Socket 以ident方式进入 —— 不需要密码,但也无法在远程使用。这就是为什么 dbsu 默认不设密码:不存在可以被窃取的口令。 - 内网次之:复制与业务账号在内网使用 SCRAM 口令认证;监控和管理用户的远程访问主要面向 INFRA 节点。
- 公网最严:默认只有管理员可以从任意地址访问,且必须同时提供口令与 TLS 连接。
PgBouncer 侧的默认规则更保守一层:监控与管理账号从公网访问连接池会被显式 deny,业务用户则限定在本机与内网。
需要特别说明,默认 +dbrole_offline 规则没有设置 role,因此会应用到所有实例。要把离线用户限制到 pg_role: offline 或设置了 pg_offline_query: true 的实例,必须在对应 HBA 规则上显式增加 role: offline。
这份默认规则集是“可用性优先”的取舍:业务账号在内网使用口令认证即可接入。
ha/safe 模板将主要 TCP 规则改为 ssl,管理员从非内网位置访问必须持有客户端证书(cert);本地 ident 与部分 localhost 口令规则仍然保留。
密码策略
Pigsty 默认使用 PostgreSQL 官方推荐的 scram-sha-256 算法存储密码(pg_pwd_enc),仅在需要兼容老旧客户端时才应降级为 md5。
密码处理链路会在执行 ALTER USER ... PASSWORD 前临时关闭语句日志(SET log_statement TO 'none'),避免口令进入 PostgreSQL 日志。
但明文口令仍会出现在配置清单中,渲染后的用户 SQL 也会以 0640 权限写入 /pg/tmp/pg-user-<name>.sql;相关任务没有完整使用 Ansible no_log。因此应限制管理节点、配置仓库和自动化输出的访问,并避免对含凭据任务使用 --diff。
密码强度默认不做强制,需要时可以预加载 passwordcheck 扩展,或使用规则更丰富的 credcheck 扩展:
ha/safe 模板显式设置了上述 pg_libs;单独选择 CRIT 参数模板不会自动加载 passwordcheck。
账号有效期通过用户定义中的 expire_in(自创建起天数)或 expire_at(截止日期)声明,配合组织的密码轮换制度使用:
证书认证
口令终究可能被钓鱼、复用或撞库。对管理员这样的高权限账号,可以在 HBA 中使用 auth: cert 要求 客户端证书认证:
客户端必须持有由本地 CA 签发、CN 与数据库用户名一致的证书才能建立连接。在 HBA 仅接受 cert 的前提下,单独泄露口令不足以通过认证。
使用内置的 cert.yml 剧本签发客户端证书:
签发的证书位于 files/pki/misc/<cn>.key 与 files/pki/misc/<cn>.crt。客户端私钥应通过受控渠道交付;客户端仍需使用 verify-full 验证数据库服务端,证书体系详见 加密通信。
连接池与组件 API
数据库本体之外,还有两类入口需要认证:
PgBouncer 连接池 使用独立的 HBA 规则集与用户列表。默认关闭 pgbouncer_auth_query,此时只有声明了 pgbouncer: true 的用户才会进入 userlist.txt 并通过连接池认证;启用动态认证查询后,应重新评估可登录用户范围。
Patroni REST API 承载高可用控制指令(重启、切换、重载配置),写操作要求 HTTP Basic 认证(patroni_username 与 patroni_password),
且来源受地址白名单限制;启用 patroni_ssl_enabled 后 API 全程走 HTTPS。
Grafana、HAProxy 管理界面、MINIO 模块对象存储后端、etcd 等组件的凭证同样在配置清单中声明,完整清单与修改方式见 合规实践。
接下来
3 - 访问控制
认证 回答“你是谁”,授权回答“你能做什么”。
权限失控很少是因为缺少机制 —— PostgreSQL 的 GRANT 与 REVOKE 足够精细。问题在于缺少一套被默认执行的约定:
业务上线时直接把账号设为属主;临时排障授予超级用户后没有及时回收;新表创建后遗漏授权,最终在生产环境触发权限错误。
Pigsty 提供了一套开箱即用的基础访问控制模型作为起点:四层角色、默认权限与数据库隔离。 它减少了逐库手工授权,但仍需要部署方按业务边界分配角色,并定期核对实际权限。
角色体系
Pigsty 默认创建四个 业务角色 —— 它们不可登录,作为权限组使用:
| 角色 | 属性 | 继承 | 用途 |
|---|---|---|---|
dbrole_readonly |
NOLOGIN |
- | 全局只读访问 |
dbrole_readwrite |
NOLOGIN |
dbrole_readonly |
全局读写(DML),业务账号的默认选择 |
dbrole_admin |
NOLOGIN |
dbrole_readwrite、pg_monitor |
对象创建(DDL),管理与发布流程使用 |
dbrole_offline |
NOLOGIN |
- | 独立只读角色,可配合 HBA 限制到离线实例 |
以及四个 系统用户,各自只承担一种职责:
| 用户 | 属性 | 用途 |
|---|---|---|
postgres |
SUPERUSER |
数据库超级用户:不设密码,仅限本地 ident 登录 |
replicator |
REPLICATION |
流复制与备份,附带 pg_monitor 与只读权限 |
dbuser_dba |
SUPERUSER |
日常管理用户,继承 dbrole_admin |
dbuser_monitor |
- | 监控用户,仅持有 pg_monitor 与只读权限 |
业务账号通过 roles 字段挂载到角色组上,权限随继承而来:
角色体系本身也是声明的一部分(pg_default_roles),可以定制。
该参数是一份完整列表;调整时应保留所需的系统用户与默认角色,并同步检查 HBA、默认权限和脚本中的角色引用。
默认权限
角色解决了“权限授予谁”,还剩下另一半问题:新创建的对象如何自动获得正确的权限?
PostgreSQL 的原生答案是 ALTER DEFAULT PRIVILEGES。Pigsty 通过 pg_default_privileges 将其声明化:
只读角色获得查询与执行权限,读写角色叠加 DML,管理角色再增加对象管理所需的 DDL 辅助权限。
所有权约定
默认权限机制有一个经常被忽略的前提:它只对配置了默认权限的对象创建者生效。Pigsty 会为以下身份配置默认权限:
- 数据库系统用户
pg_dbsu,默认为postgres; - 管理用户
pg_admin_username,默认为dbuser_dba; dbrole_admin;- 每个在
pg_databases中声明的数据库属主。
应用 DDL 通常应使用声明的数据库属主;平台级管理与发布操作可以使用 dbuser_dba,或先 SET ROLE dbrole_admin。由其他用户直接创建的对象不会自动进入这套默认权限体系,除非另行为该用户配置 ALTER DEFAULT PRIVILEGES。
这不是 Pigsty 的限制,而是 PostgreSQL 默认权限机制本身的工作方式:默认权限跟随对象创建者,而不是数据库或会话中的登录用户名自动传播。
数据库隔离
默认情况下,PostgreSQL 向 PUBLIC 授予数据库 CONNECT 权限。只要 HBA 同时允许连接,可登录用户就可能进入并不属于自己的数据库;多业务共享集群时尤其需要收敛这一默认值。
在数据库定义中声明 revokeconn,即可回收公共连接权限:
启用后,该数据库上 PUBLIC 的 CONNECT 权限被撤销,只显式授予复制、监控、管理用户与数据库属主 ——
属主获得带 GRANT OPTION 的连接权限,可以自行决定向谁开放访问。在没有其他角色继承或额外授权的前提下,app_a 的账号将无法连接 app_b。
与之配套,集群初始化时还会回收数据库与 public 模式上 PUBLIC 的 CREATE 权限:
普通用户不再能在公共数据库或模式中随意创建对象,从而降低不安全 search_path 与对象覆盖带来的风险。
PostgreSQL 15 起已经收紧 public 模式的默认 CREATE 权限;Pigsty 将这项边界统一应用到所有受支持的大版本上。
离线角色与实例隔离
dbrole_offline 的设计用途,是为 ETL、报表和个人查询提供一组独立的只读权限。但角色本身只控制对象权限,并不会自动限制用户连接到哪类实例。
当前默认 HBA 中,+dbrole_offline 的内网规则没有设置 role,因此会应用到所有实例。要把它限制到 pg_role: offline 的专用实例,或标记了 pg_offline_query: true 的普通从库,需要在完整的 pg_default_hba_rules 列表中修改这一条规则:
定义 pg_default_hba_rules 会替换整组默认值,不能只保留示例中的一条。只有当 HBA 已按实例角色过滤,且用户没有同时继承其他可登录角色时,这类高消耗查询才会被限制到离线实例。资源隔离还应配合 独立服务入口、连接数和查询资源控制。
数据库之外
最小权限原则同样贯彻到主机层面:
- 超级用户
postgres不设密码,只能本地ident登录;其 sudo 权限默认限制在数据库相关服务的启停与日志查看(pg_dbsu_sudo:limit)。 - 监控用户
dbuser_monitor默认持有pg_monitor、只读角色与专用monitor模式权限,不具备业务表写权限。 - 复制用户
replicator被显式授予备份恢复所需的目录函数执行权限,而不是笼统的超级用户。
接下来
4 - 加密通信
TLS 可以提供三类保护:传输加密、服务端身份验证 与 客户端身份验证。这三项能力需要分别配置:启用服务端 TLS 并不等于客户端已经验证了服务端身份,也不等于服务端要求客户端证书。
TLS 的主要运维成本不在加密算法本身,而在证书的签发、分发、信任与轮换。缺少统一管理时,内网服务往往只启用加密,却跳过证书验证,或者干脆继续使用明文连接。
Pigsty 的做法是把 PKI 也纳入声明式管理:部署时自动创建本地自签名 CA,为受管组件签发证书并分发信任,让 TLS 在部署完成后即可使用。
本地 CA
首次执行部署时,Pigsty 会在 管理节点 上检查并按需创建 CA:
| 文件 | 说明 | 权限 |
|---|---|---|
files/pki/ca/ca.key |
CA 私钥:整个部署的信任根,务必妥善保管 | 0600(目录 0700) |
files/pki/ca/ca.crt |
CA 根证书:可以自由分发 | 0644 |
- CA 的行为由
ca_create控制:已有私钥与证书会原样复用;证书缺失但私钥存在时,会用该私钥重新签发证书。ca_create: false只禁止创建缺失的 CA 私钥;找不到ca.key时部署会直接中止,防止意外生成新的信任根。请始终成对备份和恢复ca.key与ca.crt。 - CA 证书的 CN 由
ca_cn指定,默认pigsty-ca;密钥为 RSA 4096 位。 - 有效期:CA 根证书 100 年,组件证书默认 20 年(
cert_validity:7300d)。 面向浏览器的 Nginx 证书是例外,当前默认有效期为 397 天。
较长的默认有效期用于降低私有基础设施的初始维护成本,并不意味着生产环境无需轮换。组织已有证书策略时,应缩短有效期,并建立到期监控和换证流程。
信任分发
签发证书只是一半,另一半是让每个 节点 信任这些证书。节点纳入管理时,Pigsty 将 CA 证书分发到所有节点的 /etc/pki/ca.crt,并链接进操作系统信任链:
- EL 系(RHEL、Rocky、Alma):链接至
/etc/pki/ca-trust/source/anchors/并执行update-ca-trust - Debian、Ubuntu:链接至
/usr/local/share/ca-certificates/并执行update-ca-certificates
此后,使用操作系统信任库的客户端(例如 curl)可以验证 Pigsty CA 签发的证书。
CA 证书还会发布到 Nginx 门户 的站点根目录(ca.crt),供浏览器与外部客户端下载安装。
PostgreSQL 的 libpq 客户端需要单独说明:它默认使用 ~/.postgresql/root.crt,默认 sslmode 为 prefer,不会直接使用操作系统信任库验证服务端身份。
客户端验证服务端
安全敏感的 PostgreSQL 客户端应使用 sslmode=verify-full,并指定 Pigsty CA:
verify-full 会同时验证证书链与连接主机名,因此客户端使用的 DNS 名称或 IP 地址必须出现在服务端证书的 SAN 中。外部客户端需要先安装 ca.crt,或通过 sslrootcert 指定 CA 文件。
证书矩阵
本地 CA 为下列组件签发证书,构成统一的信任链:
| 组件 | 证书身份(CN) | 部署路径 | 加密状态 |
|---|---|---|---|
| PostgreSQL | <集群>-<序号> |
/pg/cert/server.{crt,key} |
服务端 SSL 默认启用;是否强制由 HBA 决定 |
| PgBouncer | 复用 PostgreSQL 证书 | /pg/cert/ |
TLS 默认关闭(pgbouncer_sslmode) |
| Patroni | 复用 PostgreSQL 证书 | /pg/cert/ |
API HTTPS 默认关闭(patroni_ssl_enabled) |
| Etcd | <实例名> |
/etc/etcd/server.{crt,key} |
客户端与对等通信使用 TLS |
| Silo | <节点名> |
~minio/.minio/certs/ |
Silo HTTPS 默认开启(minio_https) |
| Kafka | <集群>-<序号> |
/etc/kafka/pki/kafka.pem |
kafka_security: scram 时启用 SASL_SSL/SSL;默认 plaintext |
| MySQL | <实例名> |
/etc/mysql/pki/server.{crt,key} |
强制安全传输;客户端与组复制校验证书链 |
| Nginx | pigsty(SAN 含门户域名) |
/etc/nginx/conf.d/cert/ |
HTTPS 默认开启(nginx_sslmode) |
| INFRA 节点 | <节点名> |
/etc/pki/infra.{crt,key} |
供基础设施组件使用 |
表中的“加密状态”一列如实反映了默认配置的取舍:
- 部署时启用:PostgreSQL 服务端可以接受 SSL 连接,etcd 的客户端与对等通信使用 TLS。
- 默认加密:MINIO 模块的对象存储备份流量与 Nginx Web 流量默认启用 HTTPS。
- 默认关闭,按需启用:Patroni REST API 与 PgBouncer 的 TLS 默认关闭,证书已经就位,可以通过相应参数开启;
ha/safe模板中两者均默认开启。
还有一层需要分清的区别:服务端支持 SSL 不等于强制客户端使用 SSL,更不等于客户端验证了服务端身份。
是否强制加密由 HBA 规则 决定(auth: ssl 或 cert);是否验证服务端则由客户端的 sslmode 与信任配置决定。默认规则仅对任意来源的管理员连接强制 TLS,safe 模板将主要 TCP 规则改为 ssl 或 cert,但仍保留本地 ident 与部分 localhost 口令规则。
客户端证书
内置剧本 cert.yml 用于签发客户端证书。证书的 CN 对应数据库用户名,供 HBA 的 cert 认证方式使用:
签发结果位于 files/pki/misc/<cn>.key 与 files/pki/misc/<cn>.crt。客户端私钥应通过受控渠道交付,并设置为仅对应用户可读。客户端证书解决服务端对客户端身份的验证,客户端仍需使用 verify-full 验证数据库服务端。
使用企业 CA
如果组织已有 PKI 体系,可以让 Pigsty 改用您的 CA(或由企业根 CA 签出的中间 CA)签发证书:把证书与私钥放到指定位置即可,剧本检测到已有 CA 后不会重新生成:
同时建议设置 ca_create: false:这样当私钥缺失时部署会显式失败,避免意外创建新的信任根。该开关不会阻止角色在私钥存在、证书缺失时重新签发 CA 证书,因此仍应成对检查并恢复这两个文件。
密钥保护与轮换
- CA 私钥只存在于管理节点上。它与
pigsty.yml一起构成部署中信任等级最高的资产(参见 信任边界),建议离线备份。 - CA 私钥一旦泄露,需要建立新的信任根并重新签发全部组件与客户端证书。执行前应规划新旧 CA 的信任过渡,避免一次性中断所有连接。
- 组件证书的签发源保存在管理节点的
files/pki/<component>/,节点上的证书只是部署副本。仅删除节点上的证书会重新复制原证书,不会触发重新签发。轮换时应更新或删除管理节点上的对应证书源,再执行相关剧本,并按组件要求重载或滚动重启。
接下来
5 - 数据安全
网络边界、身份认证 和 权限控制 用于降低事件发生的概率;当硬件损坏、口令泄露或误操作已经发生时,还需要依靠数据层机制控制影响并完成恢复。
数据安全要回答四个问题:数据是 完整 的吗?丢了能 恢复 吗?被拿走了会 泄密 吗?发生了什么能 查清 吗?
完整性
磁盘坏块、内存位翻转、存储固件缺陷,都可能造成 静默数据损坏:数据坏了,但没有任何报错。
Pigsty 默认启用页级数据校验和(pg_checksum:true),
集群初始化时以 data-checksums 建库,PostgreSQL 会在页面写入时计算校验和,并在读取时检查页面损坏。
页校验和主要发现存储介质、I/O 路径或写入后发生的页面损坏,不能检测所有内存错误、逻辑错误或应用写入的错误数据,也不能替代备份。
CRIT 参数模板 更进一步:校验和强制启用,不受参数影响;
同时启用 严格同步复制(synchronous_mode_strict),在没有可用同步副本时阻塞需要同步确认的写入。
该模式以不丢失已确认事务为目标,但仍依赖客户端没有降低 synchronous_commit、同步副本正常参与提交,以及故障切换只选择包含所需 WAL 的节点。RPO 需要通过目标拓扑上的故障演练验证。
可恢复性
副本主要处理节点故障,备份则处理误删除、逻辑错误、集群损坏和更大范围的灾难。 高可用 可以缩短主库故障造成的中断,但如果有人误删了数据,复制也会把误操作同步到其他副本。备份因此无可替代。
Pigsty 默认启用 pgBackRest(pgbackrest_enabled):
基础备份加上持续归档的 WAL,构成 时间点恢复(PITR)能力,可以将集群恢复到备份与 WAL 保留窗口内的目标时刻。
备份仓库由 pgbackrest_method 选择:
| 仓库 | 位置 | 默认保留策略 | 加密 |
|---|---|---|---|
local(默认) |
本地 /pg/backup 目录 |
最近 2 份全量备份 | 无 |
minio |
Silo 或外部 S3 对象存储 | 14 天 | AES-256-CBC |
对于防误删场景,还有两项辅助机制:
- 延迟从库:为关键集群声明一个
pg_delay: 1h的延迟副本。在错误操作尚未回放前,可以暂停复制并提取数据。延迟副本最终仍会追上主库,不能代替备份。 - 移除保护:
pg_safeguard与etcd_safeguard开启后,对应的移除剧本会拒绝执行,降低误删集群的风险。
备份的存在不等于恢复的能力。恢复演练应当成为例行工作:原理与决策见 时间点恢复,配置与操作见 PGSQL 备份恢复。
保密性
静态数据的保密性分三层展开:
备份加密。pgbackrest_method: minio 表示 S3 兼容对象存储仓库,可由 MINIO 模块部署的 Silo,或独立管理的 MinIO、RustFS 与外部 S3 服务提供;该预设默认启用 AES-256-CBC 加密。默认加密口令 pgBackRest 是公开值,生产环境必须修改。
ha/safe 模板按集群名称区分加密口令:
pgBR.${pg_cluster} 是可预测的示例值,configure -g 也不会替换它。生产环境应使用独立随机口令,并与备份分开保存;口令丢失会导致备份无法恢复。
本地备份仓库默认不加密。加密可以降低备份文件被单独复制或介质被盗时的泄露风险,但如果密钥与备份位于同一主机,保护效果仍会受到限制。
传输加密。备份上传 Silo 或外部 S3 服务时走 HTTPS,PostgreSQL 客户端与流复制可以通过 HBA 强制 SSL。客户端还应验证服务端证书,详见 加密通信。
静态加密。PostgreSQL 上游内核目前没有通用的内置透明数据加密(TDE),Pigsty 提供两条现实路径:
使用 Percona PostgreSQL 内核的 pg_tde 扩展实现表级透明加密(参见 pgtde 配置模板);
或使用 pgsodium、pgcrypto、anonymizer 等 安全扩展 在列级实现加密与脱敏 —— safe 模板已预装这一类扩展。
此外,全盘加密(LUKS、dm-crypt)在操作系统层解决介质被盗问题,与数据库层方案互补。
审计与追溯
出了问题,要能回答“谁在什么时候做了什么”。Pigsty 的日志审计分层递进:
默认基线:所有 DDL 语句被记录(log_statement: ddl),执行超过 100ms 的查询被记录(log_min_duration_statement: 100),
PostgreSQL 18 及以上版本还会记录连接授权事件。
CRIT 模板:记录连接与断开事件(log_connections 与 log_disconnections);PostgreSQL 18 还会区分连接接收、认证与授权阶段。
pgaudit 扩展:需要语句级的细粒度审计(对象级读写、按角色审计)时,安装 pgaudit 并加入 pg_libs 预加载。
safe 模板已预装该扩展,加载与审计策略需按需求显式声明。
启用 INFRA 日志组件并完成 Vector 配置后,PostgreSQL 日志会汇入 VictoriaLogs 集中存储(默认保留 15 天,可按合规要求调整)。 日志和指标为安全事件的检索、告警与回溯提供输入,但事件判定、响应和证据保全仍需要配套流程。
接下来
6 - 合规实践
合规不是一个可以购买的产品,而是一种需要持续证明的状态。它由三部分组成:
- 配置:安全能力是否启用 —— 这部分由 Pigsty 直接提供;
- 流程:权限审批、变更管理、恢复演练等制度 —— 需要组织自行建立;
- 证据:能证明前两者持续有效的记录 —— Pigsty 的 配置清单、运行日志和 监控系统 可以提供其中一部分。
本页从上线前的加固清单开始,给出 Pigsty 安全能力与常见合规框架的映射关系。 这些映射用于方案设计和差距分析,不构成等保测评结论、SOC 2 审计意见或法律建议。
默认凭证清单
Pigsty 的默认凭证公开写在文档与源码中,仅供演示与本地开发使用。任何生产部署或暴露于网络的部署,上线前必须修改所有适用的默认值:
| 范围 | 默认值示例 | configure -g |
|---|---|---|
| Grafana 管理员与只读用户 | pigsty、DBUser.Viewer |
是 |
| HAProxy 管理界面 | pigsty |
是 |
| PostgreSQL 管理、监控、复制用户 | DBUser.DBA、DBUser.Monitor、DBUser.Replicator |
是 |
| Patroni REST API | Patroni.API |
是 |
| etcd root | Etcd.Root |
是 |
| MINIO 模块对象存储 root | S3User.MinIO |
是 |
| 对象存储备份与示例业务用户 | S3User.Backup、S3User.Meta、S3User.Data |
是 |
| 示例数据库用户 | DBUser.Meta、DBUser.Supa、Vibe.Coding |
是 |
| pgBackRest 加密口令 | cipher_pass: pgBackRest |
否 |
ha/safe 中的 Silo 用户与 pgBR.${pg_cluster} |
模板示例值 | 否 |
| 用户自行添加的凭据 | 自定义值 | 否 |
生成配置时可以使用 -g,随机化配置向导识别的内置参数和示例字符串:
配置向导会把生成的密码输出到终端,因此终端记录和自动化日志也应按敏感信息保护。生成完成后还要检查配置文件,单独替换 pgBackRest cipher_pass、ha/safe 中未覆盖的 MINIO 模块示例值和自定义凭据。
上线加固清单
部署前:
- 明确 网络边界:数据库端口不暴露公网,移除演示配置中防火墙放行的
5432 - 确定证书策略:使用内置 CA,或接入企业 PKI(参见 使用企业 CA)
- 规划 客户端验证:为数据库客户端配置
sslmode=verify-full与可信 CA - 规划账号体系:业务账号按 四层角色 分级,声明
expire_in过期时间 - 规划 备份仓库、保留周期、加密口令和异地副本
- 评估是否采用
ha/safe加固模板与 CRIT 参数模板
部署后:
- 确认
configure -g覆盖的凭据与未覆盖的备份、对象存储、自定义凭据均已修改 - 审查实际生效的 HBA 规则(
/pg/data/pg_hba.conf)是否与声明及预期一致 - 查询实际用户、角色、默认权限 和数据库
CONNECT授权,并与配置清单比较 - 执行一次全量备份与 恢复演练,验证备份链路可用
- 确认日志采集、监控告警与通知通道可用
周期性:
- 权限审计:核对
pg_users声明与实际授权,清理过期与离职账号 - 凭证与证书轮换
- 恢复演练与故障切换演练
- 跟进 Pigsty 与上游组件的安全更新
合规证据
声明式配置为合规审计提供了稳定的证据入口,但还需要保留运行时状态,证明配置已经应用并持续有效。
| 证据 | 来源 |
|---|---|
| 安全配置基线及其变更历史 | pigsty.yml 配置清单与 Git 提交记录 |
| 访问控制矩阵 | pg_default_roles、pg_users 与 pg_hba_rules 声明 |
| 实际生效的认证规则 | 各实例渲染出的 pg_hba.conf,用于与声明比较并发现漂移 |
| 实际用户与权限 | PostgreSQL 系统目录、数据库 ACL、\du+ 与 \ddp+ |
| 操作与连接日志 | PostgreSQL 日志(DDL、慢查询、连接),VictoriaLogs 集中留存 |
| 备份记录 | pgBackRest 备份信息与监控面板 |
| 安全事件与告警记录 | 监控系统告警历史 |
| 证书清单 | files/pki/ 目录与各组件部署证书 |
等保三级映射
《GB/T 22239-2019》三级要求中“安全计算环境”部分与 Pigsty 能力的对应关系:
| 控制要求 | Pigsty 能力 | 需要补充 |
|---|---|---|
| 身份鉴别唯一性 | 独立账号体系,SCRAM-SHA-256 密码存储 | 账号实名管理制度 |
| 口令复杂度与定期更换 | passwordcheck、credcheck 扩展,expire_in 账号过期 |
启用扩展;轮换制度 |
| 登录失败处理 | 可借助 credcheck 等扩展实现 |
按需启用与配置 |
| 访问控制与最小权限 | 四层角色模型、默认权限与数据库隔离 | 权限审批流程 |
| 安全审计 | DDL、连接、慢查询日志,pgaudit,集中日志留存 |
CRIT 模板或手工启用连接日志;留存周期按要求调整 |
| 通信保密性 | 本地 CA 与 TLS,HBA 强制 ssl 或 cert |
强制 TLS、客户端 verify-full 与证书轮换 |
| 数据完整性 | 页级校验和(默认启用),严格同步复制(CRIT) | 存储保护、故障模型与演练 |
| 数据保密性 | 备份 AES 加密,TDE 与列级加密路径 | 按需启用 |
| 数据备份恢复 | pgBackRest、PITR 与远端 S3 兼容仓库 | 恢复演练制度 |
| 剩余信息保护 | - | 介质销毁与擦除流程 |
等保还包括安全物理环境、安全通信网络、安全管理制度等部分,超出数据库发行版的能力范畴: Pigsty 可以支持“安全计算环境”中与数据库相关的部分技术控制,机房、网络设备与管理制度仍需在整体方案中补足。
SOC 2 映射
SOC 2 信任服务准则(TSC)中与数据库直接相关的部分控制点:
| 控制点 | Pigsty 能力 | 需要补充 |
|---|---|---|
| CC6.1 逻辑访问安全 | HBA、RBAC、默认权限与数据库隔离 | 权限设计、审批与定期复核 |
| CC6.2 用户注册与授权 | 声明式用户、角色和有效期 | 入职、变更、离职和身份核验流程 |
| CC6.3 访问变更与撤销 | pg_users、角色调整、REVOKE 与到期时间 |
工单、授权批准和及时回收证据 |
| CC6.6 外部边界威胁 | 防火墙、监听地址、HBA 与管理入口限制 | 网络架构、边界设备和持续验证 |
| CC6.7 信息传输与移动 | TLS、客户端验证与备份加密 | 数据导出、介质和第三方传输策略 |
| CC7.2 系统监控 | Victoria 可观测性栈,数千项指标与告警 | 告警响应流程 |
| CC7.3 事件追溯 | 集中日志,审计扩展 | 日志审查流程 |
| A1.2 可用性与恢复 | 高可用 与 PITR | 演练记录与 RTO、RPO 目标 |
供应链与漏洞响应
合规审查越来越关注软件供应链,Pigsty 在分发与响应侧提供以下保障:
包完整性:Pigsty 软件仓库(repo.pigsty.io、repo.pigsty.cc)中的 RPM、DEB 包经 GPG 签名,
公钥指纹为 9592 A7BC 7A68 2E73 3337 6E09 E793 5D8D B9BD 8B20(B9BD8B20),可在信任前核验。但部署时写入的仓库定义以及 INFRA 节点 上的本地仓库,默认不强制逐包签名验证;生产环境应检查包管理器的仓库信任与验签设置。
漏洞响应:安全问题通过 GitHub 私有漏洞报告或邮件渠道私下披露(参见 SECURITY.md), 项目目标是在 3 个工作日内确认、7 天内给出初步评估。
版本支持:安全修复随最新稳定版发布,保持升级是获得安全修复的方式;需要长期锁定版本的用户,可通过 订阅服务 获得延长支持。
接下来
- 🛡️ 安全模型:从默认基线到加固梯度
- 🔰 安全建议:快速上手场景的最小加固动作
- 📄
ha/safe模板:安全加固配置示例
