How to Set a Dynamic Variable in Haproxy

Haproxy conditional based on a dynamic variable

I discovered a way to solve this. There are conditionals for ACLs called 'always_true' and 'always_false' which as their name suggests will cause the ACL they are used in to always return true or respectively false. So I set that in my config like so:

acl do_redir always_true

then I construct a redirect stmt using this ACL later on in my config:

redirect code 307 prefix http://someurl if do_redir

The ACL do_redir then is my mechanism for toggling the redirect behavior of haproxy. I'm changing this in the haproxy config and restarting the process using chef so it all happens pretty quick.

An alternative method for modifiyng this ACL which I haven't gotten to work yet is to use the haproxy socket. This appears to have an advantage over my current method in that it doesn't require a restart and potentially lost connections, or the complexity and added risk of modifying the haproxy config file.

Dynamic server name and header in HAProxy

About Header manipulation

As the ALERT message say you can't use request header in the response. You should replace the following line.

Wrong line

http-response set-header X-Target  %[req.hdr(Host)]

Right Line

http-request set-header X-Target  %[req.hdr(Host)]

The Backend-Server should not remove this header. If you not want to send the Backend-Server the 'X-Target' host header then can you use a session variable to save the host header from the request to the response phase.

http-request set-var(txn.my_host) req.hdr(host),lower
http-response set-header X-Target %[var(txn.my_host)]

In the documentation are the set-var and set-header directive quite good explained.

http://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4-http-request

About the server manipulation

This line could not work because haproxy tries to resolve the target server at start time.

server web-servers site.%[req.hdr(Host),regsub(^www.,,)]:80 check

In newer version of haproxy. like 2.1, can you dynamically resolve and set the destination hosts.

http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4.2-http-request%20do-resolve

I assume you want to change the host header for the target server that the right virtual server is used.

My suggestion to solve your issue is to change the host header and set the server name to a resolvable address.

backend backend-default
option forwardfor

http-response set-header X-Publishing-system website

http-request set-header X-Target %[req.hdr(Host)]

http-request replace-header Host ^www(.*) site.\1
http-request set-header X-NewTarget %[req.hdr(Host),regsub(^www.,,)]

server web-servers site.example.com:80 check

This backend config is only syntax checked.

About dynamic backend server

The server should be resolved dynamically.
For that solution is at least HAProxy 2.0 necessary.

I copy here some parts of the doc http-request do-resolve for this answer.

You will need to add a section resolvers to your config

resolvers mydns
# use here your prefered DNS Servers
nameserver local 127.0.0.53:53
nameserver google 8.8.8.8:53
timeout retry 1s
hold valid 10s
hold nx 3s
hold other 3s
hold obsolete 0s
accepted_payload_size 8192

frontend frontend-http

bind *:80
bind *:443

# define capture buffer for backend
declare capture request len 60

acl redirect path_beg -i /rd
use_backend backend-tracking if redirect

default_backend backend-default

# ... some more backends

backend backend-default
option forwardfor

http-response set-header X-Publishing-system website

http-request set-header X-Target %[req.hdr(Host)]

# replace www with site in host header
http-request replace-header Host ^www(.*) site.\1

# if necessary set X-NewTarget header
http-request set-header X-NewTarget %[req.hdr(Host),regsub(^www.,,)]

# do dynamic host resolving for dynamic
# server destination for
# the replaced Host Header above
http-request do-resolve(txn.myip,mydns,ipv4) hdr(Host),lower

# print the resolved IP in the log
http-request capture var(txn.myip) id 0

# rule to prevent HAProxy from reconnecting to services
# on the local network (forged DNS name used to scan the network)
# add the IP Range for the destination host here
http-request deny if { var(txn.myip) -m ip 127.0.0.0/8 10.0.0.0/8 }
http-request set-dst var(txn.myip)

server clear 0.0.0.0:0

Please take care about the note in the documentation

NOTE: Don't forget to set the "protection" rules to ensure HAProxy won't be used to scan the network or worst won't loop over itself...

Haproxy dynamic backend matching request header

You can use the variable in the use backend directive.

Here is a snippet the full answer is here.
https://stackoverflow.com/a/61931107/6778826

frontend fe1
...
use_backend %[req.hdr(key),lower]

backend value
server something.value.com


Related Topics



Leave a reply



Submit