Skip to content

PostgreSQL 安全加固建议

系统级安全加固

操作系统配置

bash
# 最小化安装原则
# 移除不必要的软件包
yum remove -y unneeded-package

# 配置防火墙,仅开放必要端口
tfirewall-cmd --permanent --add-port=5432/tcp
firewall-cmd --reload

# 禁用不必要的服务
systemctl disable --now avahi-daemon cups

# 设置文件系统权限
chmod 700 /var/lib/pgsql/14/data/
chown -R postgres:postgres /var/lib/pgsql/

# 启用SELinux或AppArmor
systemctl enable --now selinux

PostgreSQL用户管理

bash
# 确保PostgreSQL运行在专用用户下
id postgres

# 限制postgres用户的shell访问
chsh -s /bin/nologin postgres

# 设置强密码策略
vim /etc/login.defs
PASS_MAX_DAYS 90
PASS_MIN_DAYS 7
PASS_WARN_AGE 14

数据库配置安全

监听设置

bash
# 编辑postgresql.conf
vim /var/lib/pgsql/14/data/postgresql.conf

# 仅监听必要的IP地址
listen_addresses = '127.0.0.1,192.168.1.100'

# 禁用不必要的服务
max_prepared_transactions = 0
shared_preload_libraries = ''

# 限制连接数
max_connections = 100

认证配置

bash
# 编辑pg_hba.conf
vim /var/lib/pgsql/14/data/pg_hba.conf

# 使用MD5或SCRAM-SHA-256认证
host    all             all             192.168.1.0/24         scram-sha-256

# 拒绝所有其他连接
host    all             all             0.0.0.0/0               reject

# 限制超级用户本地访问
host    postgres        postgres        127.0.0.1/32         scram-sha-256

安全参数配置

sql
-- 禁用远程超级用户访问
ALTER SYSTEM SET superuser_reserved_connections = 3;

-- 启用密码复杂度检查
ALTER SYSTEM SET password_encryption = 'scram-sha-256';

-- 限制密码有效期
ALTER ROLE app_user WITH VALID UNTIL '2025-12-31';

-- 启用连接超时
ALTER SYSTEM SET tcp_keepalives_idle = 60;
ALTER SYSTEM SET tcp_keepalives_interval = 10;
ALTER SYSTEM SET tcp_keepalives_count = 5;

-- 禁用不必要的SQL功能
ALTER SYSTEM SET plpgsql.check_asserts = 'on';
ALTER SYSTEM SET default_transaction_read_only = 'off';

-- 启用日志记录
ALTER SYSTEM SET log_statement = 'ddl';
ALTER SYSTEM SET log_connections = 'on';
ALTER SYSTEM SET log_disconnections = 'on';
ALTER SYSTEM SET log_error_verbosity = 'verbose';

访问控制安全

角色与权限管理

sql
-- 遵循最小权限原则
CREATE ROLE app_user WITH LOGIN PASSWORD 'secure_password';
GRANT SELECT, INSERT, UPDATE ON TABLE app_data TO app_user;

-- 创建只读角色
CREATE ROLE read_only;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only;

-- 限制角色只能访问特定IP
-- 使用pg_hba.conf实现

-- 定期审查权限
SELECT grantee, privilege_type, table_name 
FROM information_schema.role_table_grants 
WHERE table_schema = 'public';

连接限制

sql
-- 安装pg_hba_diff扩展监控pg_hba.conf变更
CREATE EXTENSION IF NOT EXISTS pg_hba_diff;

-- 使用pg_connections_limit限制连接
CREATE EXTENSION IF NOT EXISTS pg_connections_limit;
ALTER ROLE app_user WITH CONNECTION LIMIT 10;

加密安全

数据传输加密

bash
# 启用SSL/TLS
ssl = on
ssl_cert_file = '/etc/postgresql/ssl/server.crt'
ssl_key_file = '/etc/postgresql/ssl/server.key'
ssl_ca_file = '/etc/postgresql/ssl/ca.crt'
ssl_min_protocol_version = 'TLSv1.2'

数据静态加密

bash
# 使用透明数据加密(TDE)
# 对于PostgreSQL 14+,可以使用pg_tde扩展
CREATE EXTENSION IF NOT EXISTS pg_tde;

# 或者使用文件系统加密
# 例如使用LUKS加密数据目录
cryptsetup luksFormat /dev/sdb1
cryptsetup open /dev/sdb1 pg_data
mkfs.ext4 /dev/mapper/pg_data
mount /dev/mapper/pg_data /var/lib/pgsql/14/data/

敏感数据加密

sql
-- 使用pgcrypto扩展加密敏感数据
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- 加密列数据
ALTER TABLE users ADD COLUMN email_encrypted bytea;
UPDATE users SET email_encrypted = pgp_sym_encrypt(email, 'encryption_key');

-- 查询加密数据
SELECT pgp_sym_decrypt(email_encrypted, 'encryption_key') AS email FROM users;

审计与监控

启用审计日志

sql
-- 配置详细审计日志
ALTER SYSTEM SET log_statement = 'all';
ALTER SYSTEM SET log_duration = 'on';
ALTER SYSTEM SET log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h ';
ALTER SYSTEM SET log_rotation_size = '100MB';
ALTER SYSTEM SET log_rotation_age = '1d';

-- 重启生效
SELECT pg_reload_conf();

安装审计扩展

sql
-- 安装pgAudit扩展
CREATE EXTENSION IF NOT EXISTS pgaudit;

-- 配置审计策略
ALTER SYSTEM SET pgaudit.log = 'read, write, function';
ALTER SYSTEM SET pgaudit.log_catalog = 'on';
ALTER SYSTEM SET pgaudit.log_parameter = 'on';

监控设置

bash
# 安装Prometheus和Grafana监控
# 配置postgres_exporter
wget https://github.com/prometheus-community/postgres_exporter/releases/download/v0.15.0/postgres_exporter-0.15.0.linux-amd64.tar.gz
tar -xzf postgres_exporter-0.15.0.linux-amd64.tar.gz

# 创建监控用户
CREATE ROLE prometheus WITH LOGIN PASSWORD 'monitor_password';
GRANT pg_monitor TO prometheus;

备份与恢复安全

备份策略

bash
# 使用pg_basebackup进行物理备份
pg_basebackup -h localhost -U replication -D /backup/pg_base -F t -z -P

# 使用pg_dump进行逻辑备份
pg_dump -h localhost -U postgres -d mydb -F c -b -v -f /backup/mydb.dump

# 加密备份文件
openssl enc -aes-256-cbc -salt -in /backup/mydb.dump -out /backup/mydb.dump.enc -k "backup_password"

# 定期测试恢复
pg_restore -h localhost -U postgres -d testdb /backup/mydb.dump

备份验证

sql
-- 验证备份完整性
pg_restore -l /backup/mydb.dump

-- 检查备份文件大小
ls -lh /backup/

-- 监控备份作业
SELECT pid, query_start, state, query 
FROM pg_stat_activity 
WHERE query LIKE '%backup%';

漏洞管理

定期更新

bash
# 定期更新PostgreSQL
# 对于RHEL/CentOS
yum update -y postgresql14-server

# 对于Ubuntu/Debian
apt update && apt upgrade -y postgresql-14

# 应用安全补丁
# 关注官方安全公告:https://www.postgresql.org/support/security/

漏洞扫描

bash
# 使用OpenVAS或Nessus进行漏洞扫描
# 或者使用pg_scan工具

# 检查已知漏洞
# 使用psqlcheck工具
python3 psqlcheck.py --host localhost --port 5432 --user postgres

CVE监控

bash
# 订阅PostgreSQL安全邮件列表
# https://www.postgresql.org/list/pgsql-announce/

# 使用OWASP Dependency-Check检查依赖漏洞
dependency-check.sh --scan /usr/pgsql-14/lib --format HTML --output /tmp/dependency-check-report.html

应急响应

制定应急响应计划

bash
# 创建应急响应文档
# 包含:
# 1. 应急响应团队成员及联系方式
# 2. 应急响应流程
# 3. 常见安全事件处理步骤
# 4. 恢复步骤
# 5. 事后分析流程

# 定期演练应急响应
# 每季度进行一次安全事件演练

安全事件处理

sql
-- 检测可疑活动
SELECT * FROM pg_stat_activity 
WHERE state = 'active' 
AND query LIKE '%DROP%' 
AND client_addr != '127.0.0.1';

-- 终止可疑连接
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE pid = suspicious_pid;

-- 记录事件
INSERT INTO security_events (event_time, event_type, description, affected_object)
VALUES (now(), 'suspicious_query', 'Detected suspicious DROP query', 'database');

版本差异考虑

  • PostgreSQL 10+:引入SCRAM-SHA-256认证方式
  • PostgreSQL 12+:增强了密码策略和审计功能
  • PostgreSQL 13+:改进了SSL/TLS配置和性能
  • PostgreSQL 14+:支持更多加密算法和审计选项
  • PostgreSQL 15+:增强了默认安全设置,如禁用远程超级用户访问

常见问题(FAQ)

Q1:如何检查PostgreSQL的安全状态?

A1:可以使用以下方法检查:

sql
-- 检查监听地址
SHOW listen_addresses;

-- 检查认证方式
SELECT * FROM pg_hba_file_rules;

-- 检查用户权限
\du+

-- 检查安全参数
SELECT name, setting FROM pg_settings WHERE name IN ('ssl', 'password_encryption', 'log_statement');

Q2:如何防范SQL注入攻击?

A2:可以采取以下措施:

  1. 使用参数化查询或预处理语句
  2. 限制数据库用户的权限
  3. 启用pgAudit审计所有SQL语句
  4. 使用Web应用防火墙(WAF)
  5. 定期进行代码审计

Q3:如何处理数据库密码泄露?

A3:立即采取以下措施:

  1. 重置所有受影响的用户密码
  2. 检查数据库日志,确认是否有未授权访问
  3. 检查数据库对象是否被篡改
  4. 启用更严格的认证方式
  5. 考虑启用多因素认证
  6. 通知相关 stakeholders

Q4:如何配置PostgreSQL的审计功能?

A4:可以通过以下方式配置:

  1. 启用内置审计日志:
    sql
    ALTER SYSTEM SET log_statement = 'all';
    ALTER SYSTEM SET log_connections = 'on';
    ALTER SYSTEM SET log_disconnections = 'on';
  2. 安装pgAudit扩展:
    sql
    CREATE EXTENSION IF NOT EXISTS pgaudit;
    ALTER SYSTEM SET pgaudit.log = 'read, write, function';

Q5:如何确保PostgreSQL备份的安全性?

A5:可以采取以下措施:

  1. 加密备份文件
  2. 限制备份文件的访问权限
  3. 存储备份到安全的位置(如异地存储)
  4. 定期测试备份恢复
  5. 监控备份作业的完整性
  6. 实现备份的版本控制
  7. 定期轮换备份密码