Appearance
PostgreSQL 证书认证
概述
证书认证(Certificate Authentication)是 PostgreSQL 提供的一种基于 SSL 客户端证书的身份验证方法。这种认证方式通过验证客户端提供的 SSL 证书来确认用户身份,提供了高安全性的连接方式。
INFO
证书认证只能在 SSL 连接上使用,因此在配置证书认证之前,必须先正确配置 SSL 连接。
工作原理
证书认证的工作流程如下:
认证过程详解
- SSL 连接建立:客户端与服务器建立 SSL 连接
- 证书请求:服务器要求客户端提供有效的 SSL 证书
- 证书验证:服务器验证证书的有效性和信任关系
- 用户名匹配:提取证书的 CN(Common Name)字段,与请求的数据库用户名进行比较
- 认证决策:如果 CN 匹配用户名或通过用户名映射验证,则允许登录
配置方法
1. pg_hba.conf 配置
在pg_hba.conf
文件中配置证书认证:
bash
# TYPE DATABASE USER ADDRESS METHOD
hostssl all all 192.168.1.0/24 cert
hostssl mydb certuser 0.0.0.0/0 cert map=certmap
bash
# 允许所有用户通过证书认证连接所有数据库
hostssl all all 0.0.0.0/0 cert
bash
# 只允许特定用户通过证书认证
hostssl mydb certuser 192.168.1.0/24 cert
bash
# 使用用户名映射的证书认证
hostssl all all 0.0.0.0/0 cert map=certmap
2. 用户名映射配置
当证书的 CN 字段与数据库用户名不同时,可以使用用户名映射:
bash
# pg_ident.conf
# MAPNAME SYSTEM-USERNAME PG-USERNAME
certmap john.doe johnuser
certmap admin.cert postgres
certmap /^(.*)\.dev$ \1
3. 配置选项
证书认证支持以下配置选项:
选项 | 描述 | 示例 |
---|---|---|
map | 指定用户名映射 | cert map=certmap |
实际应用示例
示例 1:基本证书认证配置
场景:为公司内部应用配置证书认证,确保只有持有有效证书的客户端能够连接数据库。
问题陈述:需要为一个包含敏感数据的 PostgreSQL 数据库配置高安全性的客户端认证。
解决方案:
bash
# 在pg_hba.conf中添加证书认证规则
hostssl financialdb all 10.0.0.0/8 cert
bash
# 生成客户端私钥
openssl genrsa -out client.key 2048
# 生成证书签名请求
openssl req -new -key client.key -out client.csr \
-subj "/CN=dbuser/O=Company/C=US"
# 使用CA签名证书
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client.crt -days 365
bash
# 使用证书连接数据库
psql "host=dbserver dbname=financialdb user=dbuser \
sslmode=require sslcert=client.crt sslkey=client.key \
sslrootcert=ca.crt"
分析过程:
- SSL 连接确保数据传输加密
- 证书验证确保客户端身份可信
- CN 字段"dbuser"必须与 PostgreSQL 用户名匹配
- 无需密码,基于证书的强认证
输入和输出:
输入:客户端证书(CN=dbuser)
Certificate:
Subject: CN=dbuser, O=Company, C=US
Issuer: CN=Company CA, O=Company, C=US
Validity: Not Before: 2024-01-01, Not After: 2025-01-01
输出:成功连接
psql (14.5)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384)
Type "help" for help.
financialdb=>
示例 2:使用用户名映射的证书认证
场景:企业环境中,员工证书的 CN 字段包含完整的员工信息,需要映射到简化的数据库用户名。
问题陈述:证书 CN 为"[email protected]",但数据库用户名为"john",需要建立映射关系。
解决方案:
bash
# 使用用户名映射的证书认证
hostssl companydb all 0.0.0.0/0 cert map=employee_map
bash
# 员工证书到数据库用户的映射
employee_map [email protected] john
employee_map [email protected] jane
employee_map [email protected] postgres
# 使用正则表达式进行模式匹配
employee_map /^(.+)@company\.com$ \1
bash
# 重新加载PostgreSQL配置
SELECT pg_reload_conf();
分析过程:
- 映射查找:服务器在 pg_ident.conf 中查找匹配的映射规则
- 模式匹配:支持正则表达式进行灵活的用户名转换
- 认证决策:映射成功后,使用映射后的数据库用户名进行权限检查
输入和输出:
输入:证书 CN = "[email protected]"
Certificate Subject: [email protected], O=Company Inc, C=US
映射过程:
[email protected] → john (通过employee_map映射)
输出:以用户"john"身份连接成功
companydb=> SELECT current_user;
current_user
--------------
john
(1 row)
安全考虑
证书管理最佳实践
WARNING
证书认证的安全性完全依赖于证书基础设施的安全性。确保:
- CA 私钥的安全存储
- 证书的定期轮换
- 撤销列表(CRL)的维护
1. 证书生命周期管理
2. 安全配置检查表
检查项 | 重要性 | 配置建议 |
---|---|---|
SSL 版本 | 🔴 高 | 仅允许 TLS 1.2+ |
证书有效期 | 🟡 中 | 建议 1 年或更短 |
CA 证书保护 | 🔴 高 | 离线存储,硬件安全模块 |
证书撤销 | 🟡 中 | 维护 CRL 或使用 OCSP |
密钥强度 | 🔴 高 | 至少 2048 位 RSA 或 256 位 ECC |
故障排除
常见错误和解决方案
Details
证书验证失败 错误信息:certificate verify failed
可能原因:
- 证书链不完整
- CA 证书未正确配置
- 证书已过期
解决方案:
bash
# 检查证书有效性
openssl x509 -in client.crt -text -noout
# 验证证书链
openssl verify -CAfile ca.crt client.crt
# 检查服务器SSL配置
openssl s_client -connect dbserver:5432 -cert client.crt -key client.key
Details
用户名映射失败 错误信息:certificate authentication failed for user "username"
可能原因:
- pg_ident.conf 映射规则错误
- 映射名称在 pg_hba.conf 中未正确指定
- 正则表达式语法错误
解决方案:
bash
# 检查映射配置
cat $PGDATA/pg_ident.conf | grep mapname
# 测试正则表达式
echo "[email protected]" | grep -E "^(.+)@company\.com$"
# 查看认证日志
tail -f $PGDATA/log/postgresql-*.log | grep FATAL
性能考量
证书认证性能特点
性能优化建议
- 连接池使用:减少频繁的 SSL 握手开销
- 证书缓存:服务器端缓存已验证的证书
- 简化映射规则:避免复杂的正则表达式
TIP
证书认证比密码认证在连接建立时有更高的 CPU 开销,但提供了更强的安全性。对于高频连接的应用,建议使用连接池。
与其他认证方法的比较
认证方法 | 安全性 | 复杂性 | 性能 | 适用场景 |
---|---|---|---|---|
cert | 🔴 很高 | 🟡 中等 | 🟡 中等 | 企业级应用,高安全要求 |
md5/scram | 🟡 中等 | 🟢 低 | 🟢 高 | 一般 web 应用 |
trust | 🔴 无 | 🟢 最低 | 🟢 最高 | 开发环境 |
ldap | 🟡 中等 | 🟡 中等 | 🟡 中等 | 企业目录集成 |
::: important 选择认证方法时,需要在安全性、管理复杂性和性能之间找到平衡。证书认证适合对安全性要求极高的企业环境。
:::
相关配置参数
SSL 相关参数
sql
-- 查看当前SSL配置
SHOW ssl;
SHOW ssl_cert_file;
SHOW ssl_key_file;
SHOW ssl_ca_file;
-- 查看连接的SSL信息
SELECT * FROM pg_stat_ssl WHERE pid = pg_backend_pid();
重要配置文件路径
bash
# PostgreSQL配置文件位置
$PGDATA/postgresql.conf # 主配置文件
$PGDATA/pg_hba.conf # 客户端认证配置
$PGDATA/pg_ident.conf # 用户名映射配置
通过合理配置证书认证,您可以为 PostgreSQL 数据库建立一个高安全性的访问控制机制,特别适用于企业级环境和对安全性有严格要求的应用场景。