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.

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
Check the HAProxy configuration for correctness

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
Restart the HAProxy service and check its status

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/

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

Page Contents