HAProxy routes requests to wrong server - haproxy

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

Related

How haproxy uses sni to spread traffic?

My configuration is as follows, currently the web site works fine, I also have a public ip with an ssl certificate, it doesn't work,It is routed to the web site when requested, is there any way to fix it? Thanks
acl is_a01 ssl_fc_sni -i test.xyz
acl is_a02 ssl_fc_sni -i 12.13.14.16
use_backend n1 if is_a01
use_backend n2 if is_a02
default_backend web
There is a quite good description on this blog post Enhanced SSL Load Balancing with Server Name Indication (SNI) TLS Extension.
In the documentation is this the keyword you are searching for req.ssl_sni
Here is a untested snipplet from your question
# Wait for a client hello for at most 5 seconds
tcp-request inspect-delay 5s
# optionaly check if it's ssl_hello_type 1
tcp-request content accept if { req.ssl_hello_type 1 }
# The test values (test.xyz,12.13.14.16) *MUST*
# be in the certificate
acl is_a01 req.ssl_sni -i test.xyz
acl is_a02 req.ssl_sni -i 12.13.14.16
use_backend n1 if is_a01
use_backend n2 if is_a02
default_backend web

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: 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.

Redirecting URL using HAProxy

Im trying to direct the following URL https://register.company.xzy to https://register.company.xzy/register/supplier?code=
My haproxy config has acls in it for some existing subdomains and has been working well but i cant see to get this to work:
frontend https
bind 10.10.2.150:443 ssl crt /etc/apache2/ssl/star.company.xyz.pem
mode http
option httpclose
option forwardfor
reqadd X-Forwarded-Proto:\ https
acl www.company.xyz hdr(host) -i www.company.xyz
acl portal.company.xyz hdr(host) -i portal.company.xyz
acl live.company.xyz hdr(host) -i live.company.xyz
acl register.company.xyz hdr(host) -i register.company.xyz
use_backend website_live_servers if www.company.xyz
use_backend website_live_servers if portal.company.xyz
use_backend application_live_servers if live.company.xyz
use_backend register_live_servers if register.company.xyz
backend application_live_servers
mode http
cookie SERVERID insert indirect nocache
server server1 server1.company.xyz:80 check cookie $1
backend register_live_servers
mode http
cookie SERVERID insert indirect nocache
server server2 server2.company.xyz:80 check cookie $1
backend website_live_servers
mode http
cookie SERVERID insert indirect nocache
server server3 server3.company.xyz:80 check cookie $1
server server3 server3.company.xyz:80 check cookie $2
Any ideas or guidance?
Well what you need is to rewrite URL
http-request set-path <fmt> [<condition>]
http-request set-query <fmt> [<condition>]
OR rewrite complete URI
http-request set-uri <fmt> [<condition>]
rewriting url path

redirect 301 multiple domain name haproxy

I have a lot of domain names (example.com, www.example.com, example.net, www.example.net, etc...).
How can I redirect all these domains with haproxy ?
For the moment, I am able to redirect domain name by domain name with :
redirect prefix http://www.example.com code 301 if { hdr(host) -i example.fr }
redirect prefix http://www.example.com code 301 if { hdr(host) -i www.example.fr }
But I'd like to have just one line with all my domain names...
Regards
Try an if statement that checks if the host is not www.example.com
redirect prefix http://www.example.com code 301 if !{ hdr(host) -i www.example.com }