HaProxy动态列表/映射

我正在尝试使用基于我们系统中存在的客户的域名白名单来使CORS正常工作。我们有一个白标产品,可以让公司将自定义域名CNAME到我们的系统。我们需要能够通过在HaProxy的响应中添加Access-Control-Allow-Origin: http://some.custom.domain头来动态允许来自这些自定义域的Origin

我一直在阅读有关从haproxy加载列表/映射的不同方法的文章,但我仍不确定最佳实现方式。目前我大致想到了3种可能的方法,但我想知道其他人是否有其他见解。到目前为止,我的选择是:

1.存储可用域的映射,当添加标头时可以查找这个映射。在此时如何填充此映射文件是一个问题。我想我可以通过LUA在引导过程中通过API调用来创建文件?或者它可能是一个NFS挂载文件?每次将新域添加到我们的系统中时,我们都必须重新加载,可以通过相同的API调用或直接调用maps API在套接字上进行操作。

2.使用LUA对每个请求进行实时请求haproxy的API,以验证Origin中传递的域名是否合法,并添加标头。可以使用Memcached进行最小开销,假设我们可以找到适用于memcached的LUA客户端lib。

3.可能要实现某种基于DNS的解决方案,其中我们运行自己的DNS服务器来解析这些定制域,并让HaProxy在其中进行查找。我不知道这是否可能,我只知道haproxy具有DNS功能。奇怪的是,我们实际上不想解析到IP,我们只想要一个“是”或“否”的答案。

是否有其他人知道这个问题的一个显而易见的解决方案?我正在寻找易于实现的解决方案,但最终需要请求本身的最小开销,因为这将需要在具有Origin头的每个请求上执行。

任何见解都会受到赞赏!

点赞
用户7631780
用户7631780

1/ 解决方案:

我认为最简单且最有效的解决方案是将可用的域名存储在映射中。然后,您可以通过HAProxy socket使用set mapadd map更新映射。每当域名发生变化时,无需重新加载即可更新映射。

2/ LUA解决方案:

还可以使用类似于以下功能的LUA来完成:

core.register_action("validate_origin", {"http-req"}, function(txn)
   local origin= txn.http:req_get_headers()headers["origin"][0]
   local sock = core.tcp()
   sock:connect("<API-IP>", <API-PORT>)
   sock:send("GET /api?validate=".. origin .. " HTTP/1.1\r\n Host:www\r\n ")
   domain = sock:receive("*a")
   sock:close()
   txn:set_var("txn.allow_origin", domain)
end)

在相关前端的HAProxy配置中:

http-request capture hdr("Origin") len 128
http-request lua.validate_origin if  { capture.req.hdr(0) -m found }
http-response add-header Access-Control-Allow-Origin %[var(txn.allow_origin)] if  { capture.req.hdr(0) -m found }

此解决方案会增加更多开销,因为每个CORS请求 HAProxy 都必须依赖外部资源(并且可能需要等待它) 。

2017-07-13 11:19:33