Можно ли сравнить две переменные в операторе 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
Другие вопросы по тегам