2017-03-20 118 views
1

目標是在簡單堆棧中包含HTTP/2支持:部署在多個EC2實例中的web應用+啓用PROXY協議策略的傳輸級CLB(SSL :443➝TCP:80),以卸載SSL/TLS並平衡傳入的HTTPS流量。 (1)地理定位邏輯的執行;(2)地理定位邏輯的執行;(2) (2)執行簡單的訪問控制規則;和(3)記錄。所有這些功能都需要訪問可靠的(即不可微不足道的)客戶端IP地址。 AWS中PROXY協議的唯一替代方案是切換到應用程序級平衡並使用XFF標頭提取客戶端的遠程IP地址。然而,這是不可接受的:任何人都可以簡單地改變其IP地址,只需在傳入的HTTPS請求中注入假XFF頭。 AFAIK,AWS CLBs/ELBs不會注入包含客戶端遠程IP的標頭(例如類似the True-Client-IP header in Akamai的東西)。AWS CLB/ELB + HTTP/2支持

因此,如何將H2支持添加到堆棧?經過一番研究所有可能的選項看起來不能令人滿意:因爲SSL/TLS在CLB終止

  • 目前的架構是無效的,但CLB不提供任何選項announce H2 support through ALPN

  • 使用CLB的替代方法是停止使用SSL/TLS卸載功能並將其移至EC2實例(即TCP:443➝TCP:443)。這種方式可以在SSL/TLS握手期間宣佈H2支持,但該選項需要升級EC2實例以支持額外的SSL/TSL工作負載。類似的替代品:

    • TCP:443➝SSL:443:類似於TCP:443➝TCP:443,但允許使用值得信賴的公鑰證書的列表,後臺認證。
    • SSL:443➝SSL:443:類似於TCP的端到端加密:443➝SSL:443。不是一個真正的選擇:(1)PROXY協議是not supported for this combination(並且使用XFF也不是一個選項,因爲這是傳輸級別平衡);和(2)客戶端SSL/TLS握手在CLB中執行,所以H2不會被公佈。
  • 其他選項將由一個ELB(HTTPS➝HTTP)被替換CLB。 ELB支持H2。但是(1)我們需要依靠XFF來提取客戶端IP地址(已經解釋了爲什麼這是一個問題); (2)ELB和EC2實例之間的流量爲H1(我們希望未加密的H2流量到達EC2實例)。換句話說,這不是一個選項。

總之,所有選項都有問題。恕我直言,理想的解決方案是保持原始CLB(SSL:443➝TCP:80;平衡+ SSL/TLS卸載+ PROXY協議),並允許CLB中的策略通過ALPN宣佈H2支持。但是,我擔心這在AWS中是不可能的。 CLB TCP的任何替代方案:443➝TCP:443方法?

回答

2

這個答案沒有提供明智的解決方案,因爲可能沒有一個,但我相信您在理解AWS Application Load Balancer(ALB,也稱爲ELB/2.0)方面存在差距。

任何人都可以簡單地改變它的IP地址,只需在傳入的HTTPS請求中注入一個假的XFF頭。 AFAIK,AWS CLBs/ELBs不注入包含客戶端遠程IP的標頭

這兩個數字都不正確。

客戶端的遠程IP是X-Forwarded-For中最右邊的IP地址,由平衡器發送到實例。這不能被欺騙。如果客戶端在XFF中包含一個或多個地址,則根據處理HTTP標頭的規則(從左到右,首先到最後),它們由平衡器標準化到單個標頭,並且它們出現在實際的左側客戶端IP。

請求示例:我注射2欺騙X-Forwarded-For頭到請求,一個有2個值,一個具有1 ...這裏是捲曲發:

$ curl -v http://cx-xxxxxxxx-xxxx-xxxxxxxxxx.us-east-1.elb.amazonaws.com/test/dump/headers \ 
     -H 'X-Forwarded-For: 192.168.254.252, 10.10.10.10' \ 
     -H 'X-Forwarded-For: 172.16.16.16' 
* Hostname was NOT found in DNS cache 
* Trying 52.x.x.x... 
* Connected to cx-xxxxxxxx-xxxx-xxxxxxxxxx.us-east-1.elb.amazonaws.com (52.x.x.x) port 80 (#0) 
> GET /test/dump/headers HTTP/1.1 
> User-Agent: curl/7.35.0 
> Host: cx-xxxxxxxx-xxxx-xxxxxxxxxx.us-east-1.elb.amazonaws.com 
> Accept: */* 
> X-Forwarded-For: 192.168.254.252, 10.10.10.10 
> X-Forwarded-For: 172.16.16.16 
> 
< HTTP/1.1 200 OK 

但這裏是我的情況下看到的是:

GET /test/dump/headers HTTP/1.1 
X-Forwarded-For: 192.168.254.252, 10.10.10.10, 172.16.16.16, 203.0.113.1 
X-Forwarded-Proto: http 
X-Forwarded-Port: 80 
Host: cx-xxxxxxxx-xxxx-xxxxxxxxxx.us-east-1.elb.amazonaws.com 
X-Amzn-Trace-Id: Root=1-58d0704b-557517de784f5exxxxxxxxxx 
User-Agent: curl/7.35.0 
Accept: */* 

我發送的報頭已被平衡器和X-Forwarded-For最右邊的值規已通過平衡器增加 - 這就是我跑捲曲機的IP地址,即成立傳入的連接。 ¹

這就是它總是與ALB一起工作的方式。如果客戶端提供了任何XFF,那麼當然不會信任這些XFF(儘管您仍然應該記錄或保存它們,因爲如果客戶端使用的是正確識別客戶端的代理服務器,它們可能會很有用),但最後一個在右邊總是將外部機器的地址從外部建立到ALB的連接。

這就是你總是從標題底部開始,然後從右到左解釋X-Forwarded-For:的方式,因爲這就是任何正常行爲的代理(在這種情況下,ALB會處理它們)的方式 - - 通過將其客戶端的IP地址(從其網絡堆棧報告)附加到右邊(或通過在其他任何其他地方添加額外的X-Forwarded-For頭部 - 任何一種方式在語義上有效,但ALB不使用後一種方法)。在解析時,當你遇到不屬於你自己的地址的第一個地址時,你就會停止 - 這是你可以信任的唯一地址。另外,如果客戶端在使用http連接時注入X-Forwarded-Proto: https-嘗試欺騙時已經與平衡器建立安全連接(當它們實際上並沒有連接時),則ALB將其丟棄。該實例只能看到事實:X-Forwarded-Proto: http


此外,你可能會忽視了同時連接到與HTTP/1.1的情況下,平衡做別的東西的事實,是相當有用的:

您可以使用HTTP/2 HTTPS監聽器。您可以使用一個HTTP/2連接並行發送多達128個請求。負載均衡器將這些請求轉換爲單獨的HTTP/1.1請求,並使用循環路由算法將其分發到目標組中的健康目標。

http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html

據我估計,這種能力需要負載均衡到一個全新的水平概念。在這裏我跑捲曲機的


¹ IP地址。敏感的觀察者會注意到這實際上是一個從RFC-5737的IP地址,但它在家裏被報告給我的IP地址。除了消毒目的外,我沒有另外更改實例所看到的請求標頭。否則,在這裏,原始的順序和內容被精確地保留下來。

+0

關於XFF欺騙部分:您對此絕對正確,您的解釋對於應用程序級CLB也是如此。這意味着我的問題中的PROXY協議要求並不重要(儘管我仍然喜歡傳輸級負載平衡的想法)。 –

+0

關於H2部分:我知道ELB在使用H2時的好處和 - 現在我知道XFF不能被欺騙 - 我同意ELBs是爲了添加H2支持而保持SSL/TLS在LB中卸載的方式。就個人而言,我寧願在傳輸級別的LB中進行SSL/TLS卸載,讓未加密的H2到達EC2實例,但恐怕這個選項根本不存在。 –