HAProxy的ACL调度规则

HAProxy的ACL可以对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作。

acl的定义

语法格式:
acl             [flags]      [operator]     []
acl     acl名称        条件         条件标记位     具体操作符    操作对象类型

criterion

hdr([ [,]]):完全匹配字符串 
hdr_beg([ [,]]):前缀匹配 
hdr_dir([ [,]]):路径匹配 
hdr_dom([ [,]]):域匹配 
hdr_end([ [,]]):后缀匹配 
hdr_len([ [,]]):长度匹配 
hdr_reg([ [,]]):正则表达式匹配 
hdr_sub([ [,]]):子串匹配 
dst       目标IP 
dst_port  目标PORT 
src       源IP 
src_port  源PORT

flags

-i 不区分大小写
-m 使用指定的pattern匹配方法 
-n 不做DNS解析 
-u 禁止acl重名,否则多个同名ACL匹配或关

operator

整数比较:eq、ge、gt、le、lt 
字符比较: 
- exact match (-m str) :字符串必须完全匹配模式 
- substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配 
- prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配 
- suffix match (-m end) :将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行 匹配 
- subdir match (-m dir) :查看提取出来的用斜线分隔(“/”)的字符串,如果其中任何一个匹配,则 ACL进行匹配 
- domain match    (-m dom) :查找提取的用点(“.”)分隔字符串,如果其中任何一个匹配,则ACL进 行匹配

value

- Boolean #布尔值false,true 
- integer or integer range #整数或整数范围,比如用于匹配端口范围,1024~32768 - IP address / network #IP地址或IP范围, 192.168.0.1 ,192.168.0.1/24 
-string exact –精确比较 
    substring—子串 www.magedu.com 
    suffix-后缀比较 
    prefix-前缀比较 
    subdir-路径,/wp-includes/js/jquery/jquery.js 
    domain-域名,www.magedu.com 
- regular expression #正则表达式 
- hex block #16进制

acl的调用

多个acl作为条件时的逻辑关系

与:隐式(默认)使用 
或:使用"or" 或 "||"表示 
否定:使用"!" 表示

基于acl定义不同的域名调度到不同的后端服务器

示例1:根据用户的请求的域名的不同做匹配
1.修改haproxy配置文件

frontend web
 bind 172.20.27.20:80
 mode http
 acl pc_web_page hdr(host) -i www.mylinuxops.com    #忽略大小写匹配报文头部的主机名
 acl m_web_page hdr(host) -i m.mylinuxops.com

 use_backend pc_server if pc_web_page           #ACL的调用
 use_backend m_server if m_web_page             
 default_backend backup_server                  #当请求都不符合时调转到默认页面

backend pc_server
 server web1 192.168.27.21:80 weight 1 check  inter 3s fall 3 rise 5
backend m_server
 server web2 192.168.27.22:80 weight 1 check  inter 3s fall 3 rise 5
backend back_server
 server web2 192.168.27.22:80 weight 1 check inter 3s fall 3 rise 5

2.测试

[root@localhost ~]# vim /etc/hosts
[root@localhost ~]# curl m.mylinuxops.com       #匹配到规则后调用后端对应的服务器
m.mylinuxops.com
[root@localhost ~]# curl www.mylinuxops.com
www.mylinuxops.com
[root@localhost ~]# curl dl.mylinuxops.com      #没有匹配到规则调用默认的服务器
welcome to mylinuxops.com

acl的与、或和非

与:当用户请求的域名即满足第一个匹配条件也满足第二个条件时就调用后端的服务器组
或:当用户请求的域名满足第一个匹配条件或者第二个条件就调用某个后端服务器组
非:当用户的请求不满足条件是调用某个后端的服务器组
示例:或的使用
1.修改haproxy配置文件

frontend web
 bind 172.20.27.20:80
 mode http                  
 acl pc_web_page hdr_dom(host) -i www.mylinuxops.com        #配置acl规则,规则名字pc_web_page,匹配用户请求的域名,忽略大小写,匹配的内容为www.mylinuxops.com
 acl mobile_web_page hdr_dom(host) -i m.mylinuxops.com      #配置acl规则,规则名字mobile_web_page,匹配用户请求的域名,忽略大小写,匹配的内容为m.mylinuxops.com

 use_backend pc_server if pc_web_page                         #配置调用规则,当匹配规则所定义的条件时,调用pc_host所定义的后端服务器
 use_backend mobile_server if mobile_web_page                 #配置调用规则,当匹配规则所定义的条件时,调用mobile_host所定义的后端服务器

backend pc_server
 server web1 192.168.27.21:80 weight 1 check inter 3s fall 3 rise 5
backend mobile_host
 server web2 192.168.27.22:80 weight 1 check inter 3s fall 3 rise 5
backend backup_server
 server web2 192.168.27.22:80 weight 1 check inter 3s fall 3 rise 5

2.测试

[root@localhost ~]# curl www.mylinuxops.com
www.mylinuxops.com          #返回的为web1上虚拟主机定义的主页面
[root@localhost ~]# curl m.mylinuxops.com
ojbk                        #由于后端服务器没有此域名的虚拟主机,所以返回了一个服务器默认的index.html页面

acl基于源地址做调度

使用acl,对IP地址做匹配,做到从某个地址或者地址段来的就调度到哪个后端的服务器上
示例:

frontend web
 bind 172.20.27.20:80
 mode http
 acl ip_range_test src 192.168.27.0/24 172.20.27.10
 use_backend m_server if ip_range_test
 default_backend backup_server

backend pc_server
 server web1 192.168.27.21:80 weight 1 check  inter 3s fall 3 rise 5
backend m_server
 server web2 192.168.27.22:80 weight 1 check  inter 3s fall 3 rise 5
backend backup_server
 server web2 192.168.27.22:80 weight 1 check inter 3s fall 3 rise 5

测试
查看nginx上测试页面

[root@web2 ~]# cat /data/www/index.html 
m.mylinuxops.com 
[root@web2 ~]# cat /apps/nginx/html/index.html 
welcome to mylinuxops.com

在172.20.27.10上测试访问

[root@localhost ~]# curl m.mylinuxops.com
m.mylinuxops.com                    #访问到了m.mylinuxops.com的主页面
[root@localhost ~]# curl www.mylinuxops.com
welcome to mylinuxops.com           #由于后端没有设定www.mylinux.com的virtualserver所里跳转到了默认页面

acl基于地址段做拒绝

使用acl对地址段做判断,对匹配的做拒绝操作

frontend web
 bind 172.20.27.20:80
 mode http
 acl ip_range_test src 192.168.27.0/24 172.20.27.10
 block if ip_range_test             #对ip地址段做拒绝时使用block
 default_backend backup_server
 #option httpchk HEAD /monitor-page/index.html HTTP/1.0 

backend pc_server
 server web1 192.168.27.21:80 weight 1 check  inter 3s fall 3 rise 5
backend m_server
 server web2 192.168.27.22:80 weight 1 check  inter 3s fall 3 rise 5
backend backup_server
 server web2 192.168.27.22:80 weight 1 check inter 3s fall 3 rise 5

测试
使用172.20.27.10主机进行访问

[root@localhost ~]# curl www.mylinuxops.com

403 Forbidden

#被拒绝 Request forbidden by administrative rules. [root@localhost ~]# curl m.mylinuxops.com

403 Forbidden

Request forbidden by administrative rules.

acl基于用户浏览器的类型

1.取得各浏览器的user-agent信息

#google
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36      
#FireFox
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0

取出user-agent中具有特征意义的部分作为匹配条件,google(Chrome),FireFox(Firefox)

2.修改配置文件

frontend web
 bind 172.20.27.20:80
 mode http

 acl google hdr(user-agent) -m sub -i "Chrome"          #匹配请求首部user-agent中的字串是否包含chrome
 acl firefox hdr(user-agent) -m sub -i "Firefox"        #匹配字串中是否有Firefox
 use_backend pc_server if google
 use_backend m_server if firefox
 default_backend backup_server

backend pc_server
 server web1 192.168.27.21:80 weight 1 check  inter 3s fall 3 rise 5
backend m_server
 server web2 192.168.27.22:80 weight 1 check  inter 3s fall 3 rise 5
backend backup_server
 server web2 192.168.27.22:80 weight 1 check inter 3s fall 3 rise 5

测试
HAProxy的ACL调度规则_第1张图片HAProxy的ACL调度规则_第2张图片
使用不同浏览器访问时分别被送到后端不同的服务器上

acl规则匹配后重定向

当被acl规则匹配到后也可以将访问的url进行重定向,使用redirect进行调用规则
示例:当浏览器为firefox时调度到baidu.com

frontend web
 bind 172.20.27.20:80
 mode http

 acl google hdr(user-agent) -m sub -i "Chrome"
 use_backend pc_server if google
 acl firefox hdr(user-agent) -m sub -i "Firefox"
 redirect prefix http://www.baidu.com if firefox    #当浏览器为firefox时重定向到百度

backend pc_server
 server web1 192.168.27.21:80 weight 1 check  inter 3s fall 3 rise 5
backend m_server
 server web2 192.168.27.22:80 weight 1 check  inter 3s fall 3 rise 5

测试
HAProxy的ACL调度规则_第3张图片

基于HAProxy实现匹配后缀做动静分离

haproxy可以使用acl中的path_end,基于所要访问的文件的后缀做动静分离的匹配
示例:
1.修改HAProxy配置文件

frontend web
 bind 172.20.27.20:80
 mode http
 acl php path_end -i .php                               #配置acl acl名为php 匹配后缀为 .php 忽略大小写
 acl image path_end -i .jpg .jpeg .gif .png             #配置acl acl名为image 匹配后缀为 .jpg .jpeg .gif .png 忽略大小写

 use_backend php_server if php                          #配置调用规则当匹配php的条件时,调用php_server
 use_backend image_server if image                      #匹配调用规则当匹配image的条件时,调用image_server

backend php_server
 server web1 192.168.27.21 check port 80 inter 3s fall 3 rise 5

backend image_server
 server web1 192.168.27.22 check port 80 inter 3s fall 3 rise 5

2.修改nginx+php服务器配置

[root@php ~]# vim /apps/nginx/conf/servers/mylinuxops.conf 
server {
        server_name www.mylinuxops.com;
        listen 80;
        access_log  /apps/nginx/logs/mylinuxops.log  access_json;
        location / {
                root /data/www;
                index index.html;
        }
        location ~ \.php$ {
            root           /data/php;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
}  

3.创建网站页面

[root@php ~]# mkdir /data/php/
[root@php ~]# vim /data/php/index.php 

4.修改静态服务器配置文件

[root@image ~]# vim /apps/nginx/conf/servers/mylinuxops.conf 
server {
        server_name www.mylinuxops.com;
        listen 80;
        access_log  /apps/nginx/logs/mylinuxops.log  access_json;
        location / {
                root /data/www;
                index index.html;
        }
}

5.在资源路径下添加图片

[root@localhost ~]# ls /data/www/
1.png  index.html

测试
HAProxy的ACL调度规则_第4张图片HAProxy的ACL调度规则_第5张图片

基于路径的头部做动静分离

haproxy中也可以基于文件访问的头部做匹配将其进行动静分离,比如某几个目录内都为静态文件,则将这几个目录进行匹配
示例:
修改配置文件

frontend web
 bind 172.20.27.20:80
 mode http
 acl php_path path_end -i php                           #定义匹配PHP后缀文件
 acl static_path path_beg -i /static /images /javascript /tfs   #定义匹配静态文件的目录
 use_backend  php_server if php_path                    #php后缀文件调用后端php_server
 use_backend  static_server if static_path              #静态资源路径时调用后端static_server
backend php_server
 server web1 192.168.27.21:80 weight 1 check  inter 3s fall 3 rise 5
backend static_server
 server web2 192.168.27.22:80 weight 1 check  inter 3s fall 3 rise 5
backend backup_server

配置后端php服务器

[root@php ~]# cat /data/www/php/index.php 

配置后端static服务器

[root@static ~]# ls /data/www/images/1.png 
/data/www/images/1.png

测试访问以php结尾文件
HAProxy的ACL调度规则_第6张图片
测试访问/images开头的文件
HAProxy的ACL调度规则_第7张图片

http基于策略的访问控制

修改haproxy配置文件

frontend web
 bind 172.20.27.20:80
 mode http                      #http的访问控制需要基于http的模式来进行
 acl php_path path_end -i php
 acl static_path path_beg -i /static /images /javascript /tfs
 acl client_deny src 172.20.27.0/18             #定义拒绝访问的源地址
 http-request deny if client_deny               #对匹配到的源地址发来的请求进行拒绝
 use_backend  php_server if php_path
 use_backend  static_server if static_path
backend php_server
 server web1 192.168.27.21:80 weight 1 check  inter 3s fall 3 rise 5
backend static_server
 server web2 192.168.27.22:80 weight 1 check  inter 3s fall 3 rise 5
backend backup_server
 server web2 192.168.27.22:80 weight 1 check inter 3s fall 3 rise 5

使用172.20.27.0网段的客户机测试访问

[root@localhost ~]# curl www.mylinuxops.com

403 Forbidden

#请求被拒绝 Request forbidden by administrative rules.