2016-08-11 74 views
0

我有HaProxy終止SSL並將請求傳遞迴清漆,然後服務於緩存頁面或Nginx請求。但是,Varnish似乎將HaProxy的請求視爲HTTP/1而不是HTTP/2,並且無法提供服務。強制清漆使用代理協議1

我可以在Nginx的看到記錄以下當我嘗試打一個頁面:

" while reading PROXY protocol, client: 127.0.0.1, server: 127.0.0.1:8181 
2016/08/11 06:53:31 [error] 5682#0: *1 broken header: "GET/HTTP/1.1 
Host: www.example.com 
User-Agent: curl/7.50.2-DEV 
Accept: */* 
X-Forwarded-For: IP_Removed 
Accept-Encoding: gzip 
X-Varnish: 32777 

我發現的東西,涉及到這個here其中指出,這樣做的原因是,Nginx的不使用v2 PROXY only v1。所以,由於這個原因,我強制使用發送代理而不是send-proxy-v2交換機在HaProxy中使用協議1。但是當它變成清漆時,我認爲清漆會以某種方式將其轉換爲協議2,從而導致它無法與Nginx正常通信。

我已經從等式中刪除了清漆,並將HaProxy直接連接到Nginx,並通過HTTP/2完美工作。問題是在Varnish堆棧中發生了一些事情,可能的懷疑是Varnish使用的代理協議v2。

因此,長話短說,我該如何強制Varnish堅持使用PROXY1而不是PROXY2協議?我已經嘗試將PROXY1添加到啓動守護進程選項中,但Varnish不會接受該選項。任何幫助表示讚賞。謝謝!

更新 - 我在HaProxy後端使用send-proxy-v2開關測試了HaProxy> Nginx,並且在將Varnish引入堆棧時導致相同的問題。切換回HaProxy上的發送代理可以解決問題。所以,我確信問題是使用協議2而不是協議1的Varnish。但是如何告訴它不要?

+0

你確定你是在談論HTTP/2?這與PROXY v2協議無關。 Varnish不會說HTTP/2,它會在Varnish 5.x中引入。 –

+0

也許我對自己感到困惑,但我的理解是,當處理HTTP/2時,HaProxy作爲TCP而不是HTTP,因此有必要在後端使用send-proxy。 Nginx設置爲通過proxy_protocol開關接收此信息。我瞭解Varnish不是HTTP/2或者是SSL,但它應該將協議傳回給Nginx否? – d1ch0t0my

回答

1

據我所知,Varnish不是HTTP/2,或者做SSL,但它應該將協議傳回給Nginx否?

但首先,讓我們澄清。 HTTP/2和代理協議V2完全沒有關係。從你的頭腦中刪除HTTP/2,因爲這在任何意義上都不適用。

你的問題,其實,這樣的:

如果HAProxy的派遣代理協議V1至光油和Nginx的配置背後光油期望代理協議V1,爲什麼Nginx的抱怨破頭? Varnish是否不將代理協議V1轉發到後端?是否由於某種原因發送代理協議V2,而不是?

而對這個問題的答案是,清漆不發送任何一個。 V1和V2都不是。

您需要使用代理協議的唯一方法是,HTTP感知組件可以從上游的非HTTP感知組件(例如HAProxy)使用mode tcp或Amazon ELB接收客戶端IP地址(和端口)監聽器處於TCP模式,其中任何一種通常都是爲您進行SSL卸載,而不是HTTP請求路由,因此它需要另一種傳遞客戶端地址的機制。

第一個支持HTTP的組件可以獲取該地址並將其設置在HTTP標頭中,通常爲X-Forwarded-For,這是爲了堆棧中其餘組件的益處。因此,Varnish沒有理由向前轉發代理協議。在你的例子中沒有這樣做,並且沒有明顯的原因爲什麼Varnish甚至能夠轉發代理協議。 ¹

這使我們發現錯誤。您錯誤診斷了Nginx正在報告的問題。錯誤的頭錯誤意味着Nginx正在接收除代理協議V1之外的其他內容。隨着光環在循環中,在Nginx的請求中沒有代理協議頭² - 並且當監聽器被配置爲期望代理協議頭時,該頭是強制性的

如果組件配置爲期望代理協議V1並且它不存在,那就是總是出錯。但「不存在」意味着這一點。 V1頭不存在。這並不意味着V2是。事實並非如此。

所以,我相信這個問題是清漆使用協議2,而不是1協議

您已經說服自己不正確。代理V2轉換爲Nginx - 正如您已經嘗試使用HAProxy - 是一個錯誤,並且根本沒有代理協議頭 - 就像您從Varnish看到的那樣 - 是一個錯誤,如上所述。兩者都是錯誤配置,但類型不同。你在這裏所做的是重複錯誤,但出於完全不同的原因。

如果您通過Varnish發送所有請求,則配置Varnish以使用從傳入的代理協議機箱中獲知的信息在轉發的請求中設置X-Forwarded-For。從Nginx配置中刪除代理協議。

或者將HAProxy配置爲以HTTP模式運行,並讓其使用option forwardfor插入標頭。


¹顯然,從錯誤,光油只是發送普通的HTTP頭 - 沒有什麼看起來像代理協議。我不認爲它甚至支持將代理協議發送到原始服務器的選項,但如果我忽略了該功能,有人會說。

²我會斷言代理協議「頭」沒有正確地稱爲頭,給出了什麼意思。這是一個序言,而不是標題,儘管它不幸被稱爲標準中的「標題」。這當然不是HTTP標題。

0

如果升級清漆5.0,可以通過設置」 .proxy_header = 1" SEND代理協議版本1至NGINX