Replace regrep for HAproxy 2.x - haproxy

I need to administrate a server with a previously configured HAproxy v1.8. After updating to v2.4 I noticed the error about regrep not used anymore:
[ALERT] (1574) : parsing [/etc/haproxy/haproxy.cfg:310] : The 'reqrep' directive is not supported anymore since HAProxy 2.1. Use 'http-request replace-path', 'http-request replace-uri' or 'http-request replace-header' instead.
I was following some documentation but cannot really be sure I'm using the correct way to replace regrep. The configuration line in haproxy.cfg, in backend section:
reqrep ^([^\ :]*)\ /amc[/]?(.*) \1\ //\2
What is the correct way to update it?

It looks to me that you want to replace the path.
You can try the following, untested.
http-request replace-path /amc[/]?(.*) /\1
More examples can be found in the doc http-request replace-path

Related

How to set host-header depending on choosen backend when using HAProxy as loadbalancer

Under certain circumstances it is required to modify the host-header based on the backend selected by HAProxy loadbalancing (an example is described here: https://www.claudiokuenzler.com/blog/919/haproxy-how-use-different-http-host-header-for-each-backend-server)
My internet research shows that there are basically two ways to achieve this:
a) use "http-send-name-header Host" (not recommended according the HAProxy docs: https://www.haproxy.com/documentation/hapee/latest/onepage/#4.2-http-send-name-header)
b) use " http-request set-header Host ... if { srv_id 1 }"
(the following article describes these two techniques: https://serverfault.com/questions/876871/configure-haproxy-to-include-host-headers-for-different-backends)
Option a) works as expected but it is discouraged to be use (see https://www.haproxy.com/documentation/hapee/latest/onepage/#4.2-http-send-name-header).
For this reason I am trying to option b). Unfortunately the config cowardly refuses to work:
backend loadbalanced-backends
mode http
balance roundrobin
option forwardfor
http-request set-header Host one.domain.com if { srv_id 1 }
http-request set-header Host two.domain.com if { srv_id 2 }
server one one.domain.com:8000
server two two.domain.com:8000
The warnings printed in the log:
[WARNING] (1) : config : parsing ....cfg:14] : anonymous acl will never match because it uses keyword 'srv_id' which is incompatible with 'backend http-request header rule'
[WARNING] (1) : config : parsing ....cfg:15] : anonymous acl will never match because it uses keyword 'srv_id' which is incompatible with 'backend http-request header rule'
Besids the warning the logged request-header show that the host is not changed to one.domain.com resp. two.domain.com.
What exactly means the warning "anonymous acl will never match..."? I do not see what is wrong with the configuration. Any ideas are welcome.

How do I secure cookies in HAProxy 2.2+ using an `http-response` line?

I'm upgrading from HAProxy 1.8 to 2.2 and the command reqirep has been deprecated and removed. I used this previously to automatically add Secure to cookies that weren't previously secure. I want to use the new http-response syntax.
My old code looks like this:
rspirep ^(set-cookie:\ (?:(?!(\ Secure|ASPXAUTH=)).)*)$ \1;\ Secure
This adds ; Secure to any cookie header that doesn't contain Secure or ASPXAUTH=.
I'd like to do the same thing with one of the modern http-response commands.
Here's my initial translation:
http-request replace-header Set-Cookie (.*) %[src];\ Secure if { hdr_reg(Set-Cookie) -i (?!(\ Secure|ASPXAUTH=)) }
# Replace the "Set-Cookie" header
# That contains any value
# With the initial value with "; Secure" appended to the end
# If the cookie doesn't contain " Secure" or "ASPXAUTH=", ignoring case
Is this the right approach? Have you done this successfully?
We ended up with this as a solution. It's not perfect because it will only look for Secure modifier on the end of the Set-Cookie line but it works for what we need.
http-response replace-header Set-Cookie ^((?:.(?!\ [Ss]ecure))*)$ \1;\ Secure

How do I set up a reverse proxy in ISPConfig?

Is it possible to set up a reverse proxy in ISPConfig?
I tried this setting on a subdomain, but I only receive a error 500.
The /var/www/influxdb2.*******.***/log/error.log says the following:
==> error.log <==
[Fri Jan 01 21:24:15.963158 2021] [proxy:warn] [pid 30333] [client ***.***.***.***:59356] AH01144: No protocol handler was valid for the URL /favicon.ico (scheme 'http'). If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule., referer: https://influxdb2.*******.***/
For me, the proxy_http mod was missing.
Enable it via sudo a2enmod proxy_http and restart your apache with systemctl restart apache2 (thanks to https://serverfault.com/questions/773449/no-protocol-handler-valid-for-the-url-with-httpd-mod-proxy-balancer).
Also note that the "redirect type" setting sometimes seems to reset itself to "none" on saving (or at least does not display the correct value on loading the page as of ISPConfig 3.2.1). So double check that setting if something does not work.
For the "Domain" tab, settings are pretty straightforward. Just enter your domain and probably enable Let's Encrypt.
Note that this seems to use mod_rewrite for proxying. The Apache2 documentation on mod_rewrite states that better ProxyPass of mod_proxy should be used instead. So if anything breaks with some applications, this might be a starting point for further investigations (worked for me for reverse proxying to the HTTP endpoint of InfluxDB 2.0.3 at http://localhost:8086).

Setting a unique http request id with haproxy's http-request set-header

So I have some existing code that sets a unique request ID in our front-end load balancer:
unique-id-format %{+X}o\ %Ts_%ci_%cp_%fi_%fp_%rt_%pid
unique-id-header X-Request-Id
log-format %ci\ %r\ %ST\ %B\ %Tr\ %Tt\ %s\ %ID\ %hr
This works as expected -- X-Request-Id is created as expected, logged and passed to the backend. No problems. However, I'd like to make this request ID generation conditional. No problem -- I should just be able to use http-request set-header instead of unique-id-header:
unique-id-format %{+X}o\ %Ts_%ci_%cp_%fi_%fp_%rt_%pid
http-request set-header X-Request-Id %ID
log-format %ci\ %r\ %ST\ %B\ %Tr\ %Tt\ %s\ %ID\ %hr
(These are all in a front_end section). Maddeningly, however %ID seems to evaluate to empty when used this way. I can use a hardcoded value instead of using %ID and it works. I can also use another log field (like %Ts) and it works. It does not, however, work with %ID. Any clues would be helpful -- thanks in advance.
EDIT: Version is 1.6.11
I had the exact same issue in that I wanted to conditionally set the header if not present and %ID wasn't working as you'd expect. I found solutions suggesting to use %[unique-id] but it turns out that's only in version 1.7+. I have subsequently upgraded to 1.7 and now it works perfectly.
unique-id-format %{+X}o\ %pid%ci%cp%fi%fp%Ts%ms%rt
acl cid_exists req.hdr(X-Correlation-ID) -m found
http-request set-header X-Correlation-ID %[unique-id] unless cid_exists
http-request capture hdr(X-Correlation-ID) len 64
log-format "%ci:%cp [%tr] %ft %b/%s %Th/%Ti/%TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %{+Q}r %[capture.req.hdr(0)]"
The captured X-Correlation-ID header contains either a preexisting CID or one that this loadbalancer has created itself if missing.
The unique-id HTTP sample is referenced here.

How to fix an improper request in HAProxy

We have several (100+) clients in the field with a bug in the HTTP request. The request was previously working when directly routed to our Windows Server, but now with it fails with HAProxy v1.7 in front of it.
Here is an example request:
GET /index.aspx HTTP/1.1 \nHost: host\n\n
There is an extra space after the HTTP version before the \n.
Here is a snapshot of the relevant config.
frontend http_port_80
bind :80
mode http
reqrep (.)\ HTTP/1.1\ (.*) \1\ HTTP/1.1\2
option forwardfor
option accept-invalid-http-request
stats enable
use_backend cert_update if is_updater
use_backend getConsoleHTTP if is_getconsole
default_backend schedule_server
I have tried rewriting the request to remove the extra space and set the option accept-invalid-http-request to address the issue, but we still receive the same error.
{
type: haproxy,
timestamp: 1506545591,
termination_state: PR-,
http_status:400,
http_request:,
http_version:,
remote_addr:192.168.1.1,
bytes_read:187,
upstream_addr:-,
backend_name:http_port_80,
retries:0,
bytes_uploaded:92,
upstream_response_time:-1,
upstream_connect_time:-1,
session_duration:2382,
termination_state:PR
}
Does anyone have any ideas of how to fix the malformed request prior to haproxy rejecting it?