3. 身份认证机制与配置实战
PostgreSQL 的连接认证由 pg_hba.conf 统一裁决。客户端发起连接时,后端进程按文件自上而下逐行匹配,一旦命中第一条符合“连接类型 + 数据库 + 用户 + 来源地址”的记录,就采用该行指定的认证方法,不再继续向下查找。理解这个“首行命中即停止”的规则,是排查认证问题的第一原则。
pg_hba.conf 的字段结构与匹配逻辑
每条规则由五个基本字段构成:连接类型、数据库、用户、来源地址、认证方法,后面可跟认证选项。连接类型常见取值有 local(Unix 域套接字)、host(TCP/IP,含 SSL 与非 SSL)、hostssl(仅 SSL 加密连接)、hostnossl(仅非加密连接)。数据库和用户字段可写具体名称、逗号分隔列表,或 all;用户字段还可用 +角色名 引用角色成员。来源地址支持 CIDR 网段、单独 IP,或用 samehost、samenet 等关键字。
下面是一份典型的生产环境片段,先放行本机管理,再允许内网应用以密码认证,最后拒绝其余来源:
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
host all dba 10.0.0.0/24 scram-sha-256
hostssl appdb appuser 10.10.0.0/16 scram-sha-256
host all all 0.0.0.0/0 reject
注意最后一行 reject 的作用:它显式拒绝所有未匹配来源,避免默认放行带来的风险。修改后必须执行 SELECT pg_reload_conf(); 或 pg_ctl reload 使配置生效,无需重启实例。若某条规则写错,可用 psql -h 主机 -U 用户 -d 库名 复现连接,观察返回的 FATAL: no pg_hba.conf entry for host ... 或 password authentication failed 来定位是匹配失败还是密码校验失败。
密码加密方式:从 md5 到 scram-sha-256
PostgreSQL 支持 password(明文传输,仅建议配合 SSL)、md5 和 scram-sha-256 三种密码类方法。md5 在服务端存储的是 md5(密码+用户名) 的哈希,且握手过程可被离线暴力破解;scram-sha-256 采用加盐挑战应答,服务端不存储可直接重放的凭据,是当前推荐方案。
启用 scram 需要两步:先在 postgresql.conf 中设置 password_encryption = scram-sha-256,再重置用户密码使其以新算法存储:
ALTER SYSTEM SET password_encryption = 'scram-sha-256';
SELECT pg_reload_conf();
ALTER USER appuser WITH PASSWORD 'Str0ng_P@ss';
-- 查看存储格式:SCRAM-SHA-256$4096:...
SELECT rolname, substring(rolpassword,1,20) FROM pg_authid WHERE rolname='appuser';
若旧用户仍是 md5 哈希,认证会失败并提示 password authentication failed,此时需重新设置密码。迁移期间可临时保留 md5 规则,但应尽快完成全量切换。
LDAP、GSSAPI 与证书认证
企业环境常把认证委托给目录服务。LDAP 认证通过 ldapserver、ldapbasedn、ldapprefix/ldapsuffix 等参数拼接用户 DN 并绑定验证:
host all all 10.0.0.0/24 ldap ldapserver=ldap.corp.example \
ldapbasedn="ou=people,dc=corp,dc=example" \
ldapprefix="uid=" ldapsuffix=",ou=people,dc=corp,dc=example"
GSSAPI(Kerberos)适合已部署域控的环境,客户端用 kinit 获取票据后即可免密登录,服务端需有对应 krb5.keytab 与 SPN。证书认证则用 cert 方法,要求客户端提供由受信 CA 签发的证书,并通过 clientcert=verify-full 校验 CN 与数据库用户名一致,实现“证书即身份”。
多因素认证集成
PostgreSQL 本身不内置 MFA,但可通过组合规则实现。常见做法是:hostssl + cert 作为第一因素(持有证书),再叠加 scram-sha-256 作为第二因素(知道密码)。由于 pg_hba 一行只能指定一种方法,实际落地通常借助 PAM:在 pg_hba.conf 写 pam 方法,由 PAM 模块串联 pam_google_authenticator 等实现动态口令,从而在数据库层完成双因素校验。
实战排查与配置要点
认证失败时,先看服务端日志中的 FATAL 行:若提示 no pg_hba.conf entry,说明没有规则匹配到该来源或用户,需要补充规则;若提示 password authentication failed,说明规则已命中但凭据校验未通过,应检查密码算法是否一致、LDAP 绑定 DN 是否正确、证书 CN 是否与用户名匹配。可用 SHOW password_encryption; 确认当前加密方式,用 SELECT * FROM pg_hba_file_rules;(PostgreSQL 10+)直接查看已加载规则及其行号,快速核对顺序。
pg_hba.conf 纳入版本管理,每次变更记录“规则行、目的、生效时间”,并在变更后用 psql 从不同网段各测一次,确认放行与拒绝都符合预期。host all all 0.0.0.0/0 trust;trust 表示完全信任来源,任何能连到端口的客户端都可免密登录,等同于关闭认证。综合来看,一套稳健的认证配置应遵循“最小放行、加密优先、分层验证”的思路:本机管理用 peer,内网应用用 scram-sha-256 并强制 hostssl,跨域或高安全场景引入 LDAP、GSSAPI 或证书,必要时通过 PAM 叠加动态口令形成多因素。掌握匹配顺序与各方法的适用边界,就能在可用性与安全性之间取得平衡。