Introduction

Haproxy is a tool used for service discovery. Its features are :

  • it acts as a proxy and is stateful.
  • it does stickyness by maintaining a client at the same backend server.
  • it serves as a Loadbalancer and does High Availability with 9 LoadBalancing algorithms
    • Round Robin
    • Least
    • First
    • Source
    • URI
    • HDR
  • it facilitates security and the implementation of SSL
  • it allows address and port translation to be performed
  • it is multi-protocol and facilitates configuration in terms of timeout
  • it allows for forwarding
  • it includes a monitoring system.
  • it allows for service reload
  • it allows spof with the keepAlive tool
  • it allows for slow start
  • it allows you to do stickyness
  • it allows you to do url rewriting
  • it is used to do service discovery
Installation

Installing on a Linux system, we have:

apt-get install haproxy

The configuration is done in the file /etc/haproxy/haproxy.cfg

The following test command will allow us to see the installed version:

haproxy -v

The haproxy.cfg file is where the haproxy configuration is done, and it will be used to do about 95% of the config. It is divided into several parts:

  • global
  • default
  • frontend
  • backend
  • listen (which is intended to replace frontend and backend)

You will have more information on the dedicated note a little further.

The configurations to know are :

  • daemon configuration : it is done in the file /etc/sysconfig
  • logrotate configuration : it is done by configuring the file /etc/haproxy/haproxy.cfg
  • The data storage directory is /var/lib/haproxy
  • The haproxy error templates are in /usr/share/haproxy. These templates can help us define automatic response formats such as a 404 response. In a security context, a 404 error can be disguised with a legitimate page.
Configuration

Haproxy works in frontend and redirects requests to a set of resources in backend. To configure this service, you must first ask it to listen on :

  • an IP
  • a Port
  • a URL

This is the configuration of the frontend. Afterwards, we will have to configure the backend where we will specify resources such as servers… You can specify several services and define the type of LoadBalancing that will be applied. It is also possible to apply specific rules, to add headers on the requests which will be redirected towards the backend services. The most important thing to remember so far is the principle of frontend and backend. You can read more documentation on the official website.

Example: A client makes a request to the Haproxy listener, i.e. the request arrives on the frontend. This request will be redirected to a backend if it checks some specific frontend condition. Then we will have a path. The steps :

  • frontend: IP/URL/listening port as defined in the haproxy configuration. It is possible to have several frontends. Here, the request arrived on a precise URL or IP and on a precise port (443, 80…)

  • Application of rules: rules are applied to determine the frontend corresponding to the client request. Then a decision will be made:

    • the request can be blocked
    • the request can be modified i.e. headers can be added or removed or modified…
  • a redirection rule from the frontend to the backend

  • In the backend, a LoadBalancing decision can be applied. Rules are in place to choose the server to which the request is redirected

  • a way back

  • logging of exchanges

    In the Haproxy configuration file, we note 2 parts:

  • Global section

  • Default section

Global

This section corresponds to the parameters of the haproxy service. An example is defined as follows:

global
    log /dev/log local5 debug
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

A short explanation of these parameters:

  • log : this is how haproxy will handle the logging
  • chroot : the security of haproxy
  • stats : to allow interarguing with haproxy with third party tools including hatop to configure haproxy in GUI. It also allows you to set the timeout, which is the length of time a connection will last
  • user : the user of the haproxy service
  • group
  • daemon : this mode allows haproxy to run as a service.
  • possibly ssl

Default

This section applies if no configuration is specified (definition of a frontend and a backend for a specific request). It is as follows:

defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5000
    timeout client 50000
    timeout server 50000
    errorfile 400 /etc/haproxy/errors/400.http

On a donc :

  • log global : logging to syslog or as defined in the global section
  • mode http : LoadBalancing protocol. It is possible to define other protocols such as tcp, smtp…
  • option : allows you to specify the need to log certain options
    • option httplog
    • option dontlognull : specifies not to log when requests are null
  • timeout connect : specifies the time to try to connect to the backend. This time is in ms. After this time, if the server does not respond, the server is considered unavailable.
  • timeout client/server
  • errorfile : allows you to specify the error file that should be displayed in case of an error

When you have written a haproxy configuration file, you can test the configuration with the command :

haproxy -c -f [myconfig_file.conf]

Example:

haproxy -c -f /etc/haproxy/haproxy.conf

It is important to do this test for a new haproxy configuration file before replacing the default file.

Example

Frontend

With Haproxy, we can define several frontends and this ability allows us to mutualise this service. An example of a minimalist frontend is :

frontend myapp_front
    bind *:80
    default_backend myapp_back

The frontend keyword is used to define a new frontend. Indentation is very important when writing a Haproxy file. In frontend, you can define parameters, the most important of which are :

  • bind : Here the value *:80 has been given. * specifies that we want to listen on all ip’s of the machine on which the haproxy service is running. It is also possible to specify a specific ip. For example: bind 10.0.0.1:80.
  • default_backend : is a forced variable, it specifies the corresponding backend. The given value is the name of a backend that has been defined.

Backend

The definition of a backend is as follows :

backend myapp_back
    server server1 10.0.0.1:80

The backend keyword is used to define a backend. As a parameter, one can specify the servers one would like to link with the server keyword. In the case of multiple servers in the backend, it is possible to specify a load balancing algorithm with the balance keyword. In this example, we will use a Round Robin algorithm. The configuration is as follows:

backend myapp_back
    balance roundrobin
    server server1 10.0.0.1:80
    server server2 10.0.0.2:5000

The Round Robin algorithm is the default algorithm to use when this parameter is not specified.

In the end, we obtain the following file :

global
    log /dev/log local5 debug
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    log global
    mode http
    option httplog
    option dontlognull
    timeout connect 5000
    timeout client 50000
    timeout server 50000
    errorfile 400 /etc/haproxy/errors/400.http

frontend myapp_front
    bind *:80
    default_backend myapp_back

backend myapp_back
    balance roundrobin
    server server1 10.0.0.1:80
    server server2 10.0.0.2:5000
Options

Haproxy has many options that we can use, including :

  • ACL which allows us to better manage incoming requests and redirect them to certain backend servers
  • Forwrad for which allows to transport the IP of the client responsible for the request between the Haproxy server and the backend server. In this case, Haproxy will no longer replace the client’s ip with its ip.

In this section, we’ll just look at how to implement ACL, I recommend that you visit the Haproxy documentation for more information on its features. An ACL allows a better filtering and redirection of the requests received at the frontend level. It is possible to filter them according to the URL, which is what we will do in this example… For a filtering according to 2 urls, namely: mct.aubinaso.fr and www.aubinaso.fr, we will have the following frontend configuration:

frontend myapp_front
    bind *:80
    mode http

    acl myapp_front1 hdr_dom(host) -i mct.aubinaso.fr
    use_backend mybackend1 if myapp_front1

    acl myapp_front2 hdr_dom(host) -i www.aubinaso.fr
    use_backend mybackend2 if myapp_front2

The line http mode informs that this is an acl applied to layer 7. We have added 2 entries for loadbalancer on 2 ACLs. The urls are mct.aubinaso.co.uk and www.aubinaso.fr. So we create 2 acl rules with names myapp_front1 and myapp_front2. The keyword hdr_dom(host) retrieves the URLs of the request and depending on the url, the client will be redirected to mybackend1 or mybackend2.

Variable
NAME="John"
echo $NAME
echo "$NAME"
echo "${NAME}
Condition
if [[ -z "$string" ]]; then
  echo "String is empty"
elif [[ -n "$string" ]]; then
  echo "String is not empty"
fi