Skip to content

PostgreSQL 基于IP的访问控制

pg_hba.conf 配置基础

pg_hba.conf 是 PostgreSQL 实现基于IP访问控制的核心配置文件,用于控制哪些主机可以连接到数据库,以及使用什么认证方法。

文件位置

默认位置:

  • Linux:/var/lib/postgresql/{version}/main/pg_hba.conf
  • Windows:C:\Program Files\PostgreSQL\{version}\data\pg_hba.conf
  • macOS:/Library/PostgreSQL/{version}/data/pg_hba.conf

配置格式

pg_hba.conf 文件的每一行格式如下:

txt
# 类型    数据库    用户    地址            认证方法    可选参数
local     database  user    [auth-method]  [auth-options]
host      database  user    address        [auth-method]  [auth-options]
hostssl   database  user    address        [auth-method]  [auth-options]
hostnossl database  user    address        [auth-method]  [auth-options]

字段说明

  1. 类型

    • local:本地Unix套接字连接
    • host:TCP/IP连接(包括SSL和非SSL)
    • hostssl:仅SSL加密的TCP/IP连接
    • hostnossl:仅非SSL的TCP/IP连接
  2. 数据库:允许访问的数据库,all表示所有数据库,多个数据库用逗号分隔

  3. 用户:允许访问的用户,all表示所有用户,多个用户用逗号分隔

  4. 地址

    • IPv4:192.168.1.0/24(CIDR格式)或 192.168.1.0 255.255.255.0(掩码格式)
    • IPv6:fe80::/10(CIDR格式)
    • all:所有IP地址
  5. 认证方法

    • trust:无条件信任
    • reject:无条件拒绝
    • md5:MD5加密密码认证
    • scram-sha-256:SCRAM-SHA-256加密密码认证
    • password:明文密码认证(不推荐)
    • peer:操作系统用户匹配认证
    • ident:外部Ident服务器认证
    • ldap:LDAP认证
    • radius:RADIUS认证
    • cert:SSL证书认证

常见配置示例

1. 允许本地连接

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

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

2. 允许特定IP段访问

txt
# 允许192.168.1.0/24网段访问所有数据库,使用md5认证
host    all             all             192.168.1.0/24          md5

# 允许10.0.0.0/8网段访问特定数据库,使用scram-sha-256认证
host    mydatabase      myuser          10.0.0.0/8              scram-sha-256

3. 允许特定IP地址访问

txt
# 允许192.168.1.100访问所有数据库,使用md5认证
host    all             all             192.168.1.100/32        md5

# 允许2001:db8::1访问所有数据库,使用scram-sha-256认证
host    all             all             2001:db8::1/128         scram-sha-256

4. 拒绝特定IP访问

txt
# 拒绝192.168.2.0/24网段访问
host    all             all             192.168.2.0/24          reject

# 拒绝特定IP访问
host    all             all             192.168.1.200/32        reject

5. SSL连接配置

txt
# 仅允许SSL连接,来自192.168.1.0/24网段
hostssl all             all             192.168.1.0/24          md5

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

配置重载与验证

重载配置

修改pg_hba.conf后,需要重载配置才能生效:

bash
# 方法1:使用pg_ctl命令
pg_ctl reload -D /var/lib/postgresql/{version}/main

# 方法2:使用psql命令
psql -U postgres -c "SELECT pg_reload_conf();"

# 方法3:使用systemctl命令
sudo systemctl reload postgresql

验证配置

bash
# 检查pg_hba.conf语法
postgres=# SELECT pg_hba_file_rules();

# 查看当前连接的客户端信息
postgres=# SELECT usename, client_addr, client_hostname FROM pg_stat_activity;

最佳实践

1. 遵循最小权限原则

txt
# 不推荐:允许所有IP访问所有数据库
# host    all             all             0.0.0.0/0               md5

# 推荐:仅允许特定IP段访问特定数据库
host    mydatabase      myuser          192.168.1.0/24          md5

2. 使用安全的认证方法

txt
# 不推荐:使用trust或password认证
# host    all             all             192.168.1.0/24          trust
# host    all             all             192.168.1.0/24          password

# 推荐:使用scram-sha-256或md5认证
host    all             all             192.168.1.0/24          scram-sha-256
host    all             all             192.168.1.0/24          md5

3. 配置顺序重要

pg_hba.conf按顺序匹配规则,第一个匹配的规则生效:

txt
# 先拒绝特定IP,再允许其他IP
# 错误顺序:先允许所有,再拒绝特定IP(拒绝规则永远不会生效)
# host    all             all             0.0.0.0/0               md5
# host    all             all             192.168.2.0/24          reject

# 正确顺序:先拒绝特定IP,再允许其他IP
host    all             all             192.168.2.0/24          reject
host    all             all             0.0.0.0/0               md5

4. 使用CIDR格式

txt
# 不推荐:使用掩码格式
# host    all             all             192.168.1.0 255.255.255.0  md5

# 推荐:使用CIDR格式
host    all             all             192.168.1.0/24          md5

5. 定期审计配置

bash
# 定期检查pg_hba.conf文件
ls -l /var/lib/postgresql/{version}/main/pg_hba.conf

# 查看最近修改时间
echo "SELECT pg_stat_file('pg_hba.conf');" | psql -U postgres

6. 限制连接来源

txt
# 仅允许来自应用服务器和管理终端的连接
host    all             appuser         192.168.1.10/32         md5
# 应用服务器
host    all             adminuser       10.0.0.50/32            md5
# 管理终端
host    all             all             0.0.0.0/0               reject
# 拒绝其他所有IP

常见问题(FAQ)

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

A1:不需要重启数据库,只需要重载配置即可生效。可以使用pg_reload_conf()函数或pg_ctl reload命令重载配置。

Q2:如何测试pg_hba.conf配置是否生效?

A2:可以从不同IP地址尝试连接数据库,观察是否能成功连接。例如:

bash
# 从192.168.1.100尝试连接
psql -h 192.168.1.50 -U myuser -d mydatabase

# 从被拒绝的IP尝试连接
psql -h 192.168.2.100 -U myuser -d mydatabase

Q3:pg_hba.conf配置顺序有什么影响?

A3:pg_hba.conf按顺序匹配规则,第一个匹配的规则生效。因此,更具体的规则应该放在前面,更通用的规则放在后面。例如,拒绝特定IP的规则应该放在允许所有IP的规则前面。

Q4:如何允许来自多个IP段的访问?

A4:可以为每个IP段添加单独的规则:

txt
host    all             all             192.168.1.0/24          md5
host    all             all             10.0.0.0/8              md5
host    all             all             172.16.0.0/12           md5

Q5:如何使用SSL证书进行IP访问控制?

A5:可以结合hostssl类型和cert认证方法:

txt
# 仅允许SSL连接,并使用SSL证书认证
hostssl all             all             192.168.1.0/24          cert clientcert=1

Q6:如何查看当前连接的客户端IP?

A6:可以查询pg_stat_activity视图:

sql
SELECT usename, client_addr, client_hostname, application_name 
FROM pg_stat_activity 
WHERE state = 'active';

Q7:pg_hba.conf和postgresql.conf中的listen_addresses有什么区别?

A7:

  • listen_addresses:指定PostgreSQL服务器监听的IP地址,控制服务器接受哪些网络接口的连接
  • pg_hba.conf:控制哪些客户端IP可以连接到数据库,以及使用什么认证方法

Q8:如何配置基于主机名的访问控制?

A8:可以使用主机名代替IP地址,但需要确保DNS解析正常:

txt
# 允许来自特定主机名的连接
host    all             all             .example.com            md5