使用Spring Cloud Netflix Eureka进行安全发现

点击左上角,关注:“锅外的大佬”

专注分享国外最新技术内容

帮助每位开发者更优秀地成长

640?wx_fmt=png

构建基于Spring Cloud Netflix Eureka的标准发现机制相当容易。在发现客户端和服务器之间通过安全SSL通信构建的相同解决方案可能是稍微更先进的挑战。然而我没有在网上找到相关这样的应用程序的完整示例。让我们尝试从服务器端应用程序开始实现它。

1.生成证书

如果您开发Java应用程序已有几年了,您可能已经听说过keytool。此工具位于您的 ${JAVA_HOME}\bin目录中,用于管理密钥和证书。我们认为服务器端SpringBoot应用程序生成密钥库开始。这是适当的keytool命令,在JKS密钥存储文件中生成名为eureka.jks的证书。640?wx_fmt=png

2.设置安全发现服务器

由于Eureka服务器嵌入到Spring Boot应用程序中,我们需要使用标准的Spring Boot属性来保护它。我将生成的密钥库文件eureka.jks放在应用程序的类路径上。现在,唯一需要做的就是在 application.yml该配置文件内准备一些配置,设置到密钥库文件的位置,类型和访问密码。

server:	
  port: 8761	
  ssl:	
    enabled: true	
    key-store: classpath:eureka.jks	
    key-store-password: 123456	
    trust-store: classpath:eureka.jks	
    trust-store-password: 123456	
    key-alias: eureka

3.设置双向SSL身份验证

我们会稍微复杂一下我们的例子。标准SSL配置假定只有客户端验证服务器证书。我们将在服务器端强制进行客户端的证书身份验证。它可以通过设置属性 `server.ssl.client-auth为`need```来实现。

server:	
  ssl:	
    client-auth: need

并非全部,因为我们还必须将客户端的证书添加到服务器端的可信证书列表中。因此,首先让我们使用与服务器密钥库相同的keytool命令生成客户端的密钥库。

640?wx_fmt=png

现在,我们需要从客户端和服务器端的生成密钥库中导出证书。

640?wx_fmt=png

最后,我们将客户端的证书导入服务器的密钥库,并将服务器的证书导入客户端的密钥库。

640?wx_fmt=png

4.运行安全的Eureka服务器

示例应用程序可在GitHub上的repository sample-secure-eureka-discovery中获得。运行服务发现应用程序,Eureka的地址是localhost:8761 如果你/您尝试访问它的web仪表板,则在Web浏览器中你将得到如下异常。这意味着Eureka服务器是安全的。

640?wx_fmt=png

好吧,Eureka仪表板有时是一个有用的工具,所以让我们将客户端的密钥库导入我们的Web浏览器以便能够访问它。我们必须将客户端的密钥库从JKS转换为PKCS12格式。这是执行上述操作的命令

$ keytool -importkeystore -srckeystore client.jks -destkeystore client.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass 123456 -deststorepass 123456 -srcalias client -destalias client -srckeypass 123456 -destkeypass 123456 -noprompt

5.客户端的应用程序配置

在客户端实现安全连接时,我们通常需要执行与上一步相同的操作 - 导入密钥库。但是,这并不是一件非常简单的事情,因为Spring Cloud不提供任何允许您将SSL密钥库的位置传递给发现客户端的配置属性。值得一提的是,Eureka客户端利用Jersey客户端与服务器端应用程序进行通信。它不是Spring RestTemplate, 这可能有点令人惊讶,但我们应该记住,Spring Cloud Eureka是建立在Netflix OSS Eureka客户端之上的,它不使用Spring库。 如果您将安全凭证包含在连接URL中,则HTTP基本身份验证会自动添加到您的eureka客户端 例如 http://piotrm:12345@localhost:8761/eureka)对于更高级的配置,例如将SSL密钥库传递给HTTP客户端,我们需要提供DiscoveryClientOptionalArgs类型的Bean。以下代码片段显示了如何为发现客户端启用SSL连接。首先,我们使用javax.net.ssl.*Java系统属性设置密钥库和信任库文件的位置。然后,我们基于Java SSL设置提供Jersey客户端的自定义实现,并将其设置为 DiscoveryClientOptionalArgsbean。

@Bean	
public DiscoveryClient.DiscoveryClientOptionalArgs discoveryClientOptionalArgs() throws NoSuchAlgorithmException {	
    DiscoveryClient.DiscoveryClientOptionalArgs args = new DiscoveryClient.DiscoveryClientOptionalArgs();	
    System.setProperty("javax.net.ssl.keyStore", "src/main/resources/client.jks");	
    System.setProperty("javax.net.ssl.keyStorePassword", "123456");	
    System.setProperty("javax.net.ssl.trustStore", "src/main/resources/client.jks");	
    System.setProperty("javax.net.ssl.trustStorePassword", "123456");	
    EurekaJerseyClientBuilder builder = new EurekaJerseyClientBuilder();	
    builder.withClientName("account-client");	
    builder.withSystemSSLConfiguration();	
    builder.withMaxTotalConnections(10);	
    builder.withMaxConnectionsPerHost(10);	
    args.setEurekaJerseyClient(builder.build());	
    return args;	
}

6.在客户端启用HTTPS

上一步中提供的配置仅适用于发现客户端和Eureka服务器之间的通信。如果我们还希望保护客户端应用程序公开的HTTP端点,该怎么办?第一步与发现服务器完全相同:我们需要生成密钥库并使用内部的Spring Boot属性进行设置 application.yml

server:	
  port: ${PORT:8090}	
  ssl:	
    enabled: true	
    key-store: classpath:client.jks	
    key-store-password: 123456	
    key-alias: client	
}

在注册期间,我们需要“通知”Eureka服务器我们的应用程序的端点是安全的。为了实现它,我们应该将属性设置eureka.instance.securePortEnabled为true,并禁用非安全端口,该端口默认情况下由nonSecureporttenabled属性启用。

eureka:	
  instance:	
    nonSecurePortEnabled: false	
    securePortEnabled: true	
    securePort: ${server.port}	
    statusPageUrl: https://localhost:${server.port}/info	
    healthCheckUrl: https://localhost:${server.port}/health	
    homePageUrl: https://localhost:${server.port}	
  client:	
    securePortEnabled: true	
    serviceUrl:	
      defaultZone: https://localhost:8761/eureka/

7.运行客户端的应用程序

最后,我们可以运行客户端应用程序。启动后,应在Eureka Dashboard中显示该应用程序。

640?wx_fmt=png

所有客户端应用程序的端点都在Eureka的HTTPS协议下注册。我还覆盖了执行器端点的默认实现/info,如下面的代码片段所示。

@Component	
public class SecureInfoContributor implements InfoContributor {	
    @Override	
    public void contribute(Builder builder) {	
        builder.withDetail("hello", "I'm secure app!");	
    }	
}

现在,我们可以尝试再次访问/info端点。您应该看到与以下相同的信息。640?wx_fmt=png

或者,如果您尝试在客户端设置服务器端不信任的证书,则在启动客户端应用程序时将看到以下异常。

640?wx_fmt=png

8.结论

保护微服务和Eureka服务器之间的连接只是保护整个系统的第一步。我们需要关于微服务和配置服务器之间的安全连接,以及与 @LoadBalanced RestTemplateOpenFign客户端进行服务间通信期间的所有微服务之间的安全连接。你可以在我的书“掌握Spring Cloud”中找到这样的实现的示例,以及更多。

原文链接:https://piotrminkowski.wordpress.com/2018/05/21/secure-discovery-with-spring-cloud-netflix-eureka/

作者:PiotrMińkowski

译者:Yunooa 


推荐阅读:Spring Cloud Kubernetes指南

上篇好文:Spring Cloud : Turbine


640?wx_fmt=png


点击在看,和我一起帮助更多开发者!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值