Skip to content

PostgreSQL pg_hba.conf访问控制

核心概念

pg_hba.conf是PostgreSQL数据库的主访问控制配置文件,用于控制客户端如何连接到PostgreSQL服务器。HBA代表"Host-Based Authentication"(基于主机的认证),该文件决定了:

  • 哪些客户端可以连接到服务器
  • 使用什么认证方法进行连接验证
  • 可以访问哪些数据库和用户

pg_hba.conf配置文件位于PostgreSQL数据目录中,控制着所有来自客户端的连接请求,是数据库安全的第一道防线。

配置文件格式

pg_hba.conf文件的每一行代表一条访问控制规则,每条规则由以下字段组成,用空格或制表符分隔:

TYPE  DATABASE  USER  ADDRESS  METHOD  [OPTIONS]

字段说明

字段名描述可选值
TYPE连接类型local(本地Unix套接字)、host(TCP/IP连接)、hostssl(SSL TCP/IP连接)、hostnossl(非SSL TCP/IP连接)
DATABASE数据库名具体数据库名、all(所有数据库)、sameuser(与连接用户同名的数据库)、samerole(用户所属角色的数据库)
USER用户名具体用户名、all(所有用户)、+group(角色组)
ADDRESS客户端地址IPv4地址/掩码(如192.168.1.0/24)、IPv6地址/掩码(如::1/128)、samehost(同一主机)、samenet(同一网络)
METHOD认证方法trust、reject、md5、password、scram-sha-256、ident、peer、pam、ldap、radius、cert、gss、sspi
OPTIONS可选参数不同认证方法的特定参数

认证方式详解

1. 基于密码的认证

trust

  • 描述:完全信任,不要求密码
  • 风险:极高,仅适用于安全的本地网络或开发环境
  • 示例host all all 127.0.0.1/32 trust

password

  • 描述:明文密码认证(不推荐)
  • 风险:密码以明文传输,易被窃听
  • 示例host all all 0.0.0.0/0 password

md5

  • 描述:MD5哈希密码认证
  • 适用场景:PostgreSQL 10之前的版本
  • 示例host all all 0.0.0.0/0 md5

scram-sha-256

  • 描述:SCRAM-SHA-256加密认证(推荐)
  • 适用场景:PostgreSQL 10及以上版本
  • 安全性:比md5更安全,支持密码哈希升级
  • 示例host all all 0.0.0.0/0 scram-sha-256

2. 基于身份的认证

peer

  • 描述:基于操作系统用户身份认证
  • 适用场景:本地Unix套接字连接
  • 示例local all postgres peer

ident

  • 描述:基于客户端操作系统用户名认证
  • 适用场景:TCP/IP连接,需要ident服务
  • 示例host all all 192.168.1.0/24 ident

3. 其他认证方式

reject

  • 描述:拒绝所有匹配的连接
  • 适用场景:用于明确拒绝某些连接
  • 示例host all all 10.0.0.0/8 reject

pam

  • 描述:使用PAM(Pluggable Authentication Modules)认证
  • 适用场景:需要集成外部认证系统
  • 示例host all all 0.0.0.0/0 pam pamservice=postgresql

ldap

  • 描述:使用LDAP认证
  • 适用场景:企业级环境,集成LDAP目录服务
  • 示例host all all 0.0.0.0/0 ldap ldapserver=ldap.example.com ldapprefix="uid=" ldapsuffix=",dc=example,dc=com"

常见配置示例

1. 本地连接配置

# 允许本地Unix套接字连接,使用peer认证
local   all             all                                     peer

# 允许本地TCP/IP连接,使用scram-sha-256认证
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256

2. 远程连接配置

# 允许特定IP段连接到所有数据库,使用scram-sha-256认证
host    all             all             192.168.1.0/24          scram-sha-256

# 允许特定IP连接到特定数据库和用户
host    mydatabase      myuser          10.0.0.5/32             scram-sha-256

# 允许同一网络的所有主机连接,使用md5认证
host    all             all             samenet                 md5

3. SSL连接配置

# 只允许SSL连接,使用scram-sha-256认证
hostssl all             all             0.0.0.0/0               scram-sha-256

# 拒绝非SSL连接
hostnossl all           all             0.0.0.0/0               reject

4. 复制连接配置

# 允许复制连接,使用scram-sha-256认证
host    replication     replicauser     192.168.1.10/32         scram-sha-256
host    replication     replicauser     192.168.1.11/32         scram-sha-256

配置管理

修改pg_hba.conf文件

  1. 编辑配置文件

    bash
    # 使用文本编辑器编辑pg_hba.conf
    vi /var/lib/pgsql/15/data/pg_hba.conf
  2. 重载配置: PostgreSQL不会自动检测pg_hba.conf的修改,需要手动重载配置:

    bash
    # 使用pg_ctl重载配置
    pg_ctl reload -D /var/lib/pgsql/15/data
    
    # 或使用SQL命令
    psql -c "SELECT pg_reload_conf();"
  3. 验证配置

    bash
    # 检查配置文件语法
    postgres -C hba_file
    
    # 查看当前有效配置
    psql -c "SHOW hba_file;"

最佳实践

1. 最小权限原则

  • 只授予必要的访问权限,遵循"最小权限"原则
  • 避免使用all all all这样过于宽松的配置
  • 明确指定允许连接的IP地址范围

2. 安全的认证方式

  • 在生产环境中,始终使用安全的认证方式:
    • PostgreSQL 10+:使用scram-sha-256
    • PostgreSQL 9.x:使用md5
  • 禁用trustpassword认证方式
  • 优先使用SSL连接(hostssl

3. 配置顺序

  • pg_hba.conf规则按顺序匹配,第一条匹配的规则生效
  • 将最具体的规则放在前面,最通用的规则放在后面
  • 最后一条规则通常设置为拒绝所有未匹配的连接

4. 定期审计

  • 定期检查pg_hba.conf配置,移除不再需要的规则
  • 记录所有配置变更,包括变更原因和变更人
  • 使用版本控制系统管理pg_hba.conf文件

5. 生产环境示例配置

# 本地连接
local   all             postgres                                peer
local   all             all                                     peer

# IPv4本地连接
host    all             all             127.0.0.1/32            scram-sha-256

# IPv6本地连接
host    all             all             ::1/128                 scram-sha-256

# 应用服务器连接
hostssl all             appuser         192.168.10.0/24         scram-sha-256

# 复制连接
hostssl replication     replicauser     192.168.10.10/32        scram-sha-256
hostssl replication     replicauser     192.168.10.11/32        scram-sha-256

# 管理员远程连接
hostssl all             adminuser       203.0.113.0/24          scram-sha-256

# 拒绝所有其他连接
host    all             all             0.0.0.0/0               reject

常见问题(FAQ)

Q1:如何查找pg_hba.conf文件的位置?

A1:可以使用以下命令查找pg_hba.conf文件的位置:

sql
SHOW hba_file;

Q2:修改pg_hba.conf后需要重启数据库吗?

A2:不需要重启数据库,只需要重载配置即可:

sql
SELECT pg_reload_conf();

Q3:为什么我的连接被拒绝?

A3:连接被拒绝可能有以下原因:

  1. pg_hba.conf中没有匹配的规则
  2. 使用了错误的认证方式
  3. 规则顺序不正确,前面的规则拒绝了连接
  4. 防火墙或网络问题

可以通过查看PostgreSQL日志获取详细错误信息:

bash
tail -f /var/lib/pgsql/15/data/log/postgresql-*.log

Q4:如何允许所有IP连接?

A4:不建议允许所有IP连接,这会带来安全风险。如果必须这样做,应使用安全的认证方式并限制在SSL连接上:

hostssl all all 0.0.0.0/0 scram-sha-256

Q5:peer认证和ident认证有什么区别?

A5:

  • peer认证:仅用于本地Unix套接字连接,检查客户端操作系统用户名是否与PostgreSQL用户名匹配
  • ident认证:用于TCP/IP连接,通过ident服务获取客户端操作系统用户名,然后与PostgreSQL用户名匹配

Q6:如何配置基于LDAP的认证?

A6:LDAP认证配置示例:

host all all 0.0.0.0/0 ldap ldapserver=ldap.example.com ldapport=389 ldapsuffix="ou=People,dc=example,dc=com" ldapbinddn="cn=binduser,dc=example,dc=com" ldapbindpasswd="bindpass" ldapsearchattribute=uid

Q7:scram-sha-256和md5有什么区别?

A7:

  • scram-sha-256:更安全的认证方式,支持密码哈希升级,防止中间人攻击
  • md5:较旧的认证方式,不支持密码哈希升级,存在安全风险

PostgreSQL 14默认使用scram-sha-256,建议在所有版本中使用

Q8:如何为复制连接配置pg_hba.conf?

A8:复制连接需要使用replication作为数据库名,例如:

host replication replicauser 192.168.1.0/24 scram-sha-256

Q9:如何限制用户只能从特定IP连接?

A9:在pg_hba.conf中明确指定允许的IP地址:

host mydatabase myuser 10.0.0.5/32 scram-sha-256

Q10:如何测试pg_hba.conf配置?

A10:可以使用psql命令测试连接:

bash
# 从本地测试
psql -h localhost -U myuser -d mydatabase

# 从远程测试
psql -h 192.168.1.100 -U myuser -d mydatabase

故障排除

1. 连接被拒绝

症状

psql: error: connection to server at "192.168.1.100", port 5432 failed: FATAL:  no pg_hba.conf entry for host "10.0.0.1", user "myuser", database "mydatabase", SSL off

解决方法

  • 检查pg_hba.conf中是否存在匹配的规则
  • 检查规则中的IP地址、用户名和数据库名是否正确
  • 确保SSL配置与规则匹配

2. 认证失败

症状

psql: error: connection to server at "localhost" (::1), port 5432 failed: FATAL:  password authentication failed for user "myuser"

解决方法

  • 检查用户名和密码是否正确
  • 检查pg_hba.conf中使用的认证方法是否与用户密码存储方式匹配
  • 对于scram-sha-256认证,确保用户密码是使用scram-sha-256加密存储的

3. 配置不生效

症状:修改了pg_hba.conf但连接行为没有变化

解决方法

  • 确认已执行pg_reload_conf()命令
  • 检查PostgreSQL日志中是否有配置重载的记录
  • 确认修改的是正确的数据目录下的pg_hba.conf文件