Adaptable HAProxy URL Based Routing. HAProxy Path Based Routing
HAProxy can direct traffic to various destinations using different methods. This guide will specifically cover path-based routing in HAProxy. HAProxy Path-based routing is handy when you need to send different paths to different servers. For instance, with HAProxy URL based routing, a user going to https://f2hlabs.com/api could be sent to an API server, while a user going to https://f2hlabs.com/members could be directed to a different server.

If you’re using HAProxy in SSL passthrough mode, you’ll need to switch to SSL Termination. This is necessary when you want to route traffic based on a specific path or URL. HAProxy needs to check the packets to determine where the user is trying to go. With SSL passthrough, HAProxy can’t see the contents of the packets since it’s simply passing the connection to your backend servers. To make this work, your SSL certificate must cover both the balancer and all backend servers. There are several options to achieve this, like;
- Wildcard SSL (Paid Option)
- Cloudflare Origin Certificate (Free)
For this guide, we have used a Cloudflare Origin Certificate and copied the certificate, private key and origin certificate to a file located at /etc/ssl/f2hlabs.com/offload-ssl.pem. The same certificate also resides on our backend servers in LiteSpeed.
Table of Contents
If using cPanel, you can install your Cloudflare Origin Certificate using the “Install a certificate on a domain” option in WHM.
Create HAProxy Configuration
If you already have a HAProxy configuration file, move it aside using the command below. We will create a new file with a few lines of code.
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy-original.cfg && rm /etc/haproxy/haproxy.cfg
Now let’s create a new HAProxy configuration file.
nano /etc/haproxy/haproxy.cfg
HAProxy Frontend
Now let’s get writing code. In the file, create a frontend. In HAProxy, stipulating ssl crt and a path to the certificate will allow HAproxy to decrypt incoming connections.
frontend https_frontend
bind *:80
bind :443 ssl crt /etc/ssl/offload-cert.pem
HAProxy Path/URL-Based Routing
We have two WordPress installations on our domain: https://f2hlabs.com/wordpress1 and https://f2hlabs.com/wordpress2. We need to set up HAProxy to direct traffic for /wordpress2 to a separate server. Below the lines in the configuration file, follow the rules provided as a starting point.
With the use_backend cluster if { path_beg /wordpress2/ } rule. We are telling our HAProxy Server to route all traffic for /wordpress2/ to the backend called “cluster”.
And with the use_backend cluster if { path_beg /wordpress2 } rule, we are doing the same, but for traffic without a trailing /
use_backend cluster if { path_beg /wordpress2/ }
use_backend cluster if { path_beg /wordpress2 }
Configure Default Backend
For any traffic that doesn’t match the /wordpress2 or /wordpress2 rules, you will want to send that to a default server. To achieve this, we can use the default_backend option. We’re calling our default backend “cpanel”
default_backend cpanel
Full HAProxy Frontend Configuration – Path/URL-Based Routing
So your haproxy.cfg file should now look similar to this.
frontend https_443_frontend
bind *:80
bind :443 ssl crt /etc/ssl/offload-cert.pem
use_backend cluster if { path_beg /wordpress2/ }
use_backend cluster if { path_beg /wordpress2 }
# fallback for non-matching requests
default_backend cpanel
HAProxy Path Based Routing / HAProxy URL Based Routing
Now we need to configure our backend servers. According to this configuration, we should have one backend called “cluster” and one backend called “cpanel”. In the file, now define the backends.
backend cluster
mode http
server CAPP1 10.20.10.1:443 check ssl verify none
server CAPP2 10.20.10.2:443 check ssl verify none
server CAPP3 10.20.10.3:443 check ssl verify none
server CAPP4 10.20.10.4:443 check ssl verify none
server CAPP5 10.20.10.5:443 check ssl verify none
Here we are creating a backend called cluster and defending our cluster hosts. We are sending traffic to :443 (https) on each server, and before HAProxy sends the traffic to the backend, we are telling it to encrypt the traffic again with the ssl directive. It’s important that the SSL certificate referenced in the frontend configuration also resides and is in use on the cluster hosts, or you will receive an SSL Handshake Error.
HaProxy Default Backend Server
We now need to create a new backend for the default traffic to hit. Ours will be called cPanel. Append another backend section to the haproxy.cfg file.
backend cpanel
mode http
server ha 158.69.1.234:443 check ssl verify none
And this will now send any traffic that doesn’t match the rules in the frontend configuration to our cPanel server. So now the full configuration will look similar to this.
frontend https_443_frontend
bind *:80
bind :443 ssl crt /etc/ssl/offload-cert.pem
use_backend cluster if { path_beg /wordpress2/ }
use_backend cluster if { path_beg /wordpress2 }
# fallback for non-matching requests
default_backend cpanel
backend cluster
mode http
server CAPP1 10.20.10.1:443 check ssl verify none
server CAPP2 10.20.10.2:443 check ssl verify none
server CAPP3 10.20.10.3:443 check ssl verify none
server CAPP4 10.20.10.4:443 check ssl verify none
server CAPP5 10.20.10.5:443 check ssl verify none
backend cpanel
mode http
server ha 158.69.1.234:443 check ssl verify none
Configure Defaults
We’re not done yet. At the very end of the file, add the defaults and optionally, configure a listener. Remember to switch out SERVER-IP for your HAProxy server’s IP.
global
log /dev/log local0
log /dev/log local1 notice
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
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
listen stats
bind SERVER-IP:1936 ssl crt /etc/ssl/cert-a.pem
mode http
stats enable
stats hide-version
stats show-node
stats realm Haproxy\ Statistics
stats uri /haproxy?stats
stats admin if TRUE
stats auth User:Pass
You can now restart HAProxy, and this configuration should allow you to route traffic based on URL or Path using HAProxy.
systemctl restart haproxy
HAProxy Resources