外观
PostgreSQL 加密规范
传输加密(SSL/TLS)
SSL/TLS 配置
生成证书
bash# 创建证书目录 mkdir -p /path/to/ssl cd /path/to/ssl # 生成CA私钥 openssl genrsa -des3 -out ca.key 2048 # 生成CA证书 openssl req -new -x509 -days 3650 -key ca.key -out ca.crt # 生成服务器私钥 openssl genrsa -des3 -out server.key 2048 # 生成证书签名请求 openssl req -new -key server.key -out server.csr # 生成服务器证书 openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt # 移除私钥密码 openssl rsa -in server.key -out server.key # 设置权限 chmod 600 server.key chown postgres:postgres server.key server.crt ca.crt配置postgresql.conf
sql-- 启用SSL ALTER SYSTEM SET ssl = 'on'; -- 配置证书路径 ALTER SYSTEM SET ssl_cert_file = '/path/to/ssl/server.crt'; ALTER SYSTEM SET ssl_key_file = '/path/to/ssl/server.key'; ALTER SYSTEM SET ssl_ca_file = '/path/to/ssl/ca.crt'; -- 配置SSL协议版本 ALTER SYSTEM SET ssl_min_protocol_version = 'TLSv1.2'; ALTER SYSTEM SET ssl_max_protocol_version = 'TLSv1.3';配置pg_hba.conf
# 要求所有连接使用SSL hostssl all all 0.0.0.0/0 scram-sha-256 hostssl all all ::1/128 scram-sha-256 # 可选:允许特定IP使用非SSL连接 host all all 192.168.1.0/24 scram-sha-256
SSL 验证级别
客户端验证配置
sql-- 配置客户端证书验证 ALTER SYSTEM SET ssl_prefer_server_ciphers = 'on'; ALTER SYSTEM SET ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL';SSL 验证级别
- verify-ca:验证服务器CA证书
- verify-full:验证服务器CA证书和主机名
- 客户端连接示例:bash
psql "host=server_host dbname=dbname user=username sslmode=verify-full sslrootcert=/path/to/ca.crt"
数据加密(存储加密)
透明数据加密 (TDE) 替代方案
文件系统加密
- 使用 LUKS (Linux) 或 BitLocker (Windows) 加密数据目录
- 示例(LUKS):bash
# 创建加密卷 cryptsetup luksFormat /dev/sdb1 cryptsetup open /dev/sdb1 pg_data mkfs.ext4 /dev/mapper/pg_data mount /dev/mapper/pg_data /path/to/pg_data
表空间加密
sql-- 创建加密表空间 -- 注意:PostgreSQL 本身不支持表空间加密,需要结合文件系统加密 CREATE TABLESPACE encrypted_ts LOCATION '/path/to/encrypted/directory'; -- 创建表时使用加密表空间 CREATE TABLE encrypted_table (id INT, data TEXT) TABLESPACE encrypted_ts;
列级加密
pgcrypto 扩展
sql-- 安装pgcrypto扩展 CREATE EXTENSION IF NOT EXISTS pgcrypto; -- 创建加密表 CREATE TABLE sensitive_data ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, credit_card BYTEA NOT NULL, ssn BYTEA NOT NULL ); -- 插入加密数据 INSERT INTO sensitive_data (name, credit_card, ssn) VALUES ( 'John Doe', pgp_sym_encrypt('1234-5678-9012-3456', 'encryption_key'), pgp_sym_encrypt('123-45-6789', 'encryption_key') ); -- 查询加密数据 SELECT name, pgp_sym_decrypt(credit_card, 'encryption_key') AS credit_card, pgp_sym_decrypt(ssn, 'encryption_key') AS ssn FROM sensitive_data;哈希函数
sql-- 使用哈希函数存储密码 CREATE TABLE users ( id SERIAL PRIMARY KEY, username TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL ); -- 插入哈希密码 INSERT INTO users (username, password_hash) VALUES ('user1', crypt('password123', gen_salt('bf'))); -- 验证密码 SELECT * FROM users WHERE username = 'user1' AND password_hash = crypt('password123', password_hash);
密码加密
密码存储配置
密码加密算法
sql-- 使用scram-sha-256加密算法 ALTER SYSTEM SET password_encryption = 'scram-sha-256'; -- 验证配置 SHOW password_encryption;密码复杂度要求
sql-- 安装passwordcheck扩展(PostgreSQL 14+) CREATE EXTENSION IF NOT EXISTS passwordcheck; -- 配置密码复杂度(通过修改passwordcheck.c源码并重新编译) -- 或使用第三方扩展如pgcrypto的密码验证
连接密码加密
- 连接字符串加密
- 使用
.pgpass文件存储密码 - 配置示例:
# ~/.pgpass 文件内容 hostname:port:database:username:password *:*:*:user1:password123 - 设置权限:bash
chmod 600 ~/.pgpass
- 使用
加密扩展
pgcrypto 扩展
功能特性
- 对称加密:AES, 3DES, Blowfish
- 非对称加密:RSA
- 哈希函数:MD5, SHA-1, SHA-256, SHA-512
- 随机数生成
使用示例
sql-- 生成随机数 SELECT gen_random_bytes(16); -- 计算哈希值 SELECT md5('test'); SELECT sha256('test'); -- 非对称加密 SELECT pgp_pub_encrypt('secret message', dearmor('-----BEGIN PGP PUBLIC KEY BLOCK-----...'));
sslinfo 扩展
功能特性
- 提供SSL连接信息
- 检查客户端证书
使用示例
sql-- 安装sslinfo扩展 CREATE EXTENSION IF NOT EXISTS sslinfo; -- 查看SSL连接信息 SELECT ssl_is_used(), ssl_version(), ssl_cipher();
加密性能优化
性能影响因素
加密算法选择
- AES-256-GCM:安全性高,性能好
- 避免使用低效率算法如3DES
硬件加速
- 确保CPU支持AES-NI指令集
- 验证硬件加速是否启用:sql
SELECT name, setting FROM pg_settings WHERE name LIKE '%ssl%' OR name LIKE '%crypto%';
配置优化
sql-- 优化SSL性能 ALTER SYSTEM SET ssl_prefer_server_ciphers = 'on'; ALTER SYSTEM SET ssl_ciphers = 'HIGH:!aNULL:!MD5:!3DES'; ALTER SYSTEM SET ssl_ecdh_curve = 'prime256v1';
监控与审计
加密状态监控
检查SSL连接
sql-- 查看当前连接是否使用SSL SELECT usename, application_name, client_addr, ssl, ssl_version, ssl_cipher FROM pg_stat_activity WHERE ssl = true;审计加密配置变更
sql-- 配置日志记录加密相关配置变更 ALTER SYSTEM SET log_statement = 'ddl'; ALTER SYSTEM SET log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h ';
最佳实践
传输加密最佳实践
强制使用SSL
- 在生产环境中强制所有连接使用SSL
- 配置pg_hba.conf只允许hostssl连接
定期更新证书
- 证书有效期建议不超过365天
- 建立证书轮换机制
使用强密码套件
- 优先使用TLSv1.2或TLSv1.3
- 避免使用不安全的密码套件
数据加密最佳实践
分层加密策略
- 传输层:SSL/TLS
- 存储层:文件系统加密
- 应用层:列级加密
密钥管理
- 使用专用密钥管理系统(如HashiCorp Vault)
- 避免硬编码密钥
- 定期轮换密钥
最小权限原则
- 只有授权用户才能访问加密数据
- 限制pgcrypto扩展的使用权限
密码加密最佳实践
使用强密码算法
- 优先使用scram-sha-256
- 避免使用md5(仅用于兼容旧版本)
定期更换密码
- 配置密码有效期
- 强制用户定期更换密码
多因素认证
- 结合外部认证系统实现多因素认证
- 如使用PgAuth或集成LDAP+MFA
常见问题(FAQ)
Q1:如何检查PostgreSQL是否启用了SSL?
A1:
sql
-- 检查SSL配置
SHOW ssl;
-- 查看SSL证书文件
SHOW ssl_cert_file;
SHOW ssl_key_file;
SHOW ssl_ca_file;
-- 检查当前连接是否使用SSL
SELECT ssl_is_used();Q2:SSL加密会影响性能吗?
A2:
- SSL加密会带来一定的性能开销(通常5-15%)
- 使用硬件加速(AES-NI)可以显著降低性能影响
- 优化SSL配置可以减少性能开销
- 建议在生产环境中启用SSL,安全性收益远大于性能损失
Q3:如何实现PostgreSQL的透明数据加密(TDE)?
A3: PostgreSQL本身不直接支持TDE,但可以通过以下方式实现:
- 使用文件系统加密(LUKS、BitLocker)
- 使用存储级加密(如AWS EBS加密)
- 使用第三方解决方案(如pg_tde扩展)
- 使用加密表空间(结合文件系统加密)
Q4:如何安全地存储加密密钥?
A4:
- 使用专用密钥管理系统(KMS)
- 如HashiCorp Vault、AWS KMS、Azure Key Vault
- 避免将密钥存储在数据库服务器上
- 实现密钥轮换机制
- 限制密钥访问权限
Q5:如何验证客户端证书?
A5:
- 在pg_hba.conf中使用cert认证方式
- 配置示例:
hostssl all all 0.0.0.0/0 cert clientcert=1 - 客户端需要提供有效的证书
- 服务器验证客户端证书的有效性和信任链
