2

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

 

0

Ansible – Using dictionary to deploy pem certificates

When automating certificate deployments I wanted to have smart way of deploying them. So I went ahead and decided to use dictionaries.

For this example my variables looked more like as following :

ssl_certificates:
    domain_uno_com:
      owner: haproxy
      group: haproxy
      mode: "u=r,go="
      certificate: |
                                              -----BEGIN CERTIFICATE-----
                                              dslkajfafak234h23o4h32jkh43jqtghkjafhads;fhd89fuad9f6a8s7f6adsf
                                              < ..................... bogus info uno ...................... >
                                              yjEdslkajfafak234h23o4h32jkh43jZlcmlTaWduLCBJbmMuMR8wHQYDVQQL23
                                                -----END CERTIFICATE-----
      key: |
                                              -----BEGIN PRIVATE KEY-----
                                              dslkajfafak234h23o4h32jkh43jqtghkjafhads;fhd89fuad9f6a8s7f6adsf
                                              < ..................... bogus info uno ...................... >
                                              yjEdslkajfafak234h23o4h32jkh43jZlcmlTaWduLCBJbmMuMR8wHQYDVQQL23
                                              Edslkajfafak234h==
                                              -----END PRIVATE KEY-----
      
    domain_duo_com:
      owner: haproxy
      group: haproxy
      mode: "u=r,go="
      certificate: |
                                              -----BEGIN CERTIFICATE-----
                                              dslkajfafak234h23o4h32jkh43jqtghkjafhads;fhd89fuad9f6a8s7f6adsf
                                              < ..................... bogus info duo ...................... >
                                              yjEdslkajfafak234h23o4h32jkh43jZlcmlTaWduLCBJbmMuMR8wHQYDVQQL23
                                                -----END CERTIFICATE-----
      key: |
                                              -----BEGIN PRIVATE KEY-----
                                              dslkajfafak234h23o4h32jkh43jqtghkjafhads;fhd89fuad9f6a8s7f6adsf
                                              < ..................... bogus info duo ...................... >
                                              yjEdslkajfafak234h23o4h32jkh43jZlcmlTaWduLCBJbmMuMR8wHQYDVQQL23
                                              Edslkajfafak234h==
                                              -----END PRIVATE KEY-----

 

Once we have that within our playbook we will be using the following actions to create ourselves pem files

       - name: SSL certificates Web | Create certificate key files
         copy:
           dest: "{{web_ssl_folder}}/{{ item.key.replace('_','.') }}.pem"
           content: "{{ item.value.certificate + '\n' + item.value.key }}"
           owner: "{{ item.value.owner }}"
           group: "{{ item.value.group }}"
           mode: "{{ item.value.mode }}"
         with_dict: ssl_certificates
         no_log: true

 

Now when we run our playbook what will happen is we will get within folder defined under web_ssl_folder  new certificates called respectively domain.uno.com.pem and domain.duo.com.pem.

Of course if you add more entries you will get more created. So for you the only thing to change from here is the owner and possibly the rights ( although think twice 🙂 )

0

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 🙂

 

 

6

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 :

haproxy_rsyslog_logs

 

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

global
    log 127.0.0.1 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
    ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA



defaults
    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

 

0

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
    bind 0.0.0.0:80
    redirect scheme https code 301 if !{ ssl_fc }


frontend https-in
    bind 0.0.0.0:443 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.