暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

华为GaussDB A JDBC连接数据库(以SSL方式)

墨天轮 2019-10-12
1730

连接数据库(以SSL方式)

用户通过JDBC连接GaussDB 200服务器时,可以通过开启SSL加密客户端和服务器之间的通讯,为敏感数据在Internet上的传输提供了一种安全保障手段。本小节主要介绍应用程序通过JDBC如何采用SSL的方式连接GaussDB 200。在使用本小节所描述的方法前,默认用户已经获取了服务端和客户端所需要的证书和私钥文件,关于证书等文件的获取请参考Openssl相关文档和命令 。

服务端配置

当开启SSL模式后,必须提供根证书、服务器证书和私钥。GaussDB 200预置了这些证书,证书文件被命名为cacert.pem(根证书)、server.crt(服务端证书)和server.key(服务端私钥),并放置在了数据目录${BIGDATA_DATA_HOME}/mppdb/data1/coordinator下。当然,可以使用配置参数ssl_ca_file、ssl_cert_file和ssl_key_file修改它们的名称和存放位置。

在Unix系统上,server.crt、server.key的权限设置必须禁止任何外部或组的访问,如果使用用户自己的证书,请执行如下命令实现这一点。如果使用GaussDB 200的内置证书,GaussDB 200已经提前设置了权限,不需要再重复设置。

chmod 0600 server.key

配置步骤(假设用户的证书文件放在数据目录下,且采用默认文件名):

  • 以操作系统用户omm登录GaussDB 200集群任一主机。执行source ${BIGDATA_HOME}/mppdb/.mppdbgs_profile命令启动环境变量。
  • 开启SSL认证模式。

    gs_guc set -Z coordinator -D ${BIGDATA_DATA_HOME}/mppdb/data1/coordinator -c "ssl=on"

  • 配置客户端接入认证参数。

    gs_guc reload -Z coordinator -D ${BIGDATA_DATA_HOME}/mppdb/data1/coordinator -h "hostssl all all 127.0.0.1/32 cert"

    表示允许127.0.0.1/32网段的客户端以ssl认证方式连接到GaussDB 200服务器。

    如果服务端pg_hba.conf文件中METHOD配置为cert,则只有客户端使用证书(client.crt)中所设置的用户名(common name)才能够成功连接数据库。如果设置为md5或sha256则对连接数据库的用户没有限制。

  • 配置SSL认证相关的数字证书参数。

    各命令后所附为设置成功的回显。
    gs_guc set -Z coordinator -D ${BIGDATA_DATA_HOME}/mppdb/data1/coordinator -c "ssl_cert_file='server.crt'" gs_guc set: ssl_cert_file='server.crt'
    gs_guc set -Z coordinator -D ${BIGDATA_DATA_HOME}/mppdb/data1/coordinator -c "ssl_key_file='server.key'" gs_guc set: ssl_key_file='server.key'
    gs_guc set -Z coordinator -D ${BIGDATA_DATA_HOME}/mppdb/data1/coordinator -c "ssl_ca_file='cacert.pem'" gs_guc set: ssl_ca_file='cacert.pem'

  • 重启数据库。

    gs_om -t stop && gs_om -t start

客户端配置

不同于基于gsql或其他基于libpq的程序,JDBC默认支持服务证书确认,如果用户使用一个由认证中心(CA,全球CA或区域CA)签发的证书,则java应用程序不需要做什么,因为java拥有大部分认证中心(CA,全球CA或区域CA)签发的证书的拷贝。如果用户使用的是自签的证书,则需要配置客户端程序,使其可用,此过程依赖于openssl工具以及java自带的keytool工具,配置步骤如下:

  • 在客户端机器上,上传证书文件。

    • 以root用户登录客户端机器。
    • 创建“/tmp/cacert”目录。
      mkdir /tmp/cacert
    • 获取软件安装包中的“GaussDB-Kernel-VxxxRxxxCxx-Sslcert.tar.gz”上传到“/tmp/cacert”路径下。
    • 解压文件。
      cd /tmp/cacert tar -zxvf GaussDB-Kernel-VxxxRxxxCxx-Sslcert.tar.gz

  • 将根证书导入到trustStore中。

    openssl x509 -in cacert.pem -out cacert.crt.der -outform der

    生成中间文件cacert.crt.der。

    keytool -keystore mytruststore -alias cacert -import -file cacert.crt.der

    请用户根据提示信息输入口令,此口令为truststorepassword,例如Gauss@123。生成mytruststore。

    • cacert.pem为根证书。
    • cacert.crt.der为中间文件。
    • mytruststore为生成的密钥库名称,此名称以及别名用户可以根据需要进行修改。

  • 将客户端证书和私钥导入到keyStore中。

    openssl pkcs12 -export -out client.pkcs12 -in client.crt -inkey client.key

    请用户根据提示信息输入clientkey,默认是Gauss@MppDB,export password,例如Gauss#123。生成client.pkcs12。

    keytool -importkeystore -deststorepass Bigdata@123 -destkeystore client.jks -srckeystore client.pkcs12 -srcstorepass Gauss#123 -srcstoretype PKCS12 -alias 1 -destkeypass Bigdata@123

    此处deststorepass与destkeypass需保持一致,srcstorepass需与上条命令中的export password保持一致。生成client.jks。

示例1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//使用NonValidatingFactory通道。

public static Connection GetConnection(String username, String passwd)
    {
        //驱动类。
        String driver = "org.postgresql.Driver";   
        Properties props = new Properties();
        props.setProperty("sslfactory","org.postgresql.ssl.NonValidatingFactory")
        props.setProperty("user", "CLIENT");
        props.setProperty("password", "1234@qwer");
        props.setProperty("ssl", "true");

        String  url = "jdbc:postgresql://" + "10.10.0.13" + ':'
                    + "25308" + '/'
                    + "postgres";
        Connection conn = null;
             //连接GaussDB 200机器与GaussDB 200不在同一网段时,此时“10.10.0.13”需要替换为Manager界面上所设的mppdb.coo.cooListenIp2(应用访问IP)的取值。
        
        try
        {
            //加载驱动。
            Class.forName(driver);
        }
        catch( Exception e )
        {
            e.printStackTrace();
            return null;
        }
        
        try
        {
             //创建连接。
            conn = DriverManager.getConnection(url, props );
            System.out.println("Connection succeed!");
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
        
        return conn;
    };

//除了props.setProperty("ssl", "true");方式外还可以设置sslmode, 例如props.setProperty("sslmode", "require"); 或者props.setProperty("sslmode", "verify-ca");或者props.setProperty("sslmode", "verify-full");

示例2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//设置ssl为true,使用证书认证。

public static Connection GetConnection(String username, String passwd)
    {
        //驱动类。
        String driver = "org.postgresql.Driver";
         //设置keystore
        System.setProperty("javax.net.ssl.trustStore", "mytruststore");
        System.setProperty("javax.net.ssl.keyStore", "client.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "Gauss@123");
        System.setProperty("javax.net.ssl.keyStorePassword", "Bigdata@123");

        Properties props = new Properties();
        props.setProperty("user", "CLIENT");
        props.setProperty("password", "1234@qwer");
        props.setProperty("ssl", "true");

        String  url = "jdbc:postgresql://" + "10.10.0.13" + ':'
                    + "25308" + '/'
                    + "postgres";
        Connection conn = null;
             //连接GaussDB 200机器与GaussDB 200不在同一网段时,此时“10.10.0.13”需要替换为Manager界面上所设的mppdb.coo.cooListenIp2(应用访问IP)的取值。
        
        try
        {
            //加载驱动。
            Class.forName(driver);
        }
        catch( Exception e )
        {
            e.printStackTrace();
            return null;
        }
        
        try
        {
             //创建连接。
            conn = DriverManager.getConnection(url, props );
            System.out.println("Connection succeed!");
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
        
        return conn;
    };

//建议mytruststore和client.jks指定到文件绝对路径

示例3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//设置sslmode为require,使用证书。
public static Connection GetConnection(String username, String passwd)
    {
        //驱动类。
        String driver = "org.postgresql.Driver";
         //设置keystore
        System.setProperty("javax.net.ssl.trustStore", "mytruststore");
        System.setProperty("javax.net.ssl.keyStore", "client.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "Gauss@123");
        System.setProperty("javax.net.ssl.keyStorePassword", "Bigdata@123");

        Properties props = new Properties();
        props.setProperty("user", "CLIENT");
        props.setProperty("password", "1234@qwer");
        props.setProperty("sslmode", "require");

        String  url = "jdbc:postgresql://" + "10.10.0.13" + ':'
                    + "25308" + '/'
                    + "postgres";
        Connection conn = null;
             //连接GaussDB 200机器与GaussDB 200不在同一网段时,此时“10.10.0.13”需要替换为Manager界面上所设的mppdb.coo.cooListenIp2(应用访问IP)的取值。
        
        try
        {
            //加载驱动。
            Class.forName(driver);
        }
        catch( Exception e )
        {
            e.printStackTrace();
            return null;
        }
        
        try
        {
             //创建连接。
            conn = DriverManager.getConnection(url, props );
            System.out.println("Connection succeed!");
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
        
        return conn;
    };

//建议mytruststore和client.jks指定到文件绝对路径,也可以不使用证书,不配置truststore、keystore等相关内容。

示例4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//设置sslmode为verify-ca,使用证书。
public static Connection GetConnection(String username, String passwd)
    {
        //驱动类。
        String driver = "org.postgresql.Driver";
         //设置keystore
        System.setProperty("javax.net.ssl.trustStore", "mytruststore");
        System.setProperty("javax.net.ssl.keyStore", "client.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "Gauss@123");
        System.setProperty("javax.net.ssl.keyStorePassword", "Bigdata@123");

        Properties props = new Properties();
        props.setProperty("sslrootcert", "cacert.pem");
        props.setProperty("user", "CLIENT");
        props.setProperty("password", "1234@qwer");
        props.setProperty("sslmode", "verify-ca");

        String  url = "jdbc:postgresql://" + "10.10.0.13" + ':'
                    + "25308" + '/'
                    + "postgres";
        Connection conn = null;
             //连接GaussDB 200机器与GaussDB 200不在同一网段时,此时“10.10.0.13”需要替换为Manager界面上所设的mppdb.coo.cooListenIp2(应用访问IP)的取值。
        
        try
        {
            //加载驱动。
            Class.forName(driver);
        }
        catch( Exception e )
        {
            e.printStackTrace();
            return null;
        }
                                                                                                                                                                                                                    
        try
        {
             //创建连接。
            conn = DriverManager.getConnection(url, props );
            System.out.println("Connection succeed!");
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
        
        return conn;
    };

//建议mytruststore和client.jks,cacert.pem指定到文件绝对路径。

示例5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//设置sslmode为verify-full,使用证书。
//首先,查看服务器端证书server.crt,查看CN值,默认CN=gaussdb,修改本地hosts文件,设置服务器目标主机名为上面查看到的CN名,例如10.10.0.13    gaussdb,保存。
public static Connection GetConnection(String username, String passwd)
    {
        //驱动类。
        String driver = "org.postgresql.Driver";
         //设置keystore
        System.setProperty("javax.net.ssl.trustStore", "mytruststore");
        System.setProperty("javax.net.ssl.keyStore", "client.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "Gauss@123");
        System.setProperty("javax.net.ssl.keyStorePassword", "Bigdata@123");

        Properties props = new Properties();
        props.setProperty("sslrootcert", "cacert.pem");
        props.setProperty("user", "CLIENT");
        props.setProperty("password", "1234@qwer");
        props.setProperty("sslmode", "verify-full");

        String  url = "jdbc:postgresql://" + "gaussdb" + ':'
                    + "25308" + '/'
                    + "postgres";
        Connection conn = null;
        
        try
        {
            //加载驱动。
            Class.forName(driver);
        }
        catch( Exception e )
        {
            e.printStackTrace();
            return null;
        }
        
        try
        {
             //创建连接。
            conn = DriverManager.getConnection(url, props );
            System.out.println("Connection succeed!");
        }
        catch(Exception e)
        {
            e.printStackTrace();
            return null;
        }
        
        return conn;
    };

//建议mytruststore和client.jks,cacert.pem指定到文件绝对路径。
说明:

其中CLIENT为数据库用户名称,同时也是客户端证书中的COMMAN NAME。

以上示例均是以gsjdbc4.jar为例,若要使用gsjdbc200.jar需要将示例中的驱动名改为"com.huawei.gauss200.jdbc.Driver",链接url前缀由"jdbc:postgresql"改为"jdbc.gaussdb"

同一个进程中使用SSL连接服务器进行通讯,不允许使用多套证书或加密的证书,即使使用多套,也只会使用第一套有效的证书或者加密证书。如果使用加密的证书,建议客户端应用程序对证书密码进行加密、解密处理,避免明文密码安全问题。


查看更多:华为GaussDB 200 基于JDBC开发
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论