认证 / HBA
Pigsty 中基于主机的身份认证 HBA(Host-Based Authentication)详解。
认证是 访问控制 与 默认权限 的基础,PostgreSQL 支持多种 认证 方法。
这里主要介绍 HBA:Host Based Authentication,HBA 规则定义了哪些用户能够通过哪些方式从哪些地方访问哪些数据库。
客户端认证
要连接到 PostgreSQL 数据库,用户必须先经过认证(默认使用密码)。
您可以在连接字符串中提供密码(不安全)或使用 PGPASSWORD 环境变量或 .pgpass 文件传递密码。参考 psql 文档和 PostgreSQL连接字符串 以获取更多详细信息。
例如,连接 Pigsty 默认的 meta 数据库,可以使用以下连接串:
默认配置下,Pigsty 会启用服务端 SSL 加密,但不验证客户端 SSL 证书。要使用客户端 SSL 证书连接,你可以使用 PGSSLCERT 和 PGSSLKEY 环境变量或 sslkey 和 sslcert 参数提供客户端参数。
客户端证书(CN = 用户名)可以使用本地 CA 与 cert.yml 剧本签发。
定义HBA
在 Pigsty 中,有四个与 HBA 规则有关的参数:
pg_hba_rules:postgres HBA 规则pg_default_hba_rules:postgres 全局默认 HBA 规则pgb_hba_rules:pgbouncer HBA 规则pgb_default_hba_rules:pgbouncer 全局默认 HBA 规则
这些都是 HBA 规则对象的数组,每个 HBA 规则都是以下两种形式之一的对象:
1. 原始形式
原始形式的 HBA 与 PostgreSQL pg_hba.conf 的格式几乎完全相同:
在这种形式中,rules 字段是字符串数组,每一行都是条原始形式的 HBA规则。title 字段会被渲染为一条注释,解释下面规则的作用。
role 字段用于说明该规则适用于哪些实例角色,当实例的 pg_role 与 role 相同时,HBA 规则将被添加到这台实例的 HBA 中。
role: common的 HBA 规则将被添加到所有实例上。role: primary的 HBA 规则只会添加到主库实例上。role: replica的 HBA 规则只会添加到从库实例上。role: offline的 HBA 规则将被添加到离线实例上(pg_role=offline或pg_offline_query=true)
2. 别名形式
别名形式允许您用更简单清晰便捷的方式维护 HBA 规则:它用 addr、auth、user 和 db 字段替换了 rules。 title、role 和 order 字段则仍然生效。
addr: where 哪些 IP 地址段受本条规则影响?world:所有的 IP 地址intra:所有的内网 IP 地址段:'10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'infra:Infra 节点的 IP 地址admin:admin_ip管理节点的 IP 地址local:本地 Unix Socketlocalhost:本地 Unix Socket 以及 TCP 127.0.0.1/32 环回地址cluster:同一个 PostgresQL 集群所有成员的 IP 地址<cidr>:一个特定的 CIDR 地址块或 IP 地址
auth: how 本条规则指定的认证方式?deny:拒绝访问trust:直接信任,不需要认证pwd:密码认证,根据pg_pwd_enc参数选用md5或scram-sha-256认证sha/scram-sha-256:强制使用scram-sha-256密码认证方式。md5:md5密码认证方式,但也可以兼容scram-sha-256认证,不建议使用。ssl:在密码认证pwd的基础上,强制要求启用 SSLssl-md5:在密码认证md5的基础上,强制要求启用 SSLssl-sha:在密码认证sha的基础上,强制要求启用 SSLos/ident:使用操作系统用户的身份进行ident认证peer:使用peer认证方式,类似于os identcert:使用基于客户端 SSL 证书的认证方式,证书 CN 为用户名
user: who:哪些用户受本条规则影响?all:所有用户${dbsu}:默认数据库超级用户pg_dbsu${repl}:默认数据库复制用户pg_replication_username${admin}:默认数据库管理用户pg_admin_username${monitor}:默认数据库监控用户pg_monitor_username- 其他特定的用户或者角色
db: which:哪些数据库受本条规则影响?all:所有数据库replication:允许建立复制连接(不指定特定数据库)- 某个特定的数据库
3. 定义位置
通常,全局的 HBA 定义在 all.vars 中,如果您想要修改全局默认的 HBA 规则,可以从 conf/ha/full.yml 模板中复制一份到 all.vars 中进行修改。
pg_default_hba_rules:postgres 全局默认 HBA 规则pgb_default_hba_rules:pgbouncer 全局默认 HBA 规则
而集群特定的 HBA 规则定义在数据库的集群级配置中:
pg_hba_rules:postgres HBA 规则pgb_hba_rules:pgbouncer HBA 规则
下面是一些集群 HBA 规则的定义例子:
重载HBA
HBA 是一个静态的规则配置文件,修改后需要重载才能生效。默认的 HBA 规则集合因为不涉及 Role 与集群成员,所以通常不需要重载。
如果您设计的 HBA 使用了特定的实例角色限制,或者集群成员限制,那么当集群实例成员发生变化(新增/下线/主从切换),一部分 HBA 规则的生效条件/涉及范围发生变化,通常也需要 重载HBA 以反映最新变化。
要重新加载 postgres/pgbouncer 的 hba 规则:
底层实际执行的 Ansible 剧本命令为:
默认HBA
Pigsty 有一套默认的 HBA 规则,对于绝大多数场景来说,它已经足够安全了。这些规则使用别名形式,因此基本可以自我解释。
注意:
order字段控制规则渲染顺序。0-99用于高优先规则(如黑名单),100-650为默认规则区间,1000+用于追加规则。详见 HBA 配置。
示例:渲染 pg_hba.conf
示例:渲染 pgb_hba.conf
安全加固
对于那些需要更高安全性的场合,我们提供了一个安全加固的配置模板 conf/ha/safe.yml,使用了以下的默认 HBA 规则集: