Skip to content

PostgreSQL 连接池安全

PgBouncer 安全配置

PgBouncer 是 PostgreSQL 最常用的轻量级连接池,以下是其安全配置要点:

1. 配置文件安全

bash
# 设置配置文件权限,仅允许 root 和 pgbouncer 用户访问
chmod 600 /etc/pgbouncer/pgbouncer.ini
chown pgbouncer:pgbouncer /etc/pgbouncer/pgbouncer.ini

# 设置用户密码文件权限
chmod 600 /etc/pgbouncer/userlist.txt
chown pgbouncer:pgbouncer /etc/pgbouncer/userlist.txt

2. 认证配置

PgBouncer 支持多种认证方式,推荐使用密码文件或 PostgreSQL 原生认证:

ini
# pgbouncer.ini 中的认证配置
[databases]
* = host=127.0.0.1 port=5432

[pgbouncer]
# 监听地址(仅监听本地或特定IP)
listen_addr = 127.0.0.1
listen_port = 6432

# 认证方式
auth_type = md5
# 密码文件路径
auth_file = /etc/pgbouncer/userlist.txt
# 或使用 PostgreSQL 原生认证
auth_type = trust
# auth_type = scram-sha-256

# 用户列表查询(可选,从 PostgreSQL 获取用户信息)
auth_user = pgbouncer_auth

3. 用户密码管理

bash
# 生成加密密码(用于 userlist.txt)
psql -U postgres -c "SELECT usename, passwd FROM pg_shadow;" > /etc/pgbouncer/userlist.txt

# 或手动添加用户
cat >> /etc/pgbouncer/userlist.txt <<EOF
"admin" "md5abcdef1234567890"
"appuser" "md50987654321fedcba"
EOF

4. 访问控制

ini
# 允许连接到 PgBouncer 管理界面的 IP
admin_users = admin
stats_users = stats_user

# 限制客户端连接来源
host = 127.0.0.1
# 或允许特定网段
host = 192.168.1.0/24

PGPool-II 安全配置

PGPool-II 是功能更丰富的连接池,支持负载均衡和高可用,以下是其安全配置:

1. 配置文件安全

bash
# 设置配置文件权限
chmod 600 /etc/pgpool-II/pgpool.conf
chmod 600 /etc/pgpool-II/pool_hba.conf
chmod 600 /etc/pgpool-II/pcp.conf
chown pgpool:pgpool /etc/pgpool-II/*

2. 认证配置

PGPool-II 支持类似 PostgreSQL 的 pool_hba.conf 认证:

ini
# pgpool.conf 中的认证配置
listen_addresses = 'localhost,192.168.1.50'
port = 9999

# 认证相关配置
enable_pool_hba = on
pool_passwd = 'pool_passwd'

3. pool_hba.conf 配置

txt
# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
# 允许本地连接
local   all         all                               trust
# 允许特定网段使用 MD5 认证
host    all         all         192.168.1.0/24        md5
# 允许特定 IP 使用 SCRAM-SHA-256 认证
host    all         appuser     10.0.0.100/32         scram-sha-256
# 拒绝其他所有连接
host    all         all         0.0.0.0/0             reject

4. PCP 命令安全

PCP(PostgreSQL Cluster Manager)是 PGPool-II 的管理接口:

bash
# 生成 PCP 密码文件
pg_md5 --md5auth --username=pcp_user
# 输入密码后,会生成 /etc/pgpool-II/pcp.conf 文件

# 设置 PCP 命令访问控制
# 修改 pcp.conf,仅允许特定用户访问

连接池安全最佳实践

1. 最小权限原则

ini
# PgBouncer 配置示例:仅允许必要的数据库和用户
[databases]
appdb = host=127.0.0.1 port=5432 dbname=appdb

# 仅允许特定用户访问
auth_file = /etc/pgbouncer/userlist.txt
# userlist.txt 中只包含必要的用户

2. 加密通信

ini
# PgBouncer 启用 SSL
ssl = 1
ssl_cert_file = /etc/pgbouncer/server.crt
ssl_key_file = /etc/pgbouncer/server.key
ssl_ca_file = /etc/pgbouncer/root.crt

# PGPool-II 启用 SSL
ssl = on
ssl_cert = '/etc/pgpool-II/server.crt'
ssl_key = '/etc/pgpool-II/server.key'
ssl_ca_cert = '/etc/pgpool-II/root.crt'

3. 连接限制

ini
# PgBouncer 连接限制
max_client_conn = 1000
default_pool_size = 20
min_pool_size = 5
reserve_pool_size = 5

# PGPool-II 连接限制
max_pool = 25
min_pool_size = 5
max_connections = 1000

4. 监控与审计

ini
# PgBouncer 日志配置
log_connections = 1
log_disconnections = 1
log_pooler_errors = 1
verbose = 1

# PGPool-II 日志配置
log_connections = on
log_disconnections = on
log_statement = all
log_per_node_statement = on

5. 定期轮换密码

bash
# 定期更新 PgBouncer 密码文件
psql -U postgres -c "SELECT usename, passwd FROM pg_shadow;" > /etc/pgbouncer/userlist.txt
chmod 600 /etc/pgbouncer/userlist.txt

# 重启 PgBouncer 或重载配置
pgbouncer -R /etc/pgbouncer/pgbouncer.ini

连接池安全监控

1. PgBouncer 监控

bash
# 连接到 PgBouncer 管理界面
psql -h localhost -p 6432 -U admin pgbouncer

# 查看连接池状态
SHOW POOLS;

# 查看客户端连接
SHOW CLIENTS;

# 查看服务器连接
SHOW SERVERS;

# 查看统计信息
SHOW STATS;

2. PGPool-II 监控

bash
# 使用 PCP 命令查看状态
pcp_pool_status -h localhost -p 9898 -U pcp_user

# 查看 PGPool-II 日志
tail -f /var/log/pgpool/pgpool.log

# 使用 pgpool_adm 扩展查看状态
psql -h localhost -p 9999 -U postgres -c "SELECT * FROM pgpool_adm.pgpool_status();"

3. 系统监控

bash
# 监控连接池进程
ps aux | grep -E 'pgbouncer|pgpool'

# 监控网络连接
netstat -an | grep -E '6432|9999'
ss -an | grep -E '6432|9999'

# 监控资源使用情况
top -p $(pgrep -d',' pgbouncer)

连接池安全常见问题

1. 密码泄露风险

风险:连接池密码文件可能被未授权访问

解决方案

  • 设置严格的文件权限(600)
  • 定期轮换密码
  • 使用加密的密码存储方式
  • 限制可以访问连接池配置的用户

2. 连接劫持风险

风险:攻击者可能劫持连接池中的连接

解决方案

  • 启用 SSL 加密通信
  • 使用强认证方式(如 scram-sha-256)
  • 限制连接池的监听地址
  • 定期检查连接状态

3. 资源耗尽攻击

风险:攻击者可能通过大量连接耗尽连接池资源

解决方案

  • 设置合理的连接限制(max_client_conn)
  • 配置连接超时参数
  • 使用防火墙限制连接来源
  • 监控连接池使用率,设置告警阈值

常见问题(FAQ)

Q1:连接池和数据库服务器的认证方式需要一致吗?

A1:是的,连接池的认证方式应该与数据库服务器的认证方式兼容。例如,如果数据库使用 scram-sha-256 认证,连接池也应该配置为使用相同的认证方式,否则连接池无法正确转发认证信息。

Q2:如何安全地管理连接池的密码文件?

A2:

  • 设置严格的文件权限(chmod 600)
  • 仅允许连接池进程用户访问
  • 定期轮换密码
  • 避免在密码文件中存储明文密码
  • 使用自动化工具管理密码文件

Q3:连接池应该监听哪些地址?

A3:连接池应该仅监听必要的地址:

  • 对于仅本地使用的连接池,监听 localhost 即可
  • 对于需要远程访问的连接池,监听特定的内网 IP 地址
  • 避免监听 0.0.0.0(所有地址),除非有特殊需求

Q4:如何监控连接池的安全状态?

A4:

  • 监控连接池的连接数和使用率
  • 监控连接池日志中的错误和异常连接
  • 定期审计连接池的配置和用户列表
  • 使用入侵检测系统监控连接池的网络流量

Q5:PGPool-II 和 PgBouncer 哪个更安全?

A5:两者都可以配置为安全的连接池,安全性主要取决于配置是否正确:

  • PgBouncer 更轻量,配置简单,适合简单的连接池需求
  • PGPool-II 功能更丰富,支持更细粒度的访问控制和认证方式
  • 无论选择哪个,都需要遵循安全最佳实践,包括最小权限原则、加密通信和定期审计

Q6:如何防止连接池成为攻击目标?

A6:

  • 限制连接池的监听地址和端口访问
  • 使用强认证和加密通信
  • 设置合理的连接限制和超时参数
  • 定期更新连接池软件版本
  • 监控连接池的异常活动
  • 结合防火墙和入侵检测系统使用