前面已經詳細介紹了Haproxy基礎知識 , 今天這裡再贅述下Haproxy的重定向跳轉的設定. haproxy利用acl來實現haproxy動靜分離,然而在許多運維應用環境中,可能需要將訪問的站點請求跳轉到指定的站點上,比如客戶單端訪問kevin.a.com需要將請求轉發到bobo.b.com或將http請求重定向到https請求,再比如當客戶端訪問出錯時,需要將錯誤code程式碼提示請求到指定的錯誤頁面,諸如此類需求實現,這種情況下就需要利用haproxy的重定向功能來達到此目的。
Haproxy是一款提供高可用性、負載均衡以及基於TCP(第四層)和HTTP(第七層)應用的代理軟體,支援虛擬主機,它是免費、快速並且可靠的一種解決方案。 Haproxy特別適用於那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。Haproxy執行在時下的硬體上,完全可以支援數以萬計的 併發連線。並且它的執行模式使得它可以很簡單安全的整合進您當前的架構中, 同時可以保護你的web伺服器不被暴露到網路上。
Haproxy實現了一種事件驅動、單一程式模型,此模型支援非常大的併發連線數。多程式或多執行緒模型受記憶體限制 、系統排程器限制以及無處不在的鎖限制,很少能處理數千併發連線。事件驅動模型因為在有更好的資源和時間管理的使用者端(User-Space) 實現所有這些任務,所以沒有這些問題。此模型的弊端是,在多核系統上,這些程式通常擴充套件性較差。這就是為什麼他們必須進行優化以 使每個CPU時間片(Cycle)做更多的工作。
Haproxy支援連線拒絕 : 因為維護一個連線的開啟的開銷是很低的,有時我們很需要限制攻擊蠕蟲(attack bots),也就是說限制它們的連線開啟從而限制它們的危害。 這個已經為一個陷於小型DDoS攻擊的網站開發了而且已經拯救了很多站點,這個優點也是其它負載均衡器沒有的。
一. Haproxy實現request請求重定向
關於Hproxy 請求重定向主要會用到: redirect 和 redir 這兩類重定向配置語法。
1) redirect重定向用法: (redirect通常配置在haproxy acl部分)
redirect一般有兩個指令來執行HTTP重定向:
http-requets redirect #此種方式支援日誌變數格式
redirect #此種方式只依賴於靜態字串
這兩個指令的語法是相同的,即redirect現在被認為是傳統和配置應該移動到http-request redirect形式。
還有一個主要區別是:http-request redirect使用日誌可變格式, 而redirect語句只依賴於靜態字串。
2) redirect三種重定向方式
a) 位置重定向
使用語法如下:
redirect location <loc> [code <code>] <option> [{if | unless} <condition>]
使用位置重定向,例如下面所示指令可以將使用者重定向到所提供的精確位置, 該位置可以是第三方URL連結,也可以是本地web服務的另一個訪問路徑.
1. http-request redirect location <loc> [code <code>] [<option>] [<condition>]
2. redirect location <loc> [code <code>] [<option>] [<condition>]
相關指令引數如下:
* <loc> :一個日誌格式變數 (或簡單的字串redirect語句)描述了新位置;
* code <code>(可選):HTTP重定向的狀態程式碼來執行。 此選項下的允許的狀態碼如下所示:
* <option>(可選): 可以是以下任何或組合的宣告:
1. set-cookie NAME[=value] :一個Set-Cookie頭部被新增到重定向。該cookie被命名為名稱,可以有一個可選的值值。
2. clear-cookie NAME[=]一個特殊的Set-Cookie頭被新增到重定向。該Cookie名為名稱和最大年齡的cookie引數設定為0,目的是為了指示瀏覽器刪除cookie。
注意: 在於瀏覽器中,這是兩個不同的Cookie:NAME和NAME = 以上根據您的流量模式,必須將兩個語句適應。
* if | unless : 用於條件判斷
*<condition> (可選):用於匹配acl,一般為acl的名稱
b) 字首重定向
使用語法如下:
redirect prefix <loc> [code <code>] <option> [{if | unless} <condition>]
使用字首重定向,將使用者重定向到由concateneting建立了一個網址<pfx>和完整的原始URI路徑:
1. http-request redirect prefix <pfx> [code <code>] [<option>] [<condition>]
2. redirect prefix <pfx> [code <code>] [<option>] [<condition>]
相關指令引數如下:
* <pfx>: 一個日誌格式變數 (或簡單的字串redirect語句)描述了新的位置字首。
* code <code>(可選):HTTP重定向的狀態程式碼來執行。 此選項下的允許的狀態碼如下所示:
* <option>(可選): 可以是以下任何或組合的宣告:
drop-query :在執行串聯時從原來的URL刪除查詢字串
append-slash :配合使用drop-query ,在該URL的末尾新增一個“/”字元
set-cookie NAME[=value] :一個Set-Cookie頭部被新增到重定向。該cookie被命名為名稱,可以有一個可選的值值。
clear-cookie NAME[=] :一個特殊的Set-Cookie頭被新增到重定向。該Cookie名為名稱和最大年齡的cookie引數設定為0,目的是為了指示瀏覽器刪除cookie。
* if | unless :用於條件判斷
* <condition> (可選):用於匹配acl,一般為acl的名稱
c) 協議(計劃)重定向(比如將http重定向到https)
使用語法如下:
redirect scheme <sch> [code <code>] <option> [{if | unless} <condition>]
使用位置重定向,例如下面所示指令可以將使用者重定向到所提供的新的http協議url連結, 一般用於非安全連結跳轉到安全連結,比如http跳轉到https上
1. http-request redirect scheme <schloc> [code <code>] [<option>] [<condition>]
2. redirect scheme <sch> [code <code>] [<option>] [<condition>]
相關指令引數如下:
* <loc> :一個日誌格式變數 (或簡單的字串redirect語句)描述了新位置;
* code <code>(可選):HTTP重定向的狀態程式碼來執行。 此選項下的允許的狀態碼如下所示:
* <option>(可選): 可以是以下任何或組合的宣告:
1. set-cookie NAME[=value] :一個Set-Cookie頭部被新增到重定向。該cookie被命名為名稱,可以有一個可選的值值。
2. clear-cookie NAME[=]一個特殊的Set-Cookie頭被新增到重定向。該Cookie名為名稱和最大年齡的cookie引數設定為0,目的是為了指示瀏覽器刪除cookie。
注意: 在於瀏覽器中,這是兩個不同的Cookie:NAME和NAME = 以上根據你的流量模式,必須將兩個語句適應。
* if | unless :用於條件判斷
* <condition> (可選):用於匹配acl,一般為acl的名稱
一個簡單的例項:
acl http ssl_fc,not http-request redirect scheme https if http
下面是redirect 綜合應用的一個小示例:
acl clear dst_port 80 acl secure dst_port 8080 acl login_page url_beg /login acl logout url_beg /logout acl uid_given url_reg /login?userid=[^&]+ acl cookie_set hdr_sub(cookie) SEEN=1 redirect prefix https://kevin.com set-cookie SEEN=1 if !cookie_set redirect prefix https://kevin.com if login_page !secure redirect prefix http://kevin.com drop-query if login_page !uid_given redirect location http://kevin.com/ if !login_page secure redirect location / clear-cookie USERID= if logout
總結: redirect三種重定向可以混合使用,比較常用的有redirect prefix 和 redirect location這兩種方式,從某種理解上可以交差使用;
3) redir重定向用法:(redir通常配置在haproxy backend部分)
使用redir 會將發往backend的站點服務請求均以302狀態響應發給需要重定向的server服務或站點,此時haproxy不需要向後端web server提交請求;需要注意的是,在prefix後面不能使用/,且不能使用相對地址,以避免造成迴圈,例如:
frontend main *:80 default_backend app backend app balance roundrobin server node1 127.0.0.1:81 check weight 3 redir http://www.kevin.com
上面配置含義:所有發往localhost:81的請求做重定向,重定向到www.kevin.com因此可以實現單臺伺服器的重定向
又例如,如果我們要講訪問的站點重定向到grace.com
frontend main *:80 default_backend app backend app balance roundrobin server node1 127.0.0.1:81 check weight 3 redir http://www.grace.com
注意:redir只做跳轉,如客戶端輸入:http://ip ,將會跳轉到指定的頁面上,此時客戶端的頁面的頁面也會跳轉到指定的頁面上,之後所有的請求都會遞交到該站點(前提該站點可以與客戶端通訊),而不再發往haproxy代理站點,haproxy也不需要往後端web server提交客戶端發過來的請求。
二. haproxy實現error重定向
格式為: errorfile 錯誤程式碼code 錯誤程式碼響應提示頁路徑
* errorfile 即根據客戶端頁面錯誤code狀態將指定的錯誤狀態頁面提示給客戶端,比如友情提示頁面,一般如下:
errorfile 403 /etc/haproxy/errorfiles/403.http errorfile 500 /etc/haproxy/errorfiles/500.http errorfile 502 /etc/haproxy/errorfiles/502.http errorfile 503 /etc/haproxy/errorfiles/503.http errorfile 504 /etc/haproxy/errorfiles/504.http
例如:如果想訪問403頁面重定向到其他頁面的話 (errorloc),則參考以下配置:
frontend web_server bind *:80 default_backend webserver acl badguy src 172.16.50.10 block if badguy errorloc 403 http://grace.com/ #定義錯誤頁面重定向
errorfile 表示在使用者請求不存在的頁面時,返回一個頁面給客戶端而非有haproxy生成的錯誤程式碼,可用於所有段中;
格式: errorfile <code> <file>
errorloc 表示請求錯誤時,返回一個HTTP重定向至某URL的資訊,可以用於所有端中;
格式: errorloc <code> <url>
總結: 錯誤重定向可以更加友好地提示客戶端錯誤狀態,比如做定製頁面化跳轉,以及網站維護升級等等,當出現錯誤時,可以及時跳轉到預定好錯誤提示頁面上。
三. haproxy定義規則
1) haproxy常用的acl匹配條件
-i:不區分<value>中模式字元的大小寫; -f:從指定的檔案中載入模式; path_beg:用於測試請求的URL是否以<string>指定的模式開頭 例:匹配url以/static、/images、/javascript /stylesheets開頭 acl url_static path_beg -i /static /images /javascript /stylesheets path_end:用於測試請求的URL是否以<string>指定的模式結尾 例:匹配url以jpg、gif、png、css、js結尾 acl url_static path_end -i .jpg .gif .png .css .js hdr_beg:用於測試請求報文的指定首部的開頭部分是否符合<string>指定的模式 例:匹配請求的主機以img、video、download或ftp開頭 acl host_static hdr_beg(host) -i img. video. download. ftp. 即匹配訪問的域名是img.bobo.com,video.bobo.com,download.bobo.com,ftp.bobo.com url_beg:匹配的是整個url 例:匹配url為http://www.bobo.com.com acl is_bobo.com url_beg http://www.bobo.com.com use_backend bobo.com if is_bobo.com dst_port:判斷請求的埠 hdr_sub:判斷客戶的user-agent 例:判斷客戶端的user-agent是否為手機 acl shouji hdr_sub(user-agent) -i android iphone
2) haproxy定義分發規則
根據請求的主機頭,實現不同專案的請求,分發到不同的backend hdr_beg(host):判斷主機頭 例如: acl is_www hdr_beg(host) -i www.bobo.com.com acl is_wap hdr_beg(host) -i wap.bobo.com.com acl is_erp hdr_beg(host) -i erp.bobo.com.com acl is_interface hdr_beg(host) -i interface.bobo.com.com use_backend tomcat_erp_v2 if is_erp use_backend tomcat_interface_v2 if is_interface use_backend tomcat_web_v2 if is_www use_backend tomcat_mobile_v2 if is_wap 通過定義以上規則即可實現訪問不同的域名分發到不同的backend
3) haproxy定義重定向規則
prefix:表示重定向url location:表示重定向訪問路徑,即url不變,url後邊跟的路徑發生改變 例如: redirect prefix http://weihu.bobo.com.com/PC if is_www redirect prefix http://weihu.bobo.com.com/H5 if is_wap 說明: 當訪問is_www時,重定向到weihu.bobo.com.com/PC 當訪問is_wap時,重定向到weihu.bobo.com.com/H5
4) haproxy定義放行規則
僅放行通過驗證的IP地址或者IP範圍段; 例如: 如果訪問的是is_www,但來源IP不是指定的IP時,用http-request deny進行拒絕; acl is_www hdr_beg(host) -i www.bobo.com.com acl is_dns src 172.16.60.0/24 218.65.212.0/24 http-request deny if is_www !is_dns(滿足條件的直接進行拒絕) 也可以寫為: acl is_www hdr_beg(host) -i www.bobo.com.com acl is_dns src 172.16.60.0/24 218.65.212.0/24 user_backend www if is_www is_dns(兩個條件同時滿足才使用後端的www) 說明: 源地址有多個時,用空格進行隔開
5) haproxy定義手機只能訪問手機端,電腦端只能訪問電腦端規則
例如: 當手機訪問www.bobo.com時轉發到wap.bobo.com 當電腦訪問wap.bobo.com時轉發到www.bobo.com 配置如下: acl is_shouji hdr_sub(user-agent) -i android iphone acl is_diannao hdr_beg(host) www redirect prefix http://wap.bobo.com if shouji redirect prefix http://www.bobo.com if is_diannao !is_shouji
Haproxy 重定向跳轉 - 示例 1
1) 首先每個域名解析到自己的ip www.kevin.com 172.16.51.100 www.grace.com 172.16.51.200 www.bobo.com 172.16.51.210 2) 域名重定向 acl name_redirectA hdr_beg(host) -i www.kevin.com redirect prefix http://www.bobo.com/A if name_redirectA acl name_redirectB hdr_beg(host) -i www.grace.com redirect prefix http://www.bobo.com/B if name_redirectB 3) 跳轉規則 acl name_A hdr_beg(host) -i www.kevin.com acl name_B hdr_beg(host) -i www.grace.com acl name_C hdr_beg(host) -i www.bobo.com acl api_reqA path_beg -i /A/api acl api_reqB path_beg -i /B/api use_backend appserver_8081 if name_A or name_B #匹配"或"的規則 use_backend appserver_8082_A if name_C api_reqA #匹配"和"的規則 use_backend appserver_8082_B if name_C api_reqB backend appserver_8081 balance source server web1 172.16.51.171:8081 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 server web2 172.16.51.174:8081 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 backend appserver_8082_A server web1 172.16.51.180:80 weight 3 check inter 2000 rise 2 fall 3 backend appserver_8082_B server web1 172.16.51.180:80 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3
Haproxy 重定向跳轉 - 示例 2
redirect location <to> [code <code>] <option> [{if | unless} <condition>] redirect prefix <to> [code <code>] <option> [{if | unless} <condition>] 重定向,相當於rewrite 示例配置如下: acl shibo hdr_reg(host) -i ^(shibo.kevin.com|forum.kevin.com) #使用正則匹配 acl shibo_path path_beg -i /shibo #url 目錄 acl youxi path_beg -i /youxi acl static path_end -i .html .css .js #url 結尾檔案 acl php path_end -i .php acl jsp path_end -i .jsp .do use_backend shibo_pool if shibo or shibo_path #注意"或"的匹配用"or" use_backend youxi_pool if youxi use_backend static_pool if static use_backend php_pool if php use_backend jsp_pool if jsp default_backend www.kevin.com #當滿足host_bb.cn的策略,跳轉(重定向)到http://www.bb.cn acl host_bb.cn hdr_beg(host) -i (bb.cn|beijing.com) redirect prefix http://www.bb.cn if host_bb.cn #有個問題: haproxy能否在接到一個請求時選擇一個後端伺服器,然後301重定向url 。 #主要原因是他有5個1G的出口,這樣就能充分利用其頻寬。 #測試了一下是可以的 frontend free bind *:80 default_backend lvs2 backend lvs2 mode http option forwardfor header ORIG_CLIENT_IP server free174 172.16.51.16:8081 redir http://free71-174-grace.com:8081 weight 10 rise 3 fall 5 check inter 2000 server free173 172.16.51.15:8081 redir http://free71-173-grace.com:8081 weight 10 rise 3 fall 5 check inter 2000 #當輸入負載均衡機器的域名後,url會直接變成http://free71-17(3|4)-grace.com:8081. acl monitor hdr_beg(host) -i monitor.kevin.com #定義ACL名稱(monitor),對應的請求的主機頭是monitor.kevin.com acl shibo hdr_reg(host) -i ^(shibo.kevin.com|forum.kevin.com) #使用正則匹配 acl host_bb.cn hdr_beg(host) -i bb.cn acl host_hui.cn hdr_beg(host) -i beijing.com redirect prefix http://www.bb.cn if host_bb.cn redirect prefix http://www.bb.cn if host_hui.cn frontend localhost bind *:80 bind *:443 ssl crt /etc/ssl/bb.web/bb.web.pem redirect scheme https if !{ ssl_fc } mode http default_backend nodes # 上面配置中, 新增了redirect導向,如果連線不是通過SSL連線的,它將http重定向到https acl host_bb.cn hdr_beg(host) -i bb.cn acl host_jiu.cn hdr_beg(host) -i beijing.com acl www_jiu.cn hdr_beg(host) -i www.beijing.com acl host_hui.cn hdr_beg(host) -i pp.com acl www_hui.cn hdr_beg(host) -i www.pp.com redirect prefix http://www.bb.cn if host_bb.cn redirect prefix http://www.bb.cn if host_jiu.cn redirect prefix http://www.bb.cn if www_jiu.cn redirect prefix http://www.bb.cn if host_hui.cn redirect prefix http://www.bb.cn if www_hui.cn 訪問bb.cn,beijing.com,www.beijing.com,pp.com,www.pp.cpm 都跳轉到http://www.bb.cn
Haproxy 重定向跳轉 - 示例 3 (手機規則匹配)
一. 線上業務的實際需求 現在根據業務的實際需要,有以下幾種不同的需求。如下: a) 轉發所有手機請求 所有通過手機端訪問http.shibo.com域名的話,全部轉發到http://www.shibo.com這個地址,而PC端不受此限制。 b) 根據url進行轉發 如果手機端請求http.shibo.com這個域名的url中,以docs或者manager這兩個關鍵詞開頭的話,把該請求轉發到後端的伺服器,而PC端不受此限制。 也就是說手機端訪問具體的url地址的話,可以正常訪問。如果是直接訪問http.shibo.com域名的話,直接把該請求轉發到http://www.shibo.com這個地址。 ============================================================ 二. haproxy配置 下面根據不同的業務需求進行配置haproxy,如下。 a) 轉發所有手機請求配置 要把所有的手機端請求轉到www.shibo.com這個地址,需要我們首先把訪問的終端匹配出來,haproxy可以通過hdr_sub(user-agent)這個引數把手機端匹配出來。 手機端匹配出來後,我們就可以定義相應的規則,把手機端的請求轉發到www.shibo.com這個地址了。haproxy.cf配置檔案如下: [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 uid 188 gid 188 daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.1 option redispatch retries 3 option redispatch maxconn 2000 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend weblb bind *:80 acl is_http hdr_beg(host) http.shibo.com acl ua hdr_sub(user-agent) -i android iphone redirect prefix http://www.shibo.com if ua use_backend httpserver if is_http backend httpserver balance source server web1 127.0.0.1:8080 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 溫馨提示: 在以上配置檔案中,有以下兩行需要注意: acl ua hdr_sub(user-agent) -i android iphone redirect prefix http://www.shibo.com if ua 這兩行: 第一行是第一個ua規則,該規則是判斷是否是手機端。 注意:在此手機端,我們只匹配了安卓手機和iphone。 第二行是跳轉規則,如果匹配是手機端的話,那麼直接跳轉到http://www.shibo.com這個地址。 如果是PC端的話,預設跳轉到httpserver這個後端伺服器組。 以上配置是一臺伺服器對外只提供一個域名訪問的請求,如果有兩個域名的話,就要進行如下配置: [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 uid 188 gid 188 daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.1 option redispatch retries 3 option redispatch maxconn 2000 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend weblb bind *:80 acl is_http hdr_beg(host) http.shibo.com acl is_haproxy hdr_beg(host) haproxy.shibo.com acl ua hdr_sub(user-agent) -i android iphone redirect prefix http://www.shibo.com if ua !is_haproxy use_backend haproxyserver if ua is_haproxy use_backend haproxyserver if is_haproxy use_backend httpserver if is_http backend httpserver balance source server web1 127.0.0.1:8080 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 backend haproxyserver balance source server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 b) 測試轉發所有手機請求 在手機瀏覽器中輸入http.shibo.com會自動跳轉到http://www.shibo.com這個地址。 c) 根據url進行轉發配置 根據手機端請求的url進行轉發的話,首先也是需要匹配出手機端,然後定義url路徑規則。最後結合手機端和url路徑規則,進行跳轉。 haproxy具體配置檔案,如下: [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 uid 188 gid 188 daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.1 option redispatch retries 3 option redispatch maxconn 2000 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend weblb bind *:80 acl is_http hdr_beg(host) http.shibo.com acl is_docs url_beg /docs /manager acl ua hdr_sub(user-agent) -i android iphone redirect prefix http://www.shibo.com if ua !is_docs use_backend httpserver if ua is_docs use_backend httpserver if is_http backend httpserver balance source server web1 127.0.0.1:8080 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 溫馨提示: 在上述配置檔案中,需要以下幾行解釋下: acl is_docs url_beg /docs /manager 定義一個is_docs規則。如果url以/docs或者/manager開頭的,則全部屬於該規則。 acl ua hdr_sub(user-agent) -i android iphone redirect prefix http://www.shibo.com if ua !is_docs 這兩行首先是匹配出手機端,然後如果是手機端訪問,並且訪問的不是is_docs規則的話,則直接跳轉到http://www.shibo.com這個地址。 use_backend httpserver if ua is_docs 這條命令是,如果是手機端訪問,並且訪問的是is_docs規則的話,則直接跳轉到httpserver這個後端伺服器組。 如果是PC端的話,預設跳轉到httpserver這個後端伺服器組。 d) 測試根據url進行轉發 手機端訪問http://http.shibo.com/docs/這個連線的話,是可以直接訪問的。 ============================================================ 三. 其他haproxy相關配置 上面說明了有關手機的相關配置,在實際的生產環境中,有時候還會碰到一些奇奇怪怪的要求。 比如要求所有手機端訪問的http.shibo.com,轉到指定的頁面。haproxy主要配置檔案如下: [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. frontend weblb bind *:80 acl is_http hdr_beg(host) http.shibo.com acl ua hdr_sub(user-agent) -i android iphone redirect prefix http://www.shibo.com/?p=10624 if ua use_backend httpserver if is_http backend httpserver balance source server web1 127.0.0.1:8080 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 以上配置是所有手機端訪問的,都跳轉到http://www.shibo.com/?p=10624這個頁面。
haproxy重定向跳轉 - 示例4 (修改路徑, 即重寫URL)
1) 訪問https://www.shibo.com/guo-hui 重定向跳轉到 https://www.xiaobo.com/an-hui frontend https option http-server-close reqadd X-Forwarded-Proto:\ https acl shi_bo hdr(host) -i www.shibo.com acl guo_hui path_beg /guo-hui acl an_hui path_beg /an-hui reqirep ^([^\ ]*\ /)guo-hui(.*) \1an-hui\2 if shi_bo guo_hui #注意中間的空格, 以及\1 和 \2; redirect prefix https://www.xiaobo.com code 301 if shi_bo an_hui 2) 訪問http://front-end/app-2/do-that 重定向跳轉到 http://back-end/app-2-another-path/do-that frontend http acl do-that path_end -i /app-2/do-that use_backend server1 if do-that backend server1 reqirep ^([^\ :]*)\ /app-2/(.*) \1\ /app-2-another-path/\2 server server 172.16.60.51 3) 訪問原請求為 http://www.kevin.com/OLD/ab... 重定向到 http://www.kevin.com/NEW/ab... 在nginx裡可以通過rewrite來實現跳轉配置, 配置內容如下: server { listen 80; server_name www.kevin.com; location / { rewrite ^/OLD(.*) /NEW$1 permanent; proxy_pass http://backend_www_kevin_com; } } 在haproxy裡重定向跳轉的配置如下: frontend web80 bind *:80 acl domain_www_kevin_com hdr_beg(host) -i www.kevin.com kevin.com acl url_old url_beg -i /old reqirep ^([^\ ]*)\ /old(.*) \1\ /new\2 if domain_www_kevin_com url_old use_backend kevin_com if domain_www_kevin_com 最後總結: 通過以上haproxy和nginx的重寫配置, 可以看出二者配置的不同在於: - http://www.kevin.com/old,後端真實伺服器收到的請求被重寫為 /new/ ,並且瀏覽器收到 HTTP/1.1 302 Location: /new/ , 位址列改為 http://www.kevin.com/new/ - http://www.kevin.com/old/,或者 http://www.kevin.com/old/ab... 後端真實伺服器收到的請求被重寫為 /new/ , 瀏覽器並沒有收到 302 , 位址列依舊為 http://www.kevin.com/old/ 4) haproxy URL 重新 , 如下兩個規範配置 reqirep ^([^\ ]*)\ /books/(.*) \1\ /books.php?title=\2 reqirep ^([^\ ]*)\ /(.*) \1\ /wdn/\2 # 注意中間的空格, 以及\1 和 \2 5) reqirep可以修改http的頭; 如果haproxy 配置裡要替換主機頭, 則: 在backend 選項下面加入: reqirep ^Host:\ (.*) Host:\ 標識
haproxy重定向跳轉 - 示例5 (錯誤/黑白名單/動靜分離/讀寫(上傳和下載)分離的重定向 )
1) haproxy 錯誤重定向(403), 即黑名單設定 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. acl blacklist src 172.16.51.250 http-request deny if blacklist 如上配置後, 當來源ip是172.16.51.250時, 就直接返回一個403錯誤頁面!! ============================================================= 當haproxy配置裡限制一個來源ip訪問時, 直接給使用者返回403錯誤頁面, 會顯得不太友好, 所以haproxy重定向應運而生. 如下配置, 當來源ip是172.16.51.250時, 直接重定向跳轉到172.16.51.10的8000埠的錯誤頁面 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. acl badhost src 172.16.51.250 block if badhost errorloc 403 http://172.16.51.10:8000 在172.16.51.10機器上部署nginx, 埠為8000, 然後在nginx根目錄的index.html裡設定錯誤頁面資訊, 錯誤頁面資訊可以自己隨便定義, 比如"抱歉, 頁面臨時出錯, 運維工程師正在搶修中, 請耐心等待~" 2) haproxy 黑名單重定向 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. acl badhost src 172.16.51.250 redirect location http://172.16.51.10:8000 if badhost 在172.16.51.10機器上部署nginx, 埠為8000, 然後在nginx根目錄的index.html裡設定錯誤頁面資訊, 錯誤頁面資訊可以自己隨便定義, 比如"抱歉, 這是一個禁止訪問的來源ip地址!請嘗試從其他機器訪問." 3) haproxy 網頁重定向 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. acl shibo.com hdr_beg(host) -i shibo.com redirect code 301 location http://www.shibo.com if shibo.com 溫馨提示: 如果不寫301,只寫code預設是302,臨時重定向 (不推薦), 加上301則表示永久重定向 4) haproxy 訪問IP自動跳轉到域名 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. acl 172.16.51.10 hdr(host) -i 172.16.51.10 redirect code 301 location http://www.shibo.com if 172.16.51.10 5) haproxy 讀寫分離 配置 (即上傳和下載分離) [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. acl read method GET acl read method HEAD acl write method PUT acl write method POST use_backend dynamic if write default_backend static backend static #"上傳"讀取操作的負載代理. balance roundrobin server web1 172.16.51.30:80 check backend dynamic #"下載"寫入操作的負載代理 balance roundrobin server web2 172.16.51.40:80 check 6) haproxy 動靜分離 配置 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. frontend public bind *:80 name clear #bind 172.16.51.10:443 ssl crt /etc/haproxy/haproxy.pem #use_backend static if { hdr_beg(host) -i img } #use_backend static if { path_beg /img /css } use_backend static2 if { path_end -i .php } default_backend static1 # The static backend backend for 'Host: img', /img and /css. backend static1 balance roundrobin server statsrv1 172.16.51.20:80 check inter 1000 backend static2 balance roundrobin server statsrv2 172.16.51.30:80 check inter 1000 7) haproxy的白名單設定 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. frontend tcp-8080-front bind *:8080 mode tcp default_backend tcp-8080-back tcp-8080-back mode tcp balance leastconn tcp-request content accept if { src -f /usr/local/haproxy/white_ip_list } tcp-request content reject server tcp-8080 10.1.27.20:8080 配置中/usr/local/haproxy/white_ip_list檔案即為白名單檔案, 在檔案裡配置允許的白名單地址: 一行一個IP或者IP段。
haproxy 重定向跳轉 - 示例6
[root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. acl admin_req path_beg -i /admin use_backend admin_80 if admin_req backend admin_80 mode http balance roundrobin server apphost01_8083 172.16.50.133:80 check inter 2000 fall 3 接著去172.16.50.133伺服器上看下tomcat配置 [root@tomcat-133 ~]# vim /usr/local/tomcat/conf/server.xml ............. <Context docBase="/data02/kevin-web" path="/" reloadable="false"/> [root@tomcat-133 ~]# cd /data02/kevin-web [root@tomcat-133 kevin-web]# ls admin adminwechat index.html jquery.2.1.4.min.js META-INF WEB-INF kevin-web-0.0.1-SNAPSHOT.war [root@tomcat-133 kevin-web]# ls bobo.html 最後, 可驗證: 訪問http://www.kevin.com/admin/bobo.html 實際上返回的是172.16.50.133伺服器的/data02/kevin-web/admin/bobo.html頁面內容
haproxy 重定向跳轉 - 示例7 (haproxy 代理 https)
haproxy代理https有兩種方式: 1)haproxy伺服器本身提供ssl證照,後面的web伺服器走正常的http 2)haproxy伺服器本身只提供代理,後面的web伺服器走https(配置ssl證照) ===================================================== 第一種方式:haproxy伺服器本身提供ssl證照 注意: 需要編譯haproxy的時候支援ssl 編譯引數: [root@localhost ~]# make TARGET=linux26 USE_OPENSSL=1 ADDLIB=-lz [root@localhost ~]# ldd haproxy | grep ssl libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007fb0485e5000) [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. frontend https_frontend bind *:443 ssl crt /etc/ssl/certs/servername.pem mode http option httpclose option forwardfor reqadd X-Forwarded-Proto:\ https default_backend web_server backend web_server mode http balance roundrobin cookie SERVERID insert indirect nocache server s1 172.16.50.150:80 check cookie s1 server s2 172.16.50.151:80 check cookie s2 溫馨提示: 這裡的pem 檔案是下面兩個檔案合併而成 [root@localhost ~]# cat servername.crt servername.key |tee servername.pem ===================================================== 第二種方式:haproxy伺服器本身只提供代理,沒有ssl證照 (一般我們常用的就是這種方式) 這種方式,haproxy不需要重新編譯支援ssl,簡單方便,只需要後面的web伺服器配置好ssl即可。 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg ............. ............. frontend https_frontend bind *:443 mode tcp default_backend web_server backend web_server mode tcp balance roundrobin stick-table type ip size 200k expire 30m stick on src server s1 172.16.50.150:443 server s2 172.16.50.151:443 溫馨提示: 這種模式下mode 必須是tcp模式!!!!!!!!
haproxy重定向跳轉 - 示例8 (http, https的有關重定向, 案例分析)
需要提前說明下: 下面配置操作全部是在haproxy1.5.4版本下進行配置和通過測試的! haproxy1.3版本以下haproxy配置引數可能不能使用,所以需要注意haproxy的版本號 以下的haproxy配置可以線上上生產環境直接使用的! 一、業務要求 根據系統業務的實際需要,有以下幾種不同的需求: 1.1) http跳轉https 把所有請求http://http.kevin.com的地址全部跳轉為https://http.kevin.com這個地址。 1.2) http與https並存 伺服器同時開放http://http.kevin.com和https://http.kevin.com的訪問形式。 1.3) 同臺伺服器不同域名之間的https與http 同一臺伺服器對http.kevin.com域名訪問的全部跳轉為https://http.kevin.com,而對haproxy.kevin.com訪問走http協議, 也就是跳轉到http://haproxy.kevin.com這個地址。 1.4) 同臺伺服器多域名均使用https 同一臺伺服器對http.kevin.com和haproxy.kevin.com訪問走http是協議。 二、配置haproxy, 實現以上業務需求 2.1) http跳轉https的haproxy配置檔案內容 說實話haproxy的https配置要比nginx配置簡單的多了,只需要加入幾行程式碼即可實現https的功能。 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 uid 188 gid 188 daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.1 option redispatch retries 3 option redispatch maxconn 2000 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend weblb bind *:80 acl is_http hdr_beg(host) http.kevin.com redirect scheme https if !{ ssl_fc } bind *:443 ssl crt /etc/haproxy/kevin.com.pem use_backend httpserver if is_http backend httpserver balance source server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 溫馨提示: 在以上配置檔案中,只要需要注意下面四個選項的配置: tune.ssl.default-dh-param 2048 #因為我們的SSL金鑰使用的是2048bit加密,所以在此進行宣告。 acl is_http hdr_beg(host) http.kevin.com redirect scheme https if !{ ssl_fc } bind *:443 ssl crt /etc/haproxy/kevin.com.pem # 這三行表示把所有訪問http.kevin.com這個域名的請求,全部轉發到https://http.kevin.com這個連線。 測試: 發現在瀏覽器中,無論輸入的是http.kevin.com, 還是http://http.kevin.com, 亦或是https://http.kevin.com,都會自動跳轉到https://http.kevin.com。 這樣就達到了,把所有的http請求跳轉到https的目的。 2.2) http與https並存配置 haproxy要實現http和https並存的話,配置也很簡單,只需要把haproxy分別監控不同的埠就行,配置檔案如下: [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 user haproxy group haproxy daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull retries 3 option redispatch maxconn 2000 timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend weblb bind *:80 acl is_http hdr_beg(host) http.kevin.com use_backend httpserver if is_http backend httpserver balance source server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 frontend weblb443 bind *:443 ssl crt /etc/haproxy/kevin.com.pem acl is_443 hdr_beg(host) http.kevin.com use_backend httpserver443 if is_443 backend httpserver443 balance source server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 溫馨提示: 在以上配置檔案中,定義了兩個前端,一個前端用於監聽80埠,也就是http協議。另外一個前端監聽443埠,也就是https協議。 此時haproxy會根據客戶端請求的協議進行分發,如果發現客戶端請求的是http協議,則把該請求分發到監聽80埠的前端。 如果發現客戶端請求的是https協議,則把該請求分發到監聽443埠的前端。如此就達到了haproxy讓http和https並存的要求。 測試: 通過測試會發現,在瀏覽器中如果輸入的是http://http.kevin.com或者是http.kevin.com都會直接跳轉到http://http.kevin.com, 而輸入的是https://http.kevin.com,則只會跳轉到https://http.kevin.com。 如此就到達了,我們業務的要求實現http和https並存。 2.3) 同臺伺服器不同域名之間的https與http配置 同臺伺服器不同域名之間的http和https配置比較複雜,第一需要監聽兩個埠,第二還要根據不同的域名進行分發。 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 uid 188 gid 188 daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.1 option redispatch retries 3 option redispatch maxconn 2000 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend weblb bind *:80 acl is_haproxy hdr_beg(host) haproxy.kevin.com acl is_http hdr_beg(host) http.kevin.com redirect prefix https://http.kevin.com if is_http use_backend haproxyserver if is_haproxy backend haproxyserver balance source server web1 127.0.0.1:9090 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 frontend weblb443 bind *:443 ssl crt /etc/haproxy/kevin.com.pem acl is_443 hdr_beg(host) http.kevin.com use_backend httpserver443 if is_443 backend httpserver443 balance source server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 溫馨提示: 同臺伺服器不同域名之間的https與http配置,上面配置了兩個前端一個用於監聽80埠,並且根據不同的域名進行跳轉。 在80埠的規則中,如果客戶端請求的是http.kevin.com,這個域名的話,則haproxy會把該請求直接跳轉到https://http.kevin.com。 如果是haproxy.kevin.com,這個域名的話,則分發到後端的伺服器。 另外一個前端用於監聽443埠,用於分發客戶端https://http.kevin.com的請求。 測試: 可以發現在瀏覽器中輸入haproxy.kevin.com會跳轉到http://haproxy.kevin.com這個地址, 而如果輸入的是http.kevin.com或者是http://http.kevin.com,亦或是https://http.kevin.com的話,都會跳轉到https://http.kevin.com。 如此就達到了上面的業務要求,同臺伺服器上訪問haproxy.kevin.com直接跳轉到80埠,如果訪問的是http.kevin.com域名的話則跳轉 到https://http.kevin.com這個地址。 2.4) 同臺伺服器多域名均使用https配置 要使同臺伺服器的兩個設定多個域名都使用https協議的話,配置很簡單。只需要在haproxy中啟用各自的https配置即可。 [root@localhost ~]# vim /usr/local/haproxy/conf/haproxy.cfg global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 uid 108 gid 116 daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.1 option redispatch retries 3 option redispatch timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend web80 bind *:80 acl is_http hdr_beg(host) http.kevin.com redirect scheme https if !{ ssl_fc } bind *:443 ssl crt /etc/haproxy/kevin.com.pem acl is_haproxy hdr_beg(host) haproxy.kevin.com redirect scheme https if !{ ssl_fc } bind *:443 ssl crt /etc/haproxy/kevin.com.pem use_backend httpserver if is_http use_backend haproxyserver if is_haproxy backend httpserver balance source server web1 127.0.0.1:6060 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 backend haproxyserver balance source server web1 127.0.0.1:9090 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 測試: 在瀏覽中無論是輸入http.kevin.com、http://http.kevin.com,還是haproxy.kevin.com、http://haproxy.kevin.com,都會跳轉到相應的https地址。 這也達到了業務的要求