Protéger Apache de slowloris

Slowloris est un exploit permettant de faire un DoS sur beaucoup de serveurs web (Apache 1.x, 2.x, dhttpd,…). Slowloris garde les connections vers le serveur HTTP ouvertes en envoyant des requêtes partielles et continue d’envoyer régulièrement des entêtes afin d’éviter la fermeture des sockets.

Slowloris nécessite deux modules PERL installables avec la commande :

perl -MCPAN -e ‘install IO::Socket::INET’
perl -MCPAN -e ‘install IO::Socket::SSL’

L’attaque se fait en suite avec la commande :

./slowloris -dns www.monserveur.com -port 80

Slowloris nécessite que toutes les sockets du serveurs soient libres avant de pouvoir bloquer entierement le serveur web, ce qui peut prendre un certain temps sur les sites chargés.

A l’heure actuelle, apache ne possède pas de directives de configuration permettant de se protéger contre ce genre d’attaque.

Il est possible de détecter facilement  les attaques  effectuées à l’aide de Slowloris car elles génèrent des erreurs de type « internal dummy connections » ou bien des messages  stipulant l’incapacité de lire les headers HTTP dans les logs d’apache.

Analysons deux méthodes pour se protéger :

1. Installation de  mod_antiloris sur centos & apache v2

mod_antiloris permet de se protéger contre slowloris en comptant le nombre de connexions simultanées par adresse ip et en interdisant toute nouvelle connexion ayant dépassé un nombre limite autorisé (5 par défaut).mod_antiloris fonctionne sur Apache v2

L’installation se fait par :

yum install httpd-devel
wget  ftp://ftp.monshouwer.eu/pub/linux/mod_antiloris/mod_antiloris-0.4.tar.bz2
tar jxf mod_antiloris-0.4.tar.bz2
cd mod_antiloris-0.4
apxs -a -i -c mod_antiloris.c
service httpd restart

Le nombre de requête simultanées autorisé peut être modifié via la directive ipreadlimit dans le fichier de configuration d’apache.

2. Utilisation d’iptables

Une autre façon de se protéger d’une attaque de slowloris est d’utiliser des règles iptables.
Slowloris  utilise différents port sources pour chaque connexion. De ce fait, chaque connexion est vue comme étant
nouvelle . Il est donc possible  de limiter le nombre de nouvelles connexions pour une adresse IP donnée durant un certain laps de temps.

Exemple :

iptables -I INPUT -p tcp -m state –state NEW –dport 80 -m recent –name antislowloris –set

iptables -I INPUT -p tcp -m state –state NEW –dport 80 -m recent –name antislowloris –update –seconds 10–hitcount 5 -j DROP

iptables -A INPUT -p tcp –dport 80 -j ACCEPT

Dans cet exemple, on limite le nombre à 5 nouvelles connexions par adresse IP toutes les 10 secondes et on rejette les autres paquets provenant de cette adresse IP lorsque le seuil est dépassé.

On peut cependant remarquer les limitations de ces méthodes : la protection peut générer un certain nombre de rejets indésirables sur les serveurs chargés, notamment lorsque les « clients » passent par une passerelle NAT ou un proxy pour atteindre le serveur.

Une solution plus adaptée est donc de mettre en place un reverse proxy non vulnérable en amont du serveurs apache.

3. Utilisation de HAProxy

HAProxy est un reverse proxy servant a faire du load-balancing HTTP. Il a l’avantage de ne pas être vulnérable. L’idée est la suivante : le serveur HAProxy écoute sur le port 80/TCP et redirige les requêtes sur le port 8080/TCP (port sur lequel Apache sera en écoute).

Installation de HAProxy :

wget http://haproxy.1wt.eu/download/1.3/src/haproxy-1.3.22.tar.gz
tar zxf haproxy-1.3.22.tar.gz
cd haproxy-1.3.22
make TARGET=linux26 ARCH=i386
make install

Éditons ensuite un nouveau fichier /etc/haproxy.cfg (adapté depuis l’exemple fourni ici ) :

haproxy

Pour démarrer HAProxy, il suffit de placer dans /etc/rc.local la ligne (arrêtez Apache auparavant s’il écoute sur le port 80/TCP) :

/usr/local/sbin/haproxy -f /etc/haproxy.cfg &

Il faut ensuite changer le port d’écoute d’apache dans le fichier httpd.conf pour le faire écouter sur le port 8080/TCP en lieu et place du port 80/TCP :

# Port 80
Port 8080

Pensez également à changer les éventuelles références au port 80 dans les définitions des vhosts si vous en avez.
Redémarrer apache. Il est bien évident que le port 8080/tcp ne doit pas être accessible depuis l’extérieur.

Si l’on regarde les logs apache, on s’aperçoit que toutes les requêtes proviennent de l’adresse 127.0.0.1. Normal, puisque c’est HAProxy qui relaie les requêtes.Il faut donc installer un module apache nommé mod_rpaf pour pouvoir avoir des logs apache exploitables possédant la véritable adresse IP du client :

wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz
tar zxf mod_rpaf-0.6.tar.gz
cd mod_rpaf-0.6
apxs -i -a -c mod_rpaf.c    (pour apache v1)
apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c   (pour apache v2)

Il faut ensuite modifier le fichier httpd.conf :

RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1 10.0.0.1
RPAFheader X-Forwarded-For

Et redémarrer le serveur Web.

Masquer les informations données par Apache

Deux directives permettent de masquer les informations données par Apache. Ces directives sont à placer dans le fichier httpd.conf.

Par défaut, le paramètre ServerSignature est à On. Ainsi, sur chaque page d’erreur générée par Apache, on peut y voir le numéro de version.

ServerSignatureon

En passant ServerSignature sur Off, la page devient :

signatureoff

Le second paramètre est ServerTokens, qui permet de changer ce que répond Apache dans chaque entête de requête.

Par défaut, le serveur donne son numéro de version et le système utilisé :

servertokens

En mettant ServerTokens Prod dans le fichier httpd.conf, la réponse sera :

servertokensprod