I need to fetch the HTTP request’s domain to perform domain whitelist verification, but sometimes I cannot retrieve the host value—it returns nil. My HAProxy version is 3.1.5, and I’m using the following Lua script to get the host:
function get_host(txn)
local sni = txn.sf:ssl_fc_sni()
-- HTTP request Host header
local host = txn.sf:req_fhdr("Host")
-- In some cases (HTTP/2), domain is in :authority
if (not host or host == "") then
host = txn.sf:req_fhdr(":authority")
end
local domain = host or sni
return domain
end
core.register_action("set_proxy_extra", { "http-req", "http-res" }, function(txn)
local host = get_host(txn)
--
-- other codes has removed
--
end)
global
tune.lua.bool-sample-conversion normal
lua-load /usr/local/etc/haproxy/parse_proxy_auth.lua
frontend proxy_default_frontend
bind *:80
mode http
http-request lua.set_proxy_extra
However, when I use the log-format to print the request-line with %{+Q}r, it does have a value. Could anyone provide a complete working code example?
Thank you!
Please provide relevant haproxy config (where the get_host lua fetch is used)
@adarragon The following is part of the HAProxy and Lua code:
global
tune.lua.bool-sample-conversion normal
lua-load /usr/local/etc/haproxy/parse_proxy_auth.lua
frontend proxy_default_frontend
bind *:80
mode http
http-request lua.set_proxy_extra
function get_host(txn)
local sni = txn.sf:ssl_fc_sni()
-- HTTP request Host header
local host = txn.sf:req_fhdr("Host")
-- In some cases (HTTP/2), domain is in :authority
if (not host or host == "") then
host = txn.sf:req_fhdr(":authority")
end
local domain = host or sni
return domain
end
core.register_action("set_proxy_extra", { "http-req", "http-res" }, function(txn)
local host = get_host(txn)
end)
hope for your reply, thank you!
I don’t see errors in the way the txn.sf:req_fhdr() fetch is used from Lua
However since haproxy will accept HTTP1.X requests without host header, I’m wondering if some clients are (purposely or not) omitting that header and could explain that your get_host() Lua function sometimes returns NULL.
You may want to protect against that, see No Host header accepted in 1.1 requests · Issue #1299 · haproxy/haproxy · GitHub
I found that HTTP/1.0 requests do not correctly retrieve the Host.