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”]