一、HAProxy的ACL的功能
ACL(Access Control List)訪問控制列表,HAProxy中的ACL的匹配條件和控制條件有許多種,功能很強大,可以通過源地址、源端口、目標地址、目標端口、請求的資源類型、請求的主機等。
acl格式:acl <aclname> <criterion> [flags] [operator] [<value>] aclname:自定義acl的名稱,必填項,只能是大小寫、數字、'-'、'_'、'.'、':' criterion:表示檢查那些數據或內容,例如USERAGENT這個首部的值
四個最為常用的criterion為:
src:ip 源IP
src_port:integer 源端口
dst:ip 目標IP
dst_port:integer 目標端口
flags:定義控制條件,例如是否區分字符大小寫等,flags的可選參數如下: -i 忽略字符大小寫 -m 啟用特定的匹配方式,一般不用 -n 禁止DNS反向解析 -u 不允許aclname重復,默認是可以重名的,當兩個acl的名稱相同時,運算為或機制。 operator:判斷匹配條件,與<criterion>相比較的條件 若匹配整數值:eq,ge,gt,le,lt 若匹配字符串: value:訪問控制的具體內容或值。value的類型如下: boolean:布爾值 integer or integer range:整數或整數范圍 IP address/network:網絡地址 string(exact, substring, suffix, prefix, subdir, domain):字符串 regular expression:正則表達式 hex block
上面的指令和參數都是為了設置或定義ACL的匹配條件的,即ACL僅僅只是將匹配條件進行分類歸納,而不進行處理。若要將定義好的ACL規則做處理,便需要下面的參數來設置:
1.當符合指定的條件時使用特定的backend,<backend>表示設置的backend名,if和unless為判斷條件,<condition>為比較的對象,可以是ACL規則,要注意的是在if和unless后面可以接兩個ACL,默認表示兩個ACL同時滿足時才use_backend執行。格式如下:
use_backend <backend> [{if | unless} <condition>] #Switch to a specific backend if/unless an ACL-based condition is matched.
2.阻塞一個七層請求滿足/不滿足某一ACL匹配條件。格式如下:
block { if | unless } <condition> #Block a layer 7 request if/unless a condition is matched
例:
acl invalid_src src 192.18.29.101 #acl匹配條件為源地址為192.18.29.101,acl名為invalid_src block if invalid_src #阻斷滿足名為invalid_src的acl匹配條件 errorfile 403 /etc/fstab #並定義錯誤頁
3.配置七層的請求訪問控制,與block阻塞不同,http-request更靈活,可做黑白名單控制。只能用在mode http中。
http-request { allow | deny } [ { if | unless } <condition> ]
4.配置四層的請求訪問控制。
tcp-request connection {accept|reject} [{if | unless} <condition>]
例:
listen ssh bind :22022 balance leastconn acl invalid_src src 172.16.200.2 #定義acl匹配規則 tcp-request connection reject if invalid_src #在四層拒絕滿足名為invalid_src的acl匹配規則 mode tcp server sshsrv1 172.16.100.6:22 check server sshsrv2 172.16.100.7:22 check
二、ACL示例
要注意到的是acl關鍵字可用在frontend、listen、backend中,不能用在default中。
例1:設置HAProxy狀態頁,只允許指定IP訪問,設置如下:
listen stats #定義名稱 bind *:9099 #監聽在9099端口 acl sta src 192.168.29.1 #匹配名為sta且源IP地址為192.168.29.1的ACL規則 block if ! sta #阻斷不匹配sta規則的所有條件,!為非 stats enable #啟用stats頁 stats uri /myhaproxy?admin #自定義stats頁面uri stats realm "Hello World" stats auth admin:admin #設置狀態頁登錄賬號和密碼
訪問成功如下圖,其他IP的主機是不能成功訪問的


例2:不適用block,使用http-request來達到例1的效果。
在沒有設置訪問規則限制時,用IP為192.168.29.104的主機訪問stats主頁:

提示錯誤401,只需輸入賬號密碼即可訪問,方法為:
curl --basic -u admin:admin http://192.168.29.101:9099/myhaproxy?admin
說明IP為29.104的主機可以訪問,並無限制。
添加限制后:
listen stats #定義名稱 bind *:9099 #監聽在9099端口 acl sta src 192.168.29.1 #匹配名為sta且源IP地址為192.168.29.1的ACL規則 http-request deny unless sta #拒絕除匹配sta規則以外的規則訪問 stats enable #啟用stats頁 stats uri /myhaproxy?admin #自定義stats頁面uri stats realm "Hello World" stats auth admin:admin #設置狀態頁登錄賬號和密碼
再用IP為29.104的主機訪問效果如下:

此時錯誤為403,而29.1的主機是可以訪問的(圖太大了就省略了),說明ACL控制生效了。
例3.七層規則匹配
七層ACL規則匹配中,常用的參數是path,它用來做URL規則匹配,path包括以下參數:
path : 精確匹配
path_beg : 匹配字符串開頭的所有內容
path_dir : 子路徑匹配
path_dom :
path_end : 匹配字符串結尾的所有內容
path_len : 字符串長度匹配
path_reg : 正則表達式匹配
path_sub : 域名子串匹配
下面來舉一個使用path的具體例子,選兩台主機,安裝Nginx並用Nginx虛擬為4台主機,兩台用來處理圖片請求,兩台用來處理文本請求,利用HAProxy負載均衡的ACL控制機制實現,結構圖如下:

1.在192.168.29.102上添加監聽8080端口的虛擬主機(安裝的是Nginx),修改Nginx配置,在主配置中添加如下信息:
server { listen 8080 default_server; listen [::]:8080 default_server; server_name _; root /usr/share/nginx/html/test; #路徑要修改,盡量不使用默認,盡量模擬為兩台不同物理機的效果 # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
2.在80端口的主機root目錄下創建文件static.txt,內容為static 1;在8080端口主機root目錄下創建文件static.txt,內容為static 2。重啟Nginx服務,並確保能正常訪問,如下圖


3.用同樣的方法在192.168.29.103上創建分別監聽在80和8080端口的虛擬主機,並在根目錄下創建圖片文件,確保能正常訪問,如下圖:


4.在主機192.168.29.101上配置HAProxy
frontend myweb bind *:80 acl image path_end .png #匹配以.png結尾的path規則 acl txt path_end .txt #匹配以.txt結尾的path規則 use_backend imagesv if image #將規則image負載均衡到服務器組imagesv use_backend txtsv if txt #將規則txt負載均衡至服務器組txtsv default_backend app #默認組,無匹配時負載均衡至此 backend imagesv balance roundrobin server image1 192.168.29.103:80 check server image2 192.168.29.103:8080 check backend txtsv balance roundrobin server txt1 192.168.29.102:80 check server txt2 192.168.29.102:8080 check backend app balance leastconn cookie server insert nocache server app1 192.168.29.102:80 check cookie svr1 server app2 192.168.29.103:80 check cookie svr2
配置完成后重啟HAProxy,分別訪問192.168.29.101/image.png和192.168.29.101/static.txt,並刷新,會發現內容會不停變化,如下圖:


這說明ACL規則培植成功,HAProxy會根據請求的結尾來判斷負載均衡規則。
