Add support for stick-table backends and frontends
Hey there, I came across an unexpected behaviour when using the scripts provided here. I chose to dig into it and found out why it is not working. Unfortunately, due to my lack in lua knowledge, I am unable to fixt it. So what am I trying? In HAproxy, normally you can only have one stick-table per frontend or backend. However, you can define a frontend or backend whose sole purpose is holding a stick table (as described here). I tried to make use of that and came up with the following config (I only share the part relevant for my case):
frontend public_front
# Crowdsec bouncer >>>
# There already is a sticky table, but we want to use our backend table
# stick-table type ip size 10k expire 30m # declare a stick table to cache captcha verifications
http-request lua.crowdsec_allow # action to identify crowdsec remediation
http-request track-sc0 src table st_captcha if { var(req.remediation) -m str "captcha-allow" } # cache captcha allow decision
http-request redirect location %[var(req.redirect_uri)] if { var(req.remediation) -m str "captcha-allow" } # redirect to initial url
http-request use-service lua.reply_captcha if { var(req.remediation) -m str "captcha" } # serve captcha template if remediation is captcha
http-request use-service lua.reply_ban if { var(req.remediation) -m str "ban" } # serve ban template if remediation is ban
# Crowdsec bouncer <<<
backend st_captcha
stick-table type ip size 10k expire 30m # declare a stick table to cache captcha verifications
Now, the issue is, that when looking for the table, we call the stktable function (here):
-- captcha
if remediation == "captcha" then
if runtime.captcha_ok == false then
return remediate_fallback(txn)
end
local stk = core.frontends[txn.f:fe_name()].stktable
As far as I understood from the docs, this will give the stick table attached to the proxy - in my case the public_front. So while I cache decisions in the right table, the script will always lookup in the wrong table. I unterstand that this is a rare edge case, which is why I wanted to come up with a solution myself. But after looking through the documentation I couldn't find an easy solution to my problem. I mean, one could probably add an env var to the crowdsec-haproxy-bouncer.conf, sonmething like "custom table backend" and then provide the backend to call the function above from. But I'd consider this more than just a small change, so I wanted to open this issue here first.
Thanks for reading this. Kind regards :)