为什么这个 HAProxy ACL 与地图返回的 HTTP 方法不匹配?

为什么这个 HAProxy ACL 与地图返回的 HTTP 方法不匹配?

我正在尝试配置 HAProxy 以允许一组特定的 HTTP 方法到一组特定的路径(存储在映射中)。

例如,我有一个 haproxy 映射文件,其中包含以下内容:

/api/read_method GET
/api/write_method POST

鉴于上述映射,我希望允许GET以 开头的请求/api/read_method(但没有其他方法),以及POST以 开头的路径的请求/api/write_method(但没有 GET)。

根据文档,我得到了以下 haproxy 配置:

listen main
    # bind, doesn't really matter
    bind *:443 ssl crt server.pem
    # use path_beg to find the map entry starting with the path
    # compare the request method with the returned map entry, case insensitively as astring
    acl map_method method -i -m str %[path,map_beg(acl.map)]
    
    http-request deny unless map_method
    server app backend:80

此 ACL 似乎永远不匹配,请求始终被拒绝,即使我进行如下测试:

curl -v https://localhost/api/read_method # do a GET to the path in the map

我尝试使用以下行来调试这个问题,作为对语句的修改http-request deny

http-request return status 401 content-type text/plain lf-string "Denied, allowed method for %[path] is >(%[path,map_beg(acl.map)])< but method was >(%[method])<" unless url_method

这将以日志格式的消息拒绝该请求,并返回以下内容:

Denied, allowed method for /api/read_method is >(GET)< but request method is >(GET)<

我不明白为什么这个条件不满足 ACL,字符串是相同的,并且比较是以字符串 ( -m str) 进行的。映射肯定返回了适当的方法(显示在调试字符串中),如果我将映射查找替换为文字“ GET”,ACL 会正确通过(但当从查找中返回相同的字符串时则不会)。

答案1

它不匹配,因为%[path,map_beg(acl.map)]不扩展。实际上,ACL 比较的就是以百分号开头的那些字符method。为了证明这一点,你可以请参阅我的 stackoverflow 问题,我在其中使用 IP 地址尝试此操作

如果您将其替换为硬编码GET,您将看到它read_method开始工作。

至于如何使 ACL 与动态模式一起工作,我也想知道

相关内容