HAProxy - setting a cookie with a variable

Hi Folks,

I’m working on what will eventually be a largish openstack hosted system and all access is via haproxy on LEAP15.2 - and overall we are more than satisfied

At present we have a complicated an clunky way of redirecting each user to the correct database, based on rewriting the URL to add //db=subdomain, however this could be set as a session cookie with the subdomain name and would be far more elegant overall.

So in short I have to insert a cookie that has the subdomain (bob, fred, etc.) as a value which could then function as the identifying cookie

Currently I have tried creating a variable within the listen statement and then using that within the backend.

frontend mysite
bind *:443 ssl crt /etc/ssl/cert/mydomain.pem alpn h2,http/1.1
mode http
option httpclose
http-request set-var(txn.subdomain) req.hdr(host),lower,regsub(.mysite.com$,) if { hdr_end(host) -i .mysite.com
default_backend myservers

I can use that variable to rewrite the request etc. as mentioned above so I know that the variable is set and usable.

Looking at the backend - a simple set-cookie element looks like below.

backend myservers
mode http
http-response add-header Set-cookie DBNAME=whatdb;\ path=/
cookie SERVERID insert indirect nocache
server myserver1 192.168.0.1:8443 cookie srv1 ssl verify none check
server myserver2 192.168.1.1:8443 cookie srv2 ssl verify none check
… (10 total my servers)

This creates 2 cookies - the one for the load balancing SERVERID with the server’s name (myserver1, myserver2 etc.) and sets the cookie DBNAME with a static value of “whatdb” and a / path. Fantastic.

Just changing the DBNAME cookie to be a variable should I believe look like;

http-response add-header Set-Cookie DBNAME=%[var(txn.subdomain)];\ path=/

And this seems to almost work. The path is still / but the value of DBNAME is always empty. I can’t quite find what is wrong with the syntax or my logic.

Why? This is driving me somewhat potty!

Thanks

Tim

From the manual we can see that there are 5 types of variable

proc” : the variable is shared with the whole process
“sess” : the variable is shared with the whole session
“txn” : the variable is shared with the transaction (request and
response),
“req” : the variable is shared only during request processing,
“res” : the variable is shared only during response processing.

It seems that there are greater boundaries than is intimated above - in that a transaction or session based variable (let alone a request or response) is only allowed within one frontend or backend element.

By changing to creating a variable based on “proc” then it works as required.

frontend mysite
bind *:443 ssl crt /etc/ssl/cert/mydomain.pem alpn h2,http/1.1
mode http
option httpclose
http-request set-var(proc.subdomain) req.hdr(host),lower,regsub(\.mysite\.com$,) if { hdr_end(host) -i .mysite.com
default_backend myservers

backend myservers
mode http
http-response add-header Set-cookie DBNAME=%[var(proc.subdomain)];\ path=/
cookie SERVERID insert indirect nocache
server myserver1 192.168.0.1:8443 cookie srv1 ssl verify none check
server myserver2 192.168.1.1:8443 cookie srv2 ssl verify none check
... (10 total my servers)

Hope that helps someone

Tim