【问题标题】:Mutual Authentication in Cloud Foundry Application with NodeJS+express使用 NodeJS+express 在 Cloud Foundry 应用程序中进行相互身份验证
【发布时间】:2018-09-14 09:21:27
【问题描述】:

我开发了一个 NodeJs+express 应用程序,部署为 IBM Cloud 中的 Cloud Foundry 应用程序。 我想执行相互身份验证(客户端和服务器证书)以控制传入流量和对我的应用程序的请求。我的证书由 Secure Gateway 生成,如 here 所述,我的应用程序配置为云目标(可从本地客户端访问)。

安全网关已生成以下 pem 文件:服务器的主证书、中间证书和根证书以及目标证书和密钥。 在文档中有一个非常清晰的Nodejs example 使用 tls.createServer。

在我的场景中存在一些差异: 首先,我处于相反的情况(本地客户端通过创建隧道的安全网关连接到云应用程序)。 其次,这也是这篇文章的主要原因,我的应用被部署为 CF 应用。

阅读关于 HTTP routing 的 CF 文档我发现 IBM 云仅使用端口 80 和 443,然后通过 HTTP 将请求转发到应用程序正在侦听的端口(例如,如果我的 NodeJs 在端口 6001 上运行,而我在端口 443 上调用云端点,GoRouter 将通过 HTTP 将请求转发到正确的端口,添加 X-Forwarded-Proto 标头以将用于请求的原始协议的信息传递给应用程序。

考虑到这一点(假设这是正确的),在我的 NodeJs 代码中,我不能使用像 https.createServer(opts, app) 这样的东西,因为所有到达 App Container 的请求都将通过 HTTP。

阅读 CF 文档here 我知道可以告诉 CF 将证书转发给我的应用程序,但有些东西我无法真正理解。

首先,在负载均衡器或 GoRouter 终止 TLS 有什么区别?这种选择背后的原因是什么?

我的第二个问题是,将证书作为 HTTP 标头转发到我的应用程序后,哪种方法才是正确的处理方式?这是因为我的 NodeJs 服务器将是一个 http 服务器,使用 express 以标准方式 http.createServer(app) 创建。

感谢所有帮助我解决这个问题的人。显然,如果您有任何示例或建议,那将非常有帮助。

【问题讨论】:

    标签: node.js express ssl cloud-foundry mutual-authentication


    【解决方案1】:

    阅读有关 HTTP 路由的 CF 文档我发现 IBM 云仅使用端口 80 和 443,然后通过 HTTP 将请求转发到应用程序正在侦听的端口(例如,如果我的 NodeJs 在端口 6001 上运行并且我调用443 端口上的云端点,GoRouter 将通过 HTTP 将请求转发到正确的端口,添加 X-Forwarded-Proto 标头以将用于请求的原始协议的信息传递给应用程序。

    考虑到这一点(假设这是正确的),在我的 NodeJs 代码中,我不能使用 https.createServer(opts, app) 之类的东西,因为所有到达 App Container 的请求都将通过 HTTP。

    没错。

    首先,在负载均衡器或 GoRouter 终止 TLS 有什么区别?这种选择背后的原因是什么?

    这仅适用于您运行自己的 Cloud Foundry 平台的情况。如果您将应用程序部署到由其他人运营的 Cloud Foundry 平台,他们将做出此决定,并且不会影响您作为用户。

    作为运营商,这是您需要做出的选择。根据您的选择,需要进行一些取舍。

    1. 您可以在 LB 终止。这通常是最快的,因为 LB 在处理 TLS/SSL 方面非常有效。然后,LB 可以将未加密的流量转发到 Gorouter,这减少了 Gorouter 的工作量,但代价是不加密两者之间的流量(可能不太好,取决于安全要求)。在这种情况下,添加 x-forwarded-* 标头是 LB 的责任。

      浏览器 -> HTTPS -> LB -> HTTP -> Gorouters -> HTTP -> 你的应用

    2. 您可以使用第 4 层 LB 并在您的 Gorouter 之间平衡连接。这使 Gorouter 能够终止 TLS/SSL。他们在这方面效率很高,但不如大多数 LB。这也让你在到 Gorouter 的请求路径中进行加密。在这种情况下,Gorouter 负责添加 x-forwarded-* 标头。

      浏览器 -> HTTPS -> LB -> HTTPS -> Gorouters -> HTTP -> 你的应用

    3. 您可以在 LB 处终止,但在 LB 和 Gorouter 之间打开一个新的 TLS/SSL 会话。这是效率最低的选项,因为它需要终止两个 TLS/SSL 会话,但它在到 Gorouter 的请求路径中提供了加密。它也往往是使用非第 4 层 LB 最灵活的工作,并且它可以允许您的 LB 检查 HTTP 流量,因为您在 LB 处终止会话。在这种情况下,添加 x-forwarded-* 标头是 LB 的责任。

      浏览器 -> HTTPS (session A) -> LB -> HTTPS (session B) -> Gorouters -> HTTP -> 你的应用

    同样,如果您不是在操作 Cloud Foundry 平台,那么您可以忽略这一点。

    我的第二个问题是,将证书作为 HTTP 标头转发到我的应用程序后,哪种方法才是正确的处理方式?这是因为我的 NodeJs 服务器将是一个 http 服务器,使用 express 以标准方式 http.createServer(app) 创建。

    您不需要对创建服务器的方式做任何花哨的事情。您需要做的就是查看 x-forwarded-* 标头并使用它们来做出决定。

    1. 请求是通过 HTTPS 传入的吗?查看x-forwarded-proto,对于 HTTPS 请求应设置为 https,或查看应设置的 x-forwarded-port对于 HTTPS 请求,发送至 443

    2. 是否随请求提供了客户端证书?查看X-Forwarded-Client-Cert。如果它包含证书,则客户端提供了证书。

    3. 客户端的证书有效吗?如果您的应用收到请求,则客户端的证书有效。您知道这一点,因为平台会为您处理该部分。由于平台(LB 或 Gorouter)正在终止 TLS/SSL 连接,因此它有责任验证证书。如果您的应用收到请求并设置了x-forwarded-client-cert,则证书有效。

    4. 我如何根据客户端证书做出授权决策?这有点棘手,但通常你会从 x-forwarded-client-cert 中提取证书,读取/解析它并根据证书内容做出决定(我们知道由于平台是有效的)。您很可能会查看主题名称并将其视为用户名。然后查找该用户的角色或权限。但是,如何处理这取决于您作为开发人员。

    希望有帮助!

    【讨论】:

    • 嗨丹尼尔,首先非常感谢你的回复。你让我更清楚了。我正在尝试检查从我的节点服务器接收到的 http 标头,但我看不到任何x-forwarded-client-cert(但我看到了 x-forwarded-proto 标头)。我使用的是 IBM Cloud 中的 CF。阅读文档后我发现可能需要配置 router.client_cert_validation 只要 enable_ssl 和 client_cert_validation。我应该将这些配置放在清单中吗?我不知道如何更改这些参数,因为我看不出任何区别,XFC 标头仍未定义
    • 如果您是平台操作员,这些将是您进行的配置设置。由于您使用的是 IBM 的平台,因此您需要询问他们的平台是否支持此功能。作为公共云提供商,这可能会很棘手,因为客户端证书需要得到负载均衡器或 Gorouter 的信任。这将要求您的客户端证书由知名 CA 签名,或者您将您的 CA 添加到他们的受信任证书列表中。 Idk,我在猜测。你得问问 IBM。
    • 再次感谢丹尼尔。我试图拥有一个不在应用程序级别的控件,但我不知道这在我的场景中是否可以实现(即在到达我的应用程序之前阻止所有没有特定证书的客户端)。我希望我的负载均衡器(或 GoRouter)拒绝来自没有(特别是不仅受信任的)证书的客户端的每个请求,拒绝握手而根本没有到达我的应用程序。当所有这些情况都清楚时,我会告诉你。
    • 这样不行。平台只会检查客户端的证书是否有效且受信任。它基本上为您进行身份验证。您的应用需要进行授权并确定客户端将获得的访问级别(如果有)。
    • 我发现还存在 $wscs、$wssi、$wssn 等,但 $wscc 标头(用于此请求的客户端证书)未转发到我的节点服务器。我将询问支持我如何检索传入客户端证书的信息。
    猜你喜欢
    • 2020-12-29
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    相关资源
    最近更新 更多