1? 概述
訪問(wèn)控制列表(ACL)的使用為HAProxy提供了一個(gè)靈活的解決方案來(lái)執(zhí)行內(nèi)容交換,并且通?;趶恼?qǐng)求中提取的內(nèi)容、響應(yīng)或任何環(huán)境狀態(tài)進(jìn)行決策,HAProxy基于ACL實(shí)現(xiàn)了靈活的調(diào)度
本文介紹ACL語(yǔ)句中各個(gè)參數(shù)含義,定義ACL,使用ACL,以及結(jié)合例子來(lái)介紹ACL的使用
2? ACL作為條件時(shí)的邏輯關(guān)系
-與:隱式(默認(rèn))使用,默認(rèn)為與的關(guān)系
-或:使用“or”或“||”表示
-否定:使用“!“表示
示例:
有兩個(gè)條件為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ù)字,: . -_等符號(hào),同時(shí)區(qū)分字符大小寫
:比較的標(biāo)準(zhǔn)和條件,下一小節(jié)介紹具體用法。
的類型:
-boolean
-integeror integer range
-IPaddress / network
-string(exact, substring, suffix, prefix, subdir, domain)
-regularexpression:正則表達(dá)式
-hexblock
-i不區(qū)分大小寫
-m使用指定的pattern匹配方法
-n不做DNS解析
-u強(qiáng)制每個(gè)ACL必須唯一ID,否則多個(gè)同名ACL或關(guān)系
--強(qiáng)制flag結(jié)束.當(dāng)字符串和某個(gè)flag相似時(shí)使用
[operator]
匹配整數(shù)值:eq、ge、gt、le、lt
匹配字符串:
-exactmatch (-m str) :字符串必須完全匹配模式
-substringmatch (-m sub) :在提取的字符串中查找模式,如果其中任何一個(gè)被發(fā)現(xiàn),ACL將匹配
-prefixmatch (-m beg) :其中,beg為begin的縮寫,在提取的字符串首部中查找模式,如果其中任何一個(gè)被發(fā)現(xiàn),ACL將匹配
-suffixmatch (-m end) :將模式與提取字符串的尾部進(jìn)行比較,如果其中任何一個(gè)匹配,則ACL進(jìn)行匹配
-subdirmatch (-m dir) :查看提取出來(lái)的用斜線分隔(“/”)的字符串,如果其中任何一個(gè)匹配,則ACL進(jìn)行匹配
-domainmatch (-m dom) :查找提取的用點(diǎn)(“.”)分隔字符串,如果其中任何一個(gè)匹配,則ACL進(jìn)行匹配
3.2? 參數(shù)criterion介紹
criterion是比較的標(biāo)準(zhǔn)和條件,比較條件和標(biāo)準(zhǔn)很多:dst,dst_port,src,src_port,base : string, path : string,url: string,req.hdr([[,]]) : string,status: integer
這里將一一介紹相關(guān)用法
dst:目標(biāo)IP
dst_port:目標(biāo)PORT
src:源IP
src_port:源PORT
示例:
定義一個(gè)acl,名稱為invalid_src,指定源ip是172.18.50.61
acl??invalid_src?src??172.18.50.61
.base: string
返回第一個(gè)主機(jī)頭和請(qǐng)求的路徑部分的連接,該請(qǐng)求從第一個(gè)斜杠開始,并在問(wèn)號(hào)之前結(jié)束,對(duì)虛擬主機(jī)有用
完整的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
提取請(qǐng)求的URL路徑,該路徑從第一個(gè)斜杠開始,并在問(wèn)號(hào)之前結(jié)束(無(wú)主機(jī)部分),默認(rèn)會(huì)被調(diào)度到同一后端主機(jī)上。
完整的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
例子
表示當(dāng)來(lái)自ip:172.18.50.61訪問(wèn)http:/ip/admin的url就會(huì)被拒絕,61訪問(wèn)其他的資源不會(huì)被拒絕
acl?deny_src?src?172.18.50.61
acl?sunnypath?path_beg?/sunny
block?if?deny_srcsunnypath
.url:string
提取請(qǐng)求中的URL。一個(gè)典型的應(yīng)用是具有預(yù)取能力的緩存,以及需要從數(shù)據(jù)庫(kù)聚合多個(gè)信息并將它們保存在緩存中的網(wǎng)頁(yè)門戶入口
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
提取在一個(gè)HTTP請(qǐng)求報(bào)文的首部
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
示例二:
實(shí)現(xiàn)域名的調(diào)度,根據(jù)首部實(shí)現(xiàn),將地址為www.sunny.com 滿足acl 為imagehost的請(qǐng)求調(diào)度到image這組backend的服務(wù)器請(qǐng)求,其他的請(qǐng)求調(diào)度到默認(rèn)的組為websrv處理請(qǐng)求。這個(gè)使用要保證測(cè)試主機(jī)能夠解析haproxy服務(wù)器為www.sunny.com
acl?imagehost?hdr(host)?www.sunny.com
use_backend?image?if?imagehost
default_backendwebsrv
.status: integer
返回在響應(yīng)報(bào)文中的狀態(tài)碼,根據(jù)返回的狀態(tài)碼進(jìn)行匹配
3.3? 預(yù)定義ACL
系統(tǒng)預(yù)定義的ACL,可以直接使用
以下將介紹預(yù)定義ACL的等價(jià)配置和用法說(shuō)明
格式為
ACL名稱:ACL等價(jià)配置;ACL用法說(shuō)明
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)容長(zhǎng)度
HTTP_URL_ABS:url_reg?^[^/:]*://;匹配URL絕對(duì)路徑
HTTP_URL_SLASH:url_beg?/;匹配URL相對(duì)路徑
HTTP_URL_STAR:url?*;匹配URL?等于"*"
LOCALHOST:src?127.0.0.1/8;匹配從localhost來(lái)的連接
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ǐng)求緩沖區(qū)中的數(shù)據(jù)
WAIT_END:wait_end;等待內(nèi)容分析的結(jié)束
4? ACL使用
use_backend配置
.use_backend? ?[{if | unless} ]
當(dāng)if/unless一個(gè)基于ACL的條件匹配時(shí)切換指定backend。
例子
以下例子實(shí)現(xiàn)動(dòng)靜分離,當(dāng)訪問(wèn)php文件的時(shí)候,就往dynhost這組backend調(diào)度,其他資源默認(rèn)都發(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層請(qǐng)求if/unless一個(gè)條件匹配
.block { if | unless }
.示例:
acl?invalid_src??src172.16.200.2
block?if?invalid_src
http-request配置
對(duì)7層請(qǐng)求的訪問(wèn)控制,主要指http-request
.http-request? ?{allow | deny |add-header |set-header } [ { if | unless } ?]
根據(jù)第4層條件對(duì)傳入連接執(zhí)行操作
.tcp-request connection ?{accept|reject} ?[{if | unless} ]
注意協(xié)議和模式的匹配,默認(rèn)為HTTP協(xié)議,haproxy一般用來(lái)調(diào)度http,如果非http協(xié)議就用mode來(lái)單獨(dú)定義,如mode? tcp,不過(guò)生產(chǎn)中,mysql一般用專業(yè)調(diào)度數(shù)據(jù)庫(kù)的工具來(lái)調(diào)度
5? 例子
例子一:實(shí)現(xiàn)ssh的調(diào)度
先在ssh的配置文件更改ssh監(jiān)聽(tīng)的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
測(cè)試
在172.18.50.61上測(cè)試,每次測(cè)試完成后,都要把172.18.50.63下/root/.ssh/known_hosts下的172.18.50.63的記錄清理掉然后在重新ssh連接,否則調(diào)度中,有一臺(tái)會(huì)因?yàn)閙ac不一致導(dǎo)致安全問(wèn)題,調(diào)度成功了,但是連接不上。
ssh??172.18.50.63
例子二:實(shí)現(xiàn)mysql調(diào)度
實(shí)現(xiàn)只有主機(jī)172.18.50.61能夠通過(guò)172.18.50.73這臺(tái)機(jī)器調(diào)度到后端的mysql,其他的機(jī)器都不能通過(guò)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
測(cè)試
登陸數(shù)據(jù)庫(kù)
mysql?-uwpadmin?-pPass123456?-h?172.18.50.73
登陸數(shù)據(jù)庫(kù)后,如果用system可以調(diào)用本機(jī)的linux命令,但是查看的是本機(jī)的相關(guān)信息,如system? hostname 查看的是本機(jī)的計(jì)算機(jī)名,通過(guò)查看變量名在mysql里查看遠(yuǎn)程的連接計(jì)算機(jī)名
show?variables?like?'hostname';
例子三:基于ACL實(shí)現(xiàn)wordpress動(dòng)靜分離
注意,因?yàn)閼?yīng)用wordpress在調(diào)用php腳本時(shí),需要用到其他資源,所以default_backend要設(shè)置在處理wordpress里php文件的服務(wù)器組中,如以下的dynamicblog專門用來(lái)處理php文件,所以將default_backend設(shè)置為dynamicblog這一組服務(wù)器。
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