PostgreSQL 安全加固实战:访问控制与审计配置指南

PostgreSQL 安全加固是数据库防护体系的关键环节,本文从访问控制、认证方式、传输加密、权限管理与审计日志五个维度,提供一套可直接复制的 PostgreSQL 安全加固配置方案,帮助企业抵御未授权访问、数据泄露与越权操作风险。

适用场景

  • PostgreSQL 生产库上线前的安全基线配置
  • 数据库被扫描爆破或发现未授权访问风险后的整改
  • 等保测评中数据库安全审计与访问控制项加固
  • 多租户或多人共库环境下的最小权限隔离

前置条件

  • 已安装 PostgreSQL 的 Linux 服务器(本教程以 PostgreSQL 15 + Ubuntu 22.04 为例)
  • 具备 postgres 系统用户或超级用户权限
  • 修改配置后需重启或 reload PostgreSQL 生效

原理说明

PostgreSQL 的安全模型分为三层:pg_hba.conf 负责客户端认证(规定谁能连、用什么认证方式);角色权限体系控制登录后能做什么;SSL 加密保护传输中的数据。攻击者最常见的入侵路径是:数据库监听在公网 + 弱口令 + 使用已废弃的 md5/trust 认证。因此加固的核心是:收紧监听地址、强制 scram-sha-256 强认证、启用 SSL、按最小权限拆分角色、并开启审计日志记录所有 SQL 操作。

操作步骤

1. 收紧监听地址与端口

编辑 /etc/postgresql/15/main/postgresql.conf

# 只监听本机回环地址(如有内网应用,改为内网 IP,切勿用 0.0.0.0)
listen_addresses = '127.0.0.1'
port = 5432

若业务必须允许远程访问,务必在云安全组/防火墙层面仅放行应用服务器 IP,并将监听地址限定为该内网 IP。

2. 强制 scram-sha-256 强认证

编辑 /etc/postgresql/15/main/pg_hba.conf,将认证方式统一改为 scram-sha-256

# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             postgres                                peer
local   all             all                                     scram-sha-256
host    all             all             127.0.0.1/32            scram-sha-256
host    all             all             ::1/128                 scram-sha-256
# 内网应用访问(按需,替换为实际网段)
host    all             app_user        10.0.0.0/8              scram-sha-256

将现有用户密码迁移到 scram 认证:

# 以 postgres 用户进入
sudo -u postgres psql
ALTER USER app_user WITH PASSWORD '强密码';
# 检查用户密码加密方式(应为 SCRAM-SHA-256)
SELECT usename, substring(passwd from 1 for 20) FROM pg_shadow;

pg_shadowpasswd 字段以 SCRAM-SHA-256$ 开头即表示已使用强认证。

3. 启用 SSL 加密传输

# 生成自签名证书(生产环境建议使用受信任 CA 签发的证书)
sudo openssl req -new -x509 -days 365 -nodes -text -out /etc/postgresql/15/main/server.crt -keyout /etc/postgresql/15/main/server.key -subj "/CN=db.example.com"
sudo chmod 600 /etc/postgresql/15/main/server.key
sudo chown postgres:postgres /etc/postgresql/15/main/server.key

# 在 postgresql.conf 中启用 SSL
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'

同时将 pg_hba.conf 中的远程条目加 hostssl 前缀(仅允许 SSL 连接),并禁用非 SSL:

hostssl  all             app_user        10.0.0.0/8              scram-sha-256

4. 最小权限:拆分角色

sudo -u postgres psql

-- 创建只读账号
CREATE ROLE readonly LOGIN PASSWORD '只读密码';
GRANT CONNECT ON DATABASE appdb TO readonly;
GRANT USAGE ON SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;

-- 限制只读账号登录来源(pg_hba.conf 中单独指定)
-- hostssl appdb readonly 10.0.0.5/32 scram-sha-256

删除不再使用的超级用户角色,业务账号一律使用最小权限的非超级用户:

-- 检查超级用户
SELECT rolname FROM pg_roles WHERE rolsuper = true;
-- 回收权限示例
REVOKE ALL ON DATABASE appdb FROM PUBLIC;

5. 开启审计日志

编辑 postgresql.conf

# 开启 SQL 语句日志(生产环境可只记 DDL/DDL 与失败登录)
log_statement = 'ddl'        # none | ddl | mod | all
log_duration = on
log_connections = on
log_disconnections = on
log_min_duration_statement = 1000   # 记录超过 1 秒的慢 SQL
log_directory = 'log'
log_filename = 'postgresql-%a.log'
log_line_prefix = '%m [%p] %u@%d '  # 时间、进程、用户、数据库

重启数据库使所有配置生效:

sudo systemctl restart postgresql
sudo systemctl status postgresql

配置验证

从四个方面验证加固效果:

  1. 强认证SELECT substring(passwd from 1 for 20) FROM pg_shadow; 输出以 SCRAM-SHA-256 开头
  2. SSL 生效:客户端连接加 sslmode=requirepsql "host=10.0.0.x dbname=appdb user=app_user sslmode=require" 连接成功后执行 SELECT ssl FROM pg_stat_ssl; 返回 t
  3. 权限隔离:用 readonly 账号尝试 INSERT 应报 permission denied
  4. 审计日志:执行一条 DDL 后 tail /var/log/postgresql/postgresql-*.log 能看到对应的语句与用户名

常见问题

FAQ 1:修改 pg_hba.conf 后远程连接报 “no pg_hba.conf entry”?

说明连接请求没有匹配到任何 pg_hba.conf 规则。按从上到下、首条匹配生效的原则检查:确认连接来源 IP 与规则的网段一致(可用 SELECT client_addr FROM pg_stat_activity; 查看实际来源);确认规则放在 host 类型且方法为 scram-sha-256;确认 PostgreSQL 已 reload(SELECT pg_reload_conf();)。若使用 hostssl 而客户端未启用 SSL,也会不匹配,需在连接串加 sslmode=require

FAQ 2:开启 log_statement=all 后日志暴涨怎么办?

全量 SQL 日志在生产环境会占用大量磁盘并拖慢性能。建议改为 log_statement = 'ddl' 记录结构变更,配合 log_min_duration_statement 只记录慢查询;对于安全审计需求,可结合扩展 pgAudit(pgaudit.log = 'write,ddl')按角色精细化记录,并通过 log_rotation_age(如 1d)与 log_truncate_on_rotation 控制日志轮转,防止磁盘写满。

总结

PostgreSQL 安全加固的核心动作可概括为五步:监听地址收紧到内网、pg_hba.conf 统一 scram-sha-256 强认证、启用 SSL 加密传输、按最小权限拆分只读/读写角色、开启审计日志。这套配置能有效阻断弱口令爆破、明文传输窃听与越权访问三类主要风险。建议将配置纳入标准部署流程,并定期用 pg_shadow 密码策略检查与权限复核确认加固持续有效。