ELB和ECS群集前的Amazon API网关

Ric*_*tín 24 amazon-web-services amazon-ecs amazon-elb aws-api-gateway

我正在尝试将Amazon API网关放在应用程序负载均衡器之前,这样可以平衡流向我的ECS群集的流量,我的所有微服务都部署在那里.使用API​​网关的动机是通过lambda函数使用自定义授权程序.

系统图

在此输入图像描述

在亚马逊语中(https://aws.amazon.com/api-gateway/faqs/):" 对后端操作的代理请求也需要在Internet上公开访问 ".这迫使我让ELB公开(面向互联网)而不是内部.然后,我需要一种方法来确保只有 API网关才能访问VPC外部的ELB.

我的第一个想法是在API Gatway中使用客户端证书,但ELB似乎不支持它.

任何想法都将受到高度赞赏!

Dyl*_*son 12

考虑到它的推动方式,这似乎是API网关技术的一个巨大缺失部分.无法在VPC中调用面向内部的服务器严重限制了其作为Internet访问的身份验证前端的用途.FWIW,在Azure中,API Management支持开箱即用 - 它可以接受来自互联网的请求,并直接呼叫您的虚拟网络,否则将被防火墙关闭.在AWS下,这似乎是可行的唯一方法是使用Lambdas,这增加了一层重要的复杂性,尤其是.如果你需要支持各种二进制协议.


Dyl*_*son 6

看起来现在已经添加了这种支持。还没有测试,YMMV:

https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-api-gateway-supports-endpoint-integrations-with-private-vpcs/

  • 顺便说一句,我最终尝试了这个,是的,它确实有效,但它几乎不是超级方便 - 一开始,您只能让 API 网关与网络负载均衡器通信,而不是应用程序负载均衡器,因此,如果您当前设置了面向外部的 ALB网关正在与之通信,您需要将它们替换为网络负载平衡器(这意味着您将丢失 SSL 终止以及您可能会或可能不会使用的各种其他选项)或在 ALB 前面添加一个 NLB,这现在只能是内部的。此外,将现有路由从“HTTP”更改为“VPC 链接”并非完全无缝。 (7认同)
  • @JoshEdwards 有一篇博文 [here](https://aws.amazon.com/blogs/networking-and-content-delivery/using-static-ip-addresses-for-application-load-balancers/) 如果你还是有兴趣 (3认同)
  • 关于如何在 ALB 前设置 NLB 的任何建议? (2认同)

Cal*_*ale 5

我们决定使用标头进行检查,以确保所有流量都通过 API 网关传输。我们在应用程序环境变量中保存一个秘密,并告诉 API 网关在创建 API 时注入该秘密。然后在我们的应用程序中检查该密钥。

以下是我们正在做的事情:

在我们的基本控制器中,我们检查密钥(我们在网关后面只有一个 REST API):

string ApiGatewayPassthroughHeader = context.HttpContext.Request.Headers["ApiGatewayPassthroughHeader"];

if (ApiGatewayPassthroughHeader != Environment.GetEnvironmentVariable("ApiGatewayPassthroughHeader"))
{
    throw new error;
}
Run Code Online (Sandbox Code Playgroud)

在我们的 swagger 文件中(我们使用 swagger.json 作为 API 的来源)

"x-amazon-apigateway-integration": {
    "type": "http_proxy",
    "uri": "https://${stageVariables.url}/path/to/resource",
    "httpMethod": "post",
    "requestParameters": {
      "integration.request.header.ApiGatewayPassthroughHeader": "${ApiGatewayPassthroughHeader}"
    }
  },
Run Code Online (Sandbox Code Playgroud)

在我们的 docker compose 文件中(我们正在使用 docker,但同样可以在任何设置文件中使用)

services:
  example:
      environment:
        - ApiGatewayPassthroughHeader=9708cc2d-2d42-example-8526-4586b1bcc74d
Run Code Online (Sandbox Code Playgroud)

在构建时,我们从设置文件中获取秘密并将其替换到 swagger.json 文件中。这样我们就可以轮换设置文件中的密钥,API 网关将更新以使用应用程序正在查找的密钥。


小智 1

目前还没有办法将 API Gateway 放在私有 ELB 前面,所以你是对的,它必须面向互联网。我能想到的针对您的情况的最佳解决方法是将 ELB 置于 TCP 直通模式并终止 ELB 后面的终端主机上的客户端证书。