原因
为了提高postgresql数据库连接访问安全性,降低数据传输是被窃取偷听.所以对postgresql数据库启用ssl安全传输功能.
操作环境:
- Liunx(Centos7.6)
- postgresql-11.5
1.postgresql安装(略)
注意: 编译配置时应该加上 --with-openssl参数,让postgresql支持ssl认证方式,即
./configure ... --with-openssl
2.准备证书
创建私钥ca.key,使用des3算法,有效期2048天
openssl genrsa -des3 -out ca.key 2048
openssl req -new -key ca.key -out ca.csr -subj "/C=CN/ST=GuangDong/L=GuangZhou/O=example/OU=GZYFZX/CN=example"
- 自签名得到公钥根证书(.crt)
openssl x509 -req -days 2048 -in ca.csr -signkey ca.key -out ca.crt
2.2 准备服务器证书 server.key(私钥),server.crt(公钥)
openssl genrsa -des3 -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=GuangDong/L=GuangZhou/O=example/OU=GZYFZX/CN=PGServer"
openssl x509 -req -days 2048 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
可选移除pass phrase, 为了方便做自启动脚本, 不然的话数据库启动时又要提示你输入pass phrase.
openssl rsa -in server.key -out $PGDATA/server.key
cp ca.crt root.crt
- 2.使用ca.crt+ server.crt
cp ca.crt root.crt
cat server.crt>>root.crt
3.修改配置postgresql配置
cp root.crt $PGDATA
cp server.crt $PGDATA
cp server.key $PGDATA
chmod 0400 $PGDATA/root.crt
chmod 0400 $PGDATA/server.crt
chmod 0400 $PGDATA/server.key
ssl = on
ssl_ca_file = 'root.crt'
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
需要提供ca的公钥,服务器私钥与服务器公钥
增加连接访问ssl的配置
hostssl all all 192.168.12.1/24 cert clientcert=1,map=m1
- hostssl 表示使用ssl方式连接数据库
- all 表示可访问所有的库,可配置指定库
- all 表示所有用户都可以使用这个方式连接数据库,可配置指定用户
- 192.168.12.1/24 表示192.168.12.0-192.168.12.255这个网段的ip可以连接数据库
- cert clientcert=1 表示使用ssl证书进行认证,且不可用忽略提供证书绕过认证
- map=m1 表示使用pg_ident.conf中m1的用户映射规则
-
修改pg_ident.conf
添加内容
m1 PGClient example
- 表示PGClient用户映射到example用户,即PGClient用户以example用户身份登录,其中PGClient用户可以不在数据库用户中.
5.启动数据库服务
pg_ctl -D $PGDATA -l logfile restart
6.配置客户端证书
既然服务端已经使用ssl连接了,肯定要为连接客户端提供证书
openssl genrsa -des3 -out postgresql.key 2048
openssl req -new -key postgresql.key -out postgresql.csr -subj "/C=CN/ST=GuangDong/L=GuangZhou/O=example/OU=GZYFZX/CN=PGClient"
openssl x509 -req -days 2048 -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -in postgresql.csr -out postgresql.crt
7.客户端连接
7.1命令行客户端连接
使用postgres用户复制客户端证书到postgres 用户的.postgresql目录下
cp root.crt ~/.postgresql
cp server.crt ~/.postgresql
cp server.key ~/.postgresql
chmod 0400 ~/.postgresql/root.crt
chmod 0400 ~/.postgresql/server.crt
chmod 0400 ~/.postgresql/server.key
测试连接
psql postgresql://example@192.168.12.190:5432/example?ssl=true
出现类似以下信息表示成功连接
psql (11.2, 服务器 11.5)
SSL 连接(协议:TLSv1.2,密码:ECDHE-RSA-AES256-GCM-SHA384,密钥位:256,压缩:关闭)
输入 “help” 来获取帮助信息.
同样,证书拥有者是postgres,权限为0600才可以
psql postgresql://example@192.168.12.190:5432/example?ssl=true\&sslrootcert=/tmp/psqlssl/root.crt\&sslkey=/tmp/psqlssl/postgresql.key\&sslcert=/tmp/psqlssl/postgresql.crt
7.2 Jdbc连接
创建jdbc可识别的key格式
sslkey =字符串
提供密钥文件的完整路径。默认为/defaultdir/postgresql.pk8。
注意:密钥文件必须为PKCS-8 DER格式。可以使用openssl命令将PEM密钥转换为DER格式:
openssl pkcs8 -topk8 -inform PEM -in my.key -outform DER -out my.key.der
openssl pkcs8 -topk8 -inform PEM -in postgresql.key -outform DER -nocrypt -out postgresql.pk8
假设证书目录为/tmp/psqlssl
String url="jdbc:postgresql://PGServer:5432/example?ssl=true&sslrootcert=/tmp/psqlssl/root.crt"
+ "&sslkey=/tmp/psqlssl/postgresql.pk8&sslcert=/tmp/upssl/postgresql.crt&sslpassword=example";
String driver = "org.postgresql.Driver";
Class.forName(driver);
Properties props = new Properties();
props.setProperty("user", "example");
Connection conn = DriverManager.getConnection(url,props);
- 注意:PGServer 表示域名,必须与server.crt 的-subj中的CN 值一致
可在/etc/hosts 中添加:
192.168.12.190 PGServer
以完成把PGServer映射到192.168.12.190
假设证书目录为/tmp/psqlssl
String url="jdbc:postgresql://192.168.12.190:5432/example?ssl=true&sslmode=verify-ca&sslrootcert=/tmp/psqlssl/root.crt"
+ "&sslkey=/tmp/psqlssl/postgresql.pk8&sslcert=/tmp/upssl/postgresql.crt&sslpassword=qzt360";
String driver = "org.postgresql.Driver";
Class.forName(driver);
Properties props = new Properties();
props.setProperty("user", "example");
Connection conn = DriverManager.getConnection(url,props);
与verify-full校验方式相比,verify-ca校验方式可以不校验hostname.
spring boot配置datasource.url
spring.datasource.url=jdbc:postgresql://PGServer:5432/example?ssl=true&sslrootcert=/tmp/psqlssl/root.crt&sslkey=/tmp/psqlssl/postgresql.pk8&sslcert=/tmp/upssl/postgresql.crt&sslpassword=example
spring.datasource.user=example
其他
openssl x509 -in postgresql.crt -noout -text
openssl rsa -in postgresql.key -out postgresql.key