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


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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM