HAProxy health check in tcp mode on https 404 status code - ssl

I have two servers each running one Wildfly application server with one service available via https. The service is taking care of the https encryption. In front of the two servers I have an HAProxy as a load balancer in tcp mode to pass the ssl traffic through to the two services.
The HAProxy health check only checks if the server is online, not the service. If the service is not running Wildfly returns:
<html><head><title>Error</title></head><body>404 - Not Found</body></html>
which HAProxy interprets as healthy.
HAProxy config:
global
maxconn 2000
defaults
log global
mode http
option dontlognull
retries 3
option redispatch
timeout connect 5000
timeout client 10000
timeout server 10000
listen backend
bind *:8443
mode tcp
balance roundrobin
option httpclose
server backend1 wildfly:8443 check
server backend2 xxx.xxx.xxx.xxx:8443 check
How can I make HAProxy understand that 404 - Not Found is not healthy.

Two lines did the trick:
option httpchk /server
httpchk tells HAProxy to send an http request and check the response status
/server specifies the URI / Subdomain of my service
server backend1 wildfly:8443 check check-ssl verify none
check-ssl tells HAProxy to check via https instead of http
verify none tells HAProxy to trust the ssl certificate of the service (alternativly you can specify a .pem file)
Full HAProxy config:
global
maxconn 2000
defaults
log global
mode http
option dontlognull
retries 3
option redispatch
timeout connect 5000
timeout client 10000
timeout server 10000
listen backend
bind *:8443
mode tcp
balance roundrobin
option httpchk /server
server backend1 xxx.xxx.xxx.xxx:8443 check check-ssl verify none
server backend2 xxx.xxx.xxx.xxx:8443 check check-ssl verify none

Related

HAProxy: forward client ip (ssl traffic) to the backend

If I send SSL traffic to the backend server, I can see the client/source IP in the application logs.
ssl://host_name:8883
Problem: If I place haproxy before the backend server, I get haproxy IP as the source IP. SSL termination happens at the backend server.
haproxy.cfg:
defaults
maxconn 64000
option http-server-close
option httplog
option forwardfor
option contstats
timeout connect 5000ms
timeout client 30000ms
timeout server 30000ms
timeout tunnel 3600000ms
timeout http-keep-alive 1000ms
timeout http-request 30000ms
timeout queue 30000ms
errorfile 504 /var/504.http
frontend tcp-frontend-mqtt-tls
mode tcp
bind :8883 accept-proxy
log global
log-format %ci\ %fi:%fp\ [%t]\ %ft\ %b/%s\ %Tw/%Tc/%Tt\ %B\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq
tcp-request connection reject if { src -f /var/ip_blist.lst }
default_backend tcp-backend-mqtt-tls
backend tcp-backend-mqtt-tls
mode tcp
log global
balance leastconn
source 0.0.0.0 usesrc clientip
server mqtt-node-0 hostname:61008 resolvers my-dns check inter 1000
I've tried adding send-proxyv-v2 and send-proxy
server mqtt-node-0 hostname:61008 resolvers my-dns check inter 1000 send-proxy-v2
server mqtt-node-0 hostname:61008 resolvers my-dns check inter 1000 send-proxy
but that doesn't help as the SSL termination happens on the backend. am I missing something?
send-proxy is a good way to do it but your backend server/application needs to be able to parse the PROXY protocol to receive the IP information.

curl: (7) Failed connect to 35.229.60.183:80; (vm on google clould) Connection refused

new to linux world.
I have setup two apache webserver , one haproxy and one testpc.
I am able to curl web server with index.html contents on port 80.
but when i try to curl haproxy on any port or port 80 i am getting curl:
(7) Failed connect to 35.229.60.183:80; Connection refused
firewall is turned off on all the servers, restarted the haproxy.
haproxy config file :
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 100s
maxconn 3000
frontend myserver
bind *:80
default_backend mybackendserver
mybackendserver
balance roundrobin
mode http
server webserver 35.185.18.206:80 check
server webserver1 35.231.241.247:80 check
when I try to curl them in my test machine i am getting curl:
(7) Failed connect to 35.229.60.183:80; Connection refused
35.229.60.183 is the ip of my haproxy server.
If I recall correctly, you should enable the port :80 or whatever you use, directly from the Google Cloud dashboard.
Check this out.

HAProxy http check on for ssl?

I have some web servers which are MySQL backend. An HAProxy is in front of those web servers. All the web servers are using https.
I tried to use the http check option on both http and https to make sure if the database connection was lost, the HAProxy will failover to another node. My haproxy configuration file:
global
log /dev/log local0
maxconn 4096
#debug
#quiet
user haproxy
group haproxy
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
listen http
bind *:80
mode http
balance roundrobin
stats enable
stats auth haproxy:haproxy
cookie JSESSIONID prefix
stick on src table https
option http-server-close
option forwardfor
default-server inter 5s fall 2
option httpchk
http-check expect ! string Database\ error
server sitea 192.168.0.20 cookie sitea check port 80
server siteb 192.168.0.21 cookie siteb check port 80
listen https
bind *:443
mode tcp
balance roundrobin
stick-table type ip size 5000k expire 2h store conn_cur
stick on src
option tcplog
option ssl-hello-chk
default-server inter 5s fall 2
option httpchk
http-check expect ! string Database\ error
server sitea 192.168.0.20:443 check ssl verify none
server siteb 192.168.0.21:443 check ssl verify none
Look at the last two lines. If I specified "ssl verify none", my HAProxy can successfully check both Apache and MySQL status. However, I can't open the webpage via https(it prompts me This site can’t provide a secure connection. ERR_SSL_PROTOCOL_ERROR).
If I remove that parameter, the webpage can be opened again, but all the https servers status become DOWN in the HAProxy.
P.S. I'm using self-signed certificate currently, because I'm still on testing.
I have found the solution: since I am using https on apache nodes, I have to copy ssl certificates content to haproxy. To do that, copy and merge both private key and the certificate content issued by the CA into one single file(In my case, I put it into /etc/haproxy/haproxy.pem).
Modify the haproxy configuration, change
bind *:443
To
bind *:443 ssl crt /etc/haproxy/haproxy.pem

HAproxy times out(504 error) with large POST bodies

I have 3 nodejs web-servers spun on an ubuntu box and HAproxy to load-balance those servers on the same box. HAproxy listens at port 80(http) and 443(https, with SSL termination). There's no SSL between the HAproxy server and the web-servers.
The POST call to one of the api without SSL, passes through with any value of content-length, but when I try to do the POST call with a content-length greater than 8055 on the HAproxy with SSL connection(port443), HAproxy times out giving a 504 Gateway Timeout error.
Also, if I give an "Expect:100 continue" header to the curl command, the server responds with some delay, which I don't want to exist. Below is how the HAproxy config file looks like:
global
stats socket /var/run/haproxy.sock mode 0777
log 127.0.0.1 local0 info
log 127.0.0.1 local1 info
chroot /usr/share/haproxy
uid nobody
gid nobody
nbproc 1
daemon
maxconn 50000
frontend localnodes:https
bind *:443 ssl crt /etc/ssl/private/443_private_ssl_in.pem no-sslv3
mode http
reqadd X-Forwarded-Proto:\ https
default_backend nodes
timeout client 30000
frontend localnodes-http
bind *:80
mode http
reqadd X-Forwarded-Proto:\ http
default_backend nodes
timeout client 30000
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
log global
timeout connect 3000
timeout server 30000
option httplog
option ssl-hello-chk
option httpchk GET /
http-check expect status 404
server nodejsweb01 127.0.0.1:8000 check
server nodejsweb02 127.0.0.1:8001 check
server nodejsweb03 127.0.0.1:8002 check
I have ensured that the nodejs web-servers behind have no problem, they work fine. I have tried increasing the 'timeout server' period, no effect.
Also tried a solution on this link that tells to give an option ssl ca-file to the backend nodes, as follows:
server nodejsweb01 127.0.0.1:8000 ssl ca-file /etc/ssl/certs/ca.pem check
server nodejsweb02 127.0.0.1:8001 ssl ca-file /etc/ssl/certs/ca.pem check
server nodejsweb03 127.0.0.1:8002 ssl ca-file /etc/ssl/certs/ca.pem check
but after this option HAproxy throws an error saying no servers available at the backend.
Please tell me what am I doing wrong in HAproxy conf file, so that I make the webservers respond successfully with the SSL connection
Try this minimum config:
frontend localnodes
bind *:80
bind *:443 ssl crt /etc/ssl/private/443_private_ssl_in.pem
mode http
default_backend nodes
backend nodes
mode http
option forwardfor
option httplog
server nodejsweb01 127.0.0.1:8000 check
server nodejsweb02 127.0.0.1:8001 check
server nodejsweb03 127.0.0.1:8002 check
I suspect it's those additional options.
It could also be the SSL cert file. Is your PEM file created from a self-signed cert? How is it structured?

Haproxy backend server down due to layer 6 invalid response failed ssl handashake?

The scenario is we have two servers which are in different network . We want to have ssl communication from client to front-end and from front-end to back-end !
the front-end able to get ssl traffic and terminate the ssl, after that in back-end ssl communication is not happening the error follows as
"Server nodes/web02 is DOWN, reason: Layer6 invalid response, info: "SSL handshake failure", check duration:546ms "
This is my hapoxy config file
global
log 127.0.0.1 local1 debug
maxconn 4000
daemon
uid 99
gid 99
stats socket /tmp/haproxy.stats level admin
defaults
mode http
log global
option forwardfor
option http-server-close
timeout server 5s
timeout connect 5s
timeout client 5s
frontend www-https
bind <Ip-address>:443 ssl crt /home/user/SSL/domain-name.in.pem
reqadd X-Forwarded-Proto:\ https
default_backend nodes
backend nodes
balance roundrobin
cookie JSESSIONID prefix indirect nocache
server web01 <IP-address>:8443 ssl verify none check cookie web01
server web02 <IP-address>:8443 ssl crt /home/SSL/domain-name.in.pem ca-file /home/SSL/gdig2.crt verify required check cookie web02
any help in this greatly appreciated