在Pivotal Cloud Foundry上设置双向SSL身份验证

时间:2018-06-20 13:29:17

标签: spring-boot ssl pivotal-cloud-foundry mutual-authentication

我有一个任务是在Zuul代理应用程序(客户端)和微服务之一(服务器)之间设置两种方式的SSL身份验证。两者都是Spring Boot应用程序。 我能够使用自签名证书和下一个配置在本地完成此操作:

对于服务器,我在yml文件中设置了SSL:

server:
  port: 8081
  ssl:
    enabled: true
    key-store: classpath:MyServer.jks
    key-store-password: password
    trust-store: classpath:MyServer.jks
    trust-store-password: password
    client-auth: need

对于Zuul代理应用程序,我已经为CloseableHttpClient配置了密钥库和信任库,并配置了所需的证书:

@Bean
    public CloseableHttpClient zuulHttpClient() throws Throwable {
        final KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(keyStore.getInputStream(), keyStorePassword.toCharArray());

        LOGGER.info("Loaded keyStore: " + keyStore.getURI().toString());
        try {
            keyStore.getInputStream().close();
        } catch (final IOException e) {
            LOGGER.warning("IOException during loading keyStore");
        }
        final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(ks, keyStorePassword.toCharArray());


        final KeyStore ts = KeyStore.getInstance("JKS");
        ts.load(trustStore.getInputStream(), trustStorePassword.toCharArray());
        LOGGER.info("Loaded trustStore: " + trustStore.getURI().toString());
        try {
            trustStore.getInputStream().close();
        } catch (final IOException e) {
            LOGGER.warning("IOException during loading trustStore");
        }
        final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(ts);

        final SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(ts, new TrustSelfSignedStrategy()).loadKeyMaterial(ks, keyStorePassword.toCharArray()).build();
        final HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setSSLContext(sslContext);
        return httpClientBuilder.build();
    }

它在本地工作,但是我在PCF上设置它有问题。我能够推送客户端应用程序,但不能推送服务器应用程序。它只是冻结了一段时间,并且无法在PCF上启动,但是日志还可以,但不会引发异常。关闭服务器enabled: false的SSL,让我推送应用程序,所以看起来就是问题所在。

所以我的问题是,是否有任何简便的方法可以直接在PCF上设置2种方式的SSL?我发现了一些与此相关的主题,这些主题涉及配置Gorouter,目前正在阅读有关该主题的文档,但我在考虑是否有更简单明了的解决方案。

1 个答案:

答案 0 :(得分:3)

当前,当您在Cloud Foundry上运行应用程序时,它们从不监听HTTPS请求。他们总是在分配的端口上侦听HTTP请求。 HTTPS由GoRouter或您公司的负载平衡器在上游进行处理。 HTTPS信息通过x-forwarded-*标头传播到您的应用程序。这意味着您无需在Spring Boot应用程序中使用server.ssl.enabled,也无需担心会提供任何证书。

如果您想处理mTLS,会有些棘手。您可以让上游LB或GoRouter为您处理此问题。以类似于x-forwarded-*的方式,它验证客户端证书并确保其受信任。如果不受信任,则连接将失败。如果受信任,它将通过HTTP标头X-Forwarded-Client-Cert向您传递证书信息。至此,您知道该证书是有效且受信任的,并且可以进一步使用该证书信息来选择授权和访问权限。

此处有更多相关信息:https://docs.pivotal.io/pivotalcf/2-1/adminguide/securing-traffic.html#gorouter_mutual_auth

该平台还为每个应用程序实例管理和分配证书。您可以使用这些证书来标识您的客户。有关更多信息,请点击此处:https://docs.pivotal.io/pivotalcf/2-1/devguide/deploy-apps/instance-identity.html

如果您的运营商为您进行了所有设置,则可以使执行mTLS更加容易。如果您正在进行应用程序到应用程序的通信,那么您实际上不必对证书进行任何操作,该平台会为您提供并验证它们。如果您的客户端不在连接的平台上,这将更加棘手,因为您必须给他们提供证书,而您的运营商必须配置平台以信任他们。不过,仍然可以完成此操作,并且您的应用无需更改即可支持。


开关装置。如果您真的想使用传统方法,则可以这样做。我知道我在上面暗示了这是不可能的。以上信息适用于HTTP路由,不适用于HTTP路由。如果您为应用程序使用TCP路由,则可以使用。使用TCP路由,您的应用程序仅获取TCP数据包,因此可以对它们执行任何操作。这包括执行HTTPS。如果这是您想要的,则取决于应用程序来处理TLS。该平台仅将TCP数据包路由到您的应用程序,其余的由应用程序完成。

这意味着您需要提供服务器证书,客户端证书,并配置您的应用程序/服务器以对其进行验证。它与本地设置或传统服务器设置非常相似。通过这种方法,该平台对您几乎无济于事。

这里有一个部分描述创建TCP路由。这很简单,并且与HTTP路由相同,但是只是用于设置端口的附加标志。

https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#create-route

您还可以在此处进一步了解HTTP和TCP路由之间的区别:https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#http-vs-tcp-routes

希望有帮助!