HAproxy – backend and domain management using map

This is quick write up how to use single line for easy backend mapping within HAproxy. This has been showed to me by my buddy while challenging current configuration which started to grow.

The first thing you will need to have is to create a map file. Its structure its simple – first column is what comes is , second is what comes out. So for our domain mapping we can have file with domain name and respective backend i.e.

domain.com backend_com
www.domain.com backend.com

Next is just configuration line on your front end associating domains with backends based on the host header

use_backend %[req.hdr(host),lower,map_dom(/etc/haproxy/<PATH-TO-MAP-FILE>,<DEFAULT-BACKEND>)]


And that is it 🙂 you have now got your self really dynamic configuration



HAproxy – securing Piwik stats

So today we will be discussing how to secure Piwik stats with help of HAproxy. I didn’t find direct articles relating to how to do that so google and quick tests were my companions for this 🙂

So Piwik is quite cool project for getting your statistics. I have created a simple docker container out of it ( available on DockerHub ) and now run it on my server. Looking at documentation I wanted to have it secured so I have found the following quote :

” Use .htaccess to restrict access to a few files only, and to restrict by defined IP address.
For those running an Apache web server, it should be easy to use .htaccess (Apache’s Access Control List) files to restrict entry to Piwik. For example, when you restrict access to files, you will need to allow external access to the piwik.php and piwik.js files, as well as to the URL index.php?module=CoreAdminHome&action=optOut (for the opt-out iframe).”


So what I have done – was creating simple ACL for piwik ( yep – you can have the same name of ACLs 🙂 ) called piwik_stats and used it when deciding for backend so backend would be accessible only if coming from whitelisted IP address or only when using whitelisted parts of URL 🙂

    # Whitelist : MyHome
    acl net_whitelist_myhome  src -f /etc/haproxy/myhome

    # Piwik stats security
    acl piwik_stats  url  /index.php?module=CoreAdminHome&action=optOut
    acl piwik_stats  path /piwik.php
    acl piwik_stats  path /piwik.js

    use_backend stats_piwik  if domain_stats.example_com piwik_stats or net_whitelist_myhome


Now I know there are probably better ways to do that- if you have one – share your comments / thoughts.


Enjoy 🙂




HAproxy – Logging within docker container

Hey ,

So today we will continue looking at HAproxy – however this time we will be using Docker to host our load balancer. As far as it is no problem to just download the main image from docker hub and run instantly it does not give out of the box something that I was after …… the logs.

That’s why I went ahead and just created my own version of HAproxy which includes rsyslog. Repository with the image can be found on github.

In order to run the container we just need to execute the following commands:

  1. To get the most up to date image from my docker hub repo
    docker pull rafpe/docker-haproxy-rsyslog
  2. To start container ( assuming you have config file in current directory )
    docker run -it -d -P -v ${PWD}/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg rafpe/docker-haproxy-rsyslog


Once you do this container should be up and running and if you query for current docker containers you should see something similar to output below :



As you can see we are getting logs directly visible after querying with docker logs command.

In one of the future posts we will be investigating logs format customisations as well as features included in HAproxy since 1.6  which is log tags.


If you would have any problems configuring this because of missing config you can use sample below

    log local2
    maxconn 2000
    pidfile /var/run/haproxy.pid

    tune.ssl.default-dh-param 2048

    # SSL ciphers
    ssl-default-bind-options no-sslv3 no-tls-tickets

    mode    http
    option  httplog
    option  dontlognull
    option  forwardfor
    option  contstats
    option  http-server-close
    option log-health-checks
    retries 3
    option  redispatch
    timeout connect  5000
    timeout client  10000
    timeout server  10000

    # make sure log-format is on a single line
    log global
    log-format {"type":"haproxy","timestamp":%Ts,"http_status":%ST,"http_request":"%r","remote_addr":"%ci","bytes_read":%B,"upstream_addr":"%si","backend_name":"%b","retries":%rc,"bytes_uploaded":%U,"upstream_response_time":"%Tr","upstream_connect_time":"%Tc","session_duration":"%Tt","termination_state":"%ts"}

frontend http-in
    bind *:80
    # Default backend to be used
    default_backend will-be-back-soon

backend will-be-back-soon
   balance roundrobin



HAproxy – ACL on X-Forwarded-For


So today we will work on having correct ACLs but when we are behind a service i.e. Akamai or Cloudflare . Benefits of those services are beyond scope of this post however if you are into CDN cache / security / dDos protection then take a look.

Challenge which we are looking into today is to have appropriate ACLs within our configuration. Usually simple ACL could look like :

	  # Check restricted network
	  acl restricted_network src # Home network


and this is perfectly valid configuration entry which will work if the client is hitting our server directly. However if we decide to use one of mentioned above solutions ( or any other ) we need to make sure we can still apply our ACLs as source ip will be different. Well no worries – HAproxy is such a versatile load balancer that this is so easy to achieve. We will use here a header being passed from our service provider hiding under X-Forwarded-For which will contain client original IP address

So what I did first was to create a file ( name is arbitrary for demo ) called acl_restricted_network and placed it under /etc/haproxy/acl_restricted_network

Content of this file are IP addresses / networks which I will use in my ACL list and looks as simple as :


Then the last thing to change in our configuration of haproxy is to have this file being checked on desired ACL

    acl restricted_network hdr_ip(X-Forwarded-For) -f /etc/haproxy/acl_restricted_network


Now to ease of those of you that are worried about performance here is the quote from one of mailing lists detailing this approach

IP lists loaded from files are stored in binary trees. Even if you load one million prefixes, you should barely notice it under load, as the prefix lookup is cheaper than the header extraction itself.


And voilla 🙂 it works out of hand without any problems 🙂 and is performance friendly !


And if you are looking for more posts about haproxy checkout articles below:

[display-posts category=”haproxy” posts_per_page=”-1″ include_date=”true” order=”ASC” orderby=”title”]



HAproxy – SSL domains in crt-list

I think for those using high throughput to load balancers will know HAproxy immediately. If HAproxy is something new to you – I highly recommend to scatter around and get your self familiar with this great product. I use it personally and as well recommend it ( if the requirements match ) to my customers. I thought I will create separate category especially for this awesome piece of art and will share with you some of my challenges and discoveries I came across with.

So today I will start with the fact that HAproxy supports SNI and that you can have multiple certificates assigned. If you look at internet ( or even at the documentation ) you will see its common to use syntax like :

frontend https-in
    bind *:443 ssl crt /etc/ssl/server1.pem crt /etc/ssl/server2.pem
    http-request set-header X-Forwarded-Proto https 
    default_backend application-backend


What you can see here is that we are specifying certificates ( detailed way of HApoxy handles this can be found under link ) .  However I have been recently using crt-list which allows me to specify certificates for domains ( and also do filtering within that file ) .

File looks as easy as (basic no filtering ) :

/etc/ssl/web/domain1.net.pem domain1.net
/etc/ssl/web/domain2.net.pem domain2.net


From there in my config I use the following :

#  _____                    _                    _
# |  ___|_ __  ___   _ __  | |_  ___  _ __    __| | ___
# | |_  | '__|/ _ \ | '_ \ | __|/ _ \| '_ \  / _` |/ __|
# |  _| | |  | (_) || | | || |_|  __/| | | || (_| |\__ \
# |_|   |_|   \___/ |_| |_| \__|\___||_| |_| \__,_||___/

frontend http-in
    redirect scheme https code 301 if !{ ssl_fc }

frontend https-in
    bind ssl crt-list /etc/haproxy/crt-list.txt

    http-request set-header X-Forwarded-Proto https if { ssl_fc }


And thats how easy it is. In coming posts I will try to publish more interesting information abut HAproxy.