HAProxy(二):HAProxy的ACL規則實現智能負載均衡詳解與示例

1、HAProxy的ACL的功能

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        

 2、ACL示例

要注意到的是acl關鍵字可用在frontend、listen、backend中,不能用在default中。app

例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會根據請求的結尾來判斷負載均衡規則。

總結:上面舉了3個很簡單的HAProxy ACL訪問控制的例子,雖然例子中的配置很粗糙,但也能夠初步領略到HAProxy有着比較智能的負載均衡功能,在後面的博客中我會更深刻的介紹HAProxy的細節配置與調優

相關文章
相關標籤/搜索