场景:

项目中有一块功能是检测数据库连接的,测试完到现场报出连接postgresql测试失败的情况;

然鹅,我的代码里边通用函数连接都是通过用户密码验证的.这里出现了SSL的报错;难道是服务端配置强制要求证书验证?

而且测试环境中是可以正常连接的.那我们就先对比一下现场环境和测试环境的服务端配置好了;

处理过程:

1.对比测试环境和现场环境;

登录测试环境postgresql所在的服务器用户, psql

 

 

 登录成功,     show config_file;

 

退出psql,查看配置;    cat  /var/lib/pgsql/data/postgresql.conf | grep ssl

 

 

 我们可以看到ssl相关配置都注释掉的;也就是说测试环境的配置是不支持ssl证书验证的;

那我们看看现场环境; wtf,现场同事说data目录下没有配置文件;他们安装这个postgresql是通过一个drdb的工具安装的;百度一波只有drbd,线索断了啊!

 

 

 

 2. 查资料尝试:

网上有文章支持,这个报错有可能是ssl版本/协议不对导致的; 查  openssl version

 

 

 ssl版本一模一样.

病急乱投医,检查数据库版本; select "version"();

 

postgres版本一模一样.

僵住了.

查下官方文档.关于ssl的说明;

 

 

 

 ssl证书验证高安全性的策略的话是需要在服务端和客户端配置证书,sslmode的级别是在verify-ca和verify-full;

大胆猜测一下,当服务端不设置ssl认证时(测试环境),

客户端可以不做sslmode配置;当服务端设置了ssl认证时,客户端连接就需要说明自己的sslmode了.目测为需要配置sslmode=disable,

3.做测试代码测试;

package com.springboot.demo.testDemo.pgjdbc;

import java.sql.Connection;
import java.sql.DriverManager;

/**
* @Date 2020/6/10 16:44
* @Author zhang.fanlc
* @Description
**/
public class PgJDBC {
public static void main(String[] args) {
String url = "jdbc:postgresql://[ip]:[port]/[dbName]?sslmode=disable";
String driver = "org.postgresql.Driver";
String user = "test";
String pass = "test";
try {
Class.forName(driver);
System.out.println("开始连接...!");
Connection conn = DriverManager.getConnection(url,user,pass);
if(conn != null){
System.out.println("连接成功!");
}
}catch(Exception e){
e.printStackTrace();
}
}
}
把PgJDBC.java拷贝到现场环境;
vi PgJDBC.java, 去掉 package声明;
设置依赖,vi setEnv.sh ,export CLASSPATH=.:/home/cmspmn/lib/postgresql-42.2.8.jar:,保存,./setEnv.sh,执行;

 

javac PgJDBC.java

java PgJDBC

 

 

爆炸;sslmode=disable不起作用;

爆炸;sslmode=allow;不起作用;

投降投降.放弃挣扎;请教领导,领导说这个sslmode应该和ssl底层的验证机制匹配的,文档讲的定义不是很准确;让我用sslmode=requir配置再搞一次;

 

 不得不佩服;

解决方式:

在jdbc连接代码的url后增加sslmode=requir;

like this

connUrl = "jdbc:postgresql://" + dsIp + ":" + dsPort + "/" + dsName + "?sslmode=require";

 

 




问题虽然解决,但是无法探究服务端的配置和客户端sslmode的关系和影响;这波很亏;

 



 

posted on 2020-06-11 10:40  骊珠渎齐静落魄山石巉  阅读(1114)  评论(0编辑  收藏  举报