Introduction

HAProxy is a powerful reverse proxy that can be run as a Container. It is highly recommended to not expose Containers to users directly, but rather use a reverse HTTP/HTTPS proxy between your users and your Containers.

Configuration

To setup a HAProxy Contaienr on your RouterOS device, follow these steps bellow.

Make sure you have created a Container network before proceeding.

  1. Create HAProxy Container mount points:
    /container/mounts/add name=haproxy_etc src=disk1/haproxy-etc dst=/usr/local/etc/haproxy
  2. Create a HAProxy Container:
    /container/add remote-image=haproxy:latest interface=veth1 root-dir=disk1/haproxy mounts=haproxy_etc user=0:0 name=haproxy
  3. Connect to your RouterOS device using a SFTP client (for example, WinSCP when using Microsoft Windows) and create a new file disk1/haproxy-etc/haproxy.cfg , you can use the following config as an example:
    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 32
  4. Start the HAProxy Container:
    /container/start [find where name=haproxy]

Advanced: HAProxy with Certbot

This example shows how to configure HAProxy to serve HTTPS traffic and automatically renew the certificates by using Certbot and RFC2136.

  1. Create HAProxy Container:
    /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=yes
  2. Create a new file called haproxy.cfg  on your PC and upload it to disk1/volumes/haproxy/config/ , adjust the configuration to your needs:
    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:8080
    
    
  3. Create the Certbot Container:
    /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/li\
        ve/<FQDN>/fullchain.pem /etc/letsencrypt/live/<FQDN>/privkey.pem | tee /etc/haproxy/certs/<FQDN>.pem > /dev/null; echo -e \"set ssl cert /usr/local/e\
        tc/haproxy/certs/<FQDN>.pem <<\
        \n\$(cat /etc/haproxy/certs/<FQDN>.pem)\
        \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/certbot
    
    

    Make sure to replace all <FQDN> placeholders in the example above with your fully qualified domain name!

  4. Wait for the Container image to be downloaded and start the Certbot Container:
    /container start [find where name=certbot]
  5. Check the logs to make sure you successfully received a new certificate:
    /log print follow
  6. Start HAProxy Container:
    /container start [find where name=haproxy]
  7. Setup a schedule, for example, each day at 06:30 to check for a new certificate:
    /system scheduler
    add 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 script
    add 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\"]"
  8. Done

The certificate will automatically renew and replace old certificates in HAProxy without needing to restart the Container.



  • No labels