HAProxy not forwarding requests to backend server - haproxy

I have HAProxy (v1.5.8) as a load balancer with keepalived (v1.2.2) to maintain high availability. I also have several Jetty servers on a different machine on the local network as backend server with a webapp.
The problem I have is: I can access to the web app through it IP (z.z.z.z in the code below), but when I try to access by the VIP(y.y.y.y in the code below) I get a connection refused error. I dont have any iptables rule set (Debian 7).
My haproxy.cfg file is this one:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
chroot /var/lib/haproxy
#stats socket /run/haproxy/admin.sock mode 660 level admin
#stats timeout 30s
maxconn 4096
user haproxy
group haproxy
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
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
listen stats x.x.x.x:9000
mode http
balance
option httplog
timeout client 5000
timeout connect 4000
timeout server 30000
stats uri /haproxy_stats
stats realm HAProxy/Statistics
stats auth user:passwd
stats admin if TRUE
listen webfarm y.y.y.y:8080
mode http
stats enable
stats auth someuser:somepassword
balance roundrobin
cookie JSESSIONID prefix
option httpclose
option forwardfor
option httpchk HEAD /check.txt HTTP/1.0
server webA z.z.z.z:9400 check
In the keepalived conf file I have defined the VIP I will use (Is the same one defined in the haproxy.cfg :
virtual_ipaddress {
y.y.y.y
}
In the stats web I get the next results:
HAProxy Stats
After this, I believe that haproxy cannot get to the backends as they are displayed as frontend servers. I am missing something in the conf files?
Thank you

No, 'frontend' and 'backend' are summary lines not titles. It is normal for the servers to be between the two.
Your backend is down because it is returning a 404 to haproxy. You need to make /check.txt return a valid response.

I'd recommend simply disabling your checks until you get a bit more comfortable with HAProxy as a whole. Id also recommend you turn on the stats page, which will give you a better visualization of what HAProxy sees. See below:
###########################################
#
# HAProxy Stats page
#
###########################################
listen stats
bind *:9090
mode http
maxconn 10
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /
stats auth -----:-----

Related

How to install HAProxy and configure it in an ubuntu server?

I know I have asked this question before but i didn't get any answers for it.
How to install HAProxy and configure it in an Ubuntu server. I want to use it to map applications listening on various ports to specific URLs.
For example, if an app called page-designer is listening at http://IP:5000, then it should map it to http://IP/page-designer.
I have already installed the HAProxy package using sudo apt-get -y install haproxy. But what changes do I have to do in HAProxy main configuration file located at /etc/haproxy/haproxy.cfg before restarting the HAProxy service for the changes to take effect. And mainly after this how can I map my apps running on various ports to specific URLs like mentioned above?
haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
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/
# 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
timeout connect 5000
timeout client 50000
timeout server 50000
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 http-in
mode http
bind *:80
acl path-page-designer path_beg -i /employeeList
use_backend page-designer-backend if path-page-designer
redirect scheme https code 301 if !{ ssl_fc }
backend page-designer-backend
mode http
option httplog
option forwardfor
http-request set-path /
server appserver1 206.189.22.155:5000
To understand how haproxy works, you can find the essential config in:
https://www.haproxy.com/blog/the-four-essential-sections-of-an-haproxy-configuration/
In your case, you can try something like this...
frontend http-in
mode http
bind *:80
bind *:443 ssl crt /etc/ssl/certs/your-cert.pem
http-request redirect scheme https code 301 if !{ ssl_fc }
acl path-page-designer path_beg -i /page-designer
use_backend page-designer-backend if path-page-designer
backend page-designer-backend
mode http
option httplog
option forwardfor
http-request set-path /
server appserver1 206.189.22.155:5000

Why does HAProxy show that a server's check URL is a 404 when running curl on this URL is successful?

I'm setting up HAProxy to load-balance a resource between 3 back-ends. Here is the HAProxy config : (In the following snippets I replaced the actual domain name by example.net)
global
log 127.0.0.1 local2
log-send-hostname
maxconn 2000
pidfile /var/run/haproxy.pid
stats socket /var/run/haproxy.sock mode 600 level admin
stats timeout 30s
daemon
# SSL ciphers
...
defaults
mode http
option forwardfor
option contstats
option http-server-close
option log-health-checks
option redispatch
timeout connect 5000
timeout client 10000
timeout server 10000
...
frontend front
bind *:443 ssl crt /usr/local/etc/haproxy/front.pem
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
stats uri /haproxy?stats
option httpclose
option forwardfor
default_backend back
balance source
backend back
balance roundrobin
option httpchk GET /healthcheck HTTP/1.0
server server1 xxx.xxx.xxx.xxx:80 check inter 5s fall 2 rise 1
server server2 yyy.yyy.yyy.yyy:8003 check backup
server mysite example.net:80 check backup
The issue is the following: even though the first 2 servers respond correctly, the domain-based one always shows as a 404:
What is counter-intuitive to me is that if I use curl to access this same healthcheck, I get an HTTP 200 (like I would expect to see in the HAProxy stats) :
curl -I http://example.net/healthcheck
HTTP/1.1 200 OK
When I ping my site, I get:
# ping example.net
PING example.net (217.160.0.195) 56(84) bytes of data.
64 bytes from 217-160-0-195.elastic-ssl.ui-r.com (217.160.0.195): icmp_seq=1 ttl=50 time=45.7 ms
Is it because the IP of my domain is shared with other domains (1&1 shared hosting) that HAProxy can't access it? Why is that and how to make HAProxy reach it correctly?

HAProxy Multiport backends

I may be using the wrong terms to search, but I'm having trouble finishing connections to my backend servers though HAProxy. I am able to initially login to the servers, but then the application communicates through two others ports as well. I can go directly to one of the servers and it logs in and lunches the application correctly. Through HAProxy however, I can authenticate, and then I get a communication error. I'm thinking that HAProxy is not passing through data on the other ports. How can this be achieved?
My setup:
2 HAProxy server connected to 2 identical VM servers. HAProxy seems to be working correctly as far as telling when the service on the mcahines are running. It is passing through authentication on port 8443. But that's as far as it will go. It will not launch the VM which uses ports 3000 and 5432. Any ideas on the HAProxy setup?
Here is my configuration file:
global
ssl-server-verify none
tune.ssl.default-dh-param 2048
maxconn 256
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
timeout connect 5000
timeout client 10000
timeout server 10000
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
listen vm-port-3000
bind *:5432
server qvd4 10.0.0.1:3000
server qvdnode02 10.0.0.2:3000
listen vm-port-5432
bind *:5432
server qvd4 10.0.0.1:5432
server qvdnode02 10.0.0.2:5432
listen stats
bind :1936
stats enable
stats hide-version
stats realm Loadbalanced\ Servers
stats uri /haproxy?stats
stats auth haproxy:haproxy
frontend vm-initial-conn
bind *:8443 ssl crt /etc/ssl/certs/qvd/haproxy.pem
default_backend vmConn
backend vmConn
option forwardfor
option httpchk GET /qvd/ping HTTP/1.1
http-check expect status 200
balance roundrobin
http-request add-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Port %[dst_port]
server qvd4 10.0.0.1:8443 ssl verify none check
server qvdnode02 10.0.0.2:8443 ssl verify none check
In your vm-port-3000 you are actually binding to port 5432 instead of how it appears you intended to port 3000.
Thus, requests to port 5432 are randomly handled by either your vm-port-3000 or your vm-port-5432 listener while connections to port 3000 are not handled by HAProxy at all.

HAProxy: multiple websites, but only one of them needs to use ALL backends

I currently have a HAproxy loadbalancer setup with 2 backends for a total of 3 websites. One of the websites needs an extra server (a new backend, backend #3), but the others don't have to use this backend. Is there any way to do this? Sadly, I was not able to figure this out using the documentation. Config added. New backend is going to be .77. Thanks!
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
user haproxy
group haproxy
maxconn 2000
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
# use 7 of 8 cores, bind stats to the 7th. We want one core for OS and stuff :)
nbproc 7
cpu-map 1 1
cpu-map 2 2
cpu-map 3 3
cpu-map 4 4
cpu-map 5 5
cpu-map 6 6
cpu-map 7 7
stats bind-process 7
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
timeout connect 5000
timeout client 50000
timeout server 50000
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
listen stats 192.168.3.78:1936
stats enable
stats uri /
frontend www-http
bind 1.2.3.4:80
bind 192.168.3.78:80
reqadd X-Forwarded-Proto:\ http
bind-process 1
default_backend www-backend
frontend www-https
bind 1.2.3.4:443 ssl crt /etc/ssl/private/1.full-pem crt /etc/ssl/private/2.full-pem crt /etc/ssl/private/3.full-pem
reqadd X-Forwarded-Proto:\ https
option forwardfor
bind-process 2 3 4 5 6
default_backend www-backend
backend www-backend
redirect scheme https if !{ ssl_fc }
cookie SERVERID insert indirect nocache
server www-1 192.168.3.75:80 check cookie www-1
server www-2 192.168.3.74:80 check cookie www-2
A note about the word "backend": you used it in your question to describe the service that will get forwarded requests. To avoid confusion, I'll use here server for that, backend will be a group of server (to match the HAProxy terms).
You need two backend blocks, one with two server the other with three. In your frontend, use the hostname to choose the correct one:
frontend www-http
[...]
acl host_website3 hdr(host) -i website3.com # match the new website
use_backend www-backend-with3 if host_website3 # send it to the correct backend
default_backend www-backend
backend www-backend
redirect scheme https if !{ ssl_fc }
cookie SERVERID insert indirect nocache
server www-1 192.168.3.75:80 check cookie www-1
server www-2 192.168.3.74:80 check cookie www-2
backend www-backend-with3 # new backend here
redirect scheme https if !{ ssl_fc }
cookie SERVERID insert indirect nocache
server www-1 192.168.3.75:80 check cookie www-1
server www-2 192.168.3.74:80 check cookie www-2
server www-3 192.168.3.77:80 check cookie www-3 # with a new server here

HAproxy redirect all root requests to www

I have just installed HAproxy on a server which should do nothing to serve as redirection endpoint of any incoming naked domain request (http and https), to the www.-version. Just like the service wwwizer.com. This is my cfg:
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
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
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
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 http
bind *:80
bind *:443
acl has_www hdr_beg(host) -i www
http-request redirect code 301 location www.%[hdr(host)]%[req.uri] unless has_www
I have the A record of my domain DNS pointing to the IP of the server. However if I goto http://exmaple_url.com I get forwarded to: http://exmaple_url.com/www.exmaple_url.com instead of just http://www.exmaple_url.com
What am I doing wrong?
I followed the instruction in the documentation: https://www.haproxy.com/doc/aloha/7.0/haproxy/http_redirection.html
I expect adding https:// to the redirect location is the fix you need:
http-request redirect code 301 location https://www.%[hdr(host)]%[req.uri] unless has_www
Update for anyone using this answer. The spec must have changed, and I needed to use this modified http-request to work:
http-request redirect code 301 location https://www.%[hdr(host)]%[capture.req.uri] unless has_www
Per section 7.3.6. of the docs regarding req.uri:
https://www.haproxy.org/download/2.4/doc/configuration.txt
This is my experience with HA-Proxy version 2.3.9-53945bf 2021/03/30