我正在尝试配置 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 与动态模式一起工作,我也想知道。