保护 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:连接类型(例如
local、host、hostnossl、hostssl)。 - DATABASE:目标数据库名称。
- USER:目标数据库角色。
- ADDRESS:客户端 IP 地址范围。
- METHOD:认证机制(例如
scram-sha-256、md5、reject、trust)。
认证方法的最佳实践
在生产环境中切勿使用 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 postgresql或SELECT 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!';
遵循最小权限原则:应用程序用户应仅对其所需的特定表拥有 SELECT、INSERT、UPDATE 和 DELETE 权限,而不是超级用户状态。
4. 审计与日志配置
虽然严格来说不是访问控制机制,但强大的日志记录对于检测和调查安全事件至关重要。在 postgresql.conf 中配置日志参数以捕获相关事件。
用于安全审计的关键设置:
log_statement = 'ddl'或'all':记录所有数据定义语言(DDL)命令,例如CREATE TABLE和ALTER USER。谨慎使用'all',因为它可能产生大量日志并捕获敏感查询文本。log_connections = on:记录每次成功的连接尝试。log_disconnections = on:记录客户端断开连接的情况。log_duration = on:记录所有语句的执行时间,有时可以揭示异常活动模式。
通过结合 pg_hba.conf 中的严格访问规则、通过 SSL 强制加密、限制监听地址以及全面的日志记录,你可以为保护 PostgreSQL 部署奠定坚实基础。
基本安全步骤
- 更新
pg_hba.conf:使用scram-sha-256或peer作为认证方法。 - 强制加密:在
postgresql.conf中设置ssl = on,并在pg_hba.conf中使用hostssl条目。 - 限制监听:将
listen_addresses配置为仅必要的接口,如果可能避免使用默认的*。 - 强制最小权限:将数据库角色限制为其功能绝对需要的权限。
- 重新加载配置:修改安全文件后,始终重新加载或重启 PostgreSQL 以应用更改。
这些设置是基础。应用它们后,从允许的客户端测试,从被阻止的客户端测试,并验证日志是否显示了你预期的连接行为。