Serveur HAProxy sous GNU/Debian Lenny

Jean Baptiste FAVRE

juillet 2009

Introduction

Les applications web sont de plus en plus complexes. Elles sont amenées à traiter de plus en plus de données confidentielles: les entreprises utilisent de plus en plus de services "en ligne". Mais quid de la sécurité ? Les entreprises dépendent de plus en plus d'internet. Cependant, elles n'ont pas toujours conscience des risques qu'elle courent. Un exemple:

La revue, très rapide je vous l'accorde, des menaces amène à se poser la question suivante: comment marchent ces attaques ? En ce qui concerne Google, peu d'informations sont disponible. Il semble néanmoins qu'une erreur humaine lors d'une maintenance soit à l'origine de la panne. Une chose esr sûre en revanche, les attaques existent ! Il en existe plusieurs catégories. Certaines concernent les couches IP et TCP, d'autres les couches applicatives (HTTP par exemple).

TCP open

Il s'agit d'ouvrir suffisamment de connexion TCP sans envoyer de données pour saturer le serveur. À chaque connexion TCP ouverte (SYN, SYN-ACK, ACK) le serveur mobilise un peu de ressources mémoire et CPU et, surtout, transmet la requète au serveur web. Une fois que le serveur a atteint le nombre maximum de connexion, il cesse de traiter les suivantes. Tant que le timeout de connexion n'est pas atteint, l'application web sous-jacente est inaccessible.

HTTP saturation

Le même profil d'attaque qu'au dessus, mais cette fois, on ajoute une requète HTTP parfaitement valide. Elle sera donc traitée par le serveur web. Évidemment, plus vous envoyez de requètes, plus le serveur web va mobiliser ses resources, jusqu'à saturation de sa capacité.

Slowloris

Le principe de l'attaque est connu depuis quelques années, mais il existe maintenant un outil permettant de l'automatiser.

Il s'agit d'ouvrir une connexion TCP, d'envoyer un début de requète HTTP et... de faire durer le plaisir. Du coup, le serveur Web maintient la connexion ouverte et attend une suite qui ne viendra jamais. Là encore, le Timeout vient nous sauver, mais trop tard: l'outil ouvrant autant de connexions qu'il peut, le serveur web sature très rapidement. Il faut préciser qu'un connexion client "coûte" beaucoup moins cher en resources qu'une connexion "serveur". Donc le combat est totalement inégal.

Apache, l'un si ce n'est le serveur web le plus connu et utilisé est vulnérable à cette attaque.

Prenons l'attaque Slowloris comme exemple et tâchons de nous en protéger. Basiquement, il n'existe pas beaucoup de solutions:

C'est naturellement la dernière solution que nous allons mettre en place, à l'aide de HAProxy.

HAProxy est conçu pour traiter le plus efficacement possible le plus de connexion possible. Par exemple, 20000 connexions actives n'occupent "que" 1Go de mémoire.

Agissant comme un proxy, il peut donc encaisser le gros de l'attaque. Nous allons voir comment.

Installation

Comme d'habitude, j'utilise Debian. L'installation est donc dramatiquement complexe:

Installation de HAProxy
apt-get install haproxy

Ceci installera la version 1.3.15 de HAProxy. Problème, elle est proche de la fin. La version 1.3.18 la remplacera : (source:http://haproxy.1wt.eu/) With all these fixes, I released 1.3.18, as well as 1.3.15.9 and 1.3.14.13 which are probably among the last ones of their respective branches after 12 and 18 months of maintenance.

Pour cette raison, et pour une fois, nous allons installer la version disponible dans la branche testing. Pour cela, pas la peine d'upgrader tout votre système (ouf !) :

Configuration des préférences apt: /etc/apt/preferences
Package: *
Pin: release a=stable
Pin-Priority: 1001

Package: haproxy*
Pin: release a=testing
Pin-Priority: 500
Configurationd des sources: /etc/apt/sources.list
deb http://ftp.fr.debian.org/debian/ lenny main
deb http://security.debian.org/ lenny/updates main
deb http://volatile.debian.org/debian-volatile lenny/volatile main
deb http://ftp.fr.debian.org/debian/ squeeze main
Installation de HAProxy
apt-get update && apt-get install haproxy

Par défaut, haproxy ne démarre pas. Pour remédier à cela:

Démarrage automatique de HAProxy: /etc/default/haproxy
# Set ENABLED to 1 if you want the init script to start haproxy.
ENABLED=1
# Add extra flags here.
#EXTRAOPTS="-de -m 16"

Maintenant que HAProxy peut être démarré, il est temps de le configurer.

Architecture

Apache

2 solutions: vous n'avez qu'une machine, ou plusieurs. Dans le premier cas, vous devrez configurer Apache pour qu'il écoute sur l'interface locale. Dans le cas contraire, veillez juste à limiter les accès à la machine qui hébergera HAProxy, sinon, il sera assez simple de contourner le proxy pour s'attaquer directement au(x) serveur(s) web.

Ensuite, tout est affaire de configuration.

HAProxy

HAProxy peut être utilisé comme un load-balancer, un proxy filtrant, ou les 2. "It's up to you !"

Configuration de HAProxy: théorie

La configuration se partage en plusieurs parties:

global
Options du service.
default
Options par défaut. Elles s'appliqueront partout, sauf si elle sont reprises.
frontend
Défini la partie publique de HAProxy. Les connexions arriveront donc ici.
backend
La partie "privée". Apparaîtront ici le ou les serveurs web qu'HAProxy devra protéger.

Dans ce cas précis, nous paramétrons différents timeout. Le but de tout cela est de limiter au maximum les effets d'une attaque:

timeout client
Le temps durant lequel nous attendrons le client
timeout server
Le temps durant lequel nous attendrons le serveur web (backend)
timeout queue
Si le backend n'est pas disponible, HAProxy va conserver les requètes en file d'attente. Au bout d'un certain temps, celles-ci seront détruites.
timeout http-request
Très intéressant pour contrer slowloris: si la requète HTTP n'est pas complètement envoyée en moins 5 secondes, la connexion est fermée car jugée invalide.

Si vous avez plus d'un serveur web à protéger, il vous suffit de rajouter une ligne dans la partie backend. HAProxy se comportera alors également en load-balancer, avec tout un tas d'options supplémentaires qu'il vous faudra découvrir et maîtriser.

Configuration de HAProxy: protection anti-DDOS

Dans le cas d'une protection contre une attaque DDOS, la configuration peut ressembler à (source: http://haproxy.1wt.eu/download/1.3/examples/antidos.cfg) :

/etc/haproxy/haproxy.cfg
global
daemon
user haproxy
group haproxy
maxconn 5000

defaults
mode	http
maxconn	4950
retries	2
timeout client 60s   # Client and server timeout must match the longest
timeout server 60s   # time we may wait for a response from the server.
timeout queue  60s   # Don't queue requests too long if saturated.
timeout connect 4s   # There's no reason to change this one.
timeout http-request 5s	# A complete request may never take that long.
option httpclose
option abortonclose
balance roundrobin
option forwardfor    # set the client's IP in X-Forwarded-For.
retries 2

frontend public
bind 192.168.1.1:80
default_backend webfarm

backend webfarm
cookie JSESSIONID prefix
option httpchk HEAD /check.txt HTTP/1.0
server www01 127.0.0.1:80 cookie A check
#	server www02 127.0.0.1:8080 cookie B check

Conclusion

Voilà une présentation très très rapide du logiciel. S'il fallait lui trouver un défaut, je dirais que l'absence de support SSL est préjudiciable, mais on ne peut pas tout avoir ;-)

Pour finir, je ne peux que vous encourager à consulter la documentation officielle. Pour cela, rien de tel que quelques liens.

Sources et liens

HAProxy

Format

Ce document est disponible aux formats suivants:

À propos de Jean Baptiste FAVRE

Je suis responsable d'exploitation dans le domaine de l'hébergement. Je travaille, entre autres, sur la virtualisation et l'amélioration des performances web. De temps en temps, j'arrive à décrocher de mon clavier pour lire un bon bouquin en écoutant de la musique.

License

Creative Commons License Cette publication est publiée sous contrat Creative Common by-nc-sa

Valid XHTML 1.0 Strict |  Valid CSS |  contrat Creative Common by-nc-sa

Table des matières

  1. Introduction
  2. Installation
  3. Architecture
  4. Configuration de HAProxy: théorie
  5. Configuration de HAProxy: protection anti-DDOS
  6. Conclusion
  7. Sources et liens
  8. Format
  9. À propos ...
  10. License