GBase8a SSL 配置
GBase8a SSL 配置
GBase8a MPP Cluster 支持 SSL 标准协议, SSL 协议是一种安全性更高的协议标准, 它加入了数字签名和数字证书来实现客户端和服务器的双向身份验证,保证了通信双方更加安全的数据传输。
配置客户端使用 SSL 安全连接的方式连接到 GBase8a MPP Cluster 数据库集群的配置总体流程如下:
生成 SSL 连接证书 ==> server 配置 ==> client 配置
1. 生成 SSL 连接证书
在集群 server 端的系统中, 根据需要选择生成 SSL 密钥的目录, 下面以 GBase8a 的安装目录下的 ssl 目录保存相关文件为例进行配置说明。
1.1 在 server 上操作生成 server 端的密钥和证书
step1:
# su - gbase
$ mkdir -p /opt/gbase8a/ssl # /opt/gbase8a 是我的GBase8a安装目录,在安装目录下有权限创建 ssl 目录
$ cd /opt/gbase8a/ssl
后续的证书也秘钥生成过程中,需要填写一些信息,我除了 Country Name 填写 CN,password 填写 123456 外,其他都未填写直接回车了,项目中可以根据实际情况填写。
step2:
生成 ca-cert.pem, 需要填写 Country Name 等信息
$ openssl req -sha1 -new -x509 -nodes -days 3650 -keyout ca-key.pem > ca-cert.pem
You are about to be asked to enter information that will be incorporated into your certificate request.
......
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
执行完毕,会生成两个文件:ca-cert.pem 和 ca-key.pem
step3:
生成服务端密钥, 同样填写一些信息, password 部分( A challenge password []: ) 建议填写复杂一些的密码
$ openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem > server-req.pem
Generating a 2048 bit RSA private key
......
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
执行完毕,会生成两个文件:server-key.pem 和 server-req.pem
step4:
将 server-key.pem 导出为 RSA 类型:
$ openssl rsa -in server-key.pem -out server-key.pem
step5:
生成服务端证书 server-cert.pem
$ openssl x509 -sha1 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
ssl 证书相关查看命令:
openssl rsa -in server-key.pem -text #查看证书私钥文件中的私钥和公钥信息
openssl x509 -in server-cert.pem -noout -text #查看证书详细信息
1.2 在 server 上操作生成 client 端的密钥和证书
step1:
在同一目录下, 生成 client 端的密钥和证书, 生成密钥, 输入信息与 server 端相同。
$ openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem > client-req.pem
Generating a 2048 bit RSA private key
......
Country Name (2 letter code) [XX]:CA
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:
会生成两个文件:client-key.pem 和 client-req.pem
step2:
将 client-key.pem 导出为 RSA 类型
$ openssl rsa -in client-key.pem -out client-key.pem
step3:
生成 client-cert.pem
$ openssl x509 -sha1 -req -in client-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem
前面所有过程总共生成的8个文件:
ca-key.pem:CA 私钥, 用于生成服务器端/客户端的数字证书;
ca-cert.pem:CA 证书,用于生成服务器端/客户端的数字证书;
server-key.pem:服务器端的 RSA 私钥;
server-req.pem:服务器端的证书请求文件,用于生成服务器端的数字证书;
server-cert.pem:服务器端的数字证书;
client-key.pem:客户端的 RSA 私钥;
client-req.pem:客户端的证书请求文件,用于生成客户端的数字证书;
client-cert.pem:客户端的数字证书。
2. server 配置
step1:
修改集群配置文件 gbase_8a_gcluster.cnf, 在 [gbased] 里添加 ssl 信息。 以路径 /opt/gbase8a/ssl 为例, 添加示例如下:
$ vi $GCLUSTER_BASE/config/gbase_8a_gcluster.cnf
[client]
port=5258
socket=/tmp/gcluster_5258.sock
connect_timeout=43200
#default-character-set=gbk
default-character-set=utf8
[gbased]
basedir = /opt/gcluster/server
datadir = /opt/gcluster/userdata/gcluster
socket=/tmp/gcluster_5258.sock
pid-file = /opt/gcluster/log/gcluster/gclusterd.pid
#default-character-set=gbk
default-character-set=utf8
# server cfg for ssl
ssl-ca=/opt/gbase8a/ssl/ca-cert.pem
ssl-cert=/opt/gbase8a/ssl/server-cert.pem
ssl-key=/opt/gbase8a/ssl/server-key.pem
log-error
port=5258
core-file
step2:
重启集群,查看配置是否成功
$ gcluster_services all restart
step3:
执行 gccli, 登录集群
$ gccli -ugbase -p
step4:
查看 ssl 参数状态, 配置成功则显示为“YES”。
gbase> show variables like 'have_%ssl';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl | YES |
| have_ssl | YES |
+---------------+-------+
3. client 配置
集群 client 的配置,直接在 client 端的 Linux 上配置。
step1:
将 server 端生成的 ca-cert.pem,client-key.pem,client-cert.pem 文件拷贝到 client 端,
修改 client 端的集群配置文件 gbase_8a_gcluster.cnf,在 [client] 里添加 ssl 信息, 以路径 /opt/gbase8a/ssl 为例:
注意:如果客户端是独立安装的 gccli 工具客户端,则配置文件位于:gccli 安装目标路径/config/gbase_8a_gcluster.cnf
$ vi $GCLUSTER_BASE/config/gbase_8a_gcluster.cnf
[client]
port=5258
socket=/tmp/gcluster_5258.sock
connect_timeout=43200
#default-character-set=gbk
default-character-set=utf8
# client cfg for ssl
ssl-ca=/opt/gbase8a/ssl/ca-cert.pem
ssl-cert=/opt/gbase8a/ssl/client-cert.pem
ssl-key=/opt/gbase8a/ssl/client-key.pem
step2:
通过 client 端远程访问 server 并执行 status 命令查看当前连接是否为 ssl 加密连接(ssl 部分显示有 “Cipher in use”,如果未走ssl则显示"Not in use")
$ gccli -h192.168.1.162 -ugbase -p
gbase> status
如果是单独创建的 gbasessl 用户,则执行:
$ gccli -h192.168.1.162 -ugbasessl -p -Dtestdb01
gbase> status
--------------
/home/frank/gccli/gcluster/server/bin/gbase ver 9.5.3.14.121230, for unknown-linux-gnu (x86_64) using readline 6.3
Connection id: 18
Current database: testdb01
Current user: gbasessl@192.168.1.82
SSL: Cipher in use is DHE-RSA-AES256-SHA ==> 说明当前连接时SSL加密连接
Current pager: stdout
......
step3:
如果 client 端没有进行上述 ssl 配置, 则仍然会按默认方式(非ssl)连接 server。如果想要强制用户必须使用 ssl 连接,则可以通过如下方式配置来强制指定的用户必须使用 ssl 连接:
gbase> grant all on testdb01.* to gbase require ssl
gbase用于原来已经在使用了,为了不影响原来的使用,gbase用户连接方式在服务器端不做强制要求配置,我直接单独创建一个新用户 gbasessl 来指定必须SSL连接(grant ...... require ssl):
gbase> create user gbasessl identified by '1q2w3e';
gbase> grant all on testdb01.* to gbasessl require ssl;
gbase> quit;
$ gccli -h192.168.1.162 -ugbasessl -p -Dtestdb01
gbase> status
查看用户是否备服务器配置为强制SSL连接,可以通过查询系统表 gbase.user 来看:
$ gccli -h192.168.1.162 -ugbase -p -Dtestdb01
gbase> select user,ssl_type from gbase.user;
+-----------------+----------+
| user | ssl_type |
+-----------------+----------+
| root | |
| gbase | |
| gbasessl | ANY |
+-----------------+----------+
为空代表没有强制必须使用SSL连接,不为空(ANY | X509 | SPECIFIED)都代表必须使用SSL连接。
ssl 连接参数:
--skip-ssl:客户端强制使用非SSL连接
--ssl:客户端强制使用SSL连接
如果不加参数,默认优先使用非SSL连接
gbasessl 账号连接测试(创建用户时指定了 require ssl):
$ gccli -h192.168.1.162 -ugbasessl -Dtestdb01 -p --skip-ssl
客户端指定非SSL(--skip-ssl),我 gbasessl 服务器强制ssl(require ssl),所以会连接失败
$ gccli -h192.168.1.162 -ugbasessl -Dtestdb01 -p
gbase> status;
客户端不指定,连接成功,为SSL
$ gccli -h192.168.1.162 -ugbasessl -Dtestdb01 -p --ssl
gbase> status;
客户端指定SSL(--ssl),连接成功,为SSL
gbase 账号连接测试(默认未指定 require ssl)
gbase账号服务器没有设置强制ssl
$ gccli -h192.168.1.162 -ugbase -Dtestdb01 -p --skip-ssl
gbase> status
客户端指定非SSL(--skip-ssl),连接成功,为普通连接(Not in use)
$ gccli -h192.168.1.162 -ugbasessl -Dtestdb01 -p
gbase> status;
客户端不指定,连接成功,为SSL
$ gccli -h192.168.1.162 -ugbasessl -Dtestdb01 -p --ssl
gbase> status;
客户端指定SSL(--ssl),连接成功,为SSL。
1)客户端指定 --ssl 但如果客户端配置未配置 ssl-cert、ssl-key 参数时,也能连接成功,为非SSL连接。
2)ssl-ca:非必须参数,如果不校验CA证书的话,不需要配置;
如果 gccli 客户端配置文件(gbase_8a_gcluster.cnf)未配置对应参数,也可以直接在 gccli 命令行指定 ssl 参数:
$ gccli -h192.168.1.162 -ugbase -Dtestdb01 -p --ssl --ssl-cert=/opt/gbase8a/gccli/ssl/client-cert.pem --ssl-key=/opt/gbase8a/gccli/ssl/client-key.pem
$ gccli -h192.168.1.162 -ugbasessl -Dtestdb01 -p --ssl --ssl-cert=/opt/gbase8a/gccli/ssl/client-cert.pem --ssl-key=/opt/gbase8a/gccli/ssl/client-key.pem
如果要校验CA证书,则指定 --ssl-ca CA证书文件路径(非必须):
$ gccli -h192.168.1.162 -ugbase -Dtestdb01 -p --ssl --ssl-cert=/opt/gbase8a/gccli/ssl/client-cert.pem --ssl-key=/opt/gbase8a/gccli/ssl/client-key.pem --ssl-ca=/opt/gbase8a/gccli/ssl/ca-cert.pem
$ gccli -h192.168.1.162 -ugbasessl -Dtestdb01 -p --ssl --ssl-cert=/opt/gbase8a/gccli/ssl/client-cert.pem --ssl-key=/opt/gbase8a/gccli/ssl/client-key.pem --ssl-ca=/opt/gbase8a/gccli/ssl/ca-cert.pem
jdbc 使用 ssl 加密连接传输数据
如果数据库的客户端应用(client)使用 jdbc 方式使用 ssl 加密连接方式,则应用客户端的配置参考如下:
如果使用 jdbc 进行 ssl 数据传输,前提也是必须 server 支持 ssl,必须先开启 server 端的 ssl 功能(开启配置详情可参考上面的 《1. 生成 SSL 连接证书》和《2. server 配置》章节)。
配置操作的命令集如下:
因为前面我配置过了,所以下面的1)和2)步骤我直接跳过,直接从步骤3)开始
1)生成 ssl 文件(直接在 linux 下执行即可)
生成 server 证书:
$ mkdir -p /opt/gbase8a/ssl
$ cd /opt/gbase8a/ssl
$ openssl genrsa 2048 > ca-key.pem # CA 私钥
$ openssl req -sha1 -new -x509 -nodes -days 3650 -key ca-key.pem -out ca-cert.pem # CA 证书。
注意:CA私钥和CA证书生成的两步也可以合并成一步操作:openssl req -sha1 -new -x509 -nodes -days 3650 -keyout ca-key.pem > ca-cert.pem 来代替
$ openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem -out server-req.pem # 服务器私钥
$ openssl rsa -in server-key.pem -out server-key.pem # 转为 RSA 格式,文件名也可以命名为:server-key.rsa
$ openssl x509 -sha1 -req -in server-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem # 服务器证书
$ openssl verify -CAfile ca-cert.pem server-cert.pem # 验证
生成 client 证书:
$ openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout client-key.pem -out client-req.pem # 客户端私钥
$ openssl rsa -in client-key.pem -out client-key.pem # 转为 RSA 格式,文件名也可以命名为:client-key.rsa
$ openssl x509 -sha1 -req -in client-req.pem -days 3650 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem # 客户端证书
$ openssl verify -CAfile ca-cert.pem client-cert.pem # 验证
ssl 证书相关查看命令:
openssl rsa -in server-key.pem -text #查看证书私钥文件中的私钥和公钥信息
openssl x509 -in server-cert.pem -noout -text #查看证书详细信息
2)server 配置开启 ssl 功能:
vi $GCLUSTER_BASE/config/gbase_8a_gcluster.cnf
# 在 [gbased] 下配置 ssl 相关文件的路径
# server cfg for ssl
ssl-ca=/opt/gbase8a/ssl/ca-cert.pem
ssl-cert=/opt/gbase8a/ssl/server-cert.pem
ssl-key=/opt/gbase8a/ssl/server-key.pem
3)server 集群服务重启:
gcluster_services all restart
4)查看服务器SSL配置:
$ gccli -ugbase -p
gbase> show variables like '%SSL%';
经过前面三步集群已经开启ssl功能,针对jdbc按照如下使用步骤:
1) 生成jdbc连接用密钥(根据 ca-cert.pem 生成 truststore)
# su - frank
$ mkdir -p /home/frank/demo/ssl-certs/
$ cd /home/frank/demo/ssl-certs/
$ cp /home/frank/gccli/ssl/ca-cert.pem ./
$ cp /home/frank/gccli/ssl/client-cert.pem ./
$ keytool -import -alias GBaseCACert -file ca-cert.pem -keystore truststore
说明: ca-cert.pem 为服务器端生成 ssl 文件时生成的文件,执行该步骤后会提示输入认证密码,比如输入123456(jdbc连接会用到), Trust this certificate? [no]: yes
2)把 gbase Client 证书转换成DER格式:
$ openssl x509 -outform DER -in client-cert.pem -out client.cert
3)根据 client.cert 文件生成客户端 keystore 文件:
$ keytool -import -alias GBaseClientCertificate -file client.cert -keystore keystore
说明: client-cert.pem 为生成 ssl 文件时生成的文件,执行该步骤后会提示输入认证密码,比如输入123456(jdbc连接会用到),Trust this certificate? [no]: yes
4)上述步骤会生成两个文件 truststore, keystore,将这两个文件拷贝到 jdbc 可以访问的路径下(例如:/home/frank/demo/ssl-certs/),我直接在该demo可访问的目录下生成的,无需再拷贝了
5) 参考下面方式编写连接测试代码(参考官方的《GBase 8a 程序员手册JDBC篇.pdf》中的ssl jdbc连接的介绍编码测试):
Main.java:
public class Main {
public static void main(String args[]) {
String str = "=== dbconnector in ===";
System.out.println(CommonUtil.getMethodName() + str);
System.out.println(CommonUtil.getMethodName() + "====================No SSL");
GBase8aClient.connectTest();
System.out.println(CommonUtil.getMethodName() + "====================SSL01");
GBase8aClient.connectTestSSL01();
System.out.println(CommonUtil.getMethodName() + "====================SSL02");
GBase8aClient.connectTestSSL02();
System.out.println(CommonUtil.getMethodName() + "====================SSL03");
GBase8aClient.connectTestSSL03();
System.out.println(CommonUtil.getMethodName() + "====================SSL04");
GBase8aClient.connectTestSSL04();
}
}
GBase8aClient.java
public class GBase8aClient {
public static void connectTest() {
// 不设置 useSSL & requireSSL,使用非SSL连接
String url = "jdbc:gbase://192.168.1.162:5258/testdb01";
String user = "gbase";
String pwd = "1q2w3e";
Connection conn = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(url, user, pwd);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("show status like '%SSL%'");
while (rs.next()) {
// 仅打印 Ssl_cipher, Ssl_cipher_list, Ssl_verify_depth, Ssl_verify_mode, Ssl_version
if (rs.getString(1).startsWith("Ssl_cipher") ||
rs.getString(1).startsWith("Ssl_ver")) {
System.out.println(rs.getString(1) + "-----"
+ rs.getString(2).substring(0,min(50,rs.getString(2).length())));
}
}
} catch (ClassNotFoundException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: ClassNotFound!");
} catch (SQLException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: conn failed!");
} finally {
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
public static void connectTestSSL01() {
// 设置 useSSL & requireSSL,也设置 keystore & truststore
String url = "jdbc:gbase://192.168.1.162:5258/testdb01?useSSL=true&requireSSL=true";
String trustStorePath = "/home/frank/demo/ssl-certs/truststore";
String keyStorePath = "/home/frank/demo/ssl-certs/keystore";
String user = "gbase";
String pwd = "1q2w3e";
System.setProperty("javax.net.ssl.keyStore", keyStorePath);
System.setProperty("javax.net.ssl.keyStorePassword", "123456");
System.setProperty("javax.net.ssl.trustStore", trustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", "123456");
System.out.println(CommonUtil.getMethodName() + "keyStore:" + System.getProperty("javax.net.ssl.keyStore"));
System.out.println(CommonUtil.getMethodName() + "keyStorePassword:" + System.getProperty("javax.net.ssl.keyStorePassword"));
System.out.println(CommonUtil.getMethodName() + "trustStore:" + System.getProperty("javax.net.ssl.trustStore"));
System.out.println(CommonUtil.getMethodName() + "trustStorePassword:" + System.getProperty("javax.net.ssl.trustStorePassword"));
Connection conn = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(url, user, pwd);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("show status like '%SSL%'");
while (rs.next()) {
// 仅打印 Ssl_cipher, Ssl_cipher_list, Ssl_verify_depth, Ssl_verify_mode, Ssl_version
if (rs.getString(1).startsWith("Ssl_cipher") ||
rs.getString(1).startsWith("Ssl_ver")) {
System.out.println(rs.getString(1) + "-----"
+ rs.getString(2).substring(0,min(50,rs.getString(2).length())));
}
}
} catch (ClassNotFoundException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: ClassNotFound!");
} catch (SQLException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: conn failed!" + e.getMessage());
} finally {
System.getProperties().remove("javax.net.ssl.keyStore");
System.getProperties().remove("javax.net.ssl.keyStorePassword");
System.getProperties().remove("javax.net.ssl.trustStore");
System.getProperties().remove("javax.net.ssl.trustStorePassword");
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
public static void connectTestSSL02() {
// 设置 useSSL & requireSSL,设置 keystore,不设置 truststore
String url = "jdbc:gbase://192.168.1.162:5258/testdb01?useSSL=true&requireSSL=true";
String keyStorePath = "/home/frank/demo/ssl-certs/keystore";
String user = "gbase";
String pwd = "1q2w3e";
System.setProperty("javax.net.ssl.keyStore", keyStorePath);
System.setProperty("javax.net.ssl.keyStorePassword", "123456");
System.out.println(CommonUtil.getMethodName() + "keyStore:" + System.getProperty("javax.net.ssl.keyStore"));
System.out.println(CommonUtil.getMethodName() + "keyStorePassword:" + System.getProperty("javax.net.ssl.keyStorePassword"));
System.out.println(CommonUtil.getMethodName() + "trustStore:" + System.getProperty("javax.net.ssl.trustStore"));
System.out.println(CommonUtil.getMethodName() + "trustStorePassword:" + System.getProperty("javax.net.ssl.trustStorePassword"));
Connection conn = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(url, user, pwd);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("show status like '%SSL%'");
while (rs.next()) {
// 仅打印 Ssl_cipher, Ssl_cipher_list, Ssl_verify_depth, Ssl_verify_mode, Ssl_version
if (rs.getString(1).startsWith("Ssl_cipher") ||
rs.getString(1).startsWith("Ssl_ver")) {
System.out.println(rs.getString(1) + "-----"
+ rs.getString(2).substring(0,min(50,rs.getString(2).length())));
}
}
} catch (ClassNotFoundException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: ClassNotFound!");
} catch (SQLException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: conn failed!" + e.getMessage());
} finally {
System.getProperties().remove("javax.net.ssl.keyStore");
System.getProperties().remove("javax.net.ssl.keyStorePassword");
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
public static void connectTestSSL03() {
// 设置 useSSL & requireSSL,不设置 keystore & truststore
String url = "jdbc:gbase://192.168.1.162:5258/testdb01?useSSL=true&requireSSL=true";
String user = "gbase";
String pwd = "1q2w3e";
System.out.println(CommonUtil.getMethodName() + "keyStore:" + System.getProperty("javax.net.ssl.keyStore"));
System.out.println(CommonUtil.getMethodName() + "keyStorePassword:" + System.getProperty("javax.net.ssl.keyStorePassword"));
System.out.println(CommonUtil.getMethodName() + "trustStore:" + System.getProperty("javax.net.ssl.trustStore"));
System.out.println(CommonUtil.getMethodName() + "trustStorePassword:" + System.getProperty("javax.net.ssl.trustStorePassword"));
Connection conn = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(url, user, pwd);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("show status like '%SSL%'");
while (rs.next()) {
// 仅打印 Ssl_cipher, Ssl_cipher_list, Ssl_verify_depth, Ssl_verify_mode, Ssl_version
if (rs.getString(1).startsWith("Ssl_cipher") ||
rs.getString(1).startsWith("Ssl_ver")) {
System.out.println(rs.getString(1) + "-----"
+ rs.getString(2).substring(0,min(50,rs.getString(2).length())));
}
}
} catch (ClassNotFoundException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: ClassNotFound!");
} catch (SQLException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: conn failed!" + e.getMessage());
} finally {
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
//官方手册没有 sslmode 和 verifyServerCertificate 的介绍,下面这个纯属是通过查阅网上其他资料的介绍之后的尝试测试
public static void connectTestSSL04() {
// 设置 useSSL & requireSSL,不设置 keystore & truststore
// 尝试gbase8a 不支持 sslmode: disable | allow | prefer | require | verify-ca | verify-full
// 尝试设置 verifyServerCertificate = true,没有报错,能SSL连接,但也和之前几个没有区别
String url = "jdbc:gbase://192.168.1.162:5258/testdb01?useSSL=true&requireSSL=true&verifyServerCertificate=true";
String user = "gbase";
String pwd = "1q2w3e";
System.out.println(CommonUtil.getMethodName() + "keyStore:" + System.getProperty("javax.net.ssl.keyStore"));
System.out.println(CommonUtil.getMethodName() + "keyStorePassword:" + System.getProperty("javax.net.ssl.keyStorePassword"));
System.out.println(CommonUtil.getMethodName() + "trustStore:" + System.getProperty("javax.net.ssl.trustStore"));
System.out.println(CommonUtil.getMethodName() + "trustStorePassword:" + System.getProperty("javax.net.ssl.trustStorePassword"));
Connection conn = null;
try {
Class.forName("com.gbase.jdbc.Driver");
conn = DriverManager.getConnection(url, user, pwd);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("show status like '%SSL%'");
while (rs.next()) {
// 仅打印 Ssl_cipher, Ssl_cipher_list, Ssl_verify_depth, Ssl_verify_mode, Ssl_version
if (rs.getString(1).startsWith("Ssl_cipher") ||
rs.getString(1).startsWith("Ssl_ver")) {
System.out.println(rs.getString(1) + "-----"
+ rs.getString(2).substring(0,min(50,rs.getString(2).length())));
}
}
} catch (ClassNotFoundException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: ClassNotFound!");
} catch (SQLException e) {
System.out.println(CommonUtil.getMethodName() + "ERROR: conn failed!" + e.getMessage());
e.printStackTrace();
} finally {
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
5)编译 jar 拷贝到 /home/frank/demo/ 执行程序连接数据库
$ java -Xbootclasspath/a:gbase-connector-java-9.5.0.1-build1-bin.jar -jar dbconnector-1.0-SNAPSHOT-shaded-with-dependencies.jar
可以对比看出,几种不同的连接方式 show status like '%SSL%' 显示的信息有区别SSL还是非SSL:
[frank@localhost demo]$ java -Xbootclasspath/a:gbase-connector-java-9.5.0.1-build1-bin.jar -jar dbconnector-1.0-SNAPSHOT-shaded-with-dependencies.jar
[main:27] === dbconnector in ===
[main:29] ====================No SSL
Ssl_cipher-----
Ssl_cipher_list-----
Ssl_verify_depth-----0
Ssl_verify_mode-----0
Ssl_version-----
[main:31] ====================SSL01
[connectTestSSL01:82] keyStore:/home/frank/demo/ssl-certs/keystore
[connectTestSSL01:83] keyStorePassword:123456
[connectTestSSL01:84] trustStore:/home/frank/demo/ssl-certs/truststore
[connectTestSSL01:85] trustStorePassword:123456
Ssl_cipher-----AES256-SHA
Ssl_cipher_list-----ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM
Ssl_verify_depth-----18446744073709551615
Ssl_verify_mode-----5
Ssl_version-----TLSv1
[main:33] ====================SSL02
[connectTestSSL02:130] keyStore:/home/frank/demo/ssl-certs/keystore
[connectTestSSL02:131] keyStorePassword:123456
[connectTestSSL02:132] trustStore:null
[connectTestSSL02:133] trustStorePassword:null
Ssl_cipher-----AES256-SHA
Ssl_cipher_list-----ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM
Ssl_verify_depth-----18446744073709551615
Ssl_verify_mode-----5
Ssl_version-----TLSv1
[main:35] ====================SSL03
[connectTestSSL03:173] keyStore:null
[connectTestSSL03:174] keyStorePassword:null
[connectTestSSL03:175] trustStore:null
[connectTestSSL03:176] trustStorePassword:null
Ssl_cipher-----AES256-SHA
Ssl_cipher_list-----ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM
Ssl_verify_depth-----18446744073709551615
Ssl_verify_mode-----5
Ssl_version-----TLSv1
[main:37] ====================SSL04
[connectTestSSL04:215] keyStore:null
[connectTestSSL04:216] keyStorePassword:null
[connectTestSSL04:217] trustStore:null
[connectTestSSL04:218] trustStorePassword:null
Ssl_cipher-----AES256-SHA
Ssl_cipher_list-----ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM
Ssl_verify_depth-----18446744073709551615
Ssl_verify_mode-----5
Ssl_version-----TLSv1
另外,针对 GBase8a jdbc 连接,尝试了一下如果连接时指定 sslmode 参数(sslmode = disable | allow | prefer | require | verify-ca | verify-full),发现驱动不支持,会报下面错误信息:
[connectTestSSL04:236] ERROR: conn failed!driver not support property sslmode.
貌似客户端 jdbc 无法设置 sslmode,只能系统默认。
后来又尝试了设置 verifyServerCertificate=true,发现和之前几种情况(connectTestSSL01/02/03)相同。
关于 useSSL 和 requireSSL 参数说明:
useSSL:是否建立SSL连接;
requireSSL:true代表如果服务端不支持SSL连接则失败,如果不指定该参数则默认为false、即如果服务端不支持SSL连接则会协商使用普通(非SSL)方式连接;
附:
openssl主要参数:
req 大致有3个功能:生成证书请求文件、验证证书请求文件和创建根CA
-x509 说明生成自签名证书
-nodes openssl req在自动创建私钥时,将总是加密该私钥文件,并提示输入加密的密码。可以使用"-nodes"选项禁止加密私钥文件
-days 指定所颁发的证书有效期(单位:天)
-new 新的请求
-newkey 直接指定私钥的算法和私钥长度,例如:-newkey rsa:2048 生成一个2048长度的RSA私钥文件、用于签发
实际上,"-x509"选项和"-new"或"-newkey"配合使用时,可以不指定证书请求文件,它在自签署过程中将在内存中自动创建证书请求文件。"-newkey"和"-new"选项类似,只不过"-newkey"选项可以指定私钥的算法和长度
-keyout 指定私钥保存位置(含文件名)
-out 新的证书请求文件位置(含文件名)
-config 指定req的openssl配置文件,指定后将忽略所有的其他配置文件。如果不指定则默认使用 /etc/pki/tls/openssl.cnf 中 req段落的值
-text text显示格式
-key 用于签名待生成的请求证书的私钥文件
-subj 设置CA证书subject
详细openssl参数请使用命令帮助查看 man openssl
相关文章:

GBase8a SSL 配置
GBase8a SSL 配置 GBase8a MPP Cluster 支持 SSL 标准协议, SSL 协议是一种安全性更高的协议标准, 它加入了数字签名和数字证书来实现客户端和服务器的双向身份验证,保证了通信双方更加安全的数据传输。 配置客户端使用 SSL 安全连接的方式连…...

数据结构之队列(源代码➕图解➕习题)
前言 在学过栈之后,会了解到栈的底层是根据顺序表或者链表来构建的,那么我们今天要学习的队列是否也是基于顺序表和链表呢?那我们直接进入正题吧! 1. 队列的概念(图解) 还是跟上节一样,依旧用图…...

社区迭代|ETLCloud社区新增“论坛”啦!
ETLCloud社区是谷云科技RestCloud旗下面向开发工程师、集成研发人员等技术人员提供全方位交流和学习的开放式平台,也是ETLCloud在产品生态赋能上的一大亮点,旨在能够帮助更多的用户更快捷高效的掌握技能,也为企业提供集成人才培养赋能&#x…...

ohos的代码同步以及添加自己的代码
首先我们需要获取到官方的repo工具,命令如下curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > ./repo,这里我们就拿到repo工具了,这个repo可以放任意地方,也可以放 /usr/local/bin/repo下,这样可以…...

Python的Pandas库(二)进阶使用
Python开发实用教程 DataFrame的运算 DataFrame重载了运算符,支持许多的运算 算术运算 运算方法运算说明df.add(other)对应元素的加,如果是标量,就每个元素加上标量df.radd(other)等效于otherdfdf.sub(other)对应元素相减,如果…...

如何才能从程序员到架构师?
1 引言 小团队一般 10 人左右,其中常常是技术最牛的人做架构师(或TL)。所以,架构师在广大码农中的占比大概平均不到 10%。而架构师也可以分为初级、中级、高级三档,江湖上真正高水平的软件架构师就更少了。 所以&…...

dvadmin-打包发布-nginx-静态服务器配置-防火墙设置
文章目录 1.下载nginx2.nginx常用命令3.dvadmin打包发布4.防火墙设置 1.下载nginx 也从作者下载的网址下载:https://download.csdn.net/download/m0_67316550/88470098 2.nginx常用命令 注意:一定要在dos窗口启动,不要直接双击nginx.exe&a…...

Win10中Pro/E鼠标滚轮不能缩放该怎么办?
Pro/E安装好后,鼠标滚轮不能缩放模型,该怎么办?问题多发生在win8/win10上,新装了PROE,发现滑动鼠标中键不能放大缩小。 彩虹图纸管理软件_图纸管理系统_图纸文档管理软件系统_彩虹EDM【官网】彩虹EDM图纸管理软件系统…...

腾讯云轻量应用服务器性能如何?值得入手吗?
腾讯云轻量应用服务器性能怎么样?轻量服务器的CPU内存计算性能和同规格的标准型云服务器CVM性能处于同一水准,性能很不错,具有100%CPU性能,并且价格很优惠,值得买。腾讯云百科txybk.com分享腾讯云轻量应用服务器性能测…...

主流大语言模型的技术细节
主流大语言模型的技术原理细节从预训练到微调https://mp.weixin.qq.com/s/P1enjLqH-UWNy7uaIviWRA 比较 LLaMA、ChatGLM、Falcon 等大语言模型的细节:tokenizer、位置编码、Layer Normalization、激活函数等。2. 大语言模型的分布式训练技术:数据并行、…...

面试经典150题——Day22
文章目录 一、题目二、题解 一、题目 6. Zigzag Conversion The string “PAYPALISHIRING” is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) P A H N A P L S I I G …...

for循环三种跳出循环的方法(retrun、continue、break)
1、continue:指的是跳出当前循环,即不执行continue后的语句,直接进入下次循环。 【continue语句和break语句差不多。不同的是,它不是退出一个循环,而是跳出当前循环,进行下一轮循环】 public static void…...

React中的受控组件(controlled component)和非受控组件(uncontrolled component)
聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

python 查找波峰和波谷
import numpy as np import matplotlib.pyplot as plt from scipy.signal import find_peaks# 生成示例信号 x np.array([1, 3, 7, 1, 2, 6, 0, 4, 3, 2, 5, 1])# 寻找波峰 peaks, _ find_peaks(x)# 寻找波谷(使用信号的负数形式) valleys, _ find_pe…...

深入理解 Document Load 和 Document Ready 的区别
目录 前言: 一、Document Ready 二、Document Load 三、理解和总结 前言: 在前端开发中,理解页面加载的不同阶段是至关重要的。特别是当我们需要在页面加载到特定阶段时执行某些操作时,我们需要知道应该使用 document ready 还…...

有趣的算法(七) ——快速排序改进算法
有趣的算法(七) ——快速排序改进算法 目录 有趣的算法(七) ——快速排序改进算法 本文章向大家介绍有趣的算法(七) ——快速排序改进算法,主要内容包括其使用实例、应用技巧、基本知识点总结…...

Vue3 + Tsx 集成 ace-editor编辑器
Ace Editor介绍 Ace Editor(全名:Ajax.org Cloud9 Editor)是一个开源的代码编辑器,旨在提供强大的代码编辑功能,通常用于构建基于Web的代码编辑应用程序。它最初由Cloud9 IDE开发,现在由开源社区维护。 主…...

TypeScritpt中的namespace
namesapce 它是在ES模块诞生前,ts自己发明的模块功能,目前已经不推荐使用了,namespace意为命名空间,就是模块化的意思。 1. 基本用法 namespace用来建立一个容器,内部的所有变量和函数只能在容器内部才能使用。 nam…...

LeetCode75——Day17
文章目录 一、题目二、题解 一、题目 1493. Longest Subarray of 1’s After Deleting One Element Given a binary array nums, you should delete one element from it. Return the size of the longest non-empty subarray containing only 1’s in the resulting array.…...

Spring中Bean的作用域
目录 一、什么是Bean的作用域 二、Scope注解 三、Bean的6种作用域 3.1 singleton单例模式 3.2 prototype 原型模式 3.3 request 3.4 session 3.5 application 3.6 websocket 一、什么是Bean的作用域 在之前学习的过程中,我们把作用域定义为:限定程序中变…...

什么是命令行参数解析和选项处理?
在C语言中,命令行参数解析和选项处理是一项关键的编程技术,它使程序能够从命令行接受参数和选项,以在运行时进行不同的配置和控制。这对于命令行工具、应用程序和脚本编写非常重要,因为它允许用户以不同的方式自定义程序的行为。本…...

网络协议--TFTP:简单文件传送协议
15.1 引言 TFTP(Trivial File Transfer Protocol)即简单文件传送协议,最初打算用于引导无盘系统(通常是工作站或X终端)。和将在第27章介绍的使用TCP的文件传送协议(FTP)不同,为了保持简单和短小࿰…...

MongoDB 的集群架构与设计
一、前言 MongoDB 有三种集群架构模式,分别为主从复制(Master-Slaver)、副本集(Replica Set)和分片(Sharding)模式。 Master-Slaver 是一种主从复制的模式,目前已经不推荐使用。Re…...

volatile 系列之实现原理
我们通过volatile解决了由于编译器的指令重排序导致的可见性问题,这意味着volatile 底层用到了内存屏障,下面我们从它的部分源码中找一下内存屏障相关的痕迹。 通过javap-V VolatileExample.class打印VolatileExample类的字节指令如下。 public static …...

【黑马程序员】mysql进阶篇笔记
2023年10月26日17:50:43 58.01. 进阶-课程介绍(Av765670802,P58) 59.02. 进阶-存储引擎-MySQL体系结构(Av765670802,P59) 60.03. 进阶-存储引擎-简介(Av765670802,P60) 61.04. 进阶-存储引擎-InnoDB介绍(Av765670802,P61) 62.05. 进阶-存储引擎-MyISAM和Memory(Av765670802…...

A - Block Sequence
思路: (1)对于每一个位置,有三种选择,一是选择删除,二是选择当排头清洗,三是被前面的排头清洗; (2)注意到总是要求将最后一位数清洗完,即前面信…...

0031【Edabit ★☆☆☆☆☆】【使用箭头函数】Using Arrow Functions
0031【Edabit ★☆☆☆☆☆】【使用箭头函数】Using Arrow Functions data_structures language_fundamentals Instructions Create a function that returns the given argument, but by using an arrow function. An arrow function is constructed like so: arrowFunc(/*p…...

C#,数值计算——分类与推理,基座向量机(SVM,Support Vector Machines)的计算方法与源程序
把 Support Vector Machines 翻译成 支持向量机 是书呆子翻译。基座向量机 不好吗。 1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Support Vector Machines /// </summary> public class Svm { priv…...

面试总结之消息中间件
RabbitMQ的消息如何实现路由 RabbitMQ是一个基于AMQP协议实现的分布式消息中间件,AMQP具体的工作机制是生产者将消息发送到RabbitMQ Broker上的Exchange交换机上,Exchange交换机将收到的消息根据路由规则发给绑定的队列(Queue)&am…...

Java零基础入门-逻辑运算符
前言 Java是一种广泛应用的编程语言,在在这里插入代码片软件开发中有着重要的地位。本文将介绍Java中的逻辑运算符及其在程序设计中的应用,希望能够帮助零基础的读者更好地入门学习Java。 摘要 本文将介绍Java中的三种逻辑运算符:与运算符…...