Можно ли сравнить две переменные в операторе HAProxy ACL?
Можно ли сравнить сравнение двух переменных в инструкции ACL HAProxy? Например, предполагая, что оба host
заголовок и X-CORRECT-HOST
заголовок равен "example.com".
acl correct_host hdr(host) -i example.com # THIS RETURNS TRUE
acl correct_host hdr(X-CORRECT-HOST) -i example.com # THIS RETURNS TRUE
Я попробовал несколько вещей и прочитал документацию, но, похоже, ничего не получилось. Вот пара примеров, которые я пробовал, чтобы все возвращали false:
acl correct_host hdr(host) -i hdr(X-CORRECT-HOST)
acl correct_host hdr(host) -m str hdr(X-CORRECT-HOST)
acl correct_host hdr(host) -i %[hdr(X-CORRECT-HOST)]
acl correct_host hdr(host) -m str %[hdr(X-CORRECT-HOST)]
2 ответа
Это можно сделать сstrcmp
https://cbonte.github.io/haproxy-dconv/2.6/configuration.html#7.3.1-strcmp
например
http-request set-var(txn.host) hdr(host)
# Check whether the client is attempting domain fronting.
acl ssl_sni_http_host_match ssl_fc_sni,strcmp(txn.host) eq 0
Вы можете использовать lua(необходимо собрать haproxy с поддержкой lua)
Вы можете проверить с помощью:
haproxy -vv|grep -i lua
что-то вроде этого:
OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_LUA=1
Built with Lua version : Lua 5.3.1
или построить с lua, что-то вроде:
make TARGET=linux2628 USE_LUA=1 LUA_LIB=/opt/lua-5.3.1/lib LUA_INC=/opt/lua-5.3.1/include
затем
$ ./haproxy -v
Nuster version 2.0.0.18
Copyright (C) 2017-2018, Jiang Wenyuan, <koubunen AT gmail DOT com >
HA-Proxy version 1.8.12 2018/06/27
Copyright 2000-2018 Willy Tarreau <willy@haproxy.org>
конф:
global
debug
lua-load compare_header_value.lua
frontend web1
bind *:8080
mode http
default_backend app1
backend app1
mode http
http-request set-var(req.two_header_value_equal) lua.compare_header_value(hdr1,hdr2)
http-request deny unless { var(req.two_header_value_equal) -m bool }
server s1 127.0.0.1:8000
compare_header_value.lua
function compare_header_value(txn, h1, h2)
local hdr = txn.http:req_get_headers()
if hdr[h1] == nil or hdr[h2] == nil then
return false
end
if hdr[h1][0] == hdr[h2][0] then
return true
end
return false
end
core.register_fetches("compare_header_value", compare_header_value)
тогда вы можете использовать ACL следующим образом:
http-request deny unless { var(req.two_header_value_equal) -m bool }
Тестовое задание:
1 тот же заголовок
curl -v http://127.0.0.1:8080/ -H "hdr1: 1" -H "hdr2: 1"
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.60.0
> Accept: */*
> hdr1: 1
> hdr2: 1
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
2 разных заголовка
curl -v http://127.0.0.1:8080/ -H "hdr1: 1" -H "hdr2: 2"
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.60.0
> Accept: */*
> hdr1: 1
> hdr2: 2
>
* HTTP 1.0, assume close after body
< HTTP/1.0 403 Forbidden