How to pass 4 level domain to cluster in haproxy - haproxy

I have an issue with haproxy: it is not passing 4-level domains to the cluster in HTTP. I can pass to the third level.
Part of haproxy config regarding http
frontend http
bind *:8080
use_backend dev if { hdr_sub(host) -i dev.example.sk }
use_backend staging if { hdr_sub(host) -i staging.example.sk }
use_backend prod if { hdr_sub(host) -i example.sk }
default_backend prod
So product.dev.example.sk will go nicely to dev
But test.product.dev.example.sk will not be passed to dev and fails in default prod.
Do you know how to achieve that test.product.dev.example.sk will go to dev?

Related

Specific routing for subdomains and wildcard domain on HAProxy

How could I achieve the correcting routing for specific subdomains and then route any domains that doesnt match any of the previous ACLSs?
frontend web_dashs
mode http
bind *:443 ssl crt /etc/ssl/domain/
http-request add-header X-Forwarded-Proto https
redirect scheme https if !{ ssl_fc }
acl domain_a hdr_sub(host) -i a.domain.com
acl domain_b hdr_sub(host) -i b.domain.com
acl wilds hdr(host) -i
# Default Route to normal backends
use_backend backend_a if domain_a
use_backend backend_b if domain_b
use_backend backend_c if wilds
Basically, what i'm trying to do is basically:
a. ----> backend A
b. ----> backend B
*.-----> backend C
Thanks in advance.
ACL is not needed for matching the rest, just use default_backend:
frontend web_dashs
mode http
bind *:443 ssl crt /etc/ssl/domain/
http-request add-header X-Forwarded-Proto https
redirect scheme https if !{ ssl_fc }
acl domain_a hdr_sub(host) -i a.domain.com
acl domain_b hdr_sub(host) -i b.domain.com
use_backend backend_a if domain_a
use_backend backend_b if domain_b
default_backend backend_c

HAProxy ACL - Backend resolution

Given this HAProxy configuration:
acl acl-api-qa hdr(host) -i qa.example.com
use_backend backend-api-qa if acl-api-qa
backend backend-api-qa
mode http
balance leastconn
server-template api 10 _api._env=qa.service.consul resolvers consul resolve-prefer ipv4 check
acl acl-api-test hdr(host) -i test.example.com
use_backend backend-api-test if acl-api-test
backend backend-api-test
mode http
balance leastconn
server-template api 10 _api._env=test.service.consul resolvers consul resolve-prefer ipv4 check
Traffic is only getting routed to qa.example.com but test.example.com is a 503: service unavaliable as HAProxy seems to short-circuit when it encounters the first backend and ignores the next set of ACls and backends. Is this an ordering problem? can I not interweave ACLs and backends? Should these be built out as an ACLs section followed by a Backends section?
that appears to be the case? This worked for me:
acl acl-api-test hdr(host) -i test.example.com
acl acl-api-qa hdr(host) -i qa.example.com
use_backend backend-api-test if acl-api-test
use_backend backend-api-qa if acl-api-qa
backend backend-api-test
mode http
balance leastconn
server-template api 10 _api._env=test.service.consul resolvers consul resolve-prefer ipv4 check
backend backend-api-qa
mode http
balance leastconn
server-template api 10 _api._env=qa.service.consul resolvers consul resolve-prefer ipv4 check
but results in a fair bit of duplicated code in my consul template. does HAProxy expect acl, use-backend, and backend to be grouped into distinct groups?

Haproxy multiple backends accessed with same path

I have 4 java apps running on my server, 2 primary & 2 subapps, that I need to access via Haproxy.
app1 ----> listens on tcp:8442 accessed at app1.domain.org
subapp1 ----> listens on tcp:9001 and is accessed with path app1.domain.org/abc
app2 ----> listens on tcp:8444 accessed at app2.domain.org
subapp2 ----> listens on tcp:9000 and is accessed with path app2.domain.org/abc
so the sub apps are both accessed using the same path
I'm having trouble getting Haproxy to route requests to the correct sub app. With the included config accessing the primary apps is working fine, but depending on the order of the use_backend statements, all sub app requests are being routed to the same back end (which ever is listed first). No difference is observed if I reorder the ACL's though. It seems like the ACL's are not correctly matching the inbound request.
Any help is appreciated!
my config:
global
log localhost local1
log-send-hostname server-hostname
maxconn 1024
user root
group root
daemon
pidfile /var/run/haproxy.pid
ssl-default-bind-options no-sslv3 no-tls-tickets
defaults
log global
mode http
option dontlognull
option forwardfor
no option http-server-close
no option accept-invalid-http-request
timeout client 600s
timeout client-fin 10s
timeout server 600s
stats enable
stats auth user:password
stats uri /haproxyStats
listen admin
mode http
bind *:8080
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /
stats auth user:password
frontend http-in
bind *:80
acl invalid_src src 0.0.0.0/7 224.0.0.0/3
acl invalid_src src_port 0:1023
http-request deny if invalid_src
option tcplog
log-format %ci\ %f\ %b\ %ST\ %{+Q}r\ %Tr
redirect scheme https code 301 if !{ ssl_fc }
frontend https-in
bind *:443 ssl crt /etc/haproxy/ssl.cert
mode http
acl test_sapp path_beg -i /abc
acl test_sapp hdr(host) -m dom -i *app2.domain.com*
acl prod_sapp path_beg -i /abc
acl prod_sapp hdr(host) -m dom -i *app1.domain.com*
acl test_app1 hdr_end(host) -i app2.domain.com
acl prod_app1 hdr_end(host) -i app1.domain.com
acl invalid_src src 0.0.0.0/7 224.0.0.0/3
acl invalid_src src_port 0:1023
http-request deny if invalid_src
option tcplog
log-format %r
reqadd X-Forwarded-Proto:\ https
use_backend sapp-test if test_sapp
use_backend sapp-prod if prod_sapp
use_backend app-prod if prod_app1
use_backend app-test if test_app1
timeout client 600s
timeout client-fin 10s
backend app-prod
balance leastconn
option httpclose
option forwardfor
server prod-web-node 127.0.0.1:8442 cookie A check
timeout server 600s
backend app-test
option httpclose
option forwardfor
server test-web-node 127.0.0.1:8444 cookie A check
timeout server 600s
backend sapp-prod
balance leastconn
option httpclose
option forwardfor
server prod-mdr-node 127.0.0.1:9001 cookie A check
timeout server 600s
backend sapp-test
balance leastconn
option httpclose
option forwardfor
server test-mdr-node 127.0.0.1:9000 cookie A check
timeout server 600s
This is untested but I think this https-in frontend should work:
frontend https-in
bind *:443 ssl crt /etc/haproxy/ssl.cert
mode http
acl prod_domain hdr(host) -i app1.domain.com
acl test_domain hdr(host) -i app2.domain.com
acl sub_app path_beg -i /abc
acl invalid_src src 0.0.0.0/7 224.0.0.0/3
acl invalid_src src_port 0:1023
http-request deny if invalid_src
option tcplog
log-format %r
reqadd X-Forwarded-Proto:\ https
use_backend sapp-test if sub_app test_domain
use_backend sapp-prod if sub_app prod_domain
use_backend app-prod if prod_domain
use_backend app-test if test_domain
timeout client 600s
timeout client-fin 10s
The key is on the use_backend sapp-test and use_backend sapp-prod lines where the backend is only selected if both the sub_app acl and the test_domain/prod_domain acl are true. Otherwise it falls back to either the app-prod or app-test backends.
Hope that helps :)

HAProxy redirect based on path?

I need to redirect certain paths to https - frontend secured
The reason for this is that i want certain parts of my web application to only be allowed to run over https.
I've figured out how to redirect all traffic by changing my HAproxy conf like this:
frontend unsecured *:80
#timeout client 86400000
#redirect prefix http://domain.com code 301
mode http
timeout client 120s
But how can i configure it to only redirect certain sub-folder on my domain?
What i would like is to redirect only the following URLs:
http://domain.com/info
http://domain.com/echo
http://domain.com/broadcast
http://domain.com/close
http://domain.com/probe
http://domain.com/cd* (wildcard)
Is this possible?
You should use acl to match you criteria.
frontend unsecured *:80
acl is-unsecure-path01 path_beg /info
acl is-unsecure-path02 path_beg /echo
acl is-unsecure-path03 path_beg /broadcast
acl is-unsecure-path04 path_beg /close
acl is-unsecure-path05 path_beg /probe
acl is-unsecure-path06 path_beg /cd
use_backend application-backend if is-unsecure-path01
use_backend application-backend if is-unsecure-path02
use_backend application-backend if is-unsecure-path03
use_backend application-backend if is-unsecure-path04
use_backend application-backend if is-unsecure-path05
use_backend application-backend if is-unsecure-path06
backend application-backend
redirect scheme https if !{ ssl_fc }
This one should do the trick
frontend http
bind *:80
acl is-secure path_reg ^\/(info|echo|close|cd.*)
redirect scheme https code 301 if is-secure !{ ssl_fc }
use_backend the-app unless is-secure
frontend https
bind *:443 ssl crt /usr/local/etc/haproxy/ssl
use_backend the-app
backend the-app
server account-1 account:80 check
NOTE: Change the SSL cert path on your app.

haproxy acl not working in https/tcp mode

I am experiencing some problems, it seems I can't get acl's to work in tcp mode, everything works in http mode.
Here is my config.
frontend http *:80
acl http_test_acl path_beg -i /test
use_backend http_test if http_test_acl
default_backend http_default
backend http_test
balance roundrobin
server httptest 10.10.10.10:80 check
backend http_default
balance roundrobin
server httpdefault 10.10.10.10:80 check
############# HTTPS #################
frontend https *:443
mode tcp
acl https_test_acl path_beg -i /test
use_backend https_test if https_test_acl
default_backend https_default
backend https_test
mode tcp
balance roundrobin
server httpstest 10.10.10.10:443 check
backend https_default
mode tcp
balance roundrobin
server httpsdefault 10.10.10.10:443 check
Don't pay attention to ip 10.10.10.10 as I have hidden my orginal one. Could you please let me know why https is not working, http frontend/backend acl rules are working just fine.
cheers
Cause your https servers are in tcp mode (as they should be for ssl), so a layer 7 rule wont work.
for acl to work, disable tcp mode then set up ssl on the servers on your backend(hence the ssl keyword)
frontend https *:443
acl https_test_acl path_beg -i /test
use_backend https_test if https_test_acl
default_backend https_default
backend https_test
balance roundrobin
server httpstest 10.10.10.10:443 ssl check
backend https_default
balance roundrobin
server httpsdefault 10.10.10.10:443 ssl check
Alternatively instead of having to setup ssl on both your backend servers; use private IPS in the backend servers and make sure ports on the backend servers arent open to the world
backend https_test
balance roundrobin
server httpstest some_private_ip:8000 check