Haproxy - ACL rules for post requests - haproxy

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

Related

Backend routing based on cookie name substring

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

How to remove query string with reqrep in Haproxy backend?

I am trying to write a reqrep query to try and strip out a query string. I am using ACLs with urlp_end to direct to the correct backend, but the query string that is being used for that is being passed over to the backend.
The frontend uses an ACL like this:
acl Test_ACL urlp_end(device) -m str eq 14110
use_backend Device_1 if Test_ACL
In my backend I just have the server IP, but i would like to remove the device parameter in the backend. Here is an example:
https://example.com/chkimg/FRONT200GRAY8_1.JPG?device=14110
This forwards to the right backend. Basically all i want to do is in the backend traffic, strip the "?device=______" parameter from the URL, so that it just forwards this to the backend, with the entire device parameter invisible to the backend server:
https://example.com/chkimg/FRONT200GRAY8_1.JPG
Member on Haproxy forum answered this for me
http-request set-uri %[path]

HAProxy http response rewrite rspirep string

Scenario is HAProxy as a reverse-proxy for a Docker user-defined network, so the servers are reachable by service name from HAProxy. Inbound works, but I can't seem to get the response rewrite to work.
I need any traffic, foo.com/api/* to be redirected to api:9999/*.
Current config
frontend https
acl api path_beg /api
use_backend api if api
backend api
reqrep ^([^\ ]*\ /)api[/]?(.*) \1\2
rspirep (.*) /api/
server api api:9999 check
I'm pretty sure this is what's needed, but I suspect my rspirep string is NOT correct. Any help is appreciated!

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.

Route by using existing cookie

How can I route requests in haproxy using a cookie that was set on the app servers?
Example: SESS=<hash-of-username>
haproxy should not insert cookies by itself in any case.
For testing a specific server behind haproxy I can recommend this approach:
frontend http
acl is_cookie_hack_1 hdr_sub(cookie) server_test_hack=server1
acl is_cookie_hack_2 hdr_sub(cookie) server_test_hack=server2
... insert your normal acl rules here
use_backend bk_server_1 if is_cookie_hack_1
use_backend bk_server_2 if is_cookie_hack_2
... insert your normal use_backend expressions here
backend bk_server_1
...
backend bk_server_2
...
I insert the server_test_hack cookie by javascript in my browser's js console by this script:
document.cookie="server_test_hack=server1";
You can't use your existing cookie for balancing, the way you could use the URI parameter. You can't just take the md5() or build the hash table of the cookie, at least that is not documented. You could use prefix parameter for the cookie to achieve a different result. It might be what you are looking for (if you want to avoid creation of yet another cookie).
So in your case the config would look like this:
backend bk_web
balance roundrobin
cookie SESS prefix indirect nocache
server s1 192.168.10.11:80 check cookie s1
server s2 192.168.10.21:80 check cookie s2
When the request arrives without a cookie, any server is chosen by round-robin and request is redirected to it. When response arrives from the backend, HAProxy checks for the SESS cookie and if it's set, it prepends the server name (sX) to the cookie and sends it to the client. In the browser, the cookie looks like sX~, but when the next request is sent with that cookie, the backend server only sees in the cookie, as HAProxy strips the sX~ part
Source: load balancing, affinity, persistence, sticky sessions: what you need to know
If you just want to read cookies in the request and route accordingly, you can do something like this in your configuration:
frontend http
acl cookie_found hdr_sub(cookie) COOKIENAME
use_backend app_server if cookie_found
backend app_server
balance roundrobin
server channel1 X.X.X.X:PORT #Host1
server channel2 Y.Y.Y.Y:PORT #Host2