Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
deb13:haconfig [2026/09/15 08:23] – Bernard Condraudeb13:haconfig [2026/10/29 17:30] (current) – Bernard Condrau
Line 7: Line 7:
 # #
 # Features: # Features:
-#   acme integration, static blacklist, static and dynamic whitelist+#   HTTP/1, HTTP/2, HTTP/3, acme integration, static blacklist, static and dynamic whitelist
 #   handles transition from one backend server without reverse proxy to HAProxy with several backend servers #   handles transition from one backend server without reverse proxy to HAProxy with several backend servers
 # Notes: # Notes:
 #   # = comment, ## = acme integration, remove ## once you have set up acme (https://www.haproxy.com/blog/haproxy-and-let-s-encrypt) #   # = comment, ## = acme integration, remove ## once you have set up acme (https://www.haproxy.com/blog/haproxy-and-let-s-encrypt)
 #   Remove the 'default_backend' once transition is done from Certbot / Apache to acme / HAProxy #   Remove the 'default_backend' once transition is done from Certbot / Apache to acme / HAProxy
-#   Remove host acls in 'public_inbound_https' once all hosts are SSL terminated here+#   Remove 'public_inbound_https' once all hosts are SSL terminated here
 # #
 # 0. Settings # 0. Settings
Line 43: Line 43:
     log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"     log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"
     timeout connect 5s     timeout connect 5s
-    timeout client  50s +    timeout client  30s 
-    timeout server  50s+    timeout server  5m # set this high enough to allow complex websites to reply, for example Joomla during install or php calculations
  
 # 1. Public Interface (SNI Router) # 1. Public Interface (SNI Router)
 +# Receives traffic through TCP (HTTP)
 frontend public_inbound_http frontend public_inbound_http
     bind *:80     bind *:80
Line 60: Line 61:
     http-request redirect scheme https code 301 unless { ssl_fc }     http-request redirect scheme https code 301 unless { ssl_fc }
  
 +# Receives traffic through TCP (HTTP/1, HTTP/2)
 frontend public_inbound_https frontend public_inbound_https
     bind :443     bind :443
Line 74: Line 76:
     # Remove once all hosts are terminated here     # Remove once all hosts are terminated here
     acl terminate_ssl req.ssl_sni -i bak.condrau.com     acl terminate_ssl req.ssl_sni -i bak.condrau.com
 +    acl terminate_mail req.ssl_sni -i mail.condrau.com
  
     # Route conditionally based on SNI     # Route conditionally based on SNI
     use_backend http_dispatcher if terminate_ssl     use_backend http_dispatcher if terminate_ssl
 +    use_backend webmail_server if terminate_mail
     default_backend passthrough_server     default_backend passthrough_server
 +
 +# Receives traffic through UDP (HTTP/3), decrypts SSL, and processes HTTP rules
 +# HTTP/3 cannot be routed to apache web server without decrypting SSL first
 +frontend public_inbound_https3
 +
 +    # pass certs directory path so all pem files will be loaded
 +    # uncomment the following line once all hosts are SSL terminated here
 +    # bind :443
 +    bind quic4@:443 ssl crt /etc/haproxy/certs/ accept-proxy strict-sni
 +    mode http
 +
 +    # Handle Letsencrypt requests
 +    ##http-request return status 200 content-type text/plain lf-string "%[path,field(-1,/)].${ACCOUNT_THUMBPRINT}\n" if { path_beg '/.well-known/acme-challenge/' }
 +
 +    # Deny traffic based on origin (host aware)
 +    acl trusted_ip src -f /etc/haproxy/whitelist.lst # static whitelist
 +    acl whitelist_ip src,in_table(stick_table_whitelist) # dynamic whitelist
 +    acl backuppc hdr(host) -i bak.condrau.com
 +    http-request deny if backuppc !trusted_ip !whitelist_ip
 +
 +    # Let clients know we support HTTP/3
 +    http-response set-header Alt-Svc 'h3=":443"; ma=86400'
 +
 +    # Inject headers so backend servers know the original request was HTTPS
 +    http-request set-header X-Forwarded-Proto https
 +    http-request set-header X-Forwarded-Port 443
 +    http-request set-header X-Forwarded-For %[src]
 +
 +    # Route traffic based on HTTP host headers
 +    use_backend backuppc_server if backuppc
 +    default_backend http_server
  
 # 2. Transparent passthrough for encrypted TLS domains # 2. Transparent passthrough for encrypted TLS domains
Line 84: Line 119:
  
     # downstream server handling its own TLS certificates (Calypso)     # downstream server handling its own TLS certificates (Calypso)
-    server calypso 192.168.3.18:443 check+    server calypso 192.168.3.90:443 check 
 + 
 +backend webmail_server 
 +    mode tcp 
 + 
 +    # downstream (synology mail) server handling its own TLS certificates (Merkur) 
 +    server merkur 192.168.3.90:443 check check-ssl verify none
  
 # 3. Intermediary loopback backend # 3. Intermediary loopback backend
Line 92: Line 133:
     server loopback 127.0.0.1:8443 send-proxy-v2     server loopback 127.0.0.1:8443 send-proxy-v2
  
-# 4. Layer 7 http frontend+# 4. Layer 7 http frontend (HTTP/1, HTTP/2)
 # Receives traffic from the loopback, decrypts SSL, and processes HTTP rules # Receives traffic from the loopback, decrypts SSL, and processes HTTP rules
 frontend internal_inbound_http frontend internal_inbound_http
Line 124: Line 165:
 backend backuppc_server backend backuppc_server
     mode http     mode http
 +    http-reuse safe
     cookie SERVERID insert indirect nocache     cookie SERVERID insert indirect nocache
     server epione 192.168.1.50:8080 check     server epione 192.168.1.50:8080 check
Line 129: Line 171:
 backend http_server backend http_server
     mode http     mode http
 +    http-reuse aggressive
     cookie SERVERID insert indirect nocache     cookie SERVERID insert indirect nocache
-    server serenity 192.168.3.100:8080 check+    server serenity 192.168.3.100:80 check
  
 # 6. stick table that stores IPv4 addresses # 6. stick table that stores IPv4 addresses
Line 159: Line 202:
   * Remove IP address from whitelist stick table:<code>echo "clear table stick_table_whitelist key 192.168.1.99" | socat /run/haproxy/admin.sock stdio</code>   * Remove IP address from whitelist stick table:<code>echo "clear table stick_table_whitelist key 192.168.1.99" | socat /run/haproxy/admin.sock stdio</code>
   * Show content of whitelist stick table:<code>echo "show table stick_table_whitelist" | socat /run/haproxy/admin.sock stdio</code>   * Show content of whitelist stick table:<code>echo "show table stick_table_whitelist" | socat /run/haproxy/admin.sock stdio</code>
-  * To add an IP address from a DDNS service you should set the expire duration short in ''HAProxy.cfg'' because you cannot rely on the IP address being the same when you want to remove the IP address. Add this short bash script to update the stick table, it's an example for duckdns.org:<code>#!/bin/bash +  * To add an IP address for a remote computer not in one of your trusted IP ranges you should set the expire duration short in ''HAProxy.cfg'' because you cannot rely on the IP address being the same when you want to remove the IP address. You can add the following command to update and remove all entries in the stick table:<code>IP=$(curl -s https://api.ipify.org) && echo "set table stick_table_whitelist key $IP" | sudo /usr/bin/socat /run/haproxy/admin.sock stdio 
-IP=$(dig +short host.duckdns.org) +echo "clear table stick_table_whitelist" | sudo /usr/bin/socat /run/haproxy/admin.sock stdio
-ERROR=$? +
-# +
-# do not update if DIG timed out +
-if [ $ERROR -eq 0 ]; then +
-    # update HAProxy stick table +
-    echo "set table stick_table_whitelist key $IP" | socat /run/haproxy/admin.sock stdio +
-fi +
 </code> </code>
-  * Call the script from another linux computer or WSL (on Windows with a shortcut to):<code>wsl ssh -p <port> <domain> "sudo /home/<user>/batch/update.sh"</code> +  * To make this work you need to add <user> to file ''update-ip'' in ''/etc/sudoers.d'' so <user> can execute the command as root without password:<code>vim /etc/sudoers.d/update-ip 
-  * To make this work you need to add <user> to file ''update-ip'' in ''/etc/sudoers.d'' so he can execute the command as root without password:<code>vim /etc/sudoers.d/update-ip +<user> ALL=(root) NOPASSWD: /usr/bin/socat</code> 
-<user> ALL=(ALL:ALL) NOPASSWD: /home/<user>/batch/update.sh</code> +  * Call the script from another linux computer or WSL with the following file:<code>#!/bin/bash 
-  * To remove an IP address from a DDNS service you should remove the entire table because you cannot rely on the IP address being the same when you want to clear the table:<code>#!/bin/bash+# bco, 2026-09-20 
 +# update my current IP address in HAProxy stick table
 # #
-# update HAProxy stick table +IP=$(curl -s https://api.ipify.org) 
-echo "clear table stick_table_whitelist" | socat /run/haproxy/admin.sock stdio + 
-</code> +# Regex pattern matching 0-255 for individual octets 
-  * This way you can add your computer to the trusted IP list (whitelist) no matter what is the current IP address, provided that you set up a dynamic domain name which you can update with your [[#powershell|Powerhell]] script below.+octet='(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])' 
 +pattern="^${octet}\.${octet}\.${octet}\.${octet}$"
  
-===== Powershell ===== +if [[ $IP =~ $pattern ]]; then 
-  * Create the following Powershell script and use it with a shortcut to ''C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File "D:\update-dns.ps1"'':<code># D:\update-dns.ps1 + ssh -p 50322 huahin.condrau.com "echo \"set table stick_table_whitelist key $IP\" | sudo /usr/bin/socat /run/haproxy/admin.sock stdio" 
-# This is an example Powershell file for DuckDNS updater, see https://www.duckdns.org +else 
-param($domain) +    echo "Invalid IP address" 
-$duckdomain = if (!$domain) { "my-default-domain-name" } else { $domain } +    sleep 5 
-$addr = curl.exe -s "https://api.ipify.org" +    exit 1 
-curl.exe -k "https://www.duckdns.org/update?domains=$duckdomain&token=xxxxxxxx-yyyy-zzzz-*my*-*duckdnstoken*&ip=$addr"+fi 
 +exit 0
 </code> </code>
 +  * Put a shortcut on the Windows Desktop for easy access:<code>C:\Windows\System32\wsl.exe bash ~/batch/updateIP</code>
 +  * This way you can add your computer to the trusted IP list (whitelist) no matter what is the current IP address.