如何配置SpringCloud Dubbo SSL/TLS 双向认证?
当微服务所部署的服务器不在一个内网,或者内网不是很安全,担心dubbo的远程调用被中间人窃听,或者担心dubbo调用不受控制,被恶意调用。那么就需要搭建Dubbo SSL/TLS双向认证,服务提供方需要校验消费方的身份,消费方也需要校验服务提供方的身份
当微服务所部署的服务器不在一个内网,或者内网不是很安全,担心dubbo的远程调用被中间人窃听,或者担心dubbo 远程接口被恶意调用。此时就需要Dubbo SSL/TLS双向认证,服务提供方需要校验消费方的身份,消费方也需要校验服务提供方的身份。
dubbo的SSL/TLS的资料网上很少,在Dubbo官网上也很少相关的资料,可参考dubbo官网:TLS支持 | Apache Dubbo
以下是官网的示例:
Provider 端
//这是dubbo官网文档的说明,加上一些注释:
SslConfig sslConfig = new SslConfig();
//设置服务端的证书
sslConfig.setServerKeyCertChainPath("path to cert");
//设置服务端密钥
sslConfig.setServerPrivateKeyPath(args[1]);
// 如果开启双向 cert 认证
if (mutualTls) {
//设置CA证书
sslConfig.setServerTrustCertCollectionPath(args[2]);
}
ProtocolConfig protocolConfig = new ProtocolConfig("dubbo/grpc");
//开启ssl
protocolConfig.setSslEnabled(true);
Consumer 端
if (!mutualTls) {
//设置客户端信任的CA证书
sslConfig.setClientTrustCertCollectionPath(args[0]);
} else {
//设置客户端信任的CA证书
sslConfig.setClientTrustCertCollectionPath(args[0]);
//设置客户端证书
sslConfig.setClientKeyCertChainPath(args[1]);
//设置客户端密钥
sslConfig.setClientPrivateKeyPath(args[2]);
}
官网给出的示例源码:
https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-ssl
从示例里有以下几个文件:
ca.key //CA密钥 ca.pem //CA证书 client.key //客户端密钥 client.pem //客户端证书 server0.key //服务端密钥 server0.pem //服务端证书
也就是我们要在自己的项目中提供这几个密钥证书文件,然后配置上私钥和证书。可惜Demo里不是微服务架构,没办法直接拿去使用,也没有告诉我们应该如何创建自己的密钥和证书。
具体分2大步骤:
一:使用openssl工具生成相关的密钥和证书
openssl工具的安装和使用请自行学习,百度一大把教程。参考: window安装openssl
接下来我们就开始创建密钥和证书了,请按照步骤来,如果有错的可以地下评论留言一起研究讨论。
1.CA密钥和根证书
-
生成CA私钥(.key) 命令:openssl genrsa -out ca.key 1024
-
生成CA证书请求(.csr) 命令:openssl req -new -key ca.key -out ca.csr 参考以下的交互:输入相应的信息,例如公司组织名称等等。
-
自签名得到根证书(.crt)(CA给自已颁发的证书) 命令: openssl x509 -req -days 2000 -in ca.csr -signkey ca.key -out ca.crt
这样我就得到了CA根证书,接下来我们要基于根证书创建服务端和客户端的证书
2.服务器密钥和用CA根证书生成的书
-
生成私钥(.key) 命令: openssl genrsa -out server.key 1024 以下是交互过程: Enter PEM pass phrase:Viangz1234567890 Verifying - Enter PEM pass phrase:Viangz1234567890
-
生成证书请求(.csr)
命令:openssl req -new -key server.key -out server.csr 以下是交互过程: Enter pass phrase for server.key: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:guangdong Locality Name (eg, city) []:guangzhou Organization Name (eg, company) [Internet Widgits Pty Ltd]:vian Organizational Unit Name (eg, section) []:vian Common Name (e.g. server FQDN or YOUR name) []:vian Email Address []:support@vianstats.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:Viangz1234567890 An optional company name []:vian
命令:openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key 会报以下错误,是个大坑,需要修改配置配置文件或者自己创建文件夹。 Using configuration from C:\Program Files\Common Files\SSL/openssl.cnf ca: ./demoCA/newcerts is not a directory ./demoCA/newcerts: No error 上面的错误意思是找不到/demoCA/newcerts文件夹,因为证书要存储在该文件夹下, 可以去修改C:\Program Files\Common Files\SSL/openssl.cnf里的配置文件,也可以按照配置文件配置的默认存储路径,创建文件夹。 本人是修改openssl.cnf配置文件,将./demoCA改为 . [ CA_default ] dir = ./demoCA 改为:. # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. #unique_subject = no # Set to 'no' to allow creation of 继续执行 C:\Program Files\Common Files\SSL/openssl.cnf ,又报以下错误: Using configuration from C:\Program Files\Common Files\SSL/openssl.cnf C05E0000:error:80000002:system library:BIO_new_file:No such file or directory:crypto\bio\bss_file.c:67:calling fopen(./index.txt, r) C05E0000:error:10000080:BIO routines:BIO_new_file:no such file:crypto\bio\bss_file.c:75: Problem with index file: ./index.txt (could not load/parse file) 找不到index.txt文件,那就在当前目录下创建一个index.txt空文件 接着执行上面命令,结果又出现以下错误: ./serial: No such file or directory 88260000:error:80000002:system library:BIO_new_file:No such file or directory:crypto\bio\bss_file.c:67:calling fopen(./serial, r) 88260000:error:10000080:BIO routines:BIO_new_file:no such file:crypto\bio\bss_file.c:75: error while loading serial number 提示找不到serial文件,那就再手动在当前目录下创建一个serial文件,文件里随便写上数字,这里写01,注意不是文件夹 继续执行原来的命令,连续输入y就成功创建了。
-
用CA根证书签名得到证书(.crt) 命令:openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
3.客户端密钥和用CA根证书生成的客户端证书
-
生成私钥(.key)
命令:openssl genrsa -out client.key 1024 以下交互,输入密码:Viangz12*** Enter PEM pass phrase: Viangz1234*** Verifying - Enter PEM pass phrase: Viangz1234***
-
生成证书请求(.csr )
命令:openssl req -new -key client.key -out client.csr
具体的操作请参考服务端的第二步,这里不再重复。
-
用CA根证书签名得到证书(.crt)
命令:openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key
以上就是证书生成的过程,最易出错的是生成证书请求(.csr)这步,如果之前没有修改过openssl配置文件,没有在当前文件创建过newcerts文件夹、index.txt、serial文件的需要按照上面的步骤一个完善,最终的效果如下图所示:
上图中就已经创建好我们需要的几个文件。
二:在SpringCloud配置TLS双向认证
证书已经准备好了,那么我们就可以在微服务里配置了,微服务里的rpc选择的是dubbo,dubbo的底层是使用netty来实现数据通信的,在微服务里很多时候会存在相互调用的,因此就不分服务端和客户端的,存在A服务调B服务,B服务也会调A服务的情况,因此每一个微服务都需要设置服务端和客户端的配置,全部配置。
因此单独将服务拆出来放到common公共依赖包里,所有的服务都依赖这个公共服务。
创建一个配置DubboConfig:
package com.vianstats.capp.commom.dubbo.auth.filter.config;
import org.apache.dubbo.config.SslConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.validation.Valid;
@Configuration
public class DubboConfig {
@Value("${dubbo.protocol.ssl.server-key-cert-chain-path}")
private String serverKeyCertChainPath;
@Value("${dubbo.protocol.ssl.server-private-key-path}")
private String serverPrivateKeyPath;
@Value("${dubbo.protocol.ssl.server-trust-cert-collection-path}")
private String serverTrustCertCollectionPath;
@Value("${dubbo.protocol.ssl.client-key-cert-chain-path}")
private String clientKeyCertChainPath;
@Value("${dubbo.protocol.ssl.client-private-key-path}")
private String clientPrivateKeyPath;
@Value("${dubbo.protocol.ssl.client-trust-cert-collection-path}")
private String clientTrustCertCollectionPath;
/**
*
*
*
* 以下的配置文件是绝对路径,如果想在本地运行的需要改成自己本地openssl工具生成的证书
* 生产环境的证书路径配置在application配置文件上,证书放在服务器的某个安全目录下,不要使用resources下的证书
* @return
*/
@Bean
public SslConfig sslConfig(){
/**
*
* 参考示例,路径使用绝对路径,请按照自己本地存放的证书路径修改配置文件路径
* //服务端证书
* sslConfig.setServerKeyCertChainPath("D:/ssl/zs/server.crt");
* //服务端私钥
* sslConfig.setServerPrivateKeyPath("D:/ssl/zs/server.key");
* //CA根证书
* sslConfig.setServerTrustCertCollectionPath("D:/ssl/zs/ca.crt");
* //客户端证书
* sslConfig.setClientKeyCertChainPath("D:/ssl/zs/client.crt");
* //客户端私钥
* sslConfig.setClientPrivateKeyPath("D:/ssl/zs/client.key");
* //CA根证书
* sslConfig.setClientTrustCertCollectionPath("D:/ssl/zs/ca.crt");
*/
SslConfig sslConfig = new SslConfig();
//服务端证书
sslConfig.setServerKeyCertChainPath(serverKeyCertChainPath);
//服务端私钥
sslConfig.setServerPrivateKeyPath(serverPrivateKeyPath);
//CA根证书
sslConfig.setServerTrustCertCollectionPath(serverTrustCertCollectionPath);
//客户端证书
sslConfig.setClientKeyCertChainPath(clientKeyCertChainPath);
//客户端私钥
sslConfig.setClientPrivateKeyPath(clientPrivateKeyPath);
//CA根证书
sslConfig.setClientTrustCertCollectionPath(clientTrustCertCollectionPath);
return sslConfig;
}
}
然后将该maven依赖加到需要dubbo ssl的服务。在启动类加上该公共包的扫描
@ComponentScan(basePackages = {"com.vianstats.capp.commom.dubbo.auth",})
并在application.properties的文件上加上ssl开启的配置,也将证书的路径配置到application.properties上
# dubbo 协议
dubbo.protocol.id=dubbo
dubbo.protocol.name=dubbo
# dubbo 协议端口( -1 表示自增端口,从 20880 开始)
dubbo.protocol.port=-1
#开启ssl
dubbo.protocol.sslEnabled=true
#以下的配置地址都是绝对地址,上线部署时请根据证书存放的位置修改该路径,本地开发的时候也需要修改证书的位置
dubbo.protocol.ssl.server-key-cert-chain-path=D:/ssl/zs/server.crt
dubbo.protocol.ssl.server-private-key-path=D:/ssl/zs/server.key
dubbo.protocol.ssl.server-trust-cert-collection-path=D:/ssl/zs/ca.crt
dubbo.protocol.ssl.client-key-cert-chain-path=D:/ssl/zs/client.crt
dubbo.protocol.ssl.client-private-key-path=D:/ssl/zs/client.key
dubbo.protocol.ssl.client-trust-cert-collection-path=D:/ssl/zs/ca.crt
大功告成,测试了没问题。有问题欢迎指出,一起沟通学习。
更多推荐
所有评论(0)