Example HAProxy Load-Balancer Configuration
You can use a HAProxy as a load balancer in PrivX-HA deployments. This article provides an example configuration for an HAProxy load balancer running on Rocky Linux.
In the following examples the IP addresses 192.0.2.100
and 192.0.2.101
need to be substituted with your PrivX-server addresses.
The sample configuration requires that the SELinux policy allows HAProxy process to listen at ports 1080, 2222 and 3389. Run the following commands to add these ports to the list of allowed listen ports for HAProxy:
semanage port -a -t http_port_t -p tcp 1080
semanage port -a -t http_port_t -p tcp 2222
semanage port -a -t http_port_t -p tcp 3389
HTTP, HTTPS ports, and port 8443 for client-certificate authentication should already be allowed by default.
You will also need to open firewall ports for incoming connections, for example:
firewall-cmd --zone=public --permanent --add-service=http
firewall-cmd --zone=public --permanent --add-service=https
firewall-cmd --zone=public --permanent --add-port=1080/tcp
firewall-cmd --zone=public --permanent --add-port=2222/tcp
firewall-cmd --zone=public --permanent --add-port=3389/tcp
firewall-cmd --zone=public --permanent --add-port=8443/tcp
firewall-cmd --reload
Additionally, the sample configuration requires you to install a TLS key and certificate to the following paths respectively:
/etc/ssl/certs/privx-lb.crt.key
/etc/ssl/certs/privx-lb.crt
After installing, you can set the following HAProxy configuration to /etc/haproxy/haproxy.cfg
to satisfy all the load-balancer requirements described in PrivX high availability deployment:
# HAProxy load-balancer example configuration.
# Requests are distributed between servers using sticky sessions.
# In this example two instances of PrivX are running
# with private IP addresses 192.0.2.100 and 192.0.2.101
# HTTP requests except for CRLs are redirected to HTTPS.
#
# See the full configuration options online.
#
# https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to add the following to /etc/rsyslog.d/99-haproxy.conf:
# $AddUnixListenSocket /var/lib/haproxy/dev/log
# # Send HAProxy messages to a dedicated logfile
# :programname, startswith, "haproxy" {
# /var/log/haproxy.log
# stop
# }
log /dev/log/ local0
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
log global
option dontlognull
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 8h
timeout server 8h
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
# Windows smartcard CRL and web traffic redirect port
frontend privx_lb_http
bind *:80
mode http
option httpchk GET /authorizer/api/v1/cas
option httplog
option http-server-close
option forwardfor except 127.0.0.0/8
default_backend privx_http
# PrivX https port
# Needs to be 'mode http' for PrivX components
frontend privx_lb_https
bind *:443 ssl crt /etc/ssl/certs/privx-lb.crt ssl-min-ver TLSv1.3
mode http
option httpchk GET /monitor-service/api/v1/instance/status
option httplog
option http-server-close
option forwardfor except 127.0.0.0/8
default_backend privx_https
# Native clients and certificate authentication
# 'mode tcp' required for native protocol traffic
frontend privx_lb_native_ssh
bind *:2222
mode tcp
option tcplog
default_backend privx_native_ssh
frontend privx_lb_native_rdp
bind *:3389
mode tcp
option tcplog
default_backend privx_native_rdp
frontend privx_lb_client_certificate_auth
bind *:8443
mode tcp
option tcplog
default_backend privx_client_certificate_auth
frontend privx_lb_native_ssh_proxy
bind *:1080
mode tcp
option tcplog
default_backend privx_native_ssh_proxy
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
# Windows smartcard CRL endpoint and url redirection http -> https
backend privx_http
mode http
balance roundrobin
server node1 192.0.2.100:80
server node2 192.0.2.101:80
backend privx_https
mode http
# Health check PrivX instance endpoint.
option httpchk GET /monitor-service/api/v1/instance/status
# 'balance roundrobin' is required by PrivX components
balance roundrobin
# Sticky sessions are required by PrivX components.
# Setting the affinity cookie name to 'route', so no additional cookie configuration needed for PrivX components config files.
cookie route insert indirect nocache
# Backend SSL cert not verified, you should consider using 'verify required' in production environments.
server node1 192.0.2.100:443 check inter 30s ssl verify none cookie node1
server node2 192.0.2.101:443 check inter 30s ssl verify none cookie node2
# Native client traffic can use whatever load balancing, using roundrobin in this example.
backend privx_native_ssh
mode tcp
stick-table type ip size 1m expire 8h
stick on src
balance roundrobin
server node1 192.0.2.100:2222 check inter 30s
server node2 192.0.2.101:2222 check inter 30s
backend privx_native_rdp
mode tcp
stick-table type ip size 1m expire 8h
stick on src
balance roundrobin
server node1 192.0.2.100:3389 check inter 30s
server node2 192.0.2.101:3389 check inter 30s
backend privx_client_certificate_auth
mode tcp
stick-table type ip size 1m expire 8h
stick on src
balance roundrobin
server node1 192.0.2.100:8443 check inter 30s
server node2 192.0.2.101:8443 check inter 30s
backend privx_native_ssh_proxy
mode tcp
stick-table type ip size 1m expire 8h
stick on src
balance roundrobin
server node1 192.0.2.100:1080 check inter 30s
server node2 192.0.2.101:1080 check inter 30s
Then reload the HAProxy configuration with:
# systemctl reload haproxy
Known issues
When connecting to a host using a native SSH or RDP client rather than the PrivX web UI, the load balancer's IP address is stored into audit logs instead of the client's IP address. There is currently no workaround for this.