How To Deploy HAProxy as a Load Balancer for NGINX on Linux Servers
Configure HAProxy as a Load Balancer for NGINX
By default, HAProxy’s configuration files are stored under the /etc/haproxy directory and its main configuration file is /etc/haproxy/haproxy.cfg. Below is a sample HAProxy configuration for load-balancing requests to NGINX servers.
Page Contents
This example configuration shows some key aspects of HAProxy including SSL termination, redirecting HTTP to HTTPS, redirecting prefix(www to non-www), deleting HTTP headers, adding HTTP security headers, using different backends depending on the domain, setting the load balancing algorithm, and backend health checks.
Here, HAProxy is running in HTTP mode(mode http set in the default section to apply to all other sections). The frontend section is used to receive requests from clients and it listens on the HTTP port 80 and HTTPS port 433. The ssl and crt directives defined with the bind directive are used to enable SSL termination. All HTTP requests are redirected to HTTPS (using redirect scheme https code 301 if !{ ssl_fc } directive).
Requests to the tickets.fg.app domain are redirected to a specific backend (using use_backend nginx_gp2 if { hdr(host) -m dom tickets.fg.app } ), the same applies to mywpsite.com ( use_backend nginx_gp3 if { hdr(host) -m dom mywpsite.com }). Requests to all other applications are sent to the default backend that is specified using the default_backend directive ( default_backend nginx_gp1). To redirect the www prefix to non-www, the redirect prefix directive is used.
Additionally, the backend nginx_gp1 uses the least_conn load balancing algorithm because it has many servers it is passing requests to. It also has several http-response set-header directives for setting security HTTP headers.
The server directive is used to define the backend NGINX servers that HAProxy is forwarding requests to. Ensure that you specify the correct server IP addresses, otherwise, your web application or sites may not load as expected.
#cat /etc/haproxy/haproxy.conf
global maxconn 50000 log 127.0.0.1 local2 chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock user haproxy group haproxy mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 ssl-default-bind-options ssl-min-ver TLSv1.2 #ssl-dh-param-file /etc/ssl/kyu/dhparam defaults log global mode http option httplog option dontlognull option forwardfor timeout connect 30s timeout check 30s timeout client 20m timeout server 30m 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 bind *:8500 stats enable stats hide-version stats uri /monitor stats realm Haproxy\ Statistics stats refresh 5s stats admin if TRUE stats auth terpadmin:Lostp@1ss frontend http_in bind *:80 bind *:443 ssl crt /etc/ssl/certs/clientwebapp1.com.pem crt /etc/ssl/certs/clientwebapp2.com.pem crt /etc/ssl/certs/fg.app_cert.pem crt /etc/ssl/certs/clientwebapp3.com.pem crt /etc/ssl/certs/mywpsite.com.pem alpn h2,http/1.1 redirect scheme https code 301 if !{ ssl_fc } redirect prefix https://mywpsite.com code 301 if { hdr(host) -i www.mywpsite.com } use_backend nginx_gp2 if { hdr(host) -m dom tickets.fg.app } use_backend nginx_gp3 if { hdr(host) -m dom mywpsite.com } http-response set-header Strict-Transport-Security max-age=63072000 default_backend nginx_gp1 #backend for passing requests to same client web apps deployed on several servers for HA backend nginx_gp1 balance least_conn option httpchk GET / http-check expect status 200 #add security HTTP headers http-response set-header X-Frame-Options DENY http-response set-header X-XSS-Protection 1;mode=block http-response set-header X-Content-Type-Options nosniff http-response set-header Strict-Transport-Security max-age=31536000;includeSubDomains;preload http-response set-header Referrer-Policy no-referrer-when-downgrade #http-response set-header Content-Security-Policy "default-src self *.kyu.ac.ug *.mubs.ac.ug cdn.jsdelivr.net fonts.googleapis.com fonts.gstatic.com" http-response set-header Expect-CT enforce,\ max-age=86400 http-response set-header Referrer-Policy strict-origin-when-cross-origin http-response add-header X-Permitted-Cross-Domain-Policies none http-response set-header Permissions-Policy "accelerometer=(), autoplay=(), camera=(), cross-origin-isolated=(), display-capture=(), encrypted-media=(), fullscreen=(self), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), xr-spatial-tracking=(), clipboard-read=(self), clipboard-write=(self), gamepad=()" #set server cookie cookie SVR_ID insert indirect nocache dynamic secure httponly dynamic-cookie-key 934ndsdjefefwe default-server maxconn 100000 server nginx_gp1_svr1 10.10.1.4:80 check server nginx_gp1_svr2 10.10.1.4:80 check server nginx_gp1_svr3 10.20.1.4:80 check server nginx_gp1_svr3 10.20.1.5:80 check server nginx_gp1_svr3 10.20.1.6:80 check #backend for passing requests to tickets.fg.app application backend nginx_gp2 option httpchk HEAD / cookie SVR_ID insert indirect nocache dynamic secure httponly dynamic-cookie-key n3400sddsdje0992 server nginx_gp2_svr1 10.10.1.4:80 check #backend for passing requests to mywpsite.com web site backend nginx_gp3 mode http option httpchk HEAD / cookie SVR_ID insert indirect nocache dynamic secure httponly dynamic-cookie-key nKLJLDF00sdd090911 server nginx_gp3_svr1 10.10.1.5:80 check
After making changes to your HAProxy configuration file and saving it, I recommend you check it for syntax correctness using this command:
$sudo haproxy -c -f /etc/haproxy/haproxy.cfg OR #haproxy -c -f /etc/haproxy/haproxy.cfg
To apply any changes in the HAProxy configuration, you need to restart the HAProxy service and check its status to ensure that it is up and running, like this:
#systemctl restart haproxy.service #systemctl status haproxy.service
Next, test if you can access your websites and web applications on your local network or the Internet (i.e. your HAProxy server has a publicly accessible IP address, and your DNS configurations are valid for your domains and pointed to that IP).
Conclusion
In upcoming guides, I will be expounding on many of the configuration directives in the NGINX and HAProxy configurations above. Until then, stay with FOSSGuides! Your questions or comments are welcome, via the feedback form below.
References:
1. https://nginx.org/en/docs/
2. https://docs.haproxy.org/