Haproxy multiple backends accessed with same path - haproxy

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

Related

haproxy redirec to to new domain

can you help me with that issue,
i have 2 old domains (www.rvsite.com,rvsite.com) and want to redirect it to new domain www.rv-site.com with haproxy.
haproxy.cfg
# Global settings
#---------------------------------------------------------------------
global
log /dev/log local0 info
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
ssl-server-verify none
user haproxy
group haproxy
daemon
#---------------------------------------------------------------------
defaults
log global
timeout client 10m
timeout connect 10m
timeout server 10m
mode http
option tcplog
option http-keep-alive
option http-use-htx
#---------------------------------------------------------------------
frontend rvsite-front
mode http
log global
option forwardfor
bind *:80 alpn h2,http/1.1
bind *:443 ssl crt /etc/ssl/rv-ssl/rv.pem crt /etc/ssl/rv-ssl/rvsite.pem
acl rvredirect hdr(host) -i rvsite.com www.rendezvous.com
http-request redirect scheme https code 301 unless { ssl_fc }
use_backend rvsite-back if rvredirect
default_backend rvsite-back
backend rvsite-back
mode http
log global
server backend 10.3.3.236:8443 check ssl verify none

haproxy randomly responses status code 503

I know there are many questions with this title, but I tried all solutions without any luck.
I have haproxy in front of 2 apache and another third standalone server in debian 9.
when I try mysite.com (backend_g1 in the config file) with https, it is always responding 200. but when I access it using http (that I replace it to https in the haproxy config file), there are 503
responses randomly ! this is my haproxy.cfg:
global
log /dev/log local0 notice
log /dev/log local1 notice
log 127.0.0.1 local2 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
maxconn 512
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
maxconn 512
timeout connect 5000
timeout client 600000
timeout server 600000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
# HTTP Auth
userlist basic-auth-list
group is-admin
# Plaintext password
user admin password $5$GnrqkuBdodw$./ groups is-admin
frontend stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats admin if LOCALHOST
frontend http-in
bind *:80
bind *:443 ssl crt /etc/ssl/mysite.com/mysite.com.pem
mode http
acl no_https ssl_fc,not
http-request redirect scheme https code 307 if no_https
acl g0_path path -i str /265952.txt
acl g0_path path -i str /registerInfo.php
acl g0_path path -i str /register
acl g0_path path -i str /register/
acl g0_path path_beg /icon/g0/
acl g0_path path_beg /css/g0/
acl g0_path path_beg /image/g0/
acl g0_path path_beg /icon/favicon/
acl g0_path path_beg /tool/
acl g0_path path_beg /lib/
acl g0_path path_beg /libs/
acl g0_path path_beg /asset/
acl g0_path path_beg /.well-known/
acl g0_path path_beg /pay/
acl g0_path path -i str /testing987.php
acl mysite_shop_id path,map_str(/etc/haproxy/maps/mysite_shop_id.map) -m found
http-request set-path /page?id=%[path,map(/etc/haproxy/maps/mysite_shop_id.map)] if { ssl_fc } mysite_shop_id
acl app_android_myshop path -i str /app/android/mysite-myshop.apk
http-request set-path /download/mobile/android/mysite-myshop.apk if app_android_myshop
acl g0_path path_beg /download/
acl mysite_admin1234567890 path_beg /mysite_admin1234567890/
use_backend backend_g0 if g0_path || app_android_myshop
# use_backend backend_nama if nama_path
use_backend backend_mysite_admin1234567890 if mysite_admin1234567890
default_backend backend_g1
backend backend_g0
balance roundrobin
cookie SERVERID insert
option http-keep-alive
timeout http-keep-alive 10s
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server g0 127.0.0.1:800 cookie g0
backend backend_mysite_admin1234567890
acl devops-auth http_auth_group(basic-auth-list) is-admin
http-request auth realm mysite_admin1234567890 unless devops-auth
option forwardfor
server mysite_admin1234567890 127.0.0.1:19999
http-request set-path %[path,regsub(^/mysite_admin1234567890/,/)]
http-request set-header Host %[src]
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Forwarded-Port %[dst_port]
http-request set-header Connection "keep-alive"
backend backend_g1
cookie SERVERID insert
option http-keep-alive
timeout http-keep-alive 20s
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server g1 127.0.0.1:8080 cookie g1
Maybe a mistake:
...
backend backend_g0
balance roundrobin # only on app at the end of this block
cookie SERVERID insert
option http-keep-alive
timeout http-keep-alive 10s
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server g0 127.0.0.1:800 cookie g0 # only one app
...
Maybe you should remove balance roundrobin if you have only one app after
And then
server g0 127.0.0.1:800 cookie g0 # wrong port ?
server g1 127.0.0.1:8080 cookie g1

Have to restart Haproxy every few minutes

(Ubuntu 16.04, 6 cores, 24GB Ram, Haproxy 1.8.0)
I've read so much about how easy haproxy is, so we set it up, did some basic testing / load testing and things looked good. Put it into production last night, things look good, until we start getting production traffic. I have to restart haproxy every few minutes b/c sites just stop responding. The stats website isnt showing me any stats that look alarming, and the machine is hardly using any resources.
Basically here is what we see - We restart haproxy, everything works great, then a few minutes later we have to restart it again (under production load).
Looking at the stats page I see the backend gets to around 50k sessions and then stuff just stops working.
Here is my config, can you check it out and help me understand how I should tune it?
global
log 127.0.0.1:22514 local2 debug
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
# Default ciphers to use on SSL-enabled listening sockets.
# For more information, see ciphers(1SSL). This list is from:
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
ssl-default-bind-options no-sslv3
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
timeout connect 50000000
timeout client 50000000
timeout server 50000000
maxconn 80000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend loadbalanced_main
log global
bind *:80
mode http
redirect scheme https if !{ ssl_fc }
acl web1 hdr(host) -i -m sub 1.a.com
acl web2 hdr(host) -i -m sub 2.a.com
acl web3 hdr(host) -i -m sub 3.a.com
use_backend ordweb1 if web1
use_backend ordweb2 if web2
use_backend ordweb3 if web3
default_backend loadbalanced_nodes
frontend loadbalanced_main_ssl
log global
bind *:443 ssl crt /etc/ssl/private/a.com.pem crt /etc/ssl/private/b.com.pem
reqadd X-Forwarded-Proto:\ https
acl web1 hdr(host) -i -m sub 1.a.com
acl web1 hdr(host) -i -m sub 1.b.com
acl web2 hdr(host) -i -m sub 2.a.com
acl web2 hdr(host) -i -m sub 2.b.com
acl web3 hdr(host) -i -m sub 3.a.com
acl web3 hdr(host) -i -m sub 3.b.com
use_backend ordweb1 if web1
use_backend ordweb2 if web2
use_backend ordweb3 if web3
default_backend loadbalanced_nodes
backend ordweb1
mode http
redirect scheme https if !{ ssl_fc }
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
server ordweb1 10.154.18.100:80 cookie check
backend ordweb2
mode http
redirect scheme https if !{ ssl_fc }
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
server ordweb2 10.154.18.8:80 cookie check
backend ordweb3
mode http
redirect scheme https if !{ ssl_fc }
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
server ordweb3 10.154.18.9:80 cookie check
backend loadbalanced_nodes
mode http
redirect scheme https if !{ ssl_fc }
balance roundrobin
option forwardfor
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
option httpchk HEAD / HTTP/1.1\r\nHost:localhost
cookie SRV insert indirect nocache
server ordweb1 10.154.18.100:80 check cookie ordweb1
server ordweb2 10.154.18.8:80 check cookie ordweb2
server ordweb3 10.154.18.9:80 check cookie ordweb3
listen stats
bind *:1936
stats enable
stats uri /
stats hide-version
stats auth nope:blah

Adding CORS in HAPROXY 1.6.9 with rspadd headers

I have setup HAPROXY on top of Apache which is working fine but I am not able make api call from other domain, It was CORS issues so I added
rspadd Access-Control-Allow-Origin:\ *
But still it is not adding response headers in api call.
Please let me know. Is there any other way to achieve it?
Here is my whole haproxy.cfg file
global
log 127.0.0.1 local2
#log 127.0.0.1 local1 notice
#log loghost local0 info
#log /dev/log local0 info
log-tag haproxy
maxconn 4096
chroot /usr/share/haproxy
uid 99
gid 99
daemon
debug
#quiet
defaults
log global
mode http
option httplog
option dontlognull
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 5000
srvtimeout 5000
frontend https
#bind *:80
bind *:443 ssl crt /etc/ssl/certs/server.bundle.pem
option http-buffer-request
declare capture request len 400000
http-request capture req.body id 0
log-format {"%[capture.req.hdr(0)]"}
# /opt/causeway/etc/libwebsockets-cpa.pem
acl httpsapi path_beg /API
use_backend serv_https_api if httpsapi
default_backend default_apache
frontend http
bind *:80
#bind *:443 ssl crt /etc/ssl/certs/server.bundle.pem
acl api path_beg /api
use_backend serv_api if api
default_backend default_apache
backend default_apache
server apache 127.0.0.1:81
backend serv_api
server server1 127.0.0.1:7687
rspadd Access-Control-Allow-Origin:\ *
rspadd Access-Control-Max-Age:\ 31536000
backend serv_https_api
server server2 127.0.0.1:7687
rspadd Access-Control-Allow-Origin:\ *
rspadd Access-Control-Max-Age:\ 31536000
# mode tcp
# log global
# tcp-request inspect-delay 5s
# tcp-request content accept if { req.ssl_hello_type 1 }
Any help highly appriciated.

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