ACL(Access Control List)訪問控制列表,HAProxy中的ACL的匹配條件和控制條件有許多種,功能很強大,能夠經過源地址、源端口、目標地址、目標端口、請求的資源類型、請求的主機等。html
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規則作處理,便須要下面的參數來設置:nginx
1.當符合指定的條件時使用特定的backend,<backend>表示設置的backend名,if和unless爲判斷條件,<condition>爲比較的對象,能夠是ACL規則,要注意的是在if和unless後面能夠接兩個ACL,默認表示兩個ACL同時知足時才use_backend執行。格式以下:web
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
例:express
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.配置四層的請求訪問控制。cookie
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關鍵字可用在frontend、listen、backend中,不能用在default中。app
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的主機是不能成功訪問的負載均衡
在沒有設置訪問規則限制時,用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控制生效了。
七層ACL規則匹配中,經常使用的參數是path,它用來作URL規則匹配,path包括如下參數:
path : 精確匹配
path_beg : 匹配字符串開頭的全部內容
path_dir : 子路徑匹配
path_dom :
path_end : 匹配字符串結尾的全部內容
path_len : 字符串長度匹配
path_reg : 正則表達式匹配
path_sub : 域名子串匹配
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 { } }
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會根據請求的結尾來判斷負載均衡規則。