保护 PostgreSQL 数据库安全的基本配置设置

通过 pg_hba.conf 规则、SCRAM 认证、TLS 强制加密、限制监听地址、最小权限原则和审计日志来保护 PostgreSQL 安全。

保护 PostgreSQL 数据库安全的基本配置设置

保护 PostgreSQL 安全始于一个简单的问题:谁被允许连接、从哪里连接、使用什么认证方法?如果 pg_hba.conf 设置过于宽泛,或者服务器监听了不必要的接口,你的数据库攻击面就会比实际需要的大。

本指南涵盖了你应首先审查的 PostgreSQL 安全设置:pg_hba.conf、SCRAM 密码认证、TLS、网络监听器、角色权限和日志。

1. 使用 pg_hba.conf 强化客户端认证

基于主机的认证文件(pg_hba.conf)规定了哪些主机可以连接、它们可以以哪些 PostgreSQL 用户身份连接、可以访问哪些数据库,以及最重要的是,该连接所需的认证方法。

理解 pg_hba.conf 结构

pg_hba.conf 中的每一行都遵循特定格式:

TYPE DATABASE USER ADDRESS METHOD [OPTIONS]

  • TYPE:连接类型(例如 localhosthostnosslhostssl)。
  • DATABASE:目标数据库名称。
  • USER:目标数据库角色。
  • ADDRESS:客户端 IP 地址范围。
  • METHOD:认证机制(例如 scram-sha-256md5rejecttrust)。

认证方法的最佳实践

在生产环境中切勿使用 trust 方法,因为它允许任何符合连接条件的用户无需密码即可连接。推荐的现代认证方法包括:

推荐:scram-sha-256

SCRAM(加盐质询响应认证机制)通过使用更强的哈希算法和防止重放攻击,比旧的密码方法(如 md5)有显著改进。这应该是远程连接的默认选择。

# 对来自应用程序子网的远程连接强制使用 SCRAM
host    appdb   app_user 10.20.30.0/24  scram-sha-256

在创建或轮换密码之前,在 postgresql.conf 中设置 password_encryption = 'scram-sha-256'。使用旧哈希存储的现有密码不会自动转换;启用 SCRAM 后需要重置它们。

password_encryption = 'scram-sha-256'

除非有其他网络控制已限制访问,否则避免使用如下宽泛规则:

host    all     all     0.0.0.0/0       scram-sha-256

本地连接

对于源自服务器本身的连接(例如在同一台机器上运行的应用程序),使用本地套接字。最安全的设置通常是 peer(用于 Unix 域套接字),或者如果套接字被禁用或限制,则使用 scram-sha-256

# 对通过 Unix 套接字的本地连接使用 peer 认证
local   all     all             peer

显式拒绝连接

使用 reject 方法显式阻止来自危险或不受信任网络的连接。

# 阻止来自已知不安全 IP 范围的所有连接
host    all     all     192.168.1.0/24  reject

可操作提示: 修改 pg_hba.conf 后,重新加载 PostgreSQL 以使更改生效,例如使用 sudo systemctl reload postgresqlSELECT pg_reload_conf();

2. 实施 SSL/TLS 加密

为了防止敏感数据(包括密码)通过网络被截获,必须对所有远程连接强制实施 SSL/TLS 加密。

postgresql.conf 中的配置

确保在主配置文件中正确设置以下参数:

  • ssl = on:全局启用 SSL 支持。
  • ssl_cert_file:服务器证书文件的路径(例如 server.crt)。
  • ssl_key_file:服务器私钥文件的路径(例如 server.key)。

pg_hba.conf 中强制使用 SSL

要强制客户端使用 SSL,将 pg_hba.conf 中的连接类型从 host 更改为 hostssl

# 仅允许通过 SSL/TLS 的连接
hostssl all     all     0.0.0.0/0       scram-sha-256

hostssl 仅匹配 SSL 连接。确保没有其他更早或更晚的 host 规则允许相同用户在不使用 TLS 的情况下连接。为了使策略更明确,可以添加一条拒绝非 SSL 连接的规则:

hostnossl all    all     0.0.0.0/0       reject

3. 最小化攻击面

安全涉及减少数据库服务器对外部威胁的暴露。这主要通过网络配置和禁用不必要的功能来管理。

限制网络监听地址

PostgreSQL 通常默认监听 localhost,但打包部署和托管镜像可能有所不同。显式配置它仅监听需要访问的特定接口,或者如果只有本地应用程序连接,则保持监听 localhost

postgresql.conf 中:

# 如果可能,仅监听 localhost (127.0.0.1)
listen_addresses = 'localhost'

# 或者,仅监听特定的私有网络接口
# listen_addresses = '192.168.1.10'

安全警告: 如果 listen_addresses 设置为 *,则将使用所有接口。确保 pg_hba.conf 严格控制哪些 IP 范围可以连接。

禁用不必要的扩展和功能

每个启用的扩展都会增加潜在的复杂性和攻击向量。定期审计已安装的扩展,并移除生产工作负载中未使用的扩展。这可以最小化整体攻击面。

密码安全与角色

确保所有管理角色(如默认的 postgres 用户)使用 ALTER USER 设置强密码:

ALTER USER postgres WITH PASSWORD 'YourStrongAndComplexPassword123!';

遵循最小权限原则:应用程序用户应仅对其所需的特定表拥有 SELECTINSERTUPDATEDELETE 权限,而不是超级用户状态。

4. 审计与日志配置

虽然严格来说不是访问控制机制,但强大的日志记录对于检测和调查安全事件至关重要。在 postgresql.conf 中配置日志参数以捕获相关事件。

用于安全审计的关键设置:

  • log_statement = 'ddl''all':记录所有数据定义语言(DDL)命令,例如 CREATE TABLEALTER USER。谨慎使用 'all',因为它可能产生大量日志并捕获敏感查询文本。
  • log_connections = on:记录每次成功的连接尝试。
  • log_disconnections = on:记录客户端断开连接的情况。
  • log_duration = on:记录所有语句的执行时间,有时可以揭示异常活动模式。

通过结合 pg_hba.conf 中的严格访问规则、通过 SSL 强制加密、限制监听地址以及全面的日志记录,你可以为保护 PostgreSQL 部署奠定坚实基础。

基本安全步骤

  1. 更新 pg_hba.conf:使用 scram-sha-256peer 作为认证方法。
  2. 强制加密:在 postgresql.conf 中设置 ssl = on,并在 pg_hba.conf 中使用 hostssl 条目。
  3. 限制监听:将 listen_addresses 配置为仅必要的接口,如果可能避免使用默认的 *
  4. 强制最小权限:将数据库角色限制为其功能绝对需要的权限。
  5. 重新加载配置:修改安全文件后,始终重新加载或重启 PostgreSQL 以应用更改。

这些设置是基础。应用它们后,从允许的客户端测试,从被阻止的客户端测试,并验证日志是否显示了你预期的连接行为。