1、HAProxy簡(jiǎn)介
HAProxy 是一款高性能TCP/HTTP 反向代理負(fù)載均衡服務(wù)器朋其,具有如下功能:
- 根據(jù)靜態(tài)分配的cookies完成HTTP請(qǐng)求轉(zhuǎn)發(fā)
- 在多個(gè)服務(wù)器間實(shí)現(xiàn)負(fù)載均衡倦始,并且根據(jù)HTTP cookies 實(shí)現(xiàn)會(huì)話粘性
- 主備服務(wù)器切換
- 接受訪問(wèn)特定端口實(shí)現(xiàn)服務(wù)監(jiān)控
- 實(shí)現(xiàn)平滑關(guān)閉服務(wù)斗遏,不中斷已建立連接的請(qǐng)求響應(yīng),拒絕新的請(qǐng)求
- 在請(qǐng)求或響應(yīng)HTTP報(bào)文中添加楣号,修改最易,或刪除首部信息
- 根據(jù)正則規(guī)則阻斷請(qǐng)求
- 提供帶有用戶認(rèn)證機(jī)制的服務(wù)狀態(tài)報(bào)告頁(yè)面
HAProxy特別適用于那些負(fù)載特大的web站點(diǎn)怒坯,這些站點(diǎn)通常又需要會(huì)話保持或七層處理炫狱。HAProxy運(yùn)行在時(shí)下的硬件上藻懒,完全可以支持?jǐn)?shù)以萬(wàn)計(jì)的 并發(fā)連接。并且它的運(yùn)行模式使得它可以很簡(jiǎn)單安全的整合進(jìn)您當(dāng)前的架構(gòu)中视译, 同時(shí)可以保護(hù)你的web服務(wù)器不被暴露到網(wǎng)絡(luò)上嬉荆。
HAProxy 實(shí)現(xiàn)了一種事件驅(qū)動(dòng)、單一進(jìn)程模型酷含,此模型支持非常大的并發(fā)連接數(shù)鄙早。多進(jìn)程或多線程模型受內(nèi)存限制 、系統(tǒng)調(diào)度器限制以及無(wú)處不在的鎖限制椅亚,很少能處理數(shù)千并發(fā)連接限番。事件驅(qū)動(dòng)模型因?yàn)樵谟懈玫馁Y源和時(shí)間管理的用戶端(User-Space) 實(shí)現(xiàn)所有這些任務(wù),所以沒(méi)有這些問(wèn)題呀舔。此模型的弊端是弥虐,在多核系統(tǒng)上,這些程序通常擴(kuò)展性較差媚赖。這就是為什么他們必須進(jìn)行優(yōu)化以 使每個(gè)CPU時(shí)間片(Cycle)做更多的工作霜瘪。
HAProxy實(shí)際工作中,它占用用戶空間時(shí)間要比內(nèi)核運(yùn)行時(shí)間少20倍惧磺,所以對(duì)系統(tǒng)參數(shù)調(diào)優(yōu)是十分必要的一項(xiàng)工作颖对。
另外衡量一個(gè)負(fù)載均衡服務(wù)器主要考量三個(gè)指標(biāo):
1、session rate
此項(xiàng)指標(biāo)非常重要磨隘,它決定了一個(gè)load balancer 能不能分發(fā)所有接受的請(qǐng)求缤底。這項(xiàng)指標(biāo)通常是由CPU性能決定。測(cè)量指標(biāo)的大小跟傳輸?shù)拿總€(gè)對(duì)象的大小有關(guān)番捂,通常用空對(duì)象來(lái)測(cè)試训堆,Session rates 在 100,000 sessions/s 左右,使用 Xeon E5 在 2014測(cè)試白嘁。
2坑鱼、session concurrency
該指標(biāo)與前一指標(biāo)相關(guān)聯(lián)。這一指標(biāo)與服務(wù)器內(nèi)存和系統(tǒng)可以處理的文件描述符數(shù)量有關(guān)絮缅。 通常每個(gè)session占用34KB鲁沥,即大概3W個(gè)session占用1GB內(nèi)存空間,實(shí)際上耕魄,socket buffer也會(huì)占用內(nèi)存空間画恰,2W個(gè)session socket占用1GB內(nèi)存。
3吸奴、data forwarding rate
這一指標(biāo)與 session rate 相對(duì)立允扇,它的衡量單位通常是 Megabytes/s (MB/s), 或者 Gigabits/s (Gbps)缠局。傳輸較大的對(duì)象有利于該指標(biāo)的提升,因?yàn)檩^大的對(duì)象傳輸可以減少session建立和關(guān)閉浪費(fèi)的時(shí)間考润。而測(cè)量session rate 則在傳輸小對(duì)象時(shí)有利于指標(biāo)提升狭园。haproxy 在2014年使用 Xeon E5 測(cè)試成績(jī)?yōu)?0 Gbps。
2糊治、HAProxy程序環(huán)境
本文環(huán)境:CentOS7, haproxy 1.5 通過(guò)yum 安裝
程序環(huán)境:
配置文件:/etc/haproxy/haproxy.cfg
Unit File: haproxy.service
主程序:/usr/sbin/haproxy
配置文件:
global:全局配置段
進(jìn)程及安全配置相關(guān)的參數(shù)
性能調(diào)整相關(guān)的參數(shù)
Debug相關(guān)的參數(shù)
proxies:代理配置段
defaults:為frontend, backend以及l(fā)isten提供默認(rèn)配置唱矛;
frontend:前端,相當(dāng)于Nginx中的server{ ... }井辜;
backend:后端绎谦,相當(dāng)于nginx中的upstream { ... };
listen:前后端的直接組合;
**關(guān)于前端與后端的關(guān)系:一個(gè)前端可以指向多個(gè)后端粥脚;同時(shí)一個(gè)后端可以被多個(gè)調(diào)用窃肠。
3、HAProxy配置詳解
3.1 global配置段
3.1.1 進(jìn)程相關(guān)配置
-
定義日志系統(tǒng)相關(guān)屬性
log <address> [len <length>] <facility> [max level [min level]]
harpoxy 將日志發(fā)送到指定的rsyslog服務(wù)器刷允,在本地記錄也要開(kāi)啟rsyslog服務(wù)冤留;
全局端最多可配置兩個(gè)log 服務(wù)器;
< address> :日志服務(wù)器地址
[ len ] 指定記錄的日志最大長(zhǎng)度
定義運(yùn)行用戶恃锉,所屬組
1搀菩、username
2、group groupname運(yùn)行方式
1破托、意味著后臺(tái)守護(hù)進(jìn)程
3.1.2 參數(shù)調(diào)優(yōu)
maxconn <number>:設(shè)定單haproxy進(jìn)程的最大并發(fā)連接數(shù)肪跋;
maxconnrate <number>:設(shè)定單haproxy進(jìn)程每秒接受的連接數(shù);
maxsslconn <number>:設(shè)定單haproxy進(jìn)程的ssl連接最大并發(fā)連接數(shù)土砂;
maxsslrate <number>:?jiǎn)蝖aproxy進(jìn)程的ssl連接的創(chuàng)建速率上限州既;
spread-checks <0..50, in percent>:避免對(duì)于后端檢測(cè)同時(shí)并發(fā)造成
的問(wèn)題,設(shè)置錯(cuò)開(kāi)時(shí)間比萝映,范圍0到50吴叶,一般設(shè)置2-5較好。
3.1.3 用戶列表
用于對(duì)haproxy 狀態(tài)監(jiān)控頁(yè)面的用戶認(rèn)證序臂。至少要定義一個(gè)用戶列表并且添加一個(gè)用戶
密碼可以加密或明文蚌卤。
Example:
userlist L1
group G1 users tiger,scott
group G2 users xdb,scott
user tiger password $6$k6y3o.eP$JlKqe4(...)xHSwRv6J.C0/D7cV91
user scott insecure-password elgato
user xdb insecure-password hello
userlist L2
group G1
group G2
user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1
user scott insecure-password elgato groups G1,G2
user xdb insecure-password hello groups G2
3.2 proxy配置段
這部分配置在下列定義區(qū)域下使用
- defaults < name >
- frontend < name >
- backend < name >
- listen < name >
“defaults” 區(qū)域定義了frontend,backend奥秆,listen 的默認(rèn)參數(shù)
“frontend" 區(qū)域描述了接收客戶端請(qǐng)求的監(jiān)聽(tīng)配置
"backend" 區(qū)域描述接受請(qǐng)求處理的后端服務(wù)器配置
"listen" 區(qū)域描述一組前端和后端直接一對(duì)一綁定的組配置
HAProxy 配置的關(guān)鍵字與區(qū)域限制特性逊彭,即有些關(guān)鍵字在某個(gè)區(qū)域不可以使用
下面開(kāi)始講解關(guān)鍵字的用法
3.2.1 常用配置指令
1. bind [<address>]:<port_range> [, ...] [param*]
僅在frontend和listen區(qū)域使用。定義服務(wù)監(jiān)聽(tīng)端口地址等參數(shù)
[ param* ] 參數(shù)根據(jù)系統(tǒng)而定构订,一般不需要指定
example:
bind :80 #監(jiān)聽(tīng)本機(jī)所有IP的80端口
bind *:80 #監(jiān)聽(tīng)本機(jī)所有IP的80端口
bind 192.168.12.1:8080,10.1.0.12:8090
2. mode {tcp|http|health}
tcp:基于layer4實(shí)現(xiàn)代理侮叮,可代理大多數(shù)基于tcp的應(yīng)用層協(xié)議,例如ssh/mysql/pgsql等悼瘾;
http:客戶端的http請(qǐng)求會(huì)被深度解析囊榜;
health:工作為健康狀態(tài)檢查響應(yīng)模式审胸,當(dāng)請(qǐng)求到達(dá)時(shí)僅回應(yīng)“OK”即斷開(kāi)連接;
3. balance <algorithm> [ <arguments> ]
balance url_param <param> [check_post]
在backend區(qū)域定義調(diào)度算法:
< algorithm > 如下:
-
roundrobin
:
帶有權(quán)重的輪詢調(diào)度算法卸勺;
server后面使用weight來(lái)定義權(quán)重砂沛;
動(dòng)態(tài)算法:支持權(quán)重的運(yùn)行時(shí)調(diào)整,支持慢啟動(dòng)(緩慢接收大量請(qǐng)求在剛啟動(dòng)時(shí))孔庭;僅支持最大4095個(gè)后端活動(dòng)主機(jī)
-
static-rr
:
靜態(tài)的roundrobin算法尺上;
不支持權(quán)重的運(yùn)行時(shí)調(diào)整及慢啟動(dòng)材蛛;但后端主機(jī)數(shù)量無(wú)限制圆到;
-
leastconn
:
帶權(quán)重的最少連接分配動(dòng)態(tài)算法;
適用長(zhǎng)連接應(yīng)用協(xié)議卑吭,如ssh等
-
first
:
第一優(yōu)先算法芽淡;
如果第一個(gè)服務(wù)端可接受請(qǐng)求則總是把連接分配給它,直到第一個(gè)服務(wù)端處于繁忙豆赏,分配給下一個(gè)挣菲,順序按服務(wù)端的數(shù)字ID從小到大排列
source
源IP hash 算法;
該算法保證在后端服務(wù)器組沒(méi)有減少或增加的情況下掷邦,能將來(lái)自同一客戶端IP的請(qǐng)求分配至同一個(gè)服務(wù)端白胀;
該算法適合在無(wú)法使用cookie插入的TCP模式下使用
動(dòng)態(tài)算法或靜態(tài)算法取決于hash-type;
uri
uri hash 算法抚岗;
該算法hash uri 的查詢標(biāo)記的左側(cè)部分或杠,或者指定whole 參數(shù)時(shí)hash全部uri;
該算法保證訪問(wèn)同一uri的請(qǐng)求分配至同一服務(wù)端宣蔚,適用于后端為緩存服務(wù)器的情況向抢,以提高緩存命中率;
動(dòng)態(tài)算法或靜態(tài)算法取決于hash-type胚委;
另外:該算法支持追加參數(shù)[ < arguments > ]:
(1) whole :hash完整uri
(2) len number:hash指定uri的長(zhǎng)度
(3) depth nubmer:hash指定目錄深度挟鸠,每個(gè)"/"代表一個(gè)深度
- uri_param
param hash 算法;
對(duì)用戶請(qǐng)求的url中的< param >部分中的指定的參數(shù)的值(uri中"="部分)作hash計(jì)算亩冬;
該算法適用于有用戶識(shí)別參數(shù)的uri 艘希,它保證同一user id 的請(qǐng)求分配至同一服務(wù)端;
如果check_post 標(biāo)識(shí)啟用硅急,則在uri中沒(méi)有找到"?"參數(shù)時(shí)覆享,對(duì)HTTP Post 請(qǐng)求實(shí)體查找參數(shù)聲明;
動(dòng)態(tài)算法或靜態(tài)算法取決于hash-type铜秆;
Example:
balance url_param userid
balance url_param session_id check_post 64
- hdr(< name >)
HTTP 首部字段hash算法淹真;
指定的http首部將會(huì)被取出做hash計(jì)算。如果沒(méi)有值连茧,則降至輪詢調(diào)度核蘸;
動(dòng)態(tài)算法或靜態(tài)算法取決于hash-type巍糯;
4. hash_type < method >
在balance 指令中選定與hash 有關(guān)的算法,都會(huì)受此影響客扎。
默認(rèn)采取的方法為map-based
< method > 如下:
- map-based:取模法祟峦,hash數(shù)據(jù)結(jié)構(gòu)是靜態(tài)數(shù)組;
該hash是靜態(tài)的徙鱼,不支持在線調(diào)整權(quán)重宅楞,不支持慢啟動(dòng);
該算法調(diào)度平滑袱吆,后端服務(wù)器能夠均勻承受負(fù)載;
缺點(diǎn)也是明顯的:當(dāng)服務(wù)器的總權(quán)重發(fā)生變化時(shí)厌衙,即有服務(wù)器上線或下線,都會(huì)導(dǎo)致調(diào)度結(jié)果整體改變绞绒。如果想避免此種情況應(yīng)采用consistent 方法婶希;
- consistent:一致性哈希,哈希的數(shù)據(jù)結(jié)構(gòu)是“樹(shù)”蓬衡;
該hash是動(dòng)態(tài)的喻杈,支持在線調(diào)整權(quán)重,支持慢啟動(dòng)
每一個(gè)server 會(huì)在"樹(shù)"中出現(xiàn)多次狰晚, 在樹(shù)中查找hash key筒饰,并選擇最近的server;
該方法的優(yōu)點(diǎn)在于壁晒,當(dāng)服務(wù)器的總權(quán)重發(fā)生變化時(shí)瓷们,對(duì)調(diào)度結(jié)果影響是局部的,不會(huì)引起大的變動(dòng)讨衣。所以十分適合緩存服務(wù)器换棚;
缺點(diǎn):該算法不夠平滑,很容易導(dǎo)致后端服務(wù)器負(fù)載不均衡反镇。所以很有必要對(duì)服務(wù)器的權(quán)重以或者服務(wù)器ID進(jìn)行調(diào)整固蚤;
為保持均勻負(fù)載,應(yīng)該保證所有服務(wù)器ID保持一致歹茶;
5. server <name> <address>[:[port]] [param*]
default-server [param*]
server用于在backend和listen中定義一個(gè)主機(jī);
default-server 用于設(shè)定server的默認(rèn)參數(shù)夕玩;
[param*] 如下:
- weight < weight >:當(dāng)前server的權(quán)重;
- id < number > :設(shè)定server ID
- cookie < value >:為當(dāng)前server指定其cookie值惊豺,此值會(huì)在收到請(qǐng)求報(bào)文時(shí)進(jìn)行檢測(cè)燎孟,其功能在于實(shí)現(xiàn)基于cookie會(huì)話保持;
- check:對(duì)當(dāng)前server進(jìn)行健康狀態(tài)檢測(cè)尸昧;
inter < delay >:時(shí)間間隔揩页;
rise < count >:判定為“健康”狀態(tài)需要檢測(cè)的次數(shù),默認(rèn)2烹俗;
fall < count >:判定為“不健康”狀態(tài)需要檢測(cè)的次數(shù)爆侣,默認(rèn)3萍程;
addr <ipv4|ipv6>:健康狀態(tài)檢測(cè)時(shí)使用的地址;
port < port >:健康狀態(tài)檢測(cè)時(shí)使用的端口兔仰;
注意:默認(rèn)為傳輸層檢測(cè)茫负,即探測(cè)端口是否能響應(yīng);需要執(zhí)行應(yīng)用層檢測(cè)乎赴,則需要httpchk, smtpchk, mysql-check, pgsql-check, ssl-hello-chk忍法; - maxconn <maxconn>:當(dāng)前server的最大并發(fā)連接數(shù);
- maxqueue <maxqueue>:當(dāng)前server的等待隊(duì)列的最大長(zhǎng)度榕吼;
- disabled:將主機(jī)標(biāo)記為不可用饿序;
- redir <prefix>:將發(fā)往當(dāng)前server的所有請(qǐng)求GET和HEAD類(lèi)的請(qǐng)求均重定向至指定的URL;
Examples :
server first 10.1.1.1:1080 id 3 cookie first check inter 1000 maxconn 10000 maxqueue 2000
server second 10.1.1.2:1080 id 4 cookie second check inter 1000
6. option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
基于http協(xié)議作7層健康狀態(tài)檢測(cè)機(jī)制友题,默認(rèn)是基于tcp層進(jìn)行檢測(cè)嗤堰;
TCP 模式也可以使用該檢測(cè)機(jī)制
< method > < uri > < version >:請(qǐng)求報(bào)文的超始行戴质;
method 默認(rèn)方法為 OPTIONS度宦;返回狀態(tài)碼2XX,3XX意味成功告匠;
Examples :
# Relay HTTPS traffic to Apache instance and check service availability
# using HTTP request "OPTIONS * HTTP/1.1" on port 80.
backend https_relay
mode tcp
option httpchk OPTIONS /index.html HTTP/1.1\r\nHost:\ www
server apache1 192.168.1.1:443 check port 80
7. http-check expect [!] <match> <pattern>
定義檢測(cè)有效期望值戈抄;
! 表示認(rèn)定的錯(cuò)誤值;< match > 可取值為:
- status < string >
- rstatus < regex > 正則方式
- string < string >
- rstring < regex >
Examples :
# only accept status 200 as valid
http-check expect status 200
# consider SQL errors as errors
http-check expect ! string SQL\ Error
# consider status 5xx only as errors
http-check expect ! rstatus ^5
# check that we have a correct hexadecimal tag before /html
http-check expect rstring <!--tag:[0-9a-f]*</html>
8. cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
啟用基于cookie的會(huì)話黏性后专,要結(jié)合server指定的cookie參數(shù)一起實(shí)現(xiàn);
常用形式:cookie WEBSRV insert nocache indirect
Example:
backend websrvs
balance roundrobin
cookie WEBSRV insert nocache indirect
server web1 10.1.0.68:80 check weight 2 maxconn 5000 cookie web1
server web2 10.1.0.69:80 check weight 1 maxconn 3000 cookie web2
9. default_backend <backend>
當(dāng)use_backend 的使用規(guī)則沒(méi)有被匹配時(shí)划鸽,由default_backend 指定默認(rèn)服務(wù)器組;
關(guān)于use_backend 使用后續(xù)會(huì)在acl 章節(jié)中講解戚哎;
3.2.2 log 相關(guān)
為frontend
或backend
定義日志記錄機(jī)制裸诽;
log global :使用全局定義的日志記錄方式
log <address> [len <length>] <facility> [<level> [<minlevel>]]:自定義
no log :不記錄
capture request header <name> len <length>
-->記錄請(qǐng)求報(bào)文中的指定的首部的值于日志中;len用于指定要記錄的信息的長(zhǎng)度型凳;
capture response header <name> len <length>
-->記錄響應(yīng)報(bào)文中的指定的首部的值于日志中丈冬;len用于指定要記錄的信息的長(zhǎng)度;
示例:
capture request header Referer len 30
3.2.3 自定義錯(cuò)誤頁(yè)面
errorfile <code> <file>
< code > 指定HTTP返回的狀態(tài)碼甘畅。200, 400, 403, 408, 500, 502, 503, and 504 可使用埂蕊;
< file > 指定一個(gè)文件代替HTTP響應(yīng);
Example:
errorfile 503 /etc/haproxy/errorfiles/503sorry.http
- errorloc <code> <url>
- errorloc302 <code> <url>
發(fā)生錯(cuò)誤時(shí)由haproxy重定向至指定url疏唾,以上兩個(gè)命令等同蓄氧,響應(yīng)狀態(tài)碼為302
Example:
errorloc 503 http://www.mydomain.com/index...
- errorloc303 <code> <url>
響應(yīng)狀態(tài)碼為303,表示以GET方法重新請(qǐng)求頁(yè)面
3.2.4 修改請(qǐng)求或響應(yīng)報(bào)文首部
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
HAProxy把請(qǐng)求報(bào)文發(fā)往后端主機(jī)之前在請(qǐng)求報(bào)文添加“X-Forwared-For”首部
目的為使后端服務(wù)器可記錄發(fā)出請(qǐng)求客戶端的IP地址
[ except < network> ] :選擇排除的網(wǎng)絡(luò)地址
[ header < name> ] :不使用X-Forwared-For槐脏,自定義名稱(chēng)
[ if-none ]:有時(shí)請(qǐng)求原來(lái)帶有該字段喉童,此時(shí)不再更改
Example:option forwardfor if-none
reqadd <string> [{if | unless} <cond>]
rspadd <string> [{if | unless} <cond>]
在HTTP請(qǐng)求或響應(yīng)首部?jī)?nèi)容尾部添加值
Example:rspadd X-Via: HAProxy/1.5
reqdel <search> [{if | unless} <cond>]
reqidel <search> [{if | unless} <cond>] (不區(qū)分大小寫(xiě))
刪除HTTP請(qǐng)求中正則匹配的所有首部
rspdel <search> [{if | unless} <cond>]
rspidel <search> [{if | unless} <cond>] (不區(qū)分大小寫(xiě))
刪除HTTP響應(yīng)中正則匹配的所有首部。屬于安全加強(qiáng)策略顿天,刪除一些服務(wù)器版本信息堂氯,防止針對(duì)攻擊
Example:rspidel Server.*
3.2.5 超時(shí)時(shí)長(zhǎng)設(shè)定
timeout client <timeout>
設(shè)定客戶端最大非活動(dòng)時(shí)長(zhǎng)重抖, 默認(rèn)單位是ms;最好與timeout server一致
timeout server <timeout>
設(shè)定服務(wù)端最大非活動(dòng)時(shí)長(zhǎng)祖灰, 默認(rèn)單位是ms钟沛;
timeout connect <timeout>
設(shè)定最大與服務(wù)端建立連接的時(shí)長(zhǎng)
timeout http-keep-alive <timeout>
設(shè)定最大等待新請(qǐng)求的空閑時(shí)長(zhǎng),默認(rèn)單位為ms局扶;
timeout client-fin <timeout>
在客戶端側(cè)設(shè)定半關(guān)閉連接非活動(dòng)超時(shí)
timeout server-fin <timeout>
在服務(wù)端側(cè)設(shè)定半關(guān)閉連接非活動(dòng)超時(shí)
Example:
defaults http
timeout connect 5s
timeout client 30s
timeout server 30s
timeout client-fin 10s
timeout http-keep-alive 500
4恨统、使用ACLs和獲取樣本
Haproxy 能夠從請(qǐng)求報(bào)文,響應(yīng)報(bào)文三妈,從客戶端或者服務(wù)端信息畜埋,從表,環(huán)境信息等等中提取數(shù)據(jù)畴蒲。提取這樣的數(shù)據(jù)的動(dòng)作我們稱(chēng)之為獲取樣本悠鞍。進(jìn)行檢索時(shí),這些樣本可以用來(lái)實(shí)現(xiàn)各種目的模燥,比如作為粘滯表的鍵咖祭,最常用的用途是,根據(jù)預(yù)定義的模式來(lái)進(jìn)行匹配蔫骂。
訪問(wèn)控制列表(ACL)提供一個(gè)靈活方案進(jìn)行內(nèi)容切換么翰,或者在從請(qǐng)求,響應(yīng)辽旋,任何環(huán)境狀態(tài)中提取的數(shù)據(jù)基礎(chǔ)之上做出決策浩嫌。控制列表的原則很簡(jiǎn)單:
- 從數(shù)據(jù)流补胚,表码耐,環(huán)境中提取數(shù)據(jù)樣本
- 對(duì)提取的樣本可選地應(yīng)用格式轉(zhuǎn)換
- 對(duì)一個(gè)樣本應(yīng)用一個(gè)或多個(gè)模式匹配
- 當(dāng)模式匹配樣本時(shí)才執(zhí)行動(dòng)作
執(zhí)行的動(dòng)作通常是阻斷請(qǐng)求,選擇一個(gè)后端服務(wù)器或者添加一個(gè)HTTP首部
需要提醒的是溶其,獲取的樣本數(shù)據(jù)不光可以使用在acl中骚腥,也可以使用別處,例如記錄log中
定義ACL的語(yǔ)法為:
acl <aclname> <criterion> [flags] [operator] [<value>] ...
這樣一條語(yǔ)句建立了一個(gè)acl 測(cè)試握联;
這些測(cè)試應(yīng)用在請(qǐng)求或響應(yīng)中被"標(biāo)準(zhǔn)"< criterion > 部分所指定的內(nèi)容桦沉,而且可以指定[ flags] 進(jìn)行特性調(diào)整,有些< criterion > 支持操作符[operator] 進(jìn)行運(yùn)算金闽,同時(shí)一些轉(zhuǎn)換格式的關(guān)鍵字可以跟在< criterion >后面纯露,使用" , "隔開(kāi)。而值[< value >] 要求被
< criterion > 所支持的數(shù)據(jù)形式代芜,多個(gè)值使用空格分隔瓶摆。
< criterion > 通常是指獲取樣本方法的名稱(chēng)楣嘁。使用一個(gè)獲取樣本方法彻坛,暗含著其輸出樣本的類(lèi)型,類(lèi)型是以下列出的一種:
- boolean
- integer (signed or unsigned)
- IPv4 or IPv6 address
- string
- data block
ACL引擎匹配數(shù)據(jù)使用的模式類(lèi)型如下:
- boolean
- integer or integer range
- IP address / network
- string (exact, substring, suffix, prefix, subdir, domain)
- regular expression
- hex block
ACL flags 可用列表如下:
- -i : 忽略大小寫(xiě)
- -f filename : 從文件中載入模式
- -m method : 指定模式匹配方法
- -n : 禁止DNS解析
- -M : -f 載入的文件作為映射文件使用
- -u : 強(qiáng)制ACL的名稱(chēng)唯一
- -- : 強(qiáng)制結(jié)束flag結(jié)束贷掖,避免了字符串中含有的- 引起混淆
其中flag中的 -m 選項(xiàng)可使用的模式匹配方法如下,需要說(shuō)明的是有些方法已被默認(rèn)指定無(wú)需聲明渴语,例如int苹威,ip
- "found" : 只是用來(lái)探測(cè)數(shù)據(jù)流中是否存在指定數(shù)據(jù),不進(jìn)行任何比較
- "bool" : 檢查結(jié)果返回布爾值驾凶。匹配沒(méi)有模式牙甫,可以匹配布爾值或整數(shù),不匹配0和false调违,其他值可以匹配
- "int" : 匹配整數(shù)類(lèi)型數(shù)據(jù)窟哺;可以處理整數(shù)和布爾值類(lèi)型樣本,0代表false技肩,1代表true
- "ip" : 匹配IPv4且轨,IPv6地址類(lèi)型數(shù)據(jù)。該模式僅被IP地址兼容虚婿,不需要特別指定
- "bin" : 匹配二進(jìn)制數(shù)據(jù)
- "len" : 匹配樣本的長(zhǎng)度的整數(shù)值
- "str" : 精確匹配旋奢,根據(jù)字符串匹配文本
- "sub" : 子串匹配,匹配文本是否包含子串
- "reg" : 正則匹配雳锋,根據(jù)正則表達(dá)式列表匹配文本
- "beg" : 前綴匹配黄绩,檢查文本是否以指定字符串開(kāi)頭
- "end" : 后綴匹配,檢查文本是否以指定字符串結(jié)尾
- "dir" : 子目錄匹配玷过,檢查部分文本中以" / "作為分隔符的內(nèi)容是否含有指定字符串
- "dom" : 域匹配。檢查部分文本中以" . "作為分隔符的內(nèi)容是否含有指定字符串
如果獲取樣本值為整數(shù)筑煮,數(shù)值比較符可使用辛蚊,:
eq : true if the tested value equals at least one value
ge : true if the tested value is greater than or equal to at least one value
gt : true if the tested value is greater than at least one value
le : true if the tested value is less than or equal to at least one value
lt : true if the tested value is less than at least one value
想必前面一堆理論性的論述已經(jīng)把大家搞的暈頭轉(zhuǎn)向,下面結(jié)合獲取樣本方法和訪問(wèn)控制動(dòng)作指令具體闡述ACL使用方法
先介紹控制動(dòng)作指令
-
layer 4 傳輸層控制指令
tcp-request connection <action> [{if | unless} <condition>]
對(duì)tcp請(qǐng)求控制指令:
< condition > 即為ACL定義的訪問(wèn)控制列表
< action > 常用值有 "accept", "reject"
- layer 7 應(yīng)用層控制指令
#阻斷符合ACL的訪問(wèn)請(qǐng)求
block { if | unless } <condition>
#http請(qǐng)求的控制指令
http-request { allow | deny} [ { if | unless } <condition> ]
-
后端主機(jī)調(diào)用
#根據(jù)條件來(lái)調(diào)用指定后端 use_backend <backend> [{if | unless} <condition>]
由ACL定義的多個(gè)< condition > 組成聯(lián)合條件真仲,邏輯符為
and (默認(rèn)操作符袋马,可省略)
or (或者使用 "||")
! (取反)
4.1 獲取內(nèi)部狀態(tài)樣本
# 與后端建立會(huì)話速率,每秒鐘建立的新會(huì)話
be_sess_rate([<backend>]) : integer
Example :
# 某后端被請(qǐng)求過(guò)于繁忙秸应,則重定向至錯(cuò)誤頁(yè)
mode http
acl being_scanned be_sess_rate gt 100
redirect location /denied.html if being_scanned
4.2 獲取layer 4 樣本
在傳輸層獲取樣本虑凛,通常是TCP/IP 協(xié)議的IP和端口,以及建立連接速率等等软啼。而且此部分樣本通常用于"tcp-request connection"指令中的規(guī)則之中桑谍。
dst : ip #目標(biāo)地址
dst_port : integer
src : ip #源地址
src_port : integer
Example:
#阻斷來(lái)自非指定IP的訪問(wèn)8080端口的請(qǐng)求
acl myhost src 10.1.0.200
acl myport dst_port 8080
tcp-request connection reject if !myhost myport
4.3 獲取layer 7 樣本
/1
path : string
提取請(qǐng)求url的地址信息,從第一個(gè)"/"開(kāi)始祸挪,不包含host锣披,不包含參數(shù)
ACL 衍生,即包含了-m 選項(xiàng)中匹配模式方法 :
path : exact string match
path_beg : prefix match
path_dir : subdir match
path_dom : domain match
path_end : suffix match
path_len : length match
path_reg : regex match
path_sub : substring match
Example:
#請(qǐng)求資源為圖片,則調(diào)用圖片服務(wù)器后端
acl picture path_end -i .jpg .png .gif
use_backend server_pic if picture
/2
url : string
提取URL的全部?jī)?nèi)容雹仿,包含host和參數(shù)
ACL 衍生類(lèi)似增热,不再列舉
/3
req.hdr([<name>[,<occ>]]) : string
提取http請(qǐng)求的指定首部字段值,< occ >可指定出現(xiàn)的位置
ACL 衍生 :
hdr([<name>[,<occ>]]) : exact string match
hdr_beg([<name>[,<occ>]]) : prefix match
hdr_dir([<name>[,<occ>]]) : subdir match
hdr_dom([<name>[,<occ>]]) : domain match
hdr_end([<name>[,<occ>]]) : suffix match
hdr_len([<name>[,<occ>]]) : length match
hdr_reg([<name>[,<occ>]]) : regex match
hdr_sub([<name>[,<occ>]]) : substring match
Example:
#阻斷火狐瀏覽器發(fā)送的請(qǐng)求
acl firefox hdr_reg(User-Agent) -i .*firefox.*
block if firefox
/4
method : integer + string
提取請(qǐng)求報(bào)文中的請(qǐng)求方法
Example:
#拒絕GET HEAD 方式之外的HTTP請(qǐng)求
acl valid_method method GET HEAD
http-request deny if ! valid_method
4.4 內(nèi)建ACL
HAProxy有眾多內(nèi)建的ACLs胧辽,這些ACLs可直接調(diào)用峻仇,例如
- LOCALHOST 匹配來(lái)自本地IP的連接,127.0.0.1/8
- HTTP_1.1 匹配http版本1.1
- METH_GET 匹配http請(qǐng)求GET或HEAD方法
- TRUE
- FALSE
Example:
#拒絕GET HEAD 方式之外的HTTP請(qǐng)求
http-request deny if ! METH_GET