haproxy redirect to new domain if string found in request but keep and send all URL parameters - redirect

I want to do the following using haproxy:
if I get a request on domain 1 which includes a certain string (ie map1), I want to keep all that is after first / following the domain and redirect it all to domain 2. For example:
If I get https://sub1.domain1.gr/kjhkjhkh??efreerwer
I want to redirect to
https://sub2.domain2.gr/kjhkjhkh??efreerwer
Trying the following:
acl domain1_url hdr(host) sub1.domain1.gr
acl map1_uri capture.req.uri -m reg map1
http-request set-var(req.map1_uri) if domain1_url map1_uri
http-request set-path /%[var(req.map1_uri)]%[path] if { var(req.map1_uri) -m found }
http-request set-header Host sub2.domain2.gr if { var(req.map1_uri) -m found }
Is there something wrong with this logic?
Thank you in advance!

Well, I solved the problem.
I used:
acl domain1_url hdr(host) sub1.domain1.gr
acl map1_uri capture.req.uri -m reg map1
http-request redirect code 301 location http://sub2.domain2.gr%[capture.req.uri] if map1_uri
Read about it at http://patg.net/haproxy,apache/2017/08/04/haproxy/

Related

Haproxy redirect and fowarding the subdomain

I have an Haproxy server and I need when the user type any_word.registro.myserver.com.br on the browser, the Haproxy redirect to https://app2.otherserver.com.br/register/**any_word**
The any_word is a captcha (*.registro.myserver.com.br)
Today I have the following redirect that doesn't forward:
acl fqdn_register_all hdr_dom(host) -i registro.myserver.com.br
redirect prefix https://app2.otherserver.com.br/register code 302 if fqdn_register_all
How should i change the above code?
Best regards
this rule should do the work:
acl fqdn_register hdr_dom(host) -i registro.myserver.com.br
capture request header Host len 128
redirect prefix https://app2.otherserver.com.br/register/%[capture.req.hdr(0)] code 302 if fqdn_register
hope it helps.

HAProxy set authorization header from cookie

I have a backend that I don't control that works using magic links. If I use the magic link, I don't have to log on. I want to share the magic link externally without exposing the actual key as the key changes from time to time and I was hoping to use haproxy as a reverse proxy. I don't want the link to be open to the entire internet and would like to use basic auth as well. The problem I am facing is that the backend overwrites the Authorization header (it's required for the magic link to work) and I get stuck in a loop and need to log on every time
My workaround:
On first request I request the basic auth (works)
Then I write it to a cookie (this part works)
On each subsequent request, if the cookie exists, I read the cookie and set the Authorization header to the cookie value (this part does not work)
Then I run http_auth which in my mind should now work since I have overwritten the header
But it does not work. Any suggestions?
userlist auth-list
user myuser insecure-password mypass
frontend myfrontend
bind *:80
mode http
acl is-path path -i -m beg /publiclink
acl has_cookie req.hdr(X-MyAuth) -m found
http-request set-header Authorization %[req.hdr(X-MyAuth)] if has_cookie
http-request auth unless { http_auth(auth-list) }
http-request set-var(txn.myhostheader) req.hdr(Authorization) if { http_auth(auth-list) !has_cookie }
default_backend node
backend node
mode http
server dcnode1 192.168.0.1:8000 check
http-response set-header set-cookie "X-MyAuth=%[var(txn.myhostheader)]; Path=/" if { var(txn.myhostheader) -m found }
http-request replace-path /publiclink1(.*) /magiclink\1
http-request set-header Authorization "Key magiclink"
My answer is related to this point :
On each subsequent request, if the cookie exists, I read the cookie and set the Authorization header to the cookie value (this part does not work)
In your backend, you set the Set-Cookie: X-MyAuth=... header :
backend node
http-response set-header set-cookie "X-MyAuth=%[var(txn.myhostheader)]; Path=/" if { var(txn.myhostheader) -m found }
So the next request contains a Cookie header like this one : Cookie: .* X-MyAuth=.*.
But in your frontend, you use the X-MyAuth header (which probably does not exist) :
frontend myfrontend
acl has_cookie req.hdr(X-MyAuth) -m found
http-request set-header Authorization %[req.hdr(X-MyAuth)] if has_cookie
You may use the X-MyAuth cookie value like this :
frontend myfrontend
acl has_cookie cook(X-MyAuth) -m found
http-request set-header Authorization %[cook(X-MyAuth)] if has_cookie

Haproxy URL redirect

Using haproxy 2.0.13-2
Having an issue with ACL's and redirect
I want to ACL on stuff.xyz.com/mycrap.aspx and redirect that to junk.abc.com
As a test I have an
ACL acl_stuff hdr(host) -i stuff.xyz.com/junk.aspx
use_backend be_stuff if acl_stuff
backend be_stuff
stats enable
option forwardfor
http-response add-header X-Backend ohs1docker01
server ohs1docker01 ohs1docker01.def.com:80 check
However even the ACL with the backend isnt working. I hit that page and I get a 404 which leads me to believe the ACL is not getting hit so the traffic is not getting to the backend.
Im hoping someone can give me some direction on this
Looks like you want to use http-response redirect
http-response redirect code 301 location https://www.junk.abc.com if { hdr_beg(host) -i stuff.xyz.com }
The acl acl_stuff hdr(host) -i stuff.xyz.com/junk.aspx can't match because there is a mix of host and path.
To match host and path try this.
acl match_path path_beg /junk.aspx
acl match_host hdr_beg(host) -i stuff.xyz.com
http-response redirect code 301 location https://www.junk.abc.com if match_host match_path

HAProxy routes requests to wrong server

We are using HAProxy for our app. We have a separate server for site, API, docs and blog.
We have following HAproxy configurations
frontend http
mode http
bind *:80
redirect prefix https://www.kbook.com code 301 if { hdr(host) -i kbook.com }
redirect scheme https code 301 if { hdr(host) -i www.kbook.com } !{ ssl_fc }
redirect scheme https code 301 if { hdr(host) -i docs.kbook.com } !{ ssl_fc }
redirect scheme https code 301 if { hdr(host) -i api.kbook.com } !{ ssl_fc }
acl www hdr(host) -i www.kbook.com
acl docs hdr(host) -i docs.kbook.com
acl api hdr(host) -i api.kbook.com
acl blog path -i -m beg /blog
use_backend blog_server if www blog
use_backend site_server if www
use_backend api_server if api
use_backend docs_server if docs
frontend https
mode http
bind *:443 ssl crt /etc/ssl/live/wildcard_kbook.pem alpn h2,http/1.1
redirect prefix https://www.kbook.com code 301 if { hdr(host) -i kbook.com }
use_backend blog_server if { ssl_fc_sni -i www.kbook.com } { path -i -m beg /blog }
use_backend site_server if { ssl_fc_sni -i www.kbook.com }
use_backend api_server if { ssl_fc_sni -i api.kbook.com }
use_backend docs_server if { ssl_fc_sni -i docs.kbook.com }
HAProxy Version: 2.2.0-1ppa1~bionic
Issue:
When we access the site (www.kbook.com), it works sometimes. Sometimes it goes to blog server, says 404 not found. I expect "www.kbook.com" should always go to the site server.
This happens even to docs and API requests. Those requests are also going to the blog server sometimes.
HAproxy directs the requests to the wrong server. Why does it happen? is there any issue with configurations?
This was a bug in 2.2.0 and it should be fixed in 2.2.1

HAProxy: hdr_dom(host) with redirects

We have a couple of haproxy configurations running fine for the most part.
In our scenario, we simply route requests based on domain names.
Here a sample for one domain, drawmessage.com:
frontend http
bind *:80
redirect prefix http://app.drawmessage.com code 301 if { hdr_dom(host) -i www.app.drawmessage.com }
redirect prefix http://drawmessage.com code 301 if { hdr_dom(host) -i www.drawmessage.com }
redirect prefix https://drawmessage.com code 301 if { hdr_dom(host) -i drawmessage.com }
use_backend http:app.drawmessage.com if { hdr_dom(host) -i app.drawmessage.com }
use_backend http:app.drawmessage.com if { hdr_dom(host) -i app-drawmessage-com.d250.hu }
use_backend http:drawmessage.com if { hdr_dom(host) -i drawmessage.com }
use_backend http:drawmessage.com if { hdr_dom(host) -i drawmessage-com.d250.hu }
There are other domains also, this is filtered for this domain only. As you can see, after redirects for www, we apply a special redirect for drawmessage.com, but theoretically not for app.drawmessage.com.
frontend https
bind *:443 ssl crt /var/haproxy
redirect prefix https://app.drawmessage.com code 301 if { hdr_dom(host) -i www.app.drawmessage.com }
redirect prefix https://drawmessage.com code 301 if { hdr_dom(host) -i www.drawmessage.com }
use_backend https:app.drawmessage.com if { hdr_dom(host) -i app.drawmessage.com }
use_backend https:app.drawmessage.com if { hdr_dom(host) -i app-drawmessage-com.d250.hu }
use_backend https:drawmessage.com if { hdr_dom(host) -i drawmessage.com }
use_backend https:drawmessage.com if { hdr_dom(host) -i drawmessage-com.d250.hu }
The problem is that actually, we do not want a redirect to https for the subdomain app.drawmessage.com, but since we have a redirect for the domain the redirect rule applies for both. Reordering the rules in a way, so that the sorting matches the configuration we want to achieve does produce the same result, and we get haproxy warnings:
a 'redirect' rule placed after a 'use_backend' rule will still be processed before.
If the order of configuration lines affects the order of processing a request, thus the ordering is a configuration parameter itself, why are redirect rules processed before use_backend rules? ...
Anyone has a suggestion how to achieve domain-based routing, with the correct preference of redirects? I would prefer a clean and simple way, ..
Don't use hdr_dom(). Just use hdr().
redirect prefix https://drawmessage.com code 301 if { hdr(host) -i drawmessage.com }
The _dom suffix means you want to match the value given later against any number of complete, consecutive domain-name-like tokens found in the specified header, so the pattern you provide must begin either at the beginning of the string or immediately following a . and must end either at the end of the string or be immediately followed by a .. That isn't what you want to do, so hdr_dom() isn't the correct fetch to use.
The notation may imply that you are comparing left value against right value, but the comparison is actually right value against left value.
a 'redirect' rule placed after a 'use_backend' rule will still be processed before because these directives are handled by different parts of the HAProxy code, at different stages of request processing. Within each class of rule, the order is preserved, but redirects are handled near the beginning and backend selection is near the end of request processing.