Backend routing based on cookie name substring - haproxy

Example cookie name in request:
wordpress_logged_in_8df6736080e8...
I want to create an haproxy acl based on when the cookie name begins with wordpress_logged_in and then route the logged in users based on that acl to separate backend.

acl url_admin path_beg -i /wp-admin /wp-login.php
acl url_admin hdr_sub(cookie) wordpress_logged_in
This config is working for me, as it matches the whole cookie header and some URLs. Without the first ACL it's not working.

You can try to use cook_beg for the acl
acl cookie_backend cook_beg(wordpress_logged_in) -m found
...
use_backend cookie_backend if cookie_backend
...
default_backend default_backend
This Blog post explains the haproy acl Introduction to HAProxy ACLs
In the doc can you find more details Using ACLs to form conditions

Related

Haproxy - ACL rules for post requests

I would like to deny the access to a rest api endpoint if a specific query string parameter (e.g. param) is set in a post request.
E.g.: POST /api?param
Add the following ACL role to your HA Proxy configuration:
acl param_in_url query -i param
http-request deny if param_in_url

haproxy - redirect specific domain/path to other domain

i need redirect request from specific domain/path to other domain with same path, eg.
domain.com/foo/everything --> example.com/foo/everything
I think need use url_reg but I can't understand how to handle the redirect, maybe it could be such a thing?
acl redirect-foo url_reg -i ^domain.com\/foo\/*
http-request redirect code 301 location http://example.com/foo/ if redirect-foo
but obviously it doesn't work, thank anyone who can help me
You can use the following snipplet
acl host_match hdr(host) -i domain.com
acl path_match path_beg -i /foo/
http-request redirect code 301 location http://example.com/%[capture.req.uri] if host_match path_match
The acl's are described in the Documentation and in following Blog post.
Using ACLs to form conditions
Introduction to HAProxy ACLs
Documentation for capture.req.uri

HAProxy - Add Trailing Slash

I am working on a project where I need requests destined to a particular page to be routed to a separate backend.
For example, all requests for https://mycooldomain.com will go to backend "A". But, if navigating to https://mycooldomain.com/secretpage I want it to go to backend "B".
Now, I have this working but running into an issue where I need the trailing slash for this to work correctly.
So, I need a way to say if request is https://[whateverhostnameisused]/secretpage redirect to https://[whateverhostnameisused]/secretpage/.
Here is a sample of my config so far:
frontend f_https
bind *:443 ssl crt cert.pem
reqadd X-Forwarded-Proto:\ https
#define hosts
acl host_a hdr(host) -i a.mycooldomain.com
acl host_b hdr(host) -i b.mycooldomain.com
acl host_c hdr(host) -i c.mycooldomain.com
#custom acls
acl secret path_beg -i /secretpage
#Custom redirects
##define backend
use_backend b_secret if secret
use_backend b_a if host_a
use_backend b_b if host_b
use_backend b_c if host_c
default_backend b_https
backend b_secret
server secret 192.168.15.15:5575 check
It seems that you are looking for something like this:
http-request redirect scheme https drop-query append-slash if { path -m str /secretpage }
This should work if applied to either the frontend or the backend.
http://cbonte.github.io/haproxy-dconv/1.6/configuration.html#4.2-redirect%20scheme
Specifying the scheme is only necessary because the syntax requires one of location | prefix | scheme, and with the other two options, you have to reassemble the URL yourself in the config.
Note also that reqadd is not officially deprecated, but the preferred way to add that request header is like this:
http-request set-header X-Forwarded-Proto https
Note that no : is specified and the space after the header name must not be escaped with \. This accomplishes the same result, but it uses a different code path inside HAProxy, and should be a more efficient operation. You will want to use the the http-request and http-response directives instead of reqxxx and rspxxx where possible, as they are also better suited to more complex manipulations.

pass a backend from backend map to haproxy nbsrv

Can someone advise what I have to change in the nbsrv expression in order to make it work:
frontend webfarm
bind 11.22.33.44:80
...
acl MAIN_not_enough_capacity nbsrv([%[req.hdr(host),lower,map(/etc/haproxy/backend.map,bk_default)]]) eq 0
http-request redirect code 301 location http://global-swajm.example.com if MAIN_not_enough_capacity
use_backend %[req.hdr(host),lower,map(/etc/haproxy/backend.map,bk_default)]
The idea is according to the host in the header to get the right backend name from the map file.
If there are no available servers in this backend the request will be redirected to another haproxy (in another DC).
use_backend is working perfectly:
use_backend %[req.hdr(host),lower,map(/etc/haproxy/backend.map,bk_default)]
but I don't know how to modify the expression for nbsrv in order to pass the backend name:
nbsrv([%[req.hdr(host),lower,map(/etc/haproxy/backend.map,bk_default)]])
just chiming in after having struggled with the same
Use
acl MAIN_not_enough_capacity req.hdr(host),lower,map(/etc/haproxy/backend.map,bk_default),nbsrv eq 0
instead

HAProxy path_beg not redirecting

I'm testing a simple haproxy rule to make http://localhost/haproxy-dconv take me to http://cbonte.github.io/haproxy-dconv but it isn't working. 404 response seems to be from the site but the path isn't resolving.
frontend HTTP
mode http
bind *:80
acl url_dconv path_beg /haproxy-dconv
use_backend dconv-backend if url_dconv
backend dconv-backend
mode http
server dconv cbonte.github.io
Try this -
frontend HTTP
mode http
bind *:80
use_backend dconv-backend if { path_beg /haproxy-dconv/ }
backend dconv-backend
mode http
server dconv cbonte.github.io
Source: https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#use_backend
That is because the Host header that is being sent is localhost, instead of cbonte.github.io. Add this to your backend:
http-request set-header Host cbonte.github.io
Also note that without the ending slash, you will get a 301, so make sure you send http://localhost/cbonte-dconv/ and fix your ACL.
You are using Haproxy in an incorrect way.
You need to match the ACL to get the URL between host and query parameter as you do:
acl url_dconv path_beg /haproxy-dconv
Then using this ACL to redirect from localhost if ACL is matched:
redirect prefix http://cbonte.github.io code 301 if url_dconv
But again this is more a conceptual problem of thinking redirect and matching path.