2

是否可以在 HAProxy 中检查 HMAC 有效性?理想情况下,如果 HMAC 有效,我想设置一个 acl,以便我可以在规则中使用它。

我们的 Ubuntu 18.04 构建服务器(运行 Jenkins)位于防火墙后面,仅将特定 IP 范围列入白名单。

我们有一个 HAProxy (1.8) 实例接收所有入站请求并路由到适当的后端服务。

问题是 SonarCloud 已经将他们的 webhook 从一组定义的 IP 地址更改为使用 HMAC 来验证真实性。这意味着 webhook 会被防火墙阻止,除非我们向所有 Internet 流量开放它。

https://sonarcloud.io/documentation/project-administration/webhooks/#securing-your-webhooks

如果我们可以配置 HAProxy 来验证 HMAC,那么我们可以向所有流量开放服务器并使用 HAProxy 来验证这些请求(以及其他现有的 IP 白名单范围)。

4

2 回答 2

2

感谢 Michael 提供指向 HAProxy/Lua 集成的指针。我的解决方案在这里注明以供参考。

创建了以下 Lua 脚本 (hmac_validate.lua):

hmac = require('openssl.hmac')

local function tohex(s)
    return (string.gsub(s, ".", function (c)
        return string.format("%.2x", string.byte(c))
    end))
end -- tohex

function validate_sonar_hmac(txn, hmac_header_key, hmac_secret)
    local payload = txn.req:dup() -- take a copy of the request content
    local body = string.sub(payload,string.find(payload,"\r\n\r\n")+4) -- strip off the headers
    local signature = txn.sf:req_fhdr(hmac_header_key) -- get the HMAC signature sent on the request

    -- calculate hmac from body & secret
    local sc_hmac = hmac.new(hmac_secret, "sha256")
    local calculated_signature = tohex(sc_hmac:final(body))

    local signatures_match = calculated_signature == signature
    if not signatures_match then
        core.Alert("Sonar Cloud HMAC signature mismatch - received '"..signature.."' but calculated '"..calculated_signature.."'")
    end

    txn:set_var("req.sonar_request_valid", signatures_match)
end;

core.register_action("validate-sonar-hmac", {"http-req"}, validate_sonar_hmac, 2)

HA 代理配置更改为添加以下行:

global
    lua-load /etc/haproxy/hmac_validate.lua

frontend
    acl sonarcloud hdr(X-Sonar-Webhook-HMAC-SHA256) -m found
    http-request lua.validate-sonar-hmac X-Sonar-Webhook-HMAC-SHA256 {{ sonarcloud_hmac_secret }} if sonarcloud
    http-request deny if sonarcloud !{ var(req.sonar_request_valid) -m bool }
于 2019-10-09T12:06:11.723 回答
1

HAProxy 本身不做 HMAC,但可以使用 HAProxy 的 Lua 集成来完成。

一种方法是找到一个 Lua 库,它可以做你需要的 HMAC 风格,然后在 Lua 中编写一个 HAProxy 转换器来获取适当的输入并计算摘要以进行比较。

我曾经使用 HAProxy 1.6 和 Lua 5.x 实现了类似的东西,其中客户端发送了一个使用 HMAC-SHA1 签名的 URL,并且代理成功地检查了它的有效性。

不幸的是,我不再有权访问该代码,但我编写了这个 HAProxy 转换器以在 Lua 中执行 utf-8 感知 URL 转义(百分比编码) ......我在这里提到它是因为它是一种方法的完整的工作示例使用 Lua 扩展 HAProxy 功能,包括使用它所需的 Lua 代码和 HAProxy 配置,因此它可能会帮助您找到解决方案。

于 2019-09-08T20:01:19.830 回答