Haproxy中的acl的详解

haproxy 能够从请求报文,响应报文,从客户端或者服务器端,从表,环境信息等中提取数据,提取这样的数据的动作我们称之为获取样本,进行检索时,这些样本可以用来实现各种目的,比如作为粘滞表的键,最常用的用途是,根据预定义的模式来进行匹配。访问控制列表(ACL)提供一个灵活方案进行内容切换,或者从请求,响应,任何环境状态中提取的数据基础之上做出决策,控制列表的原则很简单:

  • 从数据流,表,环境中提取数据样本
  • 对提取的样本可选的应用格式转换
  • 对一个样本应用一个或多个模式匹配
  • 当模式匹配样本时才执行动作
    执行的动作通常是阻断请求,选择一个后端服务器或者添加一个HTTP手部。(hint:获取的样本数据不仅仅可以使用在acl中,也可以使用在别处,例如记录log)

ACL语法:
acl {aclname} {criterion} [flags] [operator] [{value}]…

语句解释:在请求或响应中被{criterion}部分所制定的内容,而且可以指定{flags}执行特征调整,有些{criterion}支持操作符
[operator]进行运算,同时一些转换格式的关键字可以跟在{criterion}后面,使用“,”隔开而值[{value}]要求被 {criterion}所支持的数据形式,多个值使用空格分隔。

{criterion}通常是指获取样本方法的名称,使用一个获取样本方法,暗含其输出样本的类型,类型如下:

  • boolean
  • integer(signed or unsigned)
  • IPV4 or IPv6 address
  • string
  • data block

ACL引擎匹配数据使用的模式类型如下:

  • boolean
  • integer or integer range
  • ip address / network
  • string(exact,substring,suffix,prefix,subdir,domain)
  • regular expression
  • hex block

ACL flags 可用列表:

  • -i :忽略大小写
  • -f filename :从文件中载入模式
  • -m method :制定模式匹配方法
  • -n :禁止dns解析
  • -M: -f载入的文件作为映射文件使用
  • -u:强制acl的名称唯一
  • -:强制flags结束,避免了字符串中含有的-引起混淆

其中falgs中的-m选项可使用的模式匹配方法如下,需要说明的是有些方法已被默认指定无需申明,例如:int ,ip

  • found :只是用来探测数据流中是否存在指定数据,不进行任何比较
  • bool:检查结果返回bool值,匹配没有模式,可以匹配布尔值或证书,不匹配0或false,其他值可以匹配
  • int:匹配整数数据类型,可以处理整数和布尔值类型样本,0代表false,1代表true
  • ip:匹配IPv4,IPv6地址类型数据,该模式仅被地址兼容,不需要特别指定。
  • bin:匹配二进制数据
  • len:匹配样本的长度的整数值
  • str:精确匹配,根据字符串匹配文本
  • reg:正则匹配,根据正则表达式列表匹配文本
  • beg:前缀匹配,检查文本是否以指定字符串开头
  • end:后缀匹配,检查文本是否以指定字符串结尾
  • dir:子目录匹配,检查部分文本中以‘/'作为分隔符的内容是否含有指定字符串
  • dom:域匹配,检查部分文本中以’.‘作为分隔符的内容是否含有指定字符串。

如果获取样本值为整数,数值比较符可使用:

  • eq
  • ge
  • gt
  • le
  • lt

acl具体使用方法:

控制动作指令

layer4传输层控制指令:

tcp-request connection {action} [{if | unless} {condition}]

对tcp请求控制指令
{condition}即为ACL定义的访问控制列表
{action} 常用值”accept“,”reject“

layer 7应用层控制指令

#阻断符合acl的访问请求
block {if | unless} 
#http-request请求的控制指令
http-request {allow |deny} [{if | unless} ]

后端主机调用:

#根据条件来调用指定后端
use_backend  [{if | unless} ]

由acl定义的多个《condition》组成联合条件,

  • and (默认操作符,可省略)
  • or (或者使用”||“)
  • !(取反)

获取内部状态样本

#与后端建立会话速率,每秒钟建立的新会话
be_sess_rate([]):integer

example:

#某后端被请求过去繁忙,则重定向到错误页面
mode http
acl being_scanned be_sess_rate gt 100
redirect location /denied.html if being_scanned

获取layer4样本

在传输层获取样本,通常是tcp/ip协议的ip和端口,以及建立连接速率等等,而且此部分样本通常用于 tcp-request connection 指令中的规则中:

  • dst:ip #目标地址
  • dst_port :integer
  • src:ip #源地址
  • src_port:integer

example:

#阻断来自非指定ip的访问8080端口的请求
acl myhost src 10.1.0.200
acl myport dst_port 8080
tcp-request connection reject if !myhost myhost

获取layer7样本

path:string
提取请求url的地址信息,从第一个’/‘开始,不包含host,不包含参数
acl衍生,即包含了-m选项中匹配模式方法

  • path:exact string match
  • path_beg:prefix match
  • path_dir:subdir match
  • path_dom:domain match
  • path_end:suffix match
  • path_len:length match
  • path_reg:regex match
  • path_sub: substring match

example

#请求资源为图片,则条用图片服务器后端
acl picture path_end -i .jpg .png .gif
use_backend server_pic if picture

url:string
提取URL的全部内容,包含host和参数acl衍生类似

req.hdr([{name}[,{occ}]]):string

提取http请求的指定首部字段值,{occ}可指定出现的位置acl衍生:

  • hdr([{name}[,{occ}]]):exact string match
  • hdr_beg([{name}[,{occ}]]):prefix match
  • hdr_dir([{name}[,{occ}]]):subdir match
  • hdr_dom([{name}[,{occ}]]):domain match
  • hdr_end([{name}[,{occ}]]):suffix match
  • hdr_len([{name}[,{occ}]]):length match
  • hdr_reg([{name}[,{occ}]]):regex match
  • hdr_sub([{name}[,{occ}]]):substring match

example:

#阻断火狐浏览器发送的请求
acl firefox hdr_reg(User_Agent) -i .*firefox.*
block if firefox

method :integer+string

提取请求报文中的请求方法Example:

#拒绝GET,HEAD方式之外的HTTP请求
acl valid_method method GET HEAD
http-request deny if ! valid_method

內建ACL

HAproxy有众多內建的acls,这些acls可直接调用,例如:

  • LOCALHOST 匹配来自本地ip的连接,127.0.0.1/8
  • HTTP_1.1匹配http版本1.1
  • METH_GET匹配http请求GET或HEAD方法
  • TRUE
  • FALSE

example:

拒绝GET head方式之外的http请求
http-request deny if ! METH_GET

重写URI

1、重写路径

http-request replace-uri {match-regex} {replace-fmt} [{if | unless} ]

example

#替换 /bar?q=1 为 /foo/bar?q=1
http-request replace-uri (.*) /foo\1
#替换 /bar?q=1 为 /bar/foo?q=1
http-request replace-uri ([^?]*)(\?(.*))? \1/foo\2
替换/foo/bar?q=1 为/bar?q=1
http-request replace-uri /foo/(.*) /\1
#或者
http-request replace-uri /foo/(.*) /\1 if {url_beg /foo/}

2、重写值

#格式
http-request replace-value  -regex> -fmt> [{if | unless} ]

example:

http-request replace-value X-Forwarded-For ^192\.168\.(.*)$ 172.16.\1
#将192.168 替换为172.16

你可能感兴趣的:(linux运维)