Haproxy rewrite url - haproxy

I would like to use HAProxy to route the incoming request http://example.com/test/app/v1/foo/bar to http://example.com/v1/app/foo/bar.
I went through the example at Haproxy route and rewrite based on URI path and constructed the regex:
reqrep ^([^\ ]\*)\ /([a-zA-Z]\*)/([a-zA-Z]\*)/([0-9A-Za-z]\*)/(.\*) \1\ /\4/\3/\5
However it doesnt seem to work. Could anyone help figure this out?
Thanks.

Do not escape the asterisk characters (if you are using a recent version, you can even use quotes and not escape anything):
reqrep ^([^\ ]*)\ /([a-zA-Z]*)/([a-zA-Z]*)/([0-9A-Za-z]*)/(.*) \1\ /\4/\3/\5
Following test works
$ curl -IL http://127.0.0.1/test/app/v1/foo/bar
127.0.0.1 - - [09/Jul/2016:01:45:01 +0200] "HEAD /v1/app/foo/bar HTTP/1.1" 404 0 "-" "curl/7.47.0"

Related

Replace regrep for HAproxy 2.x

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

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?

Haproxy errorfile cannot be read

I have the following Haproxy config:
frontend http-in
mode http
bind :80
option forwardfor
option httplog
reqadd X-Forwarded-Proto:\ http
default_backend http-routers
errorfile 502 /var/haproxy/404.http
acl is_internal_error status eq 404
rspdeny . if is_internal_error
When I hit the url for non existing domain, ex: http://test.example.com
I receive a timeout error (408).
However, when I retrieve the line errorfile 502 /var/haproxy/404.http, I can see the default error msg of 502 error code.
Can anyone tell why Haproxy cannot read my file /var/haproxy/404.http?
Sounds like permissions problem right off the bat. What user is haproxy running as? Can you post the permissions of /var/haproxy/404.http?
I think this is a duplicate of Haproxy behind ELB.
TL;DR;
Problems with erro_file newline format.
You need a ^M on HTTP INFO lines, not needed on the response body.
Dont know why, but it behaves that way. hope it helps.
Example file has those when open in vi(m). Don't copy the contents, it looks the same but isn't.
Cheers

HAProxy redirect to subdomain

I am trying to redirect these:
http://www.example.co.uk/blog/xyz?a=b
https://www.example.co.uk/blog/xyz?a=b
to these:
http://blog.example.co.uk/xyz?a=b
https://blog.example.co.uk/xyz?a=b
But struggling with the documentation and the best way to do this.
* Update *
This is what I have got working at the moment. If I pass in:
http://www.example.co.uk/blog?a=b
then this redirects to:
http://blog.example.co.uk?a=b
... and the section of the config:
acl blog_page path_beg -i /blog
use_backend blog_site if blog_page
backend blog_site
reqrep ^([^\ :]*)\ \/?(.*)\/blog\/?(.*) \1\ /\2\3
redirect prefix http://blog.example.co.uk code 301
The following line in the frontend section will accomplish this rewrite and redirect.
Shown as multiple lines for clarity, this must all appear on a single line of your configuration:
http-request redirect
code 301
location https://blog.example.com%[capture.req.uri,regsub(^/blog,)]
if { hdr(host) -i www.example.com } { path_beg /blog }
If the host header matches www.example.com and path begins with blog, redirect to a location beginning with the literal string https://blog.example.com then concatenate a value derived by taking the request URI (path + query string) and using regex substitution to remove /blog from the beginning.
Verifying:
$ curl -v 'http://www.example.com/blog/posts?which=this&that=1'
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to www.example.com (127.0.0.1) port 80 (#0)
> GET /blog/posts?which=this&that=1 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: www.example.com
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Content-length: 0
< Location: https://blog.example.com/posts?which=this&that=1
The redirect location appears to be correct.
If you want to redirect http and https separately, you'd need two lines, each of them testing an additional condition to determine whether the original request was over http or https.
Using the regsub() converter requires HAProxy 1.6+.

haproxy 1.5 issue with reqrep when # is part of URI

I am trying to rewrite a URL with haproxy, but when the URI contains a "#" in the string, haproxy cuts off the rest.
Example:
Incoming URL: http://foo.com/app1/abc?id=1&date=2016-07-06#access_token
The Goal is to Rewrite URL to: http://foo.com/abc?id=1&date=2016-07-06#access_token (notice the "app1" is dropped)
This is the rule I am using, but truncates the resulting URL when it encounters "#"
reqrep ^([^\ ]\ /)l2[/]?(.) \1\2
The HAproxy log: (Notice it truncated anything after the #)
Aug 4 16:06:20 localhost haproxy[5098]: xx.xx.x.xxx:61679 [04/Aug/2016:16:06:18.252] http app1/app1 0/0/0/428/2115 200 10880953 - - ---- 3/3/0/1/0 0/0 "GET /app1/abc?id=1&date=2016-07-06 HTTP/1.1"
Any advise on this?