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:域匹配,检查部分文本中以’.‘作为分隔符的内容是否含有指定字符串。
acl jsess_present cook(JSESSIONID) -m found
#应用正则表达式在缓存的前500个bytes的数据
ACL script_tag payload(0,500) -m reg -i <script>
#在系统中使用正则的-i,将使效率降低,可使用转换器
acl script_tag payload(0,500),lower -m reg <script>
匹配booleans
可使用 -m bool。
返回整数值,0表示false,其他的值表示true
匹配整数
可使用-m int。
整数匹配只能应用与正整数,同样可使用范围匹配:”1024:65535“,”1024:“ ”0:1023“
如果获取样本值为整数,数值比较符可使用:
- eq
- ge
- gt
- le
- lt
字符串匹配
字符串匹配可使用6个不同的形式:
1、exact match (-m str)
2、substring match (-m sub)
3、prefix match (-m beg)
4、suffix match (-m end)
5、subdir match (-m dir)
6、domain match (-m dom)
转换器
当前可用转换关键字包括:
- 51d.single([,*])
返回请求属性的字符串,该返回值被”51degrees-property-separator“分隔。该函数可传输最多5个属性,如果没有属性则返回value是”NoData“
#Here the header "X-51D-DeviceTypeMobileTablet" is added to the request,
# containing values for the three properties requested by using the User-Agent passed to the converter.
frontend http-in
bind *:8081
default_backend servers
http-request set-header X-51D-DeviceTypeMobileTablet %[req.fhdr(User-Agent),51d.single(DeviceType,IsMobile,IsTablet)]
- add ()
在输入的整数值上加上value,并且返回,该value可以是一个值,也可以是一个变量。 - aes-gcm-dec(,,,<aead_tag>)
使用AES128-GCM, AES192-GCM or
AES256-GCM 算法对输入进行加密,bits参数决定使用的加密算法,
http-response set-header X-Decrypted-Text %[var(txn.enc),aes_gcm_dec(128,txn.nonce,Zm9vb2Zvb29mb29wZm9vbw==,txn.aead_tag)]
- and ()
- b64dec
解密一个base64编译的字符串 - base64
转换输入为base64字符串。 - bool
如果输入值不是null则为true否则返回false - bytes([,])
-concat([],[],[])
连接字符串,
参数说明:
start:是一个固定的字符串,它将会直接拼接到样本后面,
var:变量名,将变量值转化为字符串,然后拼接到start后面。如果没有找到变量,将不会拼接任何内容
end:固定的字符串,将会拼接到var后面
tcp-request session set-var(sess.src) src
tcp-request session set-var(sess.dn) ssl_c_s_dn
tcp-request session set-var(txn.sig) str(),concat(<ip=,sess.ip,>),concat(<dn=,sess.dn,>)
http-request set-header x-hap-sig %[var(txn.sig)]
- cpl
- crc32([])
Hashes a binary input sample into an unsigned 32-bit quantity using the CRC32 hash function. - crc32c([])
- da-csv-conv([,*])
使用DeviceAtlas 识别user agent。属性值使用”deviceatlas-property-separator“分隔,或使用默认的”|“。haproxy默认支持12个不同属性
frontend www
bind *:8881
default_backend servers
http-request set-header X-DeviceAtlas-Data %[req.fhdr(user-Agent),da-csv(primaryHardwareType,osName,osVersion,browserName,browerVersion,browserRenderingEngine)]
- debug
这个转换器用于debug tool。它将会dumps input sample - div ()
Divides the input value of type signed integer by , and returns the
result as an signed integer. - djb2([])
Hashes a binary input sample into an unsigned 32-bit quantity using the DJB2 hash function. - even
如果输入值是even则返回true 否则返回false - field(,[,[count]])
提取字段
str(f1_f2_f3__f5),field(5,_) #f5
str(f1_f2_f3__f5),field(2,_,0) #f2_f3__f5
str(f1_f2_f3__f5),field(2,_,2)#f2_f3
str(f1_f2_f3__f5),field(-2,_3)#f2_f3_
str(f1_f2_f3__f5),filed(-3,_,0)#f1_f2_f3
- hex
- hex2i
16进制 - http_date([,[]])
转化日期类型 - in_table()
从表中查看结果,如果表中存在则返回true,否则返回false - ipmask(,[])
使用mask到一个ip地址,并将结果用于查找和存储。 - json([])
将输入字符串转化为json字符串,input-code即编码方式,可用:ascii,utf8,utf8s,utf8p,utf8ps
ascii:从不会失败
utf8:有编码错误
uft8s:不会失败,但是会移除编码错误
utf8p:允许并修复超长的错误,但是其他错误任然会报错
utf8ps:不会失败,修复超长错误,并移除其他编码错误
capture request header Host len 15
capture request header user-agent len 150
log-format '{"ip":"%[src]","user-agent":"%[capture.req.hdr(1),json(utf8s)]"}'
- language([,])
#this configuration switches to the backend matching a given language based on the request :
acl es req.fhdr(accept-language),language(es;fr;en) -m str es
acl fr req.fhdr(accept-language),language(es;fr;en) -m str fr
acl en req.fhdr(accept-language),language(es;fr;en) -m str en
use_backend spanish if es
use_backend french if fr
use_backend english if en
default_backend choose_your_language
- length
得到字符串的长度 - lower
转换为小写 - ltime([,])
转换为format格式时间
log-format %[date,ltime(%Y%m%d%H%M%S)]\ %ci:%cp
- map(<map_file>[,<default_value>])
- map_<match_type>(<map_file>[,<default_value>])
- map_<match_type>_<output_type>(<map_file>[,<default_value>])
使用match_type方法从map_file中查找值。并将结果使用output_type进行转换,如果没有找到值则返回default_value。如果没有设置default_value,这个转换器将失败,如果match_type没有设置将默认使用str,output_type默认str。
input type | match method | output type str | output type int | output type ip
-----------±-------------±----------------±----------------±--------------
str | str | map_str | map_str_int | map_str_ip
-----------±-------------±----------------±----------------±--------------
str | beg | map_beg | map_beg_int | map_end_ip
-----------±-------------±----------------±----------------±--------------
str | sub | map_sub | map_sub_int | map_sub_ip
-----------±-------------±----------------±----------------±--------------
str | dir | map_dir | map_dir_int | map_dir_ip
-----------±-------------±----------------±----------------±--------------
str | dom | map_dom | map_dom_int | map_dom_ip
-----------±-------------±----------------±----------------±--------------
str | end | map_end | map_end_int | map_end_ip
-----------±-------------±----------------±----------------±--------------
str | reg | map_reg | map_reg_int | map_reg_ip
-----------±-------------±----------------±----------------±--------------
str | reg | map_regm | map_reg_int | map_reg_ip
-----------±-------------±----------------±----------------±--------------
int | int | map_int | map_int_int | map_int_ip
-----------±-------------±----------------±----------------±--------------
ip | ip | map_ip | map_ip_int | map_ip_ip
-----------±-------------±----------------±----------------±-------------- - mod()
取模 - mul ()
乘法 - nbsrv
输入string类型,将其解析为后端名称,并返回后端可用服务器数量 - neg
- not
- odd
- or()
- protobuf(<field_number>,[<field_type>])
提取协议缓存信息。 - regsub(,[,])
类似sed命令
#input : x-path: a///b//c
#output:x-path:/a/b/c
http-request set-header x-path %[hdr(x-path),regsub(/+,/,g)]
- capture-req()
从请求slot从捕获信息 - capture-res()
从响应slot从捕获信息 - sdbm([avalanche])
Hashes a binary input sample into an unsigned 32-bit quantity using the SDBM
hash function - set-var()
设置变量 - sha1
Converts a binary input sample to a SHA-1 digest. The result is a binary
sample with length of 20 bytes. - sha2([])
- srv_queue
返回服务器queue session 大小 - strcmp()
比较var和输入string。
http-request set-var(txn.host) hdr(host)
acl ssl_sni_http_host_match ssl_fc_sni,strcmp(txn.host) eq 0
- sub()
减法 - table_bytes_in_rate()
从table中查找值,如果key不存在则返回0,否则返回客户端到服务端速率的平均值 - table_bytes_out_rate()
- table_conn_cnt()
从table中查找值,如果key不存在则返回0,否则返回请求连接数量 - table_conn_cur()
从table中查找值,如果key不存在则返回0,否则返回当前连接数量 - table_conn_rate()
从table中查找值,如果key不存在则返回0,否则返回连接速率 - table_gpt0()
- table_gpc0()
- table_gpc0_rate()
- table_gpc1()
- table_gpc1_rate()
- table_http_err_cnt()
- table_http_err_rate()
- table_http_req_cnt()
- table_http_req_rate()
- table_kbytes_in()
- table_kbytes_out()
- table_server_id()
- table_sess_cnt()
- table_sess_rate()
- table_trackers()
- upper
转换为大写 - url_dec
Takes an url-encoded string provided as input and returns the decoded
version as output. The input and the output are of type string. - ungrpc(<field_number>,[<field_type>])
- unset-var()
- utime([,])
log-format %[date,utime(%Y%m%d%H%M%S)]\ %ci:%cp
- word(,[,])
str(f1_f2_f3__f5),word(4,_) # f5
str(f1_f2_f3__f5),word(2,_,0) # f2_f3__f5
str(f1_f2_f3__f5),word(3,_,2) # f3__f5
str(f1_f2_f3__f5),word(-2,_,3) # f1_f2_f3
str(f1_f2_f3__f5),word(-3,_,0) # f1_f2
- wt6([])
Hashes a binary input sample into an unsigned 32-bit quantity using the WT6
hash function. - xor()
- xxh32([])
- xxh64([])
从内部状态获取信息
从内部状态获取信息可用于”monitor-fail“去上报一个内部状态给外部监视器。
- always_false:boolean
FALSE - always_true:boolean
true - avg_queue([]):integer
返回队列连接总数。 - be_conn([]):integer
当前后端建立的连接 - be_conn_free([]):integer
返回可用的连接数。 - be_sess_rate([]):integer
每秒钟建立的session数量
backend dynamic
mode http
acl beging_scanned be_sess_rate gt 100
redirect location /denied.html if beging_scanned
- bin():bin
返回二进制链, - bool():bool
返回boolean值 - connslots([]) : integer
返回后端可用的slots连接数 - cpu_calls:integer
返回调用的处理流,或已分配的请求数量 - cpu_ns_avg:integer
返回调用的处理流,或当前请求的平均秒数 - cpu_ns_tot:integer
返回总共花费的时间 - date([],[]):integer
把当前时间转化为epoch
http-response set-header Expires %[date(3600),http_date]
http-response set-header Expires %[date(3600000,ms),http_date(0,ms)]
- date_us:integer
Return the microseconds part of the date - distcc_body([,]) : binary
Parses a distcc message and returns the body associated to occurrence # of the token
- distcc_param([,]) : integer
Parses a distcc message and returns the parameter associated to occurrence # of the token .
tcp-request inspect-delay 20s
tcp-request content accept if {distcc_param(DOTI) -m found}
use_backend big_farm if {distcc_param(DOTI) gt 10000000}
- env():string
返回环境变量
http-request add-header via 1.1\ %[env(HOSTNAME)]
http-request deny if !{cook(SESSIONID) -m found} {env(STOP) -m found}
- fe_conn([]):integer
返回前端当前建立的连接数量 - fe_req_rate([]):integer
返回每秒钟发往前端的请求数量 - fe_sess_rate([]):integer
返回前端每秒钟建立的session数量
frontend mail
bind :25
mode tcp
maxconn 100
acl too_fast fe_sess_rate ge 10
tcp-request inspect-delay 100ms
tcp-request content accept if !too_fast
tcp-request content accpt if WAIT_END
- hostname:string
返回系统hostname - int():signed integer
- ipv4():ipv4
- ipv6():ipv6
- lat_ns_avg:integer
返回任务处理流从唤醒到完全调用所花费的平均时间 - lat_ns_tot:integer
返回任务处理流从唤醒到完全调用所花费的总时间 - meth():method
返回method - nbproc:integer
返回进程数 - nbsrv([]):integer
当前backend可用的服务器数量 - prio_class:integer
返回priority-class 值,该值通过:”http-request set-priority-class“ 或”tcp-request content set-priority-class" - prio_offset:integer
返回priority-offset 值,该值通过:“http-request set-priority-offset” 或“tcp-request content set-priority-offset”设置 - proc:integer
返回当前进程号,介于1到global.nbproc - queue([backend]):integer
返回后端队列连接总数。 - rand([]):integer
返回一个range内部的随机值。 - uuid([]):string
返回全局唯一id,version 4 - srv_conn([/]):integer
后端服务器当前连接数 - srv_conn_free([/]):integer
返回后端服务器可用连接 - srv_is_up([/]):boolean
后端服务器是否启用 - srv_queue([/]):integer
返回后端服务器的队列大小 - srv_sess_rate([/]):integer
返回后端服务器每秒钟建立连接数量
acl srv1_full srv_sess_rate(be1/srv1) gt 50
acl srv2_full srv_sess_rate(be1/srv2) gt 50
use_backend be2 if srv1_full or srv2_full
- stopping:boolean
- str():string
- table_avl():integer
返回当前proxy的stick-table中可用条目总数量, - table_cnt([]):integer
返回当前peoxy的stick-table中的总数量 - thread:integer
返回当前线程值,介于0 到global.nbthread-1 - var():undefined
返回变量类型
从4层获取信息
- bc_http_major:integer
返回后端连接http版本。1:HTTP/1.1 2:HTTP/2 - be_id:integer
返回当前后端id - be_name:string
返回当前后端名 - dst:ip
返回客户端连接的目的地址 - dst_conn:integer
返回当前socket建立的连接数。 - dst_is_local:boolean
返回连接地址是否为当前系统地址 - dst_port :integer
目标tcp端口 - fc_http_major : integer
返回前端连接http版本 - fc_pp_authority : string
返回tlv授权 - fc_rcvd_proxy : boolean
Returns true if the client initiated the connection with a PROXY protocol header. - fc_rtt() : integer
Returns the Round Trip Time (RTT) measured by the kernel for the client connection. - fc_rttvar() : integer
- fc_unacked : integer
返回unacked计数器,由内核计算的客户端连接 - fc_sacked : integer
返回sacked计数器,由内核计算的客户端连接 - fc_retrans : integer
返回 retransmits计数器,由内核计算的客户端连接 - fc_fackets : integer
返回 fack计数器,由内核计算的客户端连接 - fc_lost : integer
返回 lost计数器,由内核计算的客户端连接 - fc_reordering : integer
返回 reordering计数器,由内核计算的客户端连接 - fe_defbe : string
返回前端默认后端名 - fe_id:integer
当前前端id - fe_name:string
当前前端名称 - sc_bytes_in_rate([,]) : integer
- sc0_bytes_in_rate([]) : integer
- sc1_bytes_in_rate([]) : integer
- sc2_bytes_in_rate([]) : integer
从当前追踪计数器中得到客户端到服务端的平均字节速率 - sc_bytes_out_rate([,]) : integer
- sc0_bytes_out_rate([]) : integer
- sc1_bytes_out_rate([]) : integer
- sc2_bytes_out_rate([]) : integer
- sc_clr_gpc0([,]) : integer
- sc0_clr_gpc0([]) : integer
- sc1_clr_gpc0([]) : integer
- sc2_clr_gpc0([]) : integer
清空第一个通用计数器
ACL abus sc0_http_req_rate gt 10
acl kill sc0_inc_gpc0 gt 5
acl save sc0_clr_gpc0 ge0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill
- sc_conn_cnt([,]) : integer
- sc_conn_cur([,]) : integer
- sc_conn_rate([,]) : integer
- sc_get_gpc0([,]) : integer
- sc_get_gpc1([,]) : integer
- sc_get_gpt0([,]) : integer
- sc_get_gpt1([,]) : integer
- sc_gpc0_rate([,]) : integer
- sc_gpc1_rate([,]) : integer
- sc_http_err_cnt([,]) : integer
- sc_http_err_rate([,]) : integer
- sc_http_req_cnt([,]) : integer
- sc_http_req_rate([,]) : integer
- sc_inc_gpc0([,]) : integer
acl abuse sc0_http_req_rate gt 10
acl kill sc0_inc_gpc0 gt 0
tcp-request connection reject if abuse kill
- sc_inc_gpc1([,]) : integer
- sc_kbytes_in([,]) : integer
- sc_kbytes_out([,]) : integer
- sc_sess_cnt([,]) : integer
- sc_sess_rate([,]) : integer
- sc_tracked([,]) : boolean
如果当前session被tracked则返回true - sc_trackers([,]) : integer
- so_id : integer
返回当前监听socket id - src : ip
http-request set-header X-Country %[src,map_ip(geoip.lst)]
- src_bytes_in_rate([]) : integer
- src_bytes_out_rate([]) : integer
- src_clr_gpc0([]) : integer
acl abuse src_http_req_rate gt 10
acl kill src_inc_gpc0 gt 5
acl save src_clr_gpc0 ge 0
tcp-request connection accept if !abuse save
tcp-request connection reject if abuse kill
- src_clr_gpc1([]) : integer
- src_conn_cnt([]) : integer
- src_conn_cur([]) : integer
- src_conn_rate([]) : integer
- src_get_gpc0([]) : integer
- src_get_gpc1([]) : integer
- src_get_gpt0([]) : integer
- src_gpc0_rate([]) : integer
- src_gpc1_rate([]) : integer
- src_http_err_cnt([]) : integer
- src_http_err_rate([]) : integer
- src_http_req_cnt([]) : integer
- src_http_req_rate([]) : integer
- src_inc_gpc0([]) : integer
acl abuse src_http_req_rate gt 10
acl kill src_inc_gpc0 gt 0
tcp-request connection reject if abuse kill
- src_inc_gpc1([]) : integer
- src_is_local : boolean
- src_kbytes_in([]) : integer
- src_kbytes_out([]) : integer
- src_port : integer
- src_sess_cnt([]) : integer
- src_sess_rate([]) : integer
- src_updt_conn_cnt([]) : integer
listen ssh
bind :22
mode tcp
maxconn 100
stick-table type ip size 20 expire 10s store conn_cnt
tcp-request content reject if { src_updt_conn_cnt gt 3 }
server local 127.0.0.1:22
- srv_id : integer
- srv_name : string
从5层获取信息
5层即会话层,在haproxy中所有的连接握手完成后会话将会被关闭。通常包含一些ssl 协商的结果
- 51d.all([,*]) : string
返回请求属性值,被“51degrees-property-separator”所分隔。
frontend http-in
bind *:8081
default_backend servers
http-request set-header X-51D-DeviceTypeMobileTablet \
%[51d.all(DeviceType,IsMobile,IsTablet)]
- ssl_bc : boolean
当后端连接使用ssl时返回true - ssl_bc_alg_keysize : integer
- ssl_bc_alpn : string
- ssl_bc_cipher : string
- ssl_bc_client_random : binary
- ssl_bc_is_resumed : boolean
- ssl_bc_npn : string
- ssl_bc_protocol : string
- ssl_bc_unique_id : binary
- ssl_bc_server_random : binary
- ssl_bc_session_id : binary
- ssl_bc_session_key : binary
- ssl_bc_use_keysize : integer
- ssl_c_ca_err : integer
- ssl_c_ca_err_depth : integer
- ssl_c_der : binary
- ssl_c_err : integer
- ssl_c_i_dn([[,]]) : string
- ssl_c_key_alg : string
- ssl_c_notafter : string
- ssl_c_notbefore : string
- ssl_c_s_dn([[,]]) : string
- ssl_c_serial : binary
- ssl_c_sha1 : binary
- ssl_c_sig_alg : string
- ssl_c_used : boolean
- ssl_c_verify : integer
- ssl_c_version : integer
- ssl_f_der : binary
- ssl_f_i_dn([[,]]) : string
- ssl_f_key_alg : string
- ssl_f_notafter : string
- ssl_f_notbefore : string
- ssl_f_s_dn([[,]]) : string
- ssl_f_serial : binary
- ssl_f_sha1 : binary
- ssl_f_sig_alg : string
- ssl_f_version : integer
- ssl_fc : boolean
- ssl_fc_alg_keysize : integer
- ssl_fc_alpn : string
- ssl_fc_cipher : string
- ssl_fc_cipherlist_bin : binary
- ssl_fc_cipherlist_hex : string、
- ssl_fc_cipherlist_str : string
- ssl_fc_cipherlist_xxh : integer
- ssl_fc_client_random : binary
- ssl_fc_has_crt : boolean
- ssl_fc_has_early : boolean
- ssl_fc_has_sni : boolean
- ssl_fc_is_resumed : boolean
- ssl_fc_npn : string
- ssl_fc_protocol : string
- ssl_fc_unique_id : binary
- ssl_fc_server_random : binary
- ssl_fc_session_id : binary
- ssl_fc_session_key : binary
- ssl_fc_sni : string
- ssl_fc_use_keysize : integer
从缓存中获取信息 layer 6
- payload(,) : binary (deprecated)
这是req.payload的别名 - payload_lv(,[,]) : binary (deprecated)
这是req.payload_lv的别名 - req.hdrs:string
以字符串的形式返回当前请求头,包括最后的空行分隔头后body,空行可用于检测头部块, - req.hdrs_bin : binary
返回二进制形式的头。 - req.len:integer
- req_len:integer(deprecated)
返回当前请求buffer的大小,单位bytes - req.payload(,):binary
从request buffer中提取length长度的二进制块,并且从offset处开始。 - req.payload_lv(,[,]) : binary
- req.proto_http : boolean
http请求则返回true
tcp-request inspect-delay 10s
tcp-request content reject if !HTTP
tcp-request content track-sc0 base table req-rate
- req.rdp_cookie([]) : string
当请求是rdp协议,将提取rdp cookie 《name》
listen tse-farm
bind 0.0.0.0:3389
tcp-request inspect-delay 5s
tcp-request content accept if RDP_COOKIE
persis rdp-cookie
stick-table type string size 204800
stick on req.rdp_cookie(mstshash)
server srv1 1.1.1.1:3389
server srv2 2.2.2.2:3389
- req.rdp_cookie_cnt([name]):integer
解析rdp协议并返回rdp cookie 数量 - req.ssl_alpn:string
返回字符串包含ALPN(application-layer protocol negotiation),
tcp-request inspect-delay 5s
tcp-request content accept if {req_ssl_hello_type 1}
use_backend bk_acme if {req.ssl_alpn acme-tls/1}
default_backend bk_default
- req.ssl_ec_ext:boolean
返回一个布尔值用于确定客户端发送受支持的扩展在RFC4492中定义。 - req.ssl_hello_type:integer
返回整数值,包含ssl hello message的类型 - req.ssl_sni : string
返回服务名字符串
tcp-request inspect-delay 5s
tcp-request content accept if {req_ssl_heelo_type 1}
use_backend bk_allow if {req_ssl_sni -f allowed_sites}
- req.ssl_st_ext : integer
Returns 0 if the client didn’t send a SessionTicket TLS Extension (RFC5077)
Returns 1 if the client sent SessionTicket TLS Extension
Returns 2 if the client also sent non-zero length TLS SessionTicket
- req.ssl_ver : integer
返回整数值,表示SSL/TLS的版本
- res.len:integer
返回response长度 - res.payload(,) : binary
- res.payload_lv(,[,]) : binary
- res.ssl_hello_type : integer
- wait_end : boolean
tcp-request inspect-delay 2s
tcp-request content accept if WAIT_END
tcp-request inspect-delay 10s
acl goodguys src 10.0.0.0/24
acl badguys src 10.0.1.0/24
tcp-request content accept if goodguys
tcp-request content reject if badguys WAIT_END
tcp-request content reject
获取HTTP 信息 layer 7
- base:string
返回host+path - base32:integer
将base返回使用32位hash然后返回 - base32+src : binary
- capture.req.hdr():string
提取被使用“capture request header”抓取的header 的内容,idx是抓取关键字的位置。第一个为0 - capture.req.method:string
提取http请求的method - capture.req.uri:string
提取请求uri。 - capture.req.ver:string
提取请求http 版本,并返回HTTP/1.0 或HTTP/1.1 - capture.res.hdr():string
提取被使用“capture response header”抓取的header 的内容,idx是抓取关键字的位置。第一个为0 - capture.res.ver : string
提取响应http 版本,并返回HTTP/1.0 或HTTP/1.1 - req.body:binary
返回请求可用body。此功能需要 option http-buffer-request - req.body_param():string
这个提取将会假定post request 是url-encoded。然后提取body中的参数。 - req.body_len:integer
返回请求body的长度 - req.body_size:integer
返回请求body大小,并写入content-length中 - req.cook([]):string
提取请求中的cookie - req.cook_cnt([]):integer
返回cookie值的数量,或者当name没给定返回所有cookie - req.cook_val([]):integer
提取cookie并将值转换为integer - hdr([[,]]) : string
当请求时等同于req.hdr(),当响应时等同于res.hdr() - req.fhdr([,]) : string
从请求中提取header。 - req.fhdr_cnt([]) : integer
- req.hdr([[,]]) : string
- req.hdr_cnt([]) : integer
- req.hdr_ip([[,]]) : ip
- req.hdr_val([[,]]) : integer
- http_auth() : boolean
- http_auth_group() : string
- http_auth_pass : string
- http_auth_type : string
- http_auth_user : string
- http_first_req : boolean
- method : integer + string
acl valid_method method GET HEAD
http-request deny if ! valid_method
控制动作指令
layer4传输层控制指令:
tcp-request connection {action} [{if | unless} {condition}]
对tcp请求控制指令
{condition}即为ACL定义的访问控制列表
{action} 常用值”accept“,”reject“
layer 7应用层控制指令
#阻断符合acl的访问请求
block {if | unless} <condition>
#http-request请求的控制指令
http-request {allow |deny} [{if | unless} <condition>]
后端主机调用:
#根据条件来调用指定后端
use_backend <backend> [{if | unless} <condition>]
由acl定义的多个《condition》组成联合条件,
- and (默认操作符,可省略)
- or (或者使用”||“)
- !(取反)
获取内部状态样本
#与后端建立会话速率,每秒钟建立的新会话
be_sess_rate([<backend>]):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} <condition>]
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 <value> <match-regex> <replace-fmt> [{if | unless} <condition>]
example:
http-request replace-value X-Forwarded-For ^192\.168\.(.*)$ 172.16.\1
#将192.168 替换为172.16