Container - HAProxy
Container - HAProxy
Section titled “Container - HAProxy”Summary
Section titled “Summary”HAProxy (High Availability Proxy) is a powerful open-source reverse proxy and load balancer commonly used to improve server reliability and performance. Running HAProxy as a Container on RouterOS provides a secure gateway for directing HTTP/HTTPS traffic to backend services while hiding them from direct external access.
HAProxy supports multiple scheduling algorithms, health checks, SSL termination, and can handle thousands of concurrent connections with minimal resource usage. When combined with RouterOS Containers, it creates a flexible infrastructure for hosting web applications, APIs, and other network services.
Use Cases
Section titled “Use Cases”Load Balancing Across Multiple Services
Section titled “Load Balancing Across Multiple Services”HAProxy distributes incoming traffic across multiple backend servers, preventing any single server from becoming overwhelmed. This is essential when running multiple instances of a service for high availability or when different services require different backend configurations.
SSL/TLS Termination
Section titled “SSL/TLS Termination”By terminating SSL/TLS at HAProxy, backend Containers only need to handle unencrypted HTTP traffic. This simplifies certificate management, reduces CPU load on backend services, and centralizes security configuration.
URL-Based Routing
Section titled “URL-Based Routing”HAProxy can route requests to different backend pools based on URL paths, host headers, or other request attributes. This enables hosting multiple applications on the same IP address with different subdomains or path prefixes.
Rate Limiting and Protection
Section titled “Rate Limiting and Protection”HAProxy includes built-in rate limiting, connection limits, and IP reputation features that protect backend services from abuse, DDoS attacks, and excessive request rates.
Prerequisites
Section titled “Prerequisites”Container Network
Section titled “Container Network”Before deploying HAProxy, ensure you have a Container network configured. HAProxy Containers require network connectivity to receive incoming traffic and connect to backend services.
/interface/veth/printFlags: X - disabled, A - active, * - default # NAME MTU ADDRESS GATEWAY 0 veth1 1500 172.17.0.1/24 172.17.0.1If you need to create a new Container network, refer to the Container networking documentation for detailed instructions.
Storage Requirements
Section titled “Storage Requirements”HAProxy and its configuration require storage space on your RouterOS device. Ensure sufficient disk space is available for:
- Container image (approximately 50-100MB)
- Configuration files and certificates
- Logs (if logging is enabled)
Basic Configuration
Section titled “Basic Configuration”Step 1: Create Mount Points
Section titled “Step 1: Create Mount Points”Create a mount point to store the HAProxy configuration file persistently. This allows you to edit the configuration without rebuilding the Container.
/container/mounts/add name=haproxy_etc src=disk1/haproxy-etc dst=/usr/local/etc/haproxyThe mount point maps a directory on your RouterOS storage to the Container’s configuration directory.
Step 2: Create the HAProxy Container
Section titled “Step 2: Create the HAProxy Container”Add the HAProxy Container using the official HAProxy image. Specify the interface for network connectivity and the mount point for configuration.
/container/add remote-image=haproxy:latest interface=veth1 root-dir=disk1/haproxy mounts=haproxy_etc user=0:0 name=haproxyThis command:
- Downloads the latest HAProxy image from Docker Hub
- Connects the Container to the specified virtual interface
- Sets the root directory for Container data
- Mounts the configuration directory
- Runs the Container as root with specific UID/GID
Step 3: Create HAProxy Configuration File
Section titled “Step 3: Create HAProxy Configuration File”Connect to your RouterOS device using SFTP (or WinSCP on Windows) and create the configuration file at disk1/haproxy-etc/haproxy.cfg.
global log stdout format raw local0 info stats socket :9999 level admin expose-fd listeners
defaults mode http timeout client 10s timeout connect 10s timeout server 10s timeout http-request 10s
frontend http_synapse bind *:80 use_backend synapse
backend synapse server server1 172.17.0.2:8008 maxconn 32This basic configuration:
- Enables logging to stdout for Container logs
- Exposes the runtime statistics socket on port 9999
- Listens on port 80 for HTTP traffic
- Routes requests to a backend server at 172.17.0.2:8008
Step 4: Start the Container
Section titled “Step 4: Start the Container”/container start [find where name=haproxy]Verify the Container is running:
/container/printFlags: X - disabled, R - running 0 R name="haproxy" id="abc123..." interface=veth1 ...Step 5: Verify Operation
Section titled “Step 5: Verify Operation”Check the logs for startup messages:
/log print followYou should see HAProxy initialization messages indicating successful startup.
Configuration Reference
Section titled “Configuration Reference”Global Section
Section titled “Global Section”The [global](#global-section) section configures process-wide settings:
| Property | Description |
|---|---|
log | Configures logging destination and format |
stats socket | Enables the runtime statistics socket for dynamic configuration |
nbthread | Number of worker threads (match to CPU cores) |
tune.bufsize | Buffer size (adjust for large headers) |
tune.ssl.cachesize | SSL session cache size |
Defaults Section
Section titled “Defaults Section”The [defaults](#defaults-section) section sets default values for all subsequent frontend and backend sections:
defaults mode http timeout client 10s timeout connect 10s timeout server 10s timeout http-request 10s| Property | Description |
|---|---|
mode | Connection mode: http for layer 7, tcp for layer 4 |
timeout client | Maximum inactivity time for client connections |
timeout connect | Maximum time to wait for a backend connection |
timeout server | Maximum inactivity time for backend connections |
timeout http-request | Maximum time to receive a complete HTTP request |
Frontend Section
Section titled “Frontend Section”The [frontend](#frontend-section) section defines how HAProxy accepts incoming connections:
frontend frontend_webapp mode http option httplog bind *:80 bind *:443 ssl crt /usr/local/etc/haproxy/certs/ http-request redirect scheme https unless { ssl_fc } use_backend backend_webapp| Property | Description |
|---|---|
bind | Socket binding specification (address:port) |
ssl crt | SSL certificate path for HTTPS |
http-request | Manipulate incoming HTTP requests |
use_backend | Direct traffic to specified backend |
Backend Section
Section titled “Backend Section”The [backend](#backend-section) section defines backend servers and load balancing:
backend backend_webapp mode http balance roundrobin option http-server-close option forwardfor server server1 172.17.0.2:8080| Property | Description |
|---|---|
balance | Load balancing algorithm: roundrobin, leastconn, source |
option http-server-close | Close connections to backend after response |
option forwardfor | Add X-Forwarded-For header with client IP |
server | Backend server definition with address and options |
Advanced: HAProxy with SSL Certificates
Section titled “Advanced: HAProxy with SSL Certificates”This section describes how to configure HAProxy with HTTPS support using Certbot for automatic certificate management with RFC2136 DNS validation.
Step 1: Create Container with Advanced Configuration
Section titled “Step 1: Create Container with Advanced Configuration”/container/mounts/add name=MOUNT_HAPROXY src=disk1/volumes/haproxy/config dst=/usr/local/etc/haproxy/container/add remote-image=haproxy:latest interface=veth1 root-dir=disk1/images/haproxy mounts=MOUNT_HAPROXY name=haproxy start-on-boot=yes user=0:0 logging=yesKey additions:
start-on-boot=yesensures HAProxy starts automatically after rebootlogging=yesenables Container logging to RouterOS logs- Separate configuration directory for easier management
Step 2: Create HAProxy Configuration with SSL
Section titled “Step 2: Create HAProxy Configuration with SSL”Create haproxy.cfg on your local system and upload to disk1/volumes/haproxy/config/:
global log stdout format raw local0 info stats socket :9999 level admin expose-fd listeners ssl-default-bind-ciphers EECDH+AESGCM:EDH+AESGCM ssl-default-server-ciphers EECDH+AESGCM:EDH+AESGCM ssl-default-bind-options ssl-min-ver TLSv1.2 ssl-default-server-options ssl-min-ver TLSv1.2 tune.ssl.default-dh-param 2048 tune.bufsize 43768 tune.ssl.cachesize 1000000 nbthread 8
defaults log global timeout client 10s timeout connect 10s timeout server 10s timeout http-request 10s
frontend frontend_webapp mode http option httplog option http-server-close option forwardfor except 127.0.0.0/8 stick-table type ipv6 size 100k expire 30s store http_req_rate(10s) http-request track-sc0 src http-request deny deny_status 429 if { sc_http_req_rate(0) gt 10000 } bind *:80 bind *:443 ssl crt /usr/local/etc/haproxy/certs/ http-request redirect scheme https unless { ssl_fc } http-request set-header X-Forwarded-Host %[req.hdr(host)] http-request set-header X-Forwarded-For %[src] use_backend backend_webapp
backend backend_webapp mode http balance roundrobin option http-server-close option forwardfor server server1 172.17.0.2:8080This configuration includes:
- Strong SSL cipher configuration
- Rate limiting (10000 requests per 10 seconds per IP)
- HTTP to HTTPS redirection
- X-Forwarded headers for backend server logging
- High-performance SSL settings with large caches
Step 3: Create Certbot Container
Section titled “Step 3: Create Certbot Container”Create the Certbot Container for Let’s Encrypt certificate management:
/container/mounts/add name=MOUNT_CERTBOT_CONFIG src=disk1/volumes/certbot/config dst=/etc/letsencrypt/container/mounts/add name=MOUNT_CERTBOT_DATA src=disk1/volumes/certbot/data dst=/var/lib/letsencrypt/container/mounts/add name=MOUNT_CERTBOT_LOG src=disk1/volumes/certbot/log dst=/var/log/letsencrypt/container/mounts/add name=MOUNT_CERTBOT_HAPROXY src=disk1/volumes/haproxy/config dst=/etc/haproxy/container/add remote-image=certbot/dns-rfc2136 cmd="certonly -n --agree-tos --dns-rfc2136 --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini -m admin@<FQDN> --deploy-hook 'cat /etc/letsencrypt/live/<FQDN>/fullchain.pem /etc/letsencrypt/live/<FQDN>/privkey.pem | tee /etc/haproxy/certs/<FQDN>.pem > /dev/null; echo -e \"set ssl cert /usr/local/etc/haproxy/certs/<FQDN>.pem <<\n$(cat /etc/haproxy/certs/<FQDN>.pem)\n\n\" | nc 127.0.0.1:9999; echo \"commit ssl cert /usr/local/etc/haproxy/certs/<FQDN>.pem\" | nc 127.0.0.1:9999' -d <FQDN> --cert-name <FQDN>" interface=veth1 logging=yes mounts=MOUNT_CERTBOT_CONFIG,MOUNT_CERTBOT_DATA,MOUNT_CERTBOT_LOG,MOUNT_CERTBOT_HAPROXY name=certbot root-dir=disk1/images/certbot start-on-boot=yes workdir=/opt/certbotReplace all <FQDN> placeholders with your fully qualified domain name before running this command.
This configuration:
- Uses Certbot with RFC2136 DNS validation (for networks where HTTP validation is not possible)
- Automatically copies new certificates to HAProxy via the statistics socket
- Reloads HAProxy certificates without restart
- Runs with start-on-boot for automatic certificate renewal
Step 4: Run Certbot to Obtain Certificate
Section titled “Step 4: Run Certbot to Obtain Certificate”/container start [find where name=certbot]Monitor the logs for certificate generation:
/log print followLook for messages indicating successful certificate issuance. The certificate will be automatically deployed to HAProxy.
Step 5: Start HAProxy
Section titled “Step 5: Start HAProxy”/container start [find where name=haproxy]Step 6: Configure Automatic Renewal
Section titled “Step 6: Configure Automatic Renewal”Create a scheduler to run certificate renewal automatically:
/system scheduleradd interval=1d name=SCHEDULE_RenewCertbot on-event=SCRIPT_RenewCertbot policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=2025-03-10 start-time=06:30:00
/system scriptadd dont-require-permissions=no name=SCRIPT_RenewCertbot owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="/container/start [find where name=\"certbot\"]"This schedule runs daily at 6:30 AM to check for and obtain new certificates if needed.
Rate Limiting and Protection
Section titled “Rate Limiting and Protection”HAProxy includes powerful features for protecting backend services from abuse:
Connection Rate Limiting
Section titled “Connection Rate Limiting”frontend frontend_webapp stick-table type ipv6 size 100k expire 30s store http_req_rate(10s) http-request track-sc0 src http-request deny deny_status 429 if { sc_http_req_rate(0) gt 10000 }This configuration:
- Tracks request rates per source IP
- Allows 10,000 requests per 10-second window
- Returns HTTP 429 (Too Many Requests) when limit exceeded
IP Reputation
Section titled “IP Reputation”HAProxy can integrate with IP reputation services or maintain local blacklists:
frontend frontend_webapp http-request deny if { src,netmask(24) -f /etc/haproxy/blacklist.txt }Slowloris Protection
Section titled “Slowloris Protection”defaults timeout http-request 10s timeout client 10s timeout server 10sShort timeouts prevent slowloris-style attacks that hold connections open indefinitely.
Troubleshooting
Section titled “Troubleshooting”Container Will Not Start
Section titled “Container Will Not Start”- Verify sufficient storage space:
/system/resource/print - Check interface exists:
/interface/veth/print - Review mount point paths exist on storage
- Check logs for specific errors:
/log print
/container/print detailCannot Connect to Backend Services
Section titled “Cannot Connect to Backend Services”- Verify backend server is running:
/container/print - Check backend IP and port are correct in configuration
- Test connectivity from RouterOS:
/tool ping 172.17.0.2 - Verify no firewall rules block traffic
/ip/firewall/filter/print/interface/veth/print detailSSL Certificate Issues
Section titled “SSL Certificate Issues”- Verify certificate file exists:
/file print - Check certificate format is PEM with both certificate and private key
- Ensure certificate is not expired
- Verify HAProxy has read access to certificate files
Performance Issues
Section titled “Performance Issues”- Check HAProxy statistics: Connect to the statistics socket
- Review connection limits and backend server capacity
- Monitor system resources:
/system resource/print - Consider increasing thread count for multi-core systems
Logs Not Appearing
Section titled “Logs Not Appearing”- Verify logging=yes was set on Container creation
- Check RouterOS log settings:
/system/logging/print - Ensure log topics are enabled