spring-boot-admin监控使用自签发ssl证书服务。
最近做的一个项目,部署在局域网环境下,但是对安全性有比较高的要求,其中就特别提到了需要使用https协议,以及需要一个可以监控服务本身状态的功能。
ssl证书出于成本考虑,就使用keytool自签发的。
正好这个项目使用springboot做的,经过调查发现有一个spring-boot-admin是一个封装好带UI的监控springboot服务项目,于是便决定使用它。
spring-boot-admin本身使用很简单,网上教程很多,这里就不细说了。简单而言就是2步:
1、新建一个springboot工程作为admin工程,maven依赖加上
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.1.6</version>
</dependency>
然后在启动类上加上@EnableAdminServer注解
2、在要被监视的springboot主工程,maven依赖加上
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.1.0</version>
</dependency>
然后配置文件里面配上spring.boot.admin.client.url={admin工程的url}即可
然后坑就来了……
在不使用ssl证书的情况下一切正常。
然后把ssl证书一放上去……主工程启动是对admin注册失败。
admin报了javax.net.ssl.SSLHandshakeException错误。
百度了之后发现需要添加信任证书。
于是在admin工程启动类main方法里第一行加上:
System.setProperty("javax.net.ssl.trustStore",自己生成的证书路径);
然后主工程可以成功注册了,然而……
这显然是因为SSL证书的问题,在springbootadmin Q&A的网站找到了有人提这个问题,但是回答含糊不清。
看admin工程报错信息:Caused by: java.security.cert.CertificateException: No name matching admin-PC found
看意思应该是自己生成SSL证书时,域名瞎填,不匹配admin-PC导致。
于是重新生成了一个证书,域名填admin-PC,一切正常!!搞定!!
…………搞定的毛线,这个admin-PC又是什么鬼?我启动的服务明明是在本地,为什么url不是ip或者localhost而是见鬼的admin-PC?
仔细检查之后发现所谓的admin-PC其实是我自己电脑的名字。显然,我是不知道甲方电脑名字的,而且用电脑名字当域名也很扯。
既然知道是域名的问题,那么就自己加上域名就好了。于是我在自己的host里面加上192.168.20.244 sgsearch
192.168.20.244 是我电脑的局域网ip
sgsearch是我之前证书写的域名
把之前证书放回到工程里面。
可以看到绑定的域名从admin-PC变成了sgsearch。也就是只要在部署admin工程的机子上改一下host即可。
搞定!!!
…………然而并没有。
部署到lunix上之后admin服务又报错:
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
研究了半天,发现在linux上javax.net.ssl.trustStore不能使用自己生成的文件,而需要使用jdk里面的cacerts才行(两者区别谁能告诉我一下),
于是只能先,把证书导入到jdk信任库:
keytool -import -alias sgsearch -file sgsearch.cer -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts
启动时用使用信任库:
java -Djavax.net.ssl.trustStore=$JAVA_HOME/jre/lib/security/cacerts -jar jar包名字
(记得把admin工程里的System.setProperty("javax.net.ssl.trustStore",自己生成的证书路径)去掉)