SSL (Secure Sockets Layer) 是一种用于保护 TCP/IP 连接安全的标准技术。通过在 PostgreSQL 中配置 SSL,可以对网络传输的数据进行加密,有效防止数据在传输过程中被窃听或篡改,确保数据通信的安全性。
1. SSL 基础概念
1.1 SSL 简介
PostgreSQL 原生支持使用 SSL 加密客户端与服务器之间的通信。要启用此功能,需满足以下条件:
- 客户端和服务器端都必须安装 OpenSSL
- 编译 PostgreSQL 时必须启用 SSL 支持
编译时添加 --with-openssl 参数:
./configure ... --with-openssl
1.2 OpenSSL req 命令参数详解
openssl req 命令常用参数:
| 参数 | 说明 |
|---|---|
-new |
创建证书请求文件,交互式输入信息 |
-x509 |
生成自签名证书而非证书请求 |
-days n |
指定证书有效期(天) |
-nodes |
禁止对私钥文件加密 |
-text |
以文本格式打印证书请求 |
-out filename |
指定输出文件 |
-keyout filename |
指定私钥存放位置 |
-subj args |
自定义证书请求信息 |
X.509 说明:X.509 是公钥证书的格式标准,规定了数字证书的格式。X.509 证书包含公钥和标识信息(主机名、组织等),并由证书颁发机构(CA)签名或自签名。
1.3 PostgreSQL 支持的 SSL 模式
PostgreSQL 提供多种 SSL 连接模式:
| 模式 | 描述 |
|---|---|
disable |
仅尝试非 SSL 连接 |
allow |
先尝试非 SSL,失败后尝试 SSL |
prefer (默认) |
先尝试 SSL,失败后尝试非 SSL |
require |
仅尝试 SSL 连接 |
verify-ca |
仅 SSL,并验证服务器证书是否由可信 CA 签发 |
verify-full |
仅 SSL,验证 CA 签发且主题匹配连接域名/IP |
使用建议:
- 公共 CA:推荐使用
verify-full - 本地/自签名 CA:
verify-ca通常已足够
1.4 密码套件配置
PostgreSQL 通过 ssl_ciphers 参数控制允许的密码套件(仅影响 TLS 1.2 及以下版本):
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
默认值说明:
HIGH:高强度密码套件(如 AES、Camellia、3DES)MEDIUM:中等强度密码套件(如 RC4、SEED)+3DES:修正 3DES 的排序问题!aNULL:禁用匿名密码套件(易受中间人攻击)
查看当前支持的密码套件:
openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'
2. SSL 证书类型
2.1 自签名证书
自签名证书由自己签发,无需 CA 认证,适用于测试或内部环境。
生成自签名证书命令:
openssl req -new -x509 -days 365 -nodes -text -out server.crt -keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key
2.2 自签名 CA 证书
建立本地 CA 体系,更安全的解决方案:
生成根 CA 密钥和证书:
# 生成根 CA 私钥和证书请求
openssl req -new -nodes -text -out root.csr -keyout root.key -subj "/CN=root.yourdomain.com"
chmod og-rwx root.key
# 自签名生成根证书
openssl x509 -req -in root.csr -text -days 3650 -extfile /etc/pki/tls/openssl.cnf -extensions v3_ca -signkey root.key -out root.crt
生成服务器证书:
# 生成服务器证书请求
openssl req -new -nodes -text -out server.csr -keyout server.key -subj "/CN=dbhost.yourdomain.com"
chmod og-rwx server.key
# 使用根 CA 签发服务器证书
openssl x509 -req -in server.csr -text -days 365 -CA root.crt -CAkey root.key -CAcreateserial -out server.crt
2.3 权威机构 CA 证书
由知名 CA 机构签发的证书,适用于生产环境:
- 申请证书(通常需要付费)
- 获取三个文件:
- 服务器私钥
server.key - 服务器证书
server.crt - CA 证书
- 服务器私钥
部署说明:
- 服务器:部署
server.key和server.crt - 客户端:部署 CA 证书(可从 libcurl 网站获取最新 CA 证书集合)
3. PostgreSQL SSL 配置实践
3.1 单向认证配置
步骤 1:生成自签名证书
openssl req -new -x509 -days 365 -nodes -text -out server.crt -keyout server.key -subj "/CN=host"
chmod 600 server.*
cp server.* $PGDATA
步骤 2:修改配置文件
postgresql.conf:
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
pg_hba.conf:
hostnossl all all 0.0.0.0/0 reject
hostssl all all 0.0.0.0/0 md5
步骤 3:重启服务并验证
psql "host=192.168.138.81 dbname=postgres port=5432 user=pg96"
# 应显示 SSL 连接信息
3.2 双向认证配置
步骤 1:搭建 CA 环境
# 创建文件夹demoCA
mkdir -p test/demoCA/{private,newcerts}
cd test/
# 将配置文件拷贝到test
cp `openssl version -d | awk -F '"' '{print $2}'`/openssl.cnf .
# 创建serial文件,写入01
echo '01' > demoCA/serial
# 创建文件index.txt
touch demoCA/index.txt
# 修改dir参数
sed -i 's|^dir\s*=.*|dir = ./demoCA|' openssl.cnf
# 修改default_md参数
sed -i 's|^default_md\s*=.*|default_md = sha256|' openssl.cnf
步骤 2:生成根 CA 证书
# 生成根私钥
openssl genrsa -aes256 -passout pass:postgresql@123 -out demoCA/private/cakey.pem 2048
# 生成根证书请求文件
openssl req -config openssl.cnf -passin pass:postgresql@123 -new -key demoCA/private/cakey.pem -out demoCA/careq.pem -subj "/C=CN/ST=guangzhou/L=Shenzhen/O=test/OU=test/CN=localhost"
# --生成根证书时,需要修改openssl.cnf文件,设置basicConstraints=CA:TRUE
sed -i 's/^basicConstraints.*$/basicConstraints=CA:TRUE/' openssl.cnf
# 生成自签发根证书,有y直接确认
openssl ca -config openssl.cnf -out demoCA/cacert.pem -passin pass:postgresql@123 -keyfile demoCA/private/cakey.pem -selfsign -infiles demoCA/careq.pem
步骤 3:生成服务器证书
#生成服务端私钥
openssl genrsa -aes256 -passout pass:postgresql@123 -out server.key 2048
# 生成服务端证书请求文件
openssl req -config openssl.cnf -passin pass:postgresql@123 -new -key server.key -out server.req -subj "/C=CN/ST=guangzhou/L=Shenzhen/O=test/OU=test/CN=server"
# 生成服务端/客户端证书时,修改openssl.cnf文件,设置basicConstraints=CA:FALSE
sed -i 's/^basicConstraints.*$/basicConstraints=CA:FALSE/' openssl.cnf
# 生成服务端证书,有y直接确认
openssl ca -config openssl.cnf -passin pass:postgresql@123 -in server.req -out server.crt -days 3650 -md sha256
#去掉服务端私钥的密码保护
openssl rsa -in server.key -out server.key
步骤 4:生成客户端证书
#生成客户端私钥
openssl genrsa -aes256 -passout pass:postgresql@123 -out client.key 2048
# 生成客户端证书请求文件
openssl req -config openssl.cnf -passin pass:postgresql@123 -new -key client.key -out client.req -subj "/C=CN/ST=guangzhou/L=Shenzhen/O=test/OU=test/CN=test"
# 生成服务端证书,有y直接确认
openssl ca -config openssl.cnf -passin pass:postgresql@123 -in client.req -out client.crt -days 3650 -md sha256
#去掉客户端私钥的密码保护
openssl rsa -in client.key -out client.key
步骤 5:部署证书
chmod 600 server.* client.* demoCA/cacert.pem
cp server.* demoCA/cacert.pem $PGDATA
cp client.* demoCA/cacert.pem /home/postgres/certs
步骤 6:修改配置
postgresql.conf:
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'cacert.pem'
pg_hba.conf:
hostnossl all all 0.0.0.0/0 reject
hostssl all all 0.0.0.0/0 cert
步骤 7:配置客户端环境变量
export PGSSLCERT="/home/postgres/certs/client.crt"
export PGSSLKEY="/home/postgres/certs/client.key"
export PGSSLMODE="verify-ca"
export PGSSLROOTCERT="/home/postgres/certs/cacert.pem"
步骤 8:验证连接
psql "host=127.0.0.1 dbname=postgres port=5432 user=postgres sslmode=verify-ca"

4. 注意事项
- 权限管理:证书和私钥文件应设置严格权限(如 600)
- 证书有效期:注意监控证书过期时间
- 性能影响:SSL 加密会带来一定的性能开销
- 混合模式:允许 SSL 和非 SSL 连接并存时需谨慎配置 pg_hba.conf
参考资源
关注以下公众号,获取最新PG帖子。

浙公网安备 33010602011771号