HAProxy is an open-source software capable of processing Layer 4 and Layer 7 traffic. It supports high-availability, load-balancing, and proxying traffic to one or more backend servers.
Installation
Requirements
HAProxy can be installed and run on any platform that HAProxy supports. In this article we focus on the installation of HAProxy on centOS and RHEL.
If possible, install HAProxy on a dedicated server for security and performance reasons. However, you can also install it on the same server where a censhare Server is running. In this case, make sure that the following ports are not in use so that HAProxy can bind to them:
80 - Plain HTTP. It is redirects to port 443.
443 - Default HTTPs port.
30546 - By default, censhare RMI uses port 30546. Therefore, when running HAProxy on a dedicated server, we recommend to use port 30546 here as well. However, when running HAProxy on the same machine as a censhare Server, for example the Master server, use another port such as 30545. Also, ensure that your hosts.xml contains the correct port defined to use with HAProxy.
8080 - HAProxy statistics.
How to verify that the ports are available:
ss -tulnp | egrep '80|443|30546|8080'
Installation command
yum install haproxy
Configuration
Find an example of a configuration file for HAProxy that you can use for load-balancing and high-availability for censhare. The configuration file defines an environment with two censhare Servers, one of them as the Master server.
First, identify the appropriate custom values for your environment for the following items. Then adapt the example configuration file:
If the application has a custom context path that is different from the default /censhare5/client, check all entries of /censhare5/client in the configuration file. Replace the entries with the appropriate context path. For example, if the base URL is:
https://customer.example.com/censhareapp
http-request redirect code 301 location https://%[hdr(host)]/censhareapp
Upload a PEM-formatted SSL certificate file to the server. This file should contain both the private key and the certificate chain bundle. This means: When a certificate is signed by an intermediate certificate authority (CA), also include the certificate of the intermediate CA in addition to the actual certificate.
Example of a PEM-format certificate:
-----BEGIN ENCRYPTED PRIVATE KEY----- MBQGCCqGSIb3DQMHBAgD1kGN4ZslJgSCBMi1xk9jhlPxPc 9g73NQbtqZwI+9X5OhpSg/2ALxlCCjbqvzgSu8gfFZ4yo+ A .... MANY LINES LIKE THAT .... X0R+meOaudPTBxoSgCCM51poFgaqt4l6VlTN4FRpj+c/Wc blK948UAda/bWVmZjXfY4Tztah0CuqlAldOQBzu8TwE7WD H0ga/iLNvWYexG7FHLRiq5hTj0g9mUPEbeTXuPtOkTEb/0 GEs= -----END ENCRYPTED PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiIMA0GCSqGSIb3Df BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVx aWRnaXRzIFB0eSBMdGQwHhcNMTExMjMxMDg1OTQ0WhcNMT A .... MANY LINES LIKE THAT .... JjyzfN746vaInA1KxYEeI1Rx5KXY8zIdj6a7hhphpj2E04 C3Fayua4D RHyZOLmlvQ6tIChY0ClXXuefbmVSDeUHwc8Yu B7xxt8BVc69rLe HV15A0qyx77CLSj3tCx2IUXVqRs5mlSbvA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0 BAQsFADBhMQswCQYDVQQGEwJVUzEVMBMGA 1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 A .... MANY LINES LIKE THAT .... YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE-----
drwxrw----. 2 root root 26 Apr 23 15:38 /etc/haproxy/ssl -r-------- 1 root root 7086 Mar 6 12:08 /etc/haproxy/ssl/certificatefile.pem
censhare Server IP addresses or domain/host names and HTTPs ports: In the configuration example below, the servers are:
cust-prodns-css01 port 9443 cust-prodns-css02 port 9443
censhare Server IP addresses or domain/host names and RMI ports: In the configuration example below, the servers are
cust-prodns-css01 port 30546 cust-prodns-css02 port 30545
Here is the complete /etc/haproxy/haproxy.cfg example which includes the items discussed above:
global log 127.0.0.1:514 local0 info chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon tune.ssl.default-dh-param 2048 ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256: ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS defaults log global mode http balance leastconn #option tcplog log-format {"type":"haproxy","request_id":"%rt","timestamp":%Ts,"http_status":%ST, "http_request":"%r", "remote_addr":"%ci/%cp","bytes_read":%B,"upstream_addr":"%si","bytes_uploaded":%U, "upstream_response_time":"%Tr","session_duration":"%Tt"} option dontlognull option redispatch option log-health-checks retries 3 maxconn 2000 timeout connect 60000 timeout client 60000 timeout server 60000 default-server inter 10s ###################### RMI Protocol Start ###################### frontend rmi30545-in mode tcp bind *:30545 #option tcplog #option http-server-close default_backend rmi30546-out backend rmi30545-out mode tcp stick-table type ip size 1m expire 30m stick on src balance leastconn default-server inter 1s downinter 3s rise 15 fall 15 server cust-prodns-css01 cust-prodns-css01:30546 check server cust-prodns-css02 cust-prodns-css02:30546 check ###################### RMI Protocol Finish ###################### ###################### HTTP/S Protocol Start ###################### frontend web80-in *:80 http-request redirect code 301 location https://%[hdr(host)]/censhare5/client frontend web443-in mode http bind *:443 ssl crt /etc/haproxy/ssl/certificatefile.pem default_backend web443-out option forwardfor timeout client 60m timeout http-keep-alive 10s timeout http-request 5s timeout tarpit 60s acl is_websocket path_beg /censhare5/client/ acl is_websocket hdr(Upgrade) -i WebSocket acl is_websocket hdr_beg(Host) -i ws acl is_root path / capture request header Host len 64 http-request redirect scheme https code 301 if !{ ssl_fc } http-request redirect code 301 location https://%[hdr(host)]/censhare5/client if is_root backend web443-out cookie SRVID insert indirect nocache maxidle 30m maxlife 1h option forwardfor balance leastconn option ssl-hello-chk option httpchk GET /censhare5/client/img/favicon.ico http-check expect status 200 default-server inter 1s downinter 3s rise 15 fall 15 timeout check 1s timeout server 60m timeout tunnel 3600s timeout queue 30s timeout connect 5s #option http-server-close # KRED es muss disabled http-request add-header X-Forwarded-Proto https if { ssl_fc } redirect scheme https if !{ ssl_fc } http-response add-header Strict-Transport-Security max-age=31536000;\ includeSubdomains http-response add-header X-Content-Type-Options nosniff http-response add-header X-XSS-Protection 1;\ mode=block http-response add-header Referrer-Policy no-referrer http-response add-header Feature-Policy accelerometer\ 'none';\ ambient-light-sensor\ 'none';\ autoplay\ 'none';\ camera\ 'none';\ display-capture\ 'none';\ document-domain\ 'none';\ fullscreen\ 'none';\ execution-while-not-rendered\ 'none';\ execution-while-out-of-viewport\ 'none';\ gyroscope\ 'none';\ magnetometer\ 'none';\ microphone\ 'none';\ midi\ 'none';\ payment\'none';\ picture-in-picture\ 'none';\ publickey-credentials\ 'none';\ sync-xhr\ 'none';\ usb\'none';\ wake-lock\ 'none' server cust-prodns-css01 cust-prodns-css01:9443 weight 5 check ssl verify none cookie s1 server cust-prodns-css01 cust-prodns-css01:9443 weight 5 check ssl verify none cookie s2 ###################### HTTP/S Protocol Finish ###################### ###################### Statistics ###################### frontend statistics-8000 bind *:8000 mode http #option httplog # not needed !!! stats enable stats uri /haproxy stats auth admin:password stats admin if TRUE ###################### Statistics Finish ######################
Validate the configuration file:
haproxy -f /etc/haproxy/haproxy.cfg -c
Fix any issues, then start HAProxy and make sure that it starts on server reboot:
systemctl enable haproxy && systemctl start haproxy
Redirects for censhare WP
If you use censhare WP with a load balancer, such as NGINX or HAProxy, set the following redirects:
Path "/auth/" to Keycloak ( http://authentication.your-company.com:8080 )
Path "/login/" to Cloud Gateway ( http://cloud-gateway.your-company.com:8082 )
Path "/oauth2/" to Cloud Gateway ( http://cloud-gateway.your-company.com:8082 )
Path "/censhare5/client/" to Cloud Gateway ( http://cloud-gateway.your-company.com:8082 )
Path "/ws/" to censhare-Server REST ( http://censhare.your-company.com:9000 )
- Path "/tempDownload/" to censhare-Server REST ( http://censhare.your-company.com:9000 )
/tempDownload/ should be routed from the proxy directly to the censhare Server. As it does not have a separate mapping in the Cloud Gateway setup and does not use the usual login session.
Details and options
The following section contains details and explanations about the haproxy.cfg configuration file. Keep these configuration options, and customize them only if you are certain of the implications of the changes!
Load-balancing algorithms
HAProxy supports a number of load-balancing algorithms to determine how to distribute traffic to multiple backend servers.
The algorithm used above for HTTPs is leastconn: The backend server with the least number of connections is used, and then for all servers with the same amount of connections, round-robin is performed. The configuration entry:
balance leastconn
stick-table type ip size 1m expire 30m stick on src
Sticky sessions
For the leastconn load-balancing algorithm, cookies are used to ensure that clients are always sent to the same backend server. The following lines in the backend section of the configuration file define this:
cookie SRVID insert indirect nocache maxidle 30m maxlife 1h ... server cust-prodns-css01 cust-prodns-css01:9443 weight 5 check ssl verify none cookie s1 server cust-prodns-css01 cust-prodns-css01:9443 weight 5 check ssl verify none cookie s2
timeout client 60m ... timeout server 60m
WebSocket
WebSocket support is required. The following configuration entries define this:
acl is_websocket path_beg /censhare5/client/ acl is_websocket hdr(Upgrade) -i WebSocket acl is_websocket hdr_beg(Host) -i ws
HAProxy statistics
The use of HAProxy statistics is optional but recommended. This is helpful for troubleshooting web traffic issues and for capacity planning.
To encrypt traffic for the statistics URL, use the following lines instead:
###################### Statistics ###################### fontend statistics-8443 bind *:8443 ssl crt /etc/haproxy/ssl/certificatefile.pem mode http #option httplog stats enable stats uri /haproxy stats auth admin:password stats admin if TRUE ###################### Statistics Finish ######################
This uses the same PEM-encoded SSL certificate and the port 8443 that must be available.
CSP Headers
For security, you can also add Content-Security-Policy HTTP headers. For example:
http-response add-header Content-Security-Policy default-src\ 'none';\ http-response add-header Content-Security-Policy connect-src\ 'self'\ wss://%[capture.req.hdr(0)]\ https://nominatim.openstreetmap.org;\ http-response add-header Content-Security-Policy script-src\ 'self'\ 'unsafe-eval'\ https://connect.facebook.net\ https://platform.twitter.com\ 'sha256-mutaUHp7a6TAHBx7UkKbOet7lfkvyPk131k92oPYqEQ=';\ http-response add-header Content-Security-Policy img-src\ 'self'\ data:\ https://*.tile.openstreetmap.org;\ http-response add-header Content-Security-Policy worker-src\ 'self'\ blob:;\ child-src\ 'self'\ blob:;\ style-src\ 'self'\ 'unsafe-inline';\ frame-src\ *;\ media-src\ 'self';\ base-uri\ 'self';\ frame-ancestors\ 'self';\ form-action\ 'none';\ font-src\ 'self'\ data:;\ upgrade-insecure-requests
Restart HAProxy:
systemctl restart haproxy
SSL protocol versions
The HAProxy example configuration only allows HAProxy to accept TLSv1.2. The following entry in the configuration file removes the support for the SSL versions SSLv3, TLSv1.0 and TLSv1.1:
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
Note on TLS 1.3
HAProxy 1.8 and newer introduce support for 0-RTT, also known as TLS 1.3. If a customer requires TLS 1.3 support, check if the current OS provides a compiled version of HAProxy 1.8. For example, you can check if the RPM repository contains this version. By default, RHEL/CentOS 7 do not include version 1.8 in their base repositories, but RHEL/CentOS 8 do.
If version 1.8 is not available in the base RPM repository, you must compile HAProxy from source.
Cipher suites
Supported cipher suites:
ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS