2017-07-07 91 views
0

我试图让CORS根据我们系统中存在的客户列出的域名白名单。我们有一个白色标签的产品,让我们的公司CNAME将定制域添加到我们的系统中。我们需要通过在Access-Control-Allow-Origin: http://some.custom.domain标题中添加来自HaProxy的响应,允许动态地允许Origin来自任何这些自定义域。HaProxy动态列表/地图

我一直在阅读有关从haproxy加载列表/地图的不同方式,但我只是没有解决的最佳实施。我已经想出了大概3种可能的方式,但我想看看是否有其他人也有一些洞察力。我的选项到目前为止:

  1. 存储一个map我可以找到添加标题时可用的域。如何填充此映射文件是目前的问题。我想我可以在启动时通过LUA进行API调用来创建文件?或者它可能是一个NFS挂载的文件?每次将新域添加到我们的系统时,我们都必须重新加载,无论是通过相同的api调用还是直接转到套接字上的地图api。

  2. 使用LUA从现场请求通过HAProxy的每一个任务的API来验证,如果在Origin传递的域名是合法的,并添加标题。有可能使用Memcached的最少开销假设我们可以找到一个LUA用于memcached的客户端库。

  3. 可能实施某种基于DNS的解决方案,我们运行我们自己的DNS服务器来解析这些自定义域,并让HaProxy对此进行查找。我不知道这是否可行,我只是知道haproxy具有DNS功能。奇怪的是,我们实际上并不想解决知识产权问题,我们只是想要一个“是”或“否”的答案。

是否有其他人知道这个问题的明显解决方案?我正在寻找易于实现的方法,但最终将请求本身的开销降至最低,因为这需要在每个请求上发生,并且标头为Origin

任何洞察赞赏!

回答

0

1 /地图解决方案:
我认为最简单,最有效的解决办法是将现有的域存储在一个地图。 然后,您可以使用set mapadd map,通过HAProxy套接字更新地图。每当域更改时,无需在此重新加载。

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的CONF在前端中的问题:

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 } 

该解决方案引入了更多开销,因为HAProxy必须依赖于每个CORS请求的外部资源(并可能等待它)。

+0

雅我选择了列表方法。实际上我有LUA注册一个任务,在启动时从API加载列表并为每个域写入一个ACL。谢谢! – brad