1? 概述
訪問控制列表(ACL)的使用為HAProxy提供了一個靈活的解決方案來執(zhí)行內(nèi)容交換,并且通常基于從請求中提取的內(nèi)容、響應或任何環(huán)境狀態(tài)進行決策捅僵,HAProxy基于ACL實現(xiàn)了靈活的調(diào)度
本文介紹ACL語句中各個參數(shù)含義,定義ACL眨层,使用ACL,以及結(jié)合例子來介紹ACL的使用
2? ACL作為條件時的邏輯關(guān)系
-與:隱式(默認)使用庙楚,默認為與的關(guān)系
-或:使用“or”或“||”表示
-否定:使用“!“表示
示例:
有兩個條件為invalid_src和invalid_port
if??invalid_src?invalid_port?#與關(guān)系
if?invalid_src||?invalid_port?#或關(guān)系
if??!?invalid_src?#非關(guān)系
3 ACL 格式定義
3.1? ACL格式介紹
格式如下:
acl???????[flags]?[operator]?[]?...
參數(shù)介紹
:ACL名稱,自定義趴樱,可使用字母馒闷,數(shù)字,: . -_等符號叁征,同時區(qū)分字符大小寫
:比較的標準和條件窜司,下一小節(jié)介紹具體用法。
的類型:
-boolean
-integeror integer range
-IPaddress / network
-string(exact, substring, suffix, prefix, subdir, domain)
-regularexpression:正則表達式
-hexblock
-i不區(qū)分大小寫
-m使用指定的pattern匹配方法
-n不做DNS解析
-u強制每個ACL必須唯一ID航揉,否則多個同名ACL或關(guān)系
--強制flag結(jié)束.當字符串和某個flag相似時使用
[operator]
匹配整數(shù)值:eq塞祈、ge、gt帅涂、le议薪、lt
匹配字符串:
-exactmatch (-m str) :字符串必須完全匹配模式
-substringmatch (-m sub) :在提取的字符串中查找模式,如果其中任何一個被發(fā)現(xiàn)媳友,ACL將匹配
-prefixmatch (-m beg) :其中斯议,beg為begin的縮寫,在提取的字符串首部中查找模式醇锚,如果其中任何一個被發(fā)現(xiàn)哼御,ACL將匹配
-suffixmatch (-m end) :將模式與提取字符串的尾部進行比較,如果其中任何一個匹配焊唬,則ACL進行匹配
-subdirmatch (-m dir) :查看提取出來的用斜線分隔(“/”)的字符串恋昼,如果其中任何一個匹配,則ACL進行匹配
-domainmatch (-m dom) :查找提取的用點(“.”)分隔字符串赶促,如果其中任何一個匹配液肌,則ACL進行匹配
3.2? 參數(shù)criterion介紹
criterion是比較的標準和條件,比較條件和標準很多:dst鸥滨,dst_port嗦哆,src,src_port,base : string, path : string,url: string,req.hdr([[,]]) : string谤祖,status: integer
這里將一一介紹相關(guān)用法
dst:目標IP
dst_port:目標PORT
src:源IP
src_port:源PORT
示例:
定義一個acl,名稱為invalid_src,指定源ip是172.18.50.61
acl??invalid_src?src??172.18.50.61
.base: string
返回第一個主機頭和請求的路徑部分的連接,該請求從第一個斜杠開始老速,并在問號之前結(jié)束,對虛擬主機有用
完整的url中:://:@:/;?#粥喜,base指的是:/;
base:?exact?string?match
base_beg:?prefix?match
base_dir:?subdir?match
base_dom:?domain?match
base_end:?suffix?match
base_len:?length?match
base_reg:?regex?match
base_sub:?substring?match
.path: string
提取請求的URL路徑,該路徑從第一個斜杠開始橘券,并在問號之前結(jié)束(無主機部分),默認會被調(diào)度到同一后端主機上额湘。
完整的url中:://:@:/;?#,path指/;
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
例子
表示當來自ip:172.18.50.61訪問http:/ip/admin的url就會被拒絕约郁,61訪問其他的資源不會被拒絕
acl?deny_src?src?172.18.50.61
acl?sunnypath?path_beg?/sunny
block?if?deny_srcsunnypath
.url:string
提取請求中的URL。一個典型的應用是具有預取能力的緩存但两,以及需要從數(shù)據(jù)庫聚合多個信息并將它們保存在緩存中的網(wǎng)頁門戶入口
url:?exact?string?match
url_beg:?prefix?match
url_dir:?subdir?match
url_dom:?domain?match
url_end:?suffix?match
url_len:?length?match
url_reg:?regex?match
url_sub:?substring?match
.req.hdr([[,]]): string
提取在一個HTTP請求報文的首部
hdr([[,]])?:exact?string?match
hdr_beg([[,]]):?prefix?match
hdr_dir([[,]]):?subdir?match
hdr_dom([[,]]):?domain?match
hdr_end([[,]]):?suffix?match
hdr_len([[,]]):?length?match
hdr_reg([[,]]):?regex?match
hdr_sub([[,]]):?substring?match
示例一:
禁止使用curl命令
acl?not_curl?hdr_sub(User-Agent)?-i?curl
block?if?not_curl
示例二:
實現(xiàn)域名的調(diào)度鬓梅,根據(jù)首部實現(xiàn),將地址為www.sunny.com 滿足acl 為imagehost的請求調(diào)度到image這組backend的服務器請求谨湘,其他的請求調(diào)度到默認的組為websrv處理請求绽快。這個使用要保證測試主機能夠解析haproxy服務器為www.sunny.com
acl?imagehost?hdr(host)?www.sunny.com
use_backend?image?if?imagehost
default_backendwebsrv
.status: integer
返回在響應報文中的狀態(tài)碼,根據(jù)返回的狀態(tài)碼進行匹配
3.3? 預定義ACL
系統(tǒng)預定義的ACL,可以直接使用
以下將介紹預定義ACL的等價配置和用法說明
格式為
ACL名稱:ACL等價配置紧阔;ACL用法說明
TRUE:always_true坊罢;總是匹配
FALSE:always_false;從不匹配
HTTP:req_proto_http擅耽;匹配HTTP協(xié)議
HTTP_1.0:req_ver?1.0活孩;匹配HTTP協(xié)議1.0
HTTP_1.1:req_ver?1.1;匹配HTTP協(xié)議1.1
HTTP_CONTENT:hdr_val(content-length)gt?0乖仇;匹配已存在內(nèi)容長度
HTTP_URL_ABS:url_reg?^[^/:]*://憾儒;匹配URL絕對路徑
HTTP_URL_SLASH:url_beg?/;匹配URL相對路徑
HTTP_URL_STAR:url?*乃沙;匹配URL?等于"*"
LOCALHOST:src?127.0.0.1/8起趾;匹配從localhost來的連接
METH_CONNECT:method?CONNECT;匹配HTTP?CONNECT方法
METH_GET:method?GET?HEAD警儒;匹配HTTP?GET?或者?HEAD?方法
METH_HEAD:method?HEAD训裆;匹配?HTTP?HEAD?方法
METH_OPTIONS:method?OPTIONS;匹配?HTTP?OPTIONS方法
METH_POST:method?POST蜀铲;匹配?HTTP?POST?方法
METH_TRACE:method?TRACE边琉;匹配?HTTP?TRACE方法
RDP_COOKIE:req_rdp_cookie_cntgt?0;匹配RDPcookie的存在
REQ_CONTENT:req_len?gt?0记劝;匹配請求緩沖區(qū)中的數(shù)據(jù)
WAIT_END:wait_end艺骂;等待內(nèi)容分析的結(jié)束
4? ACL使用
use_backend配置
.use_backend? ?[{if | unless} ]
當if/unless一個基于ACL的條件匹配時切換指定backend。
例子
以下例子實現(xiàn)動靜分離隆夯,當訪問php文件的時候钳恕,就往dynhost這組backend調(diào)度别伏,其他資源默認都發(fā)到websrv這組backend。
acl?dynhost?path_end??.php
acl?imagehost?hdr(host)?www.sunny.com
use_backend?image?if?dynhost
default_backend??websrv
block配置
阻止7層請求if/unless一個條件匹配
.block { if | unless }
.示例:
acl?invalid_src??src172.16.200.2
block?if?invalid_src
http-request配置
對7層請求的訪問控制忧额,主要指http-request
.http-request? ?{allow | deny |add-header |set-header } [ { if | unless } ?]
根據(jù)第4層條件對傳入連接執(zhí)行操作
.tcp-request connection ?{accept|reject} ?[{if | unless} ]
注意協(xié)議和模式的匹配厘肮,默認為HTTP協(xié)議牺陶,haproxy一般用來調(diào)度http蔫仙,如果非http協(xié)議就用mode來單獨定義,如mode? tcp,不過生產(chǎn)中矾兜,mysql一般用專業(yè)調(diào)度數(shù)據(jù)庫的工具來調(diào)度
5? 例子
例子一:實現(xiàn)ssh的調(diào)度
先在ssh的配置文件更改ssh監(jiān)聽的ip的ip為非22端口托嚣,然后haproxy配置如下
listen?ssh
bind?172.18.50.63:22
balance?leastconn
acl?invalid_src??src??172.18.50.
tcp-request?connection?reject?if??invalid_src
mode?tcp
server?sshsrv1?172.18.50.65:22?check
server?sshsrv2?172.18.50.75:22?check??backup
測試
在172.18.50.61上測試巩检,每次測試完成后,都要把172.18.50.63下/root/.ssh/known_hosts下的172.18.50.63的記錄清理掉然后在重新ssh連接示启,否則調(diào)度中兢哭,有一臺會因為mac不一致導致安全問題,調(diào)度成功了夫嗓,但是連接不上迟螺。
ssh??172.18.50.63
例子二:實現(xiàn)mysql調(diào)度
實現(xiàn)只有主機172.18.50.61能夠通過172.18.50.73這臺機器調(diào)度到后端的mysql,其他的機器都不能通過172.18.50.73調(diào)度連接
listenmysql
mode?tcp
bind?172.18.50.73:3306
balance?roundrobin
acl?valid_src?src?172.18.50.61
tcp-request?connection?reject?unless?valid_src
server?mysqlsrv1?172.18.50.65:3306?check
server?mysqlsrv2172.18.50.75:3306?check
測試
登陸數(shù)據(jù)庫
mysql?-uwpadmin?-pPass123456?-h?172.18.50.73
登陸數(shù)據(jù)庫后,如果用system可以調(diào)用本機的linux命令舍咖,但是查看的是本機的相關(guān)信息矩父,如system? hostname 查看的是本機的計算機名,通過查看變量名在mysql里查看遠程的連接計算機名
show?variables?like?'hostname';
例子三:基于ACL實現(xiàn)wordpress動靜分離
注意排霉,因為應用wordpress在調(diào)用php腳本時窍株,需要用到其他資源,所以default_backend要設置在處理wordpress里php文件的服務器組中攻柠,如以下的dynamicblog專門用來處理php文件夹姥,所以將default_backend設置為dynamicblog這一組服務器。
frontend??http
bind?*:80
acl?url_dyn?path_end?-i.php
acl?url_stac?path_end-i??.jpg?.gif?.png?.css?.js?.html?.txt
default_backenddynamicblog?if?url_dyn
use_backend????staticblog?if?url_stac
reqadd?sunny-x-via:\?haproxy7c
rspdel?Server
rspadd??Server:\?Sunny-proxy7c
option?forwardfor????header?sunny-x-client
backend?staticblog
balance?????roundrobin
cookie?WEBSRV?insertnocache
server??????web6e?172.18.50.65:80?check?weight?1???inter?3000?rise?2?fall?2?cookie?cksrv1
backend?dynamicblog
balance?????roundrobin
cookie?WEBSRV?insertnocache
server?????web6e?172.18.50.75:80?check?weight?1??inter?3000?rise?2?fall?2?cookie?cksrv2
listen?stats
bind?:9091
stats?enable
stats?auth??admin:admin
stats?admin??if?TRUE