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



我有一个任务是在 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,目前正在阅读有关此主题的文档,但正在考虑是否有更简单和清晰的解决方案。

目前,当您在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

希望对您有所帮助!

最新更新