达梦数据库配置SSL通信加密

文章目录

1概述

一般数据库通信加密的话配置应用层加密或者SSL加密其中一种即可,两者同样安全。配置SSL通信加密需要有SSL证书,本文演示如何通过自签的CA证书生成服务端和客户端私钥和证书,生成这两个证书相关的文件后,将服务端证书目录拷贝到达梦数据库安装目录的bin目录下,并开启SSL通信加密,重启数据库服务。在客户端如DM管理工具或者Java程序的jdbc连接串配置客户端私钥文件路径和密码后就可以启用SSL通信加密。

可以在某一台服务器上配置好证书后下载,然后将两个文件上传到数据库服务器和其他客户端服务器。需要注意的是需要为每一个需要登录数据库的用户配置一个客户端证书。

2生成自签证书

可以使用第三方提供的CA证书和私钥生成服务端和客户端证书,也可以自己虚拟出一个CA机构进行证书的签发并生成服务端和客户端证书,一般数据库服务器和应用服务器在同一个隔离的内网环境的话使用自签证书也是可以的。

在一台机器上按要求提供SSL证书的相关信息比如国家、省、市、颁发机构等信息生成CA根证书、服务端证书、客户端相关证书,然后将对应的证书文件部署到其他服务器上的数据库目录即可,只要数据库用的是同一个服务端证书那么客户端证书就可以共用,前提是你的数据库部署的服务端证书是相同的,并且该登录数据库用户名也一致。

2.1环境检查

2.1.1操作系统

生成证书环境使用的是CentOS 7.9操作系统:

bash 复制代码
[root@localhost.localdomain:/root]# uname -a
Linux localhost.localdomain 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[root@localhost.localdomain:/root]# cat /etc/*release*
CentOS Linux release 7.9.2009 (Core)
Derived from Red Hat Enterprise Linux 7.8 (Source)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

CentOS Linux release 7.9.2009 (Core)
CentOS Linux release 7.9.2009 (Core)
cpe:/o:centos:centos:7

2.1.2openssl环境

通过以下命令检查:

bash 复制代码
[root@localhost.localdomain:/root]# openssl version -a
OpenSSL 1.0.2k-fips  26 Jan 2017
built on: reproducible build, date unspecified
platform: linux-x86_64
options:  bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx) 
compiler: gcc -I. -I.. -I../include  -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic -Wa,--noexecstack -DPURIFY -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
OPENSSLDIR: "/etc/pki/tls"
engines:  rdrand dynamic

如果未安装可到官网(https://openssl-library.org/source/old/index.html)下载源码包进行编译安装,如果可以联网的话可以使用yum进行安装:

bash 复制代码
yum install openssl

生成证书必须使用openssl。

2.1.3Java环境

java版本查询:

bash 复制代码
[root@localhost.localdomain:/root]# java -version
openjdk version "1.8.0_412"
OpenJDK Runtime Environment (build 1.8.0_412-b08)
OpenJDK 64-Bit Server VM (build 25.412-b08, mixed mode)

如果没有Java环境,在可以联网的情况下可以使用:

bash 复制代码
yum install java-1.8.0-openjdk-devel

如果无法联网的话可以达梦数据库安装自带的jdk,比如安装路径为/home/dmdba/dmdbms/

bash 复制代码
/home/dmdba/dmdbms/jdk/bin/java -version

可以将达梦自带的jdk配置为环境变量:

bash 复制代码
vi  /etc/profile
# 添加一下内容:
export JAVA_HOME=/home/dmdba/dmdbms/jdk
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

2.2配置openssl

Openssl实现了ssl协议用来管理证书以及密钥。

2.2.1修改openssl配置文件

CentOS和麒麟操作系统的openssl配置文件默认为/etc/pki/tls/openssl.cnf。备份配置文件,然后修改[ CA_default ]内容:

bash 复制代码
cp /etc/pki/tls/openssl.cnf /etc/pki/tls/openssl.cnf_bak
vi /etc/pki/tls/openssl.cnf

查看原配置文件中设置的dir目录有以下内容:

但是里面的内容都是空的。

修改内容如下:

dir:所有生成的文件存放的默认路径

database:签发过的证书的列表文件

new_certs_dir:存放所有新签发的证书

serial:下一个要签发的证书的序号,第一个从1开始

certificate:CA的证书文件的名字

private_key:CA的私钥文件的名字

default_days:签发证书的默认有效期

default_bit:私钥默认的长度大小

其他参数可以不用修改使用,在生成证书的时候通过命令行进行指定。

2.2.2创建配置文件中对应的目录和文件

bash 复制代码
[root@localhost.localdomain:/root]# vi /etc/pki/tls/openssl.cnf
[root@localhost.localdomain:/root]# mkdir -p /opt/ca
[root@localhost.localdomain:/root]# cd /opt/ca
[root@localhost.localdomain:/opt/ca]# mkdir {certs,crl,newcerts}
[root@localhost.localdomain:/opt/ca]# echo "01" > serial
[root@localhost.localdomain:/opt/ca]# touch index.txt

#创建达梦数据库服务器和客户端证书文件存放目录
[root@localhost.localdomain:/opt/ca]# mkdir server_ssl
[root@localhost.localdomain:/opt/ca]# mkdir client_ssl
#创建SYSDBA用户客户端证书存放目录,其他用户请创建与用户名相同的目录
# 数据库中每个要登录的用户都需要生成客户端证书,否则无法登录
[root@localhost.localdomain:/opt/ca]# mkdir -p client_ssl/SYSDBA

2.3自签证书与私钥生成

配置的时候建议是所有密码均设置为同一个,涉及到4个密码,容易混淆。

2.3.1生成CA私钥和根证书

如果证书包括中文信息,需要指定编码,加上-utf8参数。可以配置以下信息:颁发机构所在国家(CN),省(ST)、市(L)、组织名称(O)、单位名称(OU)、通用名称(CN:CA证书名称一般会设置为域名)、邮箱地址(emailAddress)等。

bash 复制代码
[root@localhost.localdomain:/opt/ca]# openssl req -new -x509 -days 3650 -keyout ca-key.pem -out ca-cert.pem -subj "/C=cn/ST=guangdong/L=guangzhou/O=dameng/OU=dev/CN=lw/emailAddress=abc@dm.com"
Generating a 2048 bit RSA private key
.....................................................+++
....................................+++
writing new private key to 'ca-key.pem'
Enter PEM pass phrase:【这里需要输入密码】
Verifying - Enter PEM pass phrase:【再次确认密码】
-----

ca-key.pem 为CA(证书颁发机构)私钥文件,只需要保存在CA服务器,不需要保存到数据库服务端,(也可以拷贝过去,后续其他服务器可以也可以用来颁发ssl证书),ca-cert.pem为CA的根证书是需要对外分发到客户端的,客户端在与服务器建立连接时服务端发送此证书,客户端用保存在本地的根证书来验证服务端是否正确。

2.3.2服务端私钥和前面证书生成

2.3.2.1生成服务器私钥
bash 复制代码
[root@localhost.localdomain:/opt/ca]# openssl genrsa -out server_ssl/server-key.pem
Generating RSA private key, 2048 bit long modulus
..........................................................................................................................................+++
.....+++
e is 65537 (0x10001)
2.3.2.2生成CA签名证书

签发申请生成:(如果有中文信息通用需要加-utf8参数)

bash 复制代码
[root@localhost.localdomain:/opt/ca]# openssl req -new -key server_ssl/server-key.pem -out server_ssl/server.csr -subj "/C=cn/ST=guangdong/L=guangzhou/O=dameng/OU=dev/CN=server/emailAddress=server@dm.com"

参数含义:

bash 复制代码
openssl ca:使用OpenSSL的证书颁发机构(CA)功能,用已有的CA来签署证书请求。

-days 3650:指定生成的服务器证书有效期为3650天(约10年)。

-in server_ssl/server.csr:输入文件是server_ssl目录下的server.csr(证书签名请求文件)。

-out server_ssl/server-cert.pem:输出文件是server_ssl目录下的server-cert.pem(最终生成的服务器证书)。

执行以下命令生成证书:

bash 复制代码
[root@localhost.localdomain:/opt/ca]# openssl ca -days 3650 -in server_ssl/server.csr -out server_ssl/server-cert.pem
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /opt/ca/ca-key.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Oct 30 15:48:49 2025 GMT
            Not After : Oct 28 15:48:49 2035 GMT
        Subject:
            countryName               = cn
            stateOrProvinceName       = guangdong
            organizationName          = dameng
            organizationalUnitName    = dev
            commonName                = server
            emailAddress              = server@dm.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                59:3A:5D:9C:72:EB:49:2F:C8:DC:3D:46:54:D7:BC:CA:FE:63:A2:64
            X509v3 Authority Key Identifier: 
                keyid:17:83:7C:2F:4C:98:4B:C5:3C:A6:C3:C4:5A:E1:C0:28:A4:47:FA:57

Certificate is to be certified until Oct 28 15:48:49 2035 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

如果执行报错:

system library:fopen:No such file or directory:bss_file.c:402:fopen('/opt/ca/cakey.pem','r')

那可能是private_key配错了:

2.3.2.3转换为x509格式证书

将证书格式转换为x509格式:

bash 复制代码
openssl x509 -in server_ssl/server-cert.pem -out server_ssl/server.cer

将自签名的CA根证书和私钥文件拷贝到server_ssl目录中

bash 复制代码
[root@localhost.localdomain:/opt/ca]# cp ca-cert.pem server_ssl
[root@localhost.localdomain:/opt/ca]# cp ca-key.pem server_ssl

2.3.3生成客户端用户私钥和被CA签名的证书

本节以创建SYSDBA用户的客户端证书为例,数据库的其他用户也需要生成对应的证书,否则无法登录。

生成私钥文件:

bash 复制代码
[root@localhost.localdomain:/opt/ca]# openssl genrsa -aes256 -out client_ssl/SYSDBA/client-key.pem
Generating RSA private key, 2048 bit long modulus
.....................................................................................................+++
...............+++
e is 65537 (0x10001)
Enter pass phrase for client_ssl/SYSDBA/client-key.pem:【输入密码】
Verifying - Enter pass phrase for client_ssl/SYSDBA/client-key.pem:【确认密码】

-aes256表示使用AES算法对产生的私钥加密

生成证书签发申请:输入颁发机构和申请者信息,如果有中文同样需要使用-utf8参数。

bash 复制代码
[root@localhost.localdomain:/opt/ca]# openssl req -new -key client_ssl/SYSDBA/client-key.pem -out client_ssl/SYSDBA/client.csr -subj "/C=cn/ST=guangdong/L=guangzhou/O=dameng/OU=dev/CN=SYSDBA/emailAddress=dmclient@dm.com"
Enter pass phrase for client_ssl/SYSDBA/client-key.pem:【输入客户端的私钥密码】

注意:CN一定是数据库中的用户名,否则名称不一致无法使用此证书进行登录。

使用CA根证书(也就是配置文件中指定的certificate文件ca-cert.pem)和签发申请生成证书:

bash 复制代码
[root@localhost.localdomain:/opt/ca]# openssl ca -days 365 -in client_ssl/SYSDBA/client.csr -out client_ssl/SYSDBA/client-cert.pem
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for /opt/ca/ca-key.pem:【输入开头设置的CA的私钥密码】
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Oct 30 16:05:18 2025 GMT
            Not After : Oct 30 16:05:18 2026 GMT
        Subject:
            countryName               = cn
            stateOrProvinceName       = guangdong
            organizationName          = dameng
            organizationalUnitName    = dev
            commonName                = SYSDBA
            emailAddress              = dmclient@dm.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                5E:E5:64:BE:86:4D:60:F2:43:62:89:BA:80:01:10:1D:E1:18:F0:9F
            X509v3 Authority Key Identifier: 
                keyid:17:83:7C:2F:4C:98:4B:C5:3C:A6:C3:C4:5A:E1:C0:28:A4:47:FA:57

Certificate is to be certified until Oct 30 16:05:18 2026 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

将生成的x509格式的client-key.pem和client-cert.pem合并转换为pkcs12格式的文件client-pkcs.p12:

bash 复制代码
[root@localhost.localdomain:/opt/ca]# openssl pkcs12 -export -inkey client_ssl/SYSDBA/client-key.pem -in client_ssl/SYSDBA/client-cert.pem -out client_ssl/SYSDBA/client-pkcs.p12
Enter pass phrase for client_ssl/SYSDBA/client-key.pem:【输入客户端的私钥密码】
Enter Export Password:【输入密码】
Verifying - Enter Export Password:【确认密码】

生成JDBC访问需要的.keystore文件:导入证书到keystore文件,并设置keystore文件密码:

bash 复制代码
# 导入CA根证书
[root@localhost.localdomain:/opt/ca]# keytool -import -alias ca -trustcacerts -file ca-cert.pem -keystore client_ssl/SYSDBA/.keystore -deststorepass 123456 -noprompt
证书已添加到密钥库中

# 导入服务器证书
[root@localhost.localdomain:/opt/ca]# keytool -import -alias server -trustcacerts -file server_ssl/server.cer -keystore client_ssl/SYSDBA/.keystore -deststorepass 123456 -noprompt
证书已添加到密钥库中

# 导入客户端私钥和证书
[root@localhost.localdomain:/opt/ca]# keytool -importkeystore -srckeystore client_ssl/SYSDBA/client-pkcs.p12 -srcstorepass 123456  -srcstoretype PKCS12 -keystore client_ssl/SYSDBA/.keystore -storetype PKCS12  -deststorepass 123456
正在将密钥库 client_ssl/SYSDBA/client-pkcs.p12 导入到 client_ssl/SYSDBA/.keystore...
已成功导入别名 1 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消

srcstorepass填的是Export Password设置的密码。

如果报错:keytool 错误: java.lang.Exception: 目标 pkcs12 密钥库具有不同的 storepass 和 keypass。请在指定了 -destkeypass 时重试。

则需要指定目标keystore中私钥的密码与存储密码相同:

注意:指定中文信息或者前面如果配置错了删除了客户端文件重新配置的可能还会遇到以下报错:

解决办法:删了keystore文件然后先把-keystore改为-destkeystore导入一次生成一个keystore文件,然后再导入ca根证书和服务器证书到keystore文件。

bash 复制代码
# 首先验证PKCS12 文件是否有效,无输出则损坏需要重新生成
openssl pkcs12 -info -in client_ssl/SYSDBA/client-pkcs.p12 -nodes

# 删除旧的 keystore 文件(如果存在)
[root@localhost.localdomain:/opt/ca]# rm -f client_ssl/SYSDBA/.keystore
# 先导入PKCS12文件(包含客户端私钥和证书)
[root@localhost.localdomain:/opt/ca]# keytool -importkeystore -srckeystore client_ssl/SYSDBA/client-pkcs.p12 -srcstoretype PKCS12 -srcstorepass 123456 -destkeystore client_ssl/SYSDBA/.keystore -deststoretype PKCS12 -deststorepass 123456
正在将密钥库 client_ssl/SYSDBA/client-pkcs.p12 导入到 client_ssl/SYSDBA/.keystore...
已成功导入别名 1 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消
# 导入CA根证书
[root@localhost.localdomain:/opt/ca]# keytool -import -alias ca -trustcacerts -file ca-cert.pem -keystore client_ssl/SYSDBA/.keystore -storepass 123456 -noprompt
证书已添加到密钥库中
# 导入服务器证书
[root@localhost.localdomain:/opt/ca]# keytool -import -alias server -trustcacerts -file server_ssl/server.cer -keystore client_ssl/SYSDBA/.keystore -storepass 123456 -noprompt
证书已添加到密钥库中
[root@localhost.localdomain:/opt/ca]# keytool -importkeystore -srckeystore client_ssl/SYSDBA/client-pkcs.p12 -srcstorepass 123456  -srcstoretype PKCS12 -keystore client_ssl/SYSDBA/.keystore -storetype PKCS12  -deststorepass 123456
正在将密钥库 client_ssl/SYSDBA/client-pkcs.p12 导入到 client_ssl/SYSDBA/.keystore...
存在现有条目别名 1, 是否覆盖? [否]:  y
已成功导入别名 1 的条目。
已完成导入命令: 1 个条目成功导入, 0 个条目失败或取消

将自签名的CA根证书拷贝到client_ssl/SYSDBA目录中,CA私钥文件ca-key.pem不用拷贝。

bash 复制代码
[root@localhost.localdomain:/opt/ca]# cp ca-cert.pem client_ssl/SYSDBA/

2.4证书查看

如果是从证书提供商那边拿的证书需要同时拥有客户端和服务端才能开启SSL通信加密。此外,生成的客户端要为每一个需要登录数据库的用户配置一个客户端证书。

2.4.1服务端证书

下载下来内容是这样的:(ca-key.pem是ca私钥文件可不需要)

这些都是要放到达梦数据库bin目录的server_ssl文件夹下的。

查看证书信息:

2.4.2客户端证书

下载下来内容是这样的:

这些内容是要放到客户端的电脑上,然后连接的时候指定。

3部署证书

3.1部署服务端证书

将/opt/ca/server_ssl整个目录拷贝到达梦数据库安装目录下的bin目录下,默认在bin目录下存在server_ssl目录。可以先将默认的server_ssl目录重命名,然后拷贝。

bash 复制代码
[root@localhost.localdomain:/root]# cd /home/dmdba/dmdbms/bin
[root@localhost.localdomain:/home/dmdba/dmdbms/bin]# mv server_ssl server_ssl_bak
[root@localhost.localdomain:/home/dmdba/dmdbms/bin]# cp /opt/ca/server_ssl ./ -r
[root@localhost.localdomain:/home/dmdba/dmdbms/bin]# chmod -R 777 server_ssl

集群的话也是一样配置的,在关闭集群后配置主库和备库,然后重启集群,监视器可不配置SSL加密,因为有的监视器没有实例服务。

3.2部署客户端证书

将/opt/ca/client_ssl整个目录拷贝到客户端机器上。如果是Linux机器,需要注意目录权限,可以将整个目录设置为777权限。

bash 复制代码
chmod 777 -R /opt/ca/client_ssl

如果是通过jdbc接口来加密访问数据库,是使用的.keystore文件;

如果是通过ODBC或者其他方式加密访问数据库,那么是使用ca-cert.pem、client-cert.pem和client-key.pem三个文件。

4数据库启动SSL加密通信

ENABLE_ENCRYPT:取值0、1和2,含义义分别为:

0表示在传输层不开启SSL认证和SSL通信加密;

1表示在传输层开启SSL认证和SSL通信加密;

2表示在传输层仅开启SSL认证,但不开启SSL加密。

bash 复制代码
SQL> SF_SET_SYSTEM_PARA_VALUE('ENABLE_ENCRYPT',2,1,2);

修改后重启数据库。

5客户端认证配置

设置加密后需要重启客户端。

5.1disql登录

使用旧方式登录:

会报错:SSL_do_handshake failure,进程是正常运行的

在连接的时候需要指定客户端证书位置和客户端私钥密码:

bash 复制代码
disql SYSDBA/'"密码"'@192.168.30.175:5236#"{SSL_PATH=/opt/ca/client_ssl/SYSDBA,SSL_PWD=Dangmeng123}"

SSL_PATH:客户端证书位置;

SSL_PWD:客户端私钥密码;

抓包验证:

bash 复制代码
tcpdump -i lo port 5236 -XX -vvv

发现是密文了:

5.2DM管理工具连接

如果不指定客户端证书和私钥密码则报错:

DM管理工具其实也是使用jdbc连接数据库的,所以也需要配置sslFilesPath和sslKeystorePass参数:

sslFilesPath:指定 ssl 加密文件的路径,配置为下载的/opt/ca/client_ssl/SYSDBA文件路径;登录的用户名需要与客户端证书申请中的CN名称一致,其他用户是无法使用同一个客户端ssl证书的。

sslKeystorePass:指定 ssl 加密文件的密码;也即客户端keystore文件的密码;

对于旧版本的DM管理工具是可以直接选客户端证书的,然后填写SSL验证密码。

5.3应用修改jdbc连接串

5.3.1证书下载

将客户端和服务端两个证书文件目录压缩并下载下来:

bash 复制代码
cd /opt/ca
zip -r server_ssl.zip server_ssl
zip -r client_ssl.zip client_ssl

所有需要登录数据库的用户均需要下载,并且登录的时候根据用户进行选择SSL客户端文件目录。

5.3.2上传客户端文件到数据库服务器

bash 复制代码
unzip server_ssl.zip
chmod -R 777 server_ssl

5.3.3在客户端电脑解压文件并配置jdbc

bash 复制代码
unzip client_ssl.zip
chmod -R 777 client_ssl

配置jdbc的连接url,指定sslFilesPath和sslKeystorePass参数:

bash 复制代码
String url = "jdbc:dm://192.168.30.174:5236?sslFilesPath=/opt/client_ssl/SYSDBA&sslKeystorePass=密码";

如果是Windows环境的话要注意路径的填写:

bash 复制代码
String name="dm.jdbc.driver.DmDriver";
String url="jdbc:dm://192.168.30.174:5236?sslFilesPath=E:\\dmdbms\\client_ssl\\SYSDBA&sslKeystorePass=abc123";
String user="SYSDBA";
String password="SYSDBA";

达梦社区地址:https://eco.dameng.com/