Haproxy.cfg configuration for acme challenge – openwrt

Updated configuration file for haproxy in openwrt. The acme-challenge was improved by having dedicated acls for each webserver containing a list of their own domains to redirect certbot traffic to another dedicated backend where those domains get their ssl certificates. Normal https traffic is redirected to individual backends.

global
        daemon
        nosplice

defaults
        log global
        mode http
        option httplog
        log 127.0.0.1:514 local0
        log /var/log/haproxy.log local0
        timeout client 30s
        timeout connect 30s
        timeout server 30s

frontend stats
        bind *:9000  # You can choose any port you prefer
        mode http
        stats enable
        stats uri /haproxy  # You can customize the URI path
        stats realm HAProxy\ Statistics
        stats auth username:password  # Choose a secure username and password

frontend http_in
        mode http
        option httplog
        bind *:80

        # Rate limiting
        stick-table type ip size 1m expire 10m store gpc0
        http-request track-sc0 src
        http-request deny if { src_conn_cur gt 100 }  # Limit to 100 requests per IP

        # Allow ACME challenge requests to bypass redirect
        acl acme_challenge path_beg /.well-known/acme-challenge/
        acl webserver_A_hosts hdr(host) -i site.one site.two
        acl webserver_B_hosts hdr(host) -i site.three site.four

        http-request redirect scheme https unless acme_challenge
        use_backend acme_backend_A if acme_challenge webservers_A_hosts
        use_backend acme_backend_B if acme_challenge webservers_B_hosts

        option forwardfor
        # Enhanced security headers
        http-response add-header Strict-Transport-Security max-age=31536000;\ includeSubDomains;\ preload
        http-response add-header Content-Security-Policy default-src\ 'self'
        http-response add-header X-Content-Type-Options nosniff
        http-response add-header X-Frame-Options DENY
        http-response add-header X-XSS-Protection "1; mode=block"

frontend https_in
        mode tcp
        option tcplog
        bind *:443
        acl tls req.ssl_hello_type 1
        tcp-request inspect-delay 5s
        tcp-request content accept if { req_ssl_hello_type 1 }

        # Track session data for rate limiting
        stick-table type ip size 100k expire 30m
        tcp-request content track-sc0 src
        # Use backend based on SNI
        use_backend %[req_ssl_sni,lower,word(1,:)]_tls

# Backend for ACME challenges
backend acme_backend_A
        mode http
        option httpchk
        default-server inter 3s fall 3 rise 2
        server webserver_A 192.168.1.10:80 check

backend acme_backend_B
        mode http
        option httpchk
        default-server inter 3s fall 3 rise 2
        server webserver_B 192.168.3.10:80 check

# Normal HTTPS traffic to backends

backend site.one_tls
        mode tcp
        option ssl-hello-chk
        server site.one 192.168.1.154:443 check

backend site.two_tls
        mode tcp
        option ssl-hello-chk
        server site.two 192.168.1.55:443 check

backend site.three_tls
        mode tcp
        option ssl-hello-chk
        server site.three 192.168.3.77:443 check

Explanation of Configuration:

  • Global Section: Configures global parameters for HAProxy. daemon allows HAProxy to run in the background, while nosplice prevents it from splicing connections, which can help with HTTP processing.
  • Defaults Section: Sets default logging options, timeout settings for client connections, server responses, and logs to both a remote syslog server and a local log file.
  • Frontend stats: Provides a web interface for HAProxy statistics, requiring a username and password for access. This helps administrators monitor traffic and performance.
  • Frontend http_in: Handles incoming HTTP requests, implements rate limiting to prevent abuse, and manages redirects to HTTPS while allowing certain paths (like ACME challenges) to bypass this redirection.
  • Frontend https_in: Manages incoming HTTPS traffic in TCP mode, utilizing SSL/TLS features. It inspects SSL handshakes to route requests based on the SNI field, allowing flexibility for multiple domains.
  • Backends: Each backend corresponds to a specific service or site. Health checks are configured to ensure that requests are only routed to healthy servers, and different backends are used based on the requested hostname or path.
  • Security Headers: Adding security headers helps to protect against various web vulnerabilities, such as clickjacking and XSS, enhancing the security of the web applications served.
  • Forwarding Client IPs: The option forwardfor directive, when uncommented, allows HAProxy to append the original client’s IP address to the X-Forwarded-For header. This preserves client visibility for backend servers, enhancing logging, analytics, and functionalities that rely on the original client IP. Consider enabling this if your backend services require access to client IP information.