Install HAProxy 3.0 on Ubuntu 24.04

Install HAProxy 3.0 pada Ubuntu 24.04

  • Server HAProxy : 192.168.10.10 – domain : sys-ops.id.sideka.my.id
  • Server Web1 : 192.168.10.15 – Port 80
  • Server Web2 : 192.168.10.16 – Port 80

  • Install HAProxy 3.0
apt update && apt upgrade -y
add-apt-repository ppa:vbernat/haproxy-3.0 -y
apt install haproxy -y
  • Cek versi HAProxy
haproxy -v
---<output>---
HAProxy version 3.0.2-1ppa1~noble 2024/06/14 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2029.
Known bugs: http://www.haproxy.org/bugs/bugs-3.0.2.html
Running on: Linux 6.8.0-35-generic #35-Ubuntu SMP PREEMPT_DYNAMIC Mon May 20 15:51:52 UTC 2024 x86_64

Konfigurasi HAProxy

  • Edit file haproxy.cfg
nano /etc/haproxy/haproxy.cfg
global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    maxconn 5000
    fullconn 5000
    retries 10
    log     global
    mode    http
    option  httplog
    option  dontlognull
    timeout connect 30s
    timeout client  30s
    timeout server  30s
    http-reuse always
    option  http-server-close
    option  http-keep-alive
    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

# Enable HAProxy Cache 128MB of RAM
cache haproxy-cache
    total-max-size 128
    max-age 60m
    max-object-size 1000000
    process-vary off

# Enable HAProxy Statistics
listen stats
    bind *:8765
    stats enable
    stats uri /
    stats realm Haproxy\ Statistics
    stats auth admin:admin
    stats refresh 15s

# HAProxy Frontend
frontend http_front
    bind *:80
    mode http

    # Automatically handle the X-Forwarded-For header
    option forwardfor
    http-request set-header X-Forwarded-For %[src]

    # Enable Gzip Compression
    compression algo gzip
    compression type text/html text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss
    compression offload

    # Add security headers
    http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    http-response set-header X-Content-Type-Options "nosniff"
    http-response set-header X-Frame-Options "SAMEORIGIN"
    http-response set-header X-XSS-Protection "1; mode=block"
    http-response set-header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline';"
    http-response set-header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' http: https:; img-src 'self' data: https:; font-src 'self' data: https:; frame-src 'self' data: https: blob:"
    http-response set-header Referrer-Policy "strict-origin-when-cross-origin"
    http-response set-header Permissions-Policy "microphone=(), geolocation=(self), fullscreen=()"
    
    # Enable cache lookup for frontend
    http-request cache-use haproxy-cache
    http-response cache-store haproxy-cache

    use_backend http_back

# HAProxy Backend
backend http_back
    # Load Balance Method (roundrobin, leastconn, source, random)
    balance leastconn

    # Persistence Connection
    stick-table type ip size 1m expire 30m
    stick on src

    # Remove Header Server
    http-response del-header Server

    # Health Check
    option httpchk
    http-check send meth HEAD uri / ver HTTP/1.1 hdr Host localhost
    option http-server-close
    option http-keep-alive

    # Enable cache lookup for backend
    http-request cache-use haproxy-cache
    http-response cache-store haproxy-cache

    # Backend server pool
    server web1 192.168.10.15:80 check maxconn 2500
    server web2 192.168.10.16:80 check maxconn 2500
  • Cek file konfigurasi haproxy.cfg, pastikan valid tidak ada error
  • Restart service haproxy
haproxy -f /etc/haproxy/haproxy.cfg -c
systemctl restart haproxy

Install Web Server

  • Install Web Server Nginx pada server Web1 dan Web2
### Install Nginx
apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx

apt update && apt install -y nginx
systemctl enable --now nginx
sed -i '/^\s*user\s\+nginx;/c\user www-data;' /etc/nginx/nginx.conf
-------------------------------------------------------------------------------------------------------------------------
### Install PHP
add-apt-repository ppa:ondrej/php
apt install -y php8.3 php8.3-{common,cli,gd,curl,mysql,xml,mbstring,zip,ldap,xmlrpc,curl,intl,fpm,imagick,dev,imap,opcache,soap,memcached,redis}
-------------------------------------------------------------------------------------------------------------------------
systemctl restart php8.3-fpm
systemctl restart nginx
  • Download sample file website dan copy ke folder /var/www/domain_anda pada server Web1 dan Web2
### Download Sample website
mkdir -p /var/www/sys-ops.id.sideka.my.id
git clone https://github.com/sideka-cloud/web-test.git
cp -R web-test/new/* /var/www/sys-ops.id.sideka.my.id/
chown -R www-data:www-data /var/www/sys-ops.id.sideka.my.id/
-------------------------------------------------------------------------------------------------------------------------
### Setting Virtual Host
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
nano /etc/nginx/conf.d/sys-ops.id.sideka.my.id.conf

server {
   listen 80;
   server_name sys-ops.id.sideka.my.id;
   root /var/www/sys-ops.id.sideka.my.id;

   location / {
       index index.php index.html index.htm;
       try_files $uri $uri/ /index.php?$args;
   }

         add_header Access-Control-Allow-Headers "ORIGIN, X-REQUESTED-WITH, CONTENT-TYPE";
         add_header Access-Control-Allow-Origin "*";
         add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
         add_header X-Content-Type-Options "nosniff";
         add_header X-Xss-Protection "1; mode=block";
         add_header X-Frame-Options "SAMEORIGIN";
         add_header Referrer-Policy "strict-origin-when-cross-origin";
         add_header Strict-Transport-Security "max-age=15552000; includeSubDomains;preload";
         add_header Access-Control-Max-Age "60000";
         add_header Permissions-Policy "microphone=(), geolocation=(self), fullscreen=()";
         add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' http: https:; img-src 'self' data: https:; font-src 'self' data: https:; frame-src 'self' data: https: blob:";

         proxy_hide_header X-Powered-By;
         fastcgi_hide_header X-Powered-By;
         server_tokens off;

         gzip on;
         gzip_comp_level 7;
         gzip_proxied any;
         gzip_types text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss;
         gzip_vary on;

         location ~* /\.(?!well-known\/) {
                 deny all;
         }

         location ~\.(ini|log|conf|txt|bak)$ {
                 deny all;
         }

   location ~ \.php$ {
      include /etc/nginx/fastcgi_params;
      fastcgi_pass unix:/run/php/php8.3-fpm.sock;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      include fastcgi_params;
      fastcgi_read_timeout 300;
      proxy_read_timeout 600;
   }
}
-------------------------------------------------------------------------------------------------------------------------
systemctl restart nginx

  • Akses HAproxy load balancer lewat web browser dengan url: http://ip_address atau http://domain
  • Akses HAproxy stats lewat web browser dengan url: http://ip_address:8765 atau http://domain:8765

Install Let’s Encrypt Free SSL

  • Stop service haproxy
  • Install certbot pada server haproxy
systemctl stop haproxy
apt install certbot -y
certbot certonly --standalone --agree-tos --preferred-challenges http --http-01-port 80 -d sys-ops.id.sideka.my.id -m [email protected]
  • Gabungkan isi file fullchain.pem dan privkey.pem menjadi satu file dan simpan di folder /etc/haproxy/certs
mkdir -p /etc/haproxy/certs
DOMAIN='sys-ops.id.sideka.my.id' sudo -E bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem'
  • Edit file konfigurasi HAproxy
  • Pada konfigurasi ini sudah dimasukan ssl let’s encrypt, strong ciphers, force redirect http to https dan http2 pada https
global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon
    
    # Ciphers 
    tune.ssl.default-dh-param 2048
    ssl-default-bind-options prefer-client-ciphers ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.3 
    ssl-default-bind-ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384

defaults
    maxconn 5000
    fullconn 5000
    retries 10
    log     global
    mode    http
    option  httplog
    option  dontlognull
    timeout connect 30s
    timeout client  30s
    timeout server  30s
    http-reuse always
    option  http-server-close
    option  http-keep-alive
    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

# Enable HAProxy Cache 128MB of RAM
cache haproxy-cache
    total-max-size 128
    max-age 60m
    max-object-size 1000000
    process-vary off

# Enable HAProxy Statistics
listen stats
    bind *:8765 ssl crt /etc/haproxy/certs/sys-ops.id.sideka.my.id.pem alpn h2,http/1.1
    stats enable
    stats uri /
    stats realm Haproxy\ Statistics
    stats auth admin:admin
    stats refresh 15s

# HAProxy HTTP Frontend
frontend http_front
    bind *:80
    mode http

    # Automatically handle the X-Forwarded-For header
    option forwardfor
    http-request set-header X-Forwarded-For %[src]

    # Enable Gzip Compression
    compression algo gzip
    compression type text/html text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss
    compression offload

    # Add security headers
    http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    http-response set-header X-Content-Type-Options "nosniff"
    http-response set-header X-Frame-Options "SAMEORIGIN"
    http-response set-header X-XSS-Protection "1; mode=block"
    http-response set-header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline';"
    http-response set-header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' http: https:; img-src 'self' data: https:; font-src 'self' data: https:; frame-src 'self' data: https: blob:"
    http-response set-header Referrer-Policy "strict-origin-when-cross-origin"
    http-response set-header Permissions-Policy "microphone=(), geolocation=(self), fullscreen=()"
    
    # Enable cache lookup for frontend
    http-request cache-use haproxy-cache
    http-response cache-store haproxy-cache

    # Force Redirect HTTP to HTTPS
    redirect scheme https code 301 if !{ ssl_fc }

    use_backend http_back

# HAProxy HTTPS Frontend
frontend https_front
    bind *:443 ssl crt /etc/haproxy/certs/sys-ops.id.sideka.my.id.pem alpn h2,http/1.1
    mode http

    # Automatically handle the X-Forwarded-For header
    option forwardfor
    http-request set-header X-Forwarded-For %[src]

    # Enable Gzip Compression
    compression algo gzip
    compression type text/html text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss
    compression offload

    # Add security headers
    http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    http-response set-header X-Content-Type-Options "nosniff"
    http-response set-header X-Frame-Options "SAMEORIGIN"
    http-response set-header X-XSS-Protection "1; mode=block"
    http-response set-header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline';"
    http-response set-header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' http: https:; img-src 'self' data: https:; font-src 'self' data: https:; frame-src 'self' data: https: blob:"
    http-response set-header Referrer-Policy "strict-origin-when-cross-origin"
    http-response set-header Permissions-Policy "microphone=(), geolocation=(self), fullscreen=()"

    # Enable cache lookup for frontend
    http-request cache-use haproxy-cache
    http-response cache-store haproxy-cache

    use_backend http_back

# HAProxy Backend
backend http_back
    # Load Balance Method (roundrobin, leastconn, source, random)
    balance leastconn

    # Persistence Connection
    stick-table type ip size 1m expire 30m
    stick on src

    # Remove Header Server
    http-response del-header Server

    # Health Check
    option httpchk
    http-check send meth HEAD uri / ver HTTP/1.1 hdr Host localhost
    option http-server-close
    option http-keep-alive

    # Enable cache lookup for backend
    http-request cache-use haproxy-cache
    http-response cache-store haproxy-cache

    # Backend server pool
    server web1 192.168.10.15:80 check maxconn 2500
    server web2 192.168.10.16:80 check maxconn 2500
  • Cek file konfigurasi haproxy.cfg, pastikan valid tidak ada error
  • Restart service haproxy
haproxy -f /etc/haproxy/haproxy.cfg -c
systemctl restart haproxy
  • Akses HAproxy load balancer lewat web browser dengan url: https://ip_address atau https://domain
  • Cek log HAProxy
tail -f /var/log/haproxy.log 
---<output>---
2024-06-20T18:27:24.812848+00:00 haproxy haproxy[4497]: 116.206.15.51:63715 [20/Jun/2024:18:27:24.798] 
https_front~ http_back/web1 0/0/0/13/13 200 2370 - - ---- 1/1/0/0/0 0/0 "GET https://sys-ops.id.sideka.my.id/ HTTP/2.0"
2024-06-20T18:27:24.943732+00:00 haproxy haproxy[4497]: 116.206.15.51:63715 [20/Jun/2024:18:27:24.936] 
https_front~ http_back/web1 0/0/4/2/6 200 1901 - - ---- 1/1/3/3/0 0/0 "GET https://sys-ops.id.sideka.my.id/styles.css HTTP/2.0"
2024-06-20T18:27:24.943955+00:00 haproxy haproxy[4497]: 116.206.15.51:63715 [20/Jun/2024:18:27:24.937] 
https_front~ http_back/web1 0/0/3/2/5 200 24184 - - ---- 1/1/2/2/0 0/0 "GET https://sys-ops.id.sideka.my.id/particles.min.js HTTP/2.0"
2024-06-20T18:27:24.945941+00:00 haproxy haproxy[4497]: 116.206.15.51:63715 [20/Jun/2024:18:27:24.937] 
https_front~ http_back/web1 0/0/3/2/5 200 169228 - - ---- 1/1/1/1/0 0/0 "GET https://sys-ops.id.sideka.my.id/cat.png HTTP/2.0"
2024-06-20T18:27:24.946772+00:00 haproxy haproxy[4497]: 116.206.15.51:63715 [20/Jun/2024:18:27:24.928] 
https_front~ http_back/web1 0/0/0/1/17 200 2934830 - - ---- 1/1/1/1/0 0/0 "GET https://sys-ops.id.sideka.my.id/tailwind.min.css HTTP/2.0"
2024-06-20T18:27:24.947505+00:00 haproxy haproxy[4497]: 116.206.15.51:63715 [20/Jun/2024:18:27:24.945] 
https_front~ http_back/web1 0/0/0/1/1 200 3479 - - ---- 1/1/0/0/0 0/0 "GET https://sys-ops.id.sideka.my.id/script.js HTTP/2.0"
2024-06-20T18:27:25.721839+00:00 haproxy haproxy[4497]: 116.206.15.51:63715 [20/Jun/2024:18:27:25.707] 
https_front~ http_back/web1 0/0/0/13/13 200 2370 - - ---- 1/1/0/0/0 0/0 "GET https://sys-ops.id.sideka.my.id/favicon.ico HTTP/2.0"

herdiana3389

A system administrator with skills in system administration, virtualization, linux, windows, networking, cloud computing, container, etc.