HAProxy 503 Service Unavailable - POST with Header - haproxy

The backend is not forwarding traffic to the server and returns 503 service unavailable.
My server requires the exact URL and headers. If the header is not set, the server will return 401 unauthorized and if the URL is not set, the server will return 404 Not found.
My cfg file
global
log 127.0.0.1 local0 debug
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 1000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
frontend main 0.0.0.0:80
option httpclose
option forwardfor
reqadd X-Forwarded-Proto:\ http
http-request add-header X-Forwarded-Proto http
default_backend app
backend app
balance roundrobin
server app1 100.82.185.122:32401
I am testing as following
import csv
import requests
import time
#url='http://100.82.185.122:32401/services/collector/event' #DIRECT URL
url='http://100.82.182.73/services/collector/event' #HA Proxy URL
authHeader = {'Authorization': 'Splunk {}'.format('f64e68e1-a6e4-46a1-8fe3-131023886841')}
reader = csv.DictReader(open('overheating_.csv'))
for row in reader:
#row['SystemUsage.AggregateUsage'] = 17
#row['FanSensor.RPMReading'] = 3
jsonDict = {"index":"dltk-test", "source":"csv", "sourcetype":"all-idrac", "event": row }
#print (row)
r = requests.post(url, headers=authHeader, json=jsonDict, verify=False)
print (r.text)
time.sleep(1)
Response
<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>
HAProxy Logs
Jun 28 15:30:51 localhost haproxy[25389]: 100.82.183.41:41182 [28/Jun/2022:15:30:51.906] main app/app1 0/0/-1/-1/0 503 212 - - SC-- 0/0/0/0/3 0/0 "POST /services/collector/event HTTP/1.1"
Jun 28 15:30:52 localhost haproxy[25389]: 100.82.183.41:41184 [28/Jun/2022:15:30:52.913] main app/app1 0/0/-1/-1/0 503 212 - - SC-- 0/0/0/0/3 0/0 "POST /services/collector/event HTTP/1.1"
Please guide me what's wrong here.

semanage port --add --type http_port_t --proto tcp 32401
I added this line to allow traffic on port 32401

Related

url_param routing algorithm in HAProxy

haproxy.cfg:
global
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 5000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 10m
timeout server 10m
timeout http-keep-alive 10s
timeout check 10s
maxconn 4000
listen stats
bind :9000
mode http
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /haproxy
frontend http-in
bind *:80
acl acl_is_host hdr(host) -i example.com
acl acl_is_param url_param(id) -m str server1 server2 server3 server4
use_backend worker_cluster if acl_is_host acl_is_param
backend worker_cluster
cookie APPID insert secure httponly
balance url_param id
hash-type consistent
server w1 localhost:8080 weight 40 maxconn 1000 check
server w2 localhost:8081 weight 40 maxconn 1000 check
server w3 localhost:8082 weight 10 maxconn 1000 check
server w4 localhost:8083 weight 10 maxconn 1000 check
Previously, when I had only 2 servers w1, w2 in the backend without any weights, it worked perfectly fine. But after I added 2 more servers w3,w4 with weights (All weights on servers adding to 100), I see issues like, requests with param id=server1 reaching to server w2.
Is there any mistake in the config file?
Are the weights always should add up to 100?
Haproxy version used: 1.5.18

haproxy Infinite page refresh loop

On different hosts, there are two identical sites on IIS web servers, access to them is open on two ports 443 and 9000, if I turn on both hosts in haproxy, then when the site page is opened, an endless page refresh cycle occurs. It works if you disable one of the catches or specify the weight as srv1 weight 100 srv2 weight 0. How can I fix this?
My haproxy config:
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
# log /dev/log local0
# log /dev/log local1 notice
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 10000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats mode 666 level user
ssl-default-bind-options no-sslv3
ssl-default-bind-ciphers EECDH:+AES256:-3DES:RSA+AES:RSA+3DES:!NULL:!RC4
# ssl-server-verify none
defaults
mode http
log global
option httplog
option dontlognull
#option http-server-close
#option forwardfor except 127.0.0.0/8
#option redispatch
retries 10
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 150s
timeout http-keep-alive 65s
timeout check 10s
maxconn 10000
log-format "%{+Q}o\ client = %ci:%cp, server = %si:%sp path = %HU, status = %ST, %b, t_простоя = %Ti, t_отклика = %Tr, t_сеанса = %Tt, request = %r, byte = %B"
frontend stats
bind *:8404
http-request use-service prometheus-exporter if { path /metrics }
no log
stats enable
stats uri /stats
stats refresh 10s
stats auth adm:123
frontend http
bind *:80
mode http
redirect scheme https if !{ ssl_fc }
frontend https
bind *:443 ssl crt /etc/haproxy/tls/haproxy.pem alpn h2,http/1.1
bind *:9000 ssl crt /etc/haproxy/tls/haproxy.pem alpn h2,http/1.1
option forwardfor
option http-keep-alive
http-request add-header X-Forwarded-Proto https
http-request set-header X-Client-IP %[src]
errorloc 404 https://xxxx.com/500
errorloc 500 https://xxxx.com/500
errorloc 503 https://xxxx.com/500
errorloc 504 https://xxxx.com/500
use_backend https if { hdr(host) -i xxxx.com }
use_backend 9000 if { hdr(host) -i xxxx.com:9000 }
backend https
balance roundrobin
server srv1 192.168.1.11:443 check cookie srv1 weight 80 ssl verify none
server srv2 192.168.1.111:443 check cookie srv2 weight 20 ssl verify none
backend 9000
balance roundrobin
server srv1 192.168.1.11:9000 check cookie srv1 weight 80 ssl verify none
server srv2 192.168.1.111:9000 check cookie srv2 weight 20 ssl verify none
You are using the "cookie" strategy for loadbalancing, but no way to set this cookie :
balance roundrobin
server srv1 192.168.1.11:443 check cookie srv1 weight 80 ssl verify none
server srv2 192.168.1.111:443 check cookie srv2 weight 20 ssl verify none
As a result, the client communicates with both server alternatively. This does not suit well with IIS (and/or underlying technos).
Simply tell HAProxy which cookie to use/set. For example, a cookie named SERVERID :
balance roundrobin
cookie SERVERID insert indirect nocache
server srv1 192.168.1.11:443 check cookie srv1 weight 80 ssl verify none
server srv2 192.168.1.111:443 check cookie srv2 weight 20 ssl verify none
If the client already has a SERVERID cookie, then HAProxy sends the traffic to the corresponding server.
If the client does not have a SERVERID cookie, then HAProxy chooses and instructs the client to Set-Cookie: SERVERID=s1 for example.
Source : https://www.haproxy.com/blog/load-balancing-affinity-persistence-sticky-sessions-what-you-need-to-know/

Internet explorer connection is lost after 1 minute when using haproxy in between

I have an angular client that calls a rest service deployed on an application server. Between the two stands a haproxy that forwards the requests coming from the client to the REST service. When using Internet explorer and the response time is greater than 1 minute, when the REST service returns, the response is not sent to the client. The client still waits for the response.
This seems to be a haproxy issue since when bypassing haproxy, the request returns as expected after ~3-4 minutes.
I have tried all the different timeouts (client, server, http-request) but nothing seems to solve this.
My haproxy configuration can be found below:
global
log /dev/log local0
#log /dev/log local1 notice
#chroot /var/lib/haproxy
#stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
maxconn 2000
user haproxy
group haproxy
daemon
# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
tune.maxrewrite 1024
tune.bufsize 32768
# 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/
# An alternative list with additional directives can be obtained from
# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=haproxy
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
defaults
log global
mode http
option httplog
option dontlognull
option log-separate-errors
option redispatch
retries 3
timeout connect 5000
timeout client 1200s
timeout server 1200s
errorfile 400 /var/log/haproxy/errors/400.http
errorfile 403 /var/log/haproxy/errors/403.http
errorfile 408 /var/log/haproxy/errors/408.http
errorfile 500 /var/log/haproxy/errors/500.http
errorfile 502 /var/log/haproxy/errors/502.http
errorfile 503 /var/log/haproxy/errors/503.http
errorfile 504 /var/log/haproxy/errors/504.http
listen haproxy-monitoring
bind *:1900
mode http
stats enable # Enable satistics
stats uri /haproxy?stats # Dashboard URL
stats realm Strictly\ Private
stats auth haproxyanalytics:haproxyanalytics # Username / Password
stats hide-version # Hide the version of HAProxy used
# APACHE web servers
#frontend haproxy-apache
# bind *:8001 transparent
# mode http
# default_backend apache-nodes
frontend http-in
bind *:80 transparent
acl has_special_uri path_beg /cxf
use_backend rest-service if has_special_uri
default_backend apache-web
backend apache-web
mode http
balance roundrobin
option forwardfor # ensures the forwarded request includes the actual client IP address
option httpclose
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 # defines the check HAProxy uses to test if a web server is still valid for forwarding requests
server "apache-1" ${CURRENT_NODE_IP}:${APACHE_PORT} check
backend rest-service
mode http
balance roundrobin
option forwardfor # ensures the forwarded request includes the actual client IP address
option httpclose
option accept-invalid-http-request
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 # defines the check HAProxy uses to test if a web server is still valid for forwarding requests
server "karaf-1" ${CURRENT_NODE_IP}:${KARAF_REST_PORT} check

haproxy configuration for rewriting to /myapp

Here is my haproxy configuration
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 16384
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/run/haproxy.cmd
defaults
mode http
log global
option httplog
option dontlognull
option httpclose
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 20s
timeout client 45s
timeout server 45s
timeout check 20s
maxconn 16384
listen stats :9000
mode http
stats enable
stats uri /haproxy
stats realm HAProxy\ Statistics
stats auth haproxy:password
stats admin if TRUE
listen http :80
#balance leastconn
#balance roundrobin
balance source
option http-server-close
option forwardfor
server web1 10.0.2.10:8080 check inter 3000 rise 2 fall 3
server web2 10.0.2.11:8080 check inter 3000 rise 2 fall 3
# acl has_www hdr_beg(host) -i www
# http-request redirect code 301 location myapp
It is working like this:
I type http://www.example.com:8000 or http://www.example.com so it goes to jboss's 8080 port.
My application is actually accessible through example.com/suite but because the port 80 is blocked by ISP, that's why I am using the port 8000 and because of this; my application is accessible through example.com:8000/mypp
I want to use haproxy config to forward whoever types example.com:8000 to example.com:8000/myapp
How to achieve it?
I am missing something right?
When you define "Server" in your backend nodes section, you can have URI attached to the IP and port like below to achieve what you are looking for,
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend localnodes
bind 0.0.0.0:9876
mode http
default_backend nodes
backend nodes
mode http
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 web01 127.0.0.1:8443/**myApp** check

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.