如何在AWS上部署ELB背后的API管理器并保留X-Forwarded标头?

时间:2015-06-09 20:18:35

标签: amazon-web-services wso2 amazon-elb api-manager kong

我在AWS上部署了一些RESTfull API,主要是在Elasticbeanstalk上。

我的公司正在逐步采用微服务架构,因此,我想以更专业和自动化的方式开始管理这些API。因此,我想采用某种API管理器来提供标准功能,例如路由和发现。

此外,我希望使用此类API管理器将我的一些API公开给Internet。管理员将仅通过SSL暴露给Internet,并且在将请求路由到内部API之前,应该要求外部使用者进行某种身份验证。对于我的用例,每个请求的Authorization标头中的一个简单的API Key就足够了。

我目前正在考虑将两种产品作为API管理器:WSO2和Kong。前者是在Github上托管的一个新的开源项目。

在我考虑的所有部署方案中,必须在AWS EC2实例上部署API管理器。此外,它们必须至少部署在两个不同的可用区域和Elastic Load Balancer(ELB)之后,以便为托管API提供高可用性。

我的大多数API都遵循HATEOAS约束。因此,他们的许多JSON响应都包含指向其他资源的链接,这些资源必须根据原始请求动态构建。

例如:

如果用户通过公开的API管理器从Internet发送请求,则URL将如下所示: https://apimanager.mycompany.com/accounts/123

因此,用户应该收到一个JSON响应,其中包含一个Account资源,其中包含指向订阅资源的链接。 链接URL应基于原始请求的协议,主机和端口,因此看起来像:https://apimanager.mycompany.com/subscriptions/789

为了满足上述动态链接生成要求,我的API依赖于X-Forwarded-Proto,X-Forwarded-Host和X-Forwarded-Port HTTP头。这些应该包含协议(http或https),主机名和消费者在原始请求中使用的端口,尽管请求传递了多少个代理。

但是,我注意到当请求通过ELB时,X-Forwarded-Proto和X-Forwarded-Port标头被更改为引用请求通过的最后一个ELB的值,而不是指向的值。原始请求。

例如:如果原始请求通过HTTPS访问API Manager,则Manager通过HTTP将请求转发到内部API;因此,当请求命中第二个ELB时,ELB将X-Forwarded-Proto标题改为“http”。结果,X-Forwarded-Proto标头的原始“https”值丢失。因此,API无法使用URL中的“https”协议构建正确的链接。

显然,ELB无法配置为以任何其他方式运行。我在AWS的文档中找不到任何可能影响此行为的设置。

此外,似乎没有任何更好的替代AWS的ELB。如果我选择使用其他产品(如HAProxy),或通过API Manager本身进行负载平衡,我必须将其安装在常规EC2实例上,因此会产生单点故障。

我要包含一张非正式的图表,以便更好地传达我的观点。

Diagram

此外,我找不到任何有关WSO2或Kong的部署方案的相关讨论,以任何方式解决这些问题。我不清楚这些产品应该如何与AWS的ELB相关联。

非常欢迎来自具有类似环境的其他人的评论。

谢谢。

1 个答案:

答案 0 :(得分:1)

有趣的问题/挑战 - 我不知道配置Elastic Load Balancer's X-Forwarded-*标头行为的方法。但是,您可能能够通过利用ELB的listener types的两个支持的网络层的OSI Model来解决此问题:

没有代理协议的TCP / SSL侦听器

不是使用有意终止SSL等的HTTP侦听器(OSI第7层),而是可以为内部负载均衡器使用非侵入式TCP / SSL侦听器(OSI第4层),请参阅{{3 }}:

  

对前端和后端使用TCP(第4层)时   连接,您的负载均衡器将请求转发给后端   没有修改标题的实例。 [...] [强调我的]

我没有尝试过这个,但是在这种情况下,外部HTTP / HTTPS负载均衡器添加的X-Forwarded-*标头将通过内部TCP / SSL负载均衡器不加修改地传递。

具有代理协议的TCP / SSL侦听器

或者,您也可以立即利用更高级/最近的Protocols,有关详情,请参阅介绍性博文Proxy Protocol Support for Your Load Balancer

  

直到今天,ELB只允许您获取客户端IP地址   您使用了HTTP(S)负载平衡,它将此信息添加到   Elastic Load Balancing adds Support for Proxy Protocol标题。由于X-Forwarded-For用于HTTP头   只有,如果ELB是,你无法获得客户端的IP地址   配置为TCP负载平衡。很多人告诉我们你想要的   TCP流量的类似功能,因此我们添加了对Proxy的支持   协议。它只是为客户端添加了一个人类可读的标题   发送到服务器的TCP数据的连接信息。 [...]代理协议是   在提供非HTTP流量时很有用。或者,你可以   如果您要发送HTTPS请求但不想终止,请使用它   负载均衡器上的SSL连接。 [...]

除了X-Forwarded-*标头之外,您可以X-Forwarded-Forenable代理协议处理。另一方面,您的后端层可能尚未自动促进代理协议,因此需要进行相应调整。