HAProxy ACL - Backend resolution - haproxy

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?

Related

HAProxy to Istio Ingress

Currently, I am trying to configure a load balancer from where the traffic will be sent to a Kubernetes cluster. At the edge of the cluster, Istio ingress is serving the cluster's external request. HAProxy version 1.8
I can access the service using the below command from outside the cluster.
curl -k -HHost:httpbin.example.com --resolve httpbin.example.com:32009:192.168.50.10 https://httpbin.example.com:32009/status/418:
Below is my HAProxy configuration:
Frontend:
frontend https
bind *:443 ssl crt /etc/ssl/certs/site.pem
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
default_backend httpbin
Backend:
backend httpbin
balance roundrobin
mode tcp
acl httpbin_app req_ssl_sni -i httpbin.example.com
use-server master if httpbin_app
server master 192.168.50.10:32009 check ssl verify none
http-request set-header Host httpbin.example.com
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
Using HAProxy I am getting 503 always. Also during startup, HAProxy is saying the below line:
haproxy[14260]: backend httpbin has no server available!
Can you please help to find out the right configuration for backend?
Finally with the help of HAProxy community I have found the right configuration for Istio Ingress. This is very basic. Please update the settings as per your needs. Below is the link for the configuration.
https://gist.github.com/emamulandalib/2a613f5308c29518fcbcdc6b3bad3900

HAProxy - Partial SSL Offloading

Currently, I'm using tcp mode to redirect SSL traffic to two backend nodes where the certs are loaded and processed. This is working as expecting, and in apache with SNI I can process the necessary domains.
For one of these domains, I have a need to move it to a different backend and server. My question - is it possible to get this setup in haproxy within the same frontend ip / port? I do not want to load ALL the certs into HAProxy - but it would be fine to load just the cert for the site that needs to point at a different backend.
Basically, can I run something like this without needed to load all ssl certs into haproxy?
acl host_mysite hdr(host) -i mysite.example.com
Update. Here are the existing config sections:
frontend http_frontend
bind :::80 v4v6
tcp-request inspect-delay 5s
default_backend http_backend
acl host_mysite hdr(host) -i mysite.example.com
use_backend http_backend2 if host_mysite
backend http_backend
balance roundrobin
mode http
default-server inter 4s rise 3 fall 2
fullconn 20000
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
server server1 192.168.192.1:80 maxconn 10000 check
server server2 192.168.192.2:80 maxconn 10000 check
backend http_backend2
mode http
default-server inter 4s rise 3 fall 2
fullconn 20000
server server3 192.168.192.3:80 maxconn 10000 check
frontend ssl_frontend
bind :::443 v4v6
mode tcp
default_backend ssl_backend
backend ssl_backend
balance roundrobin
mode tcp
default-server inter 4s rise 3 fall 2
fullconn 20000
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
option ssl-hello-chk
server server1 192.168.192.1:443 maxconn 10000 check
server server2 192.168.192.2:443 maxconn 10000 check

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 web server redirects

I have only one PUBLIC IP address and two web servers one for each site I run. I have been trying to setup an HAproxy to redirect the requests to the correct web server, as following:
If user calls www.domain1.com, the HA proxy send this request to internal IP 192.168.0.249
If user calls www.domain2.com, it will be redirect to internal IP 192.168.0.100
I have made some searches on the Internet and I have made the following configuration for HAProxy.
global
log 127.0.0.1 local0 notice
maxconn 2000
user haproxy
group haproxy
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
timeout connect 5000
timeout client 10000
timeout server 10000
#stats
listen StatServer 0.0.0.0:80
mode http
stats enable
stats usi /haproxy?stats
stats reaml Strictly\ Private
stats auth user:pass
frontend http-in
bind *:80
default_backend domain1
reqadd X-forwarded-Proto:\ http
acl req_dimain2 hdr_beg(host) -i www.domain2.com
acl req_domain2 hdr_beg(host) -i domain2.com
use_backend domain2 if req_domain2
backend domain2
mode http
balance roundrobin
option httplog
option httpclose
option forwardfor
cookie JSSESIONID prefix
option httpchk HEAD /check.txt HTTP/1.0
server domain2 192.168.0.249 cookie avi_cr weight 1 maxconn 2000 check port 80 inter 2000 rise 2 fall 2
backend dimain1
mode http
balance roundrobin
option httplog
option httpclose
option forwardfor
cookie JESSESSIONID prefix
option httpchk HEAD /check.txt HTTP/1.0
server domain1 192.168.0.100 cookie atc_srv weight 1 maxconn 2000 check port 80 inter 2000 rise 2 fall 2
On haproxy stats page I always have both domain1 and domain2 DOWN and pages got error 503. Any help will be appreciated.
Regards.
Marcio
503 Error means HAproxy server didn't get proper web server.You can check on HAproxy front-end part.

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