我正在尝试将Amazon API网关放在应用程序负载均衡器之前,这样可以平衡流向我的ECS群集的流量,我的所有微服务都部署在那里。使用API网关的动机是通过lambda函数使用自定义授权程序。
系统图
在亚马逊语中(https://aws.amazon.com/api-gateway/faqs/):“对后端操作的代理请求也需要在Internet上公开访问”。这迫使我让ELB公开(面向互联网)而不是内部。然后,我需要一种方法来确保只有API网关能够访问VPC外部的ELB。
我的第一个想法是在API网关中使用客户端证书,但ELB似乎不支持它。
任何想法都将受到高度赞赏!
考虑到它的推动方式,这似乎是API网关技术的一个巨大缺失部分。无法在VPC中调用面向内部的服务器严重限制了其作为Internet访问的身份验证前端的用途。 FWIW,在Azure中,API Management支持开箱即用 - 它可以接受来自互联网的请求,并直接呼叫您的虚拟网络,否则将被防火墙关闭。在AWS下,这似乎是可行的唯一方法是使用Lambdas,这增加了一层重要的复杂性,尤其是。如果你需要支持各种二进制协议。
我们决定使用标头进行检查,以确保所有流量都通过API网关传输。我们在应用环境变量中保存了一个秘密,并告诉API网关在我们创建API时注入它。然后在我们的应用中检查该密钥。
以下是我们为此所做的事情:
在我们的基本控制器中,我们检查密钥(我们在网关后面只有一个REST API):
string ApiGatewayPassthroughHeader = context.HttpContext.Request.Headers["ApiGatewayPassthroughHeader"];
if (ApiGatewayPassthroughHeader != Environment.GetEnvironmentVariable("ApiGatewayPassthroughHeader"))
{
throw new error;
}
在我们的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}"
}
},
在我们的docker compose文件中(我们使用的是docker,但同样可以在任何设置文件中使用)
services:
example:
environment:
- ApiGatewayPassthroughHeader=9708cc2d-2d42-example-8526-4586b1bcc74d
在构建时,我们从设置文件中获取秘密,并将其替换为swagger.json文件。这样我们就可以在设置文件中旋转密钥,API网关将更新为使用应用程序正在查找的密钥。
目前没有将API网关放在私人ELB面前,所以你必须面向互联网。我能想到的最佳解决方法是将ELB置于TCP传递模式,并在ELB后面的终端主机上终止客户端证书。
现在可以在ECS前面直接向Application Load Balancer(ALB)添加授权程序。
这可以直接在侦听器的规则中配置。有关详细信息,请参阅此博文:
https://aws.amazon.com/de/blogs/aws/built-in-authentication-in-alb/
如果您使用VPC Link和网络负载均衡器,则可以使用。
请看看这篇文章:https://adrianhesketh.com/2017/12/15/aws-api-gateway-to-ecs-via-vpc-link/
TL; DR
希望有所帮助!