jeremm

Jérémy MURIEL ( jeremy [at] jeremm [dot] fr )

Avr 172012
 

– Vider tout le cache (script PHP) :

<?php
        exec('echo "ban.url /*" | nc -q 1 127.0.0.1 6082');
?>

– Vider le cache d’un vhost (script BASH) :

#!/bin/bash
 
if [ ! -z $1 ] ; then
        case "$1" in
                -h|--help) echo "Usage ./clear_cache.sh HOST"; echo "For example HOST : exemple.com" ; exit 1 ;;
                *) HOST=$1;;
        esac ;
else
        echo "Usage ./clear_cache.sh HOST"; echo "For example HOST : exemple.com" ; exit 1 ;
fi
echo "ban req.http.host ~ \"$HOST\"" | nc -q 1 127.0.0.1 6082 &> /dev/null
echo "$HOST cleared"

– Vider le cache d’une URI (script BASH) :

#!/bin/bash
url="/*"
if [ ! -z $1 ] ; then
        case "$1" in
                -h|--help) echo "Usage ./clear_cache.sh URL"; echo "For example URL : /accueil" ; echo "URL= /* if argument missing"; exit 1 ;;
                *) url=$1;;
        esac ;
fi
echo "ban.url $url" | nc -q 1 127.0.0.1 6082 &> /dev/null
echo "$url cleared"

– Vider le cache d’un host avec une URL (configuration varnish) :

acl purge {
        "W.X.Y.Z";
}
sub vcl_recv {
     if (req.url ~ "^/purge-cache$") {
        if (!client.ip ~ purge) {
                error 405 "Not allowed.";
        }
        ban("req.http.host == " + req.http.host + " && req.url ~ .*");
        error 200 "Banned.";
     }
}

Pour rachaîchir, ouvrir http://www.exemple.com/purge-cache

– Rafraichir un objet avec une requête REFRESH (configuration varnish) :

sub vcl_recv {
     if (req.request == "REFRESH") {
        set req.hash_always_miss = true;
        set req.request = "GET";
     }
}

Commande pour rachaîchir :

curl -X REFRESH --header 'accept-encoding: gzip' -o /dev/null http://www.exemple.com/

– Purge une url complète quelque soit le host, les cookies,etc (configuration varnish) :

sub vcl_recv {
     if (req.request == "PURGE") {
        ban("req.url ~ " +  req.url);
        error 200"Purged url " + req.url ;
     }
}

Commande pour rachaîchir :

curl -I -X PURGE http://www.exemple.com/url_a_purge

– Rafraichir un site à partir d’une IP client (configuration varnish) :

acl purge {
        "W.X.Y.Z";
}
sub vcl_recv {
     if (client.ip ~ purge) {
        set req.hash_always_miss = true;
     }
}

– Rafraichir un site à partir d’une IP serveur secondaire (configuration varnish) :

acl purge {
        "W.X.Y.Z";
}
sub vcl_recv {
     if (server.ip ~ purge) {
        set req.hash_always_miss = true;
     }
}

Modifier votre etc/hosts pour pointer votre site sur l’IP secondaire de rafraîchissement

Avr 022012
 

Pour se protéger des attaques SYN FLOOD :

Limiter le nombre de connexions parallèles par IP :

iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 -j DROP

Pour se protéger des attaques par SYN FLOOD et QUERY FLOOD :

Limiter le nombre de connexions par seconde par IP (exemple 20 maximum sur 10 secondes sur le port 80):
Le Hitcount ne doit pas être supérieur à 20

iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 10 --hitcount 20 -j DROP

Plus radical, limiter le nombre de paquet syn par seconde :

iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 13 -j DROP

Ou limiter le nombre de paquet syn par seconde par range d’ip (exemple /28) :

iptables -A INPUT -p tcp --dport 80 --tcp-flags SYN SYN -m hashlimit --hashlimit-name Web \
--hashlimit-above 10/second --hashlimit-mode srcip --hashlimit-burst 13 --hashlimit-srcmask 28 -j DROP

Pour bloquer une requête HTTP :

iptables -I INPUT -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t' -j DROP

Pour log les IPs qui flood ajouter :

iptables -N flood
iptables -A flood -j LOG --log-prefix "FLOOD "
iptables -A flood -j DROP

et remplacer DROP par flood aux règles précédentes

Mar 062012
 

Installation debian de la dernière version :

curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -
echo "deb http://repo.varnish-cache.org/debian/ squeeze varnish-3.0" >> /etc/apt/sources.list.d/varnish.list
apt-get update
apt-get install varnish

Modification du /etc/default/varnish pour y mettre :

START=yes
NFILES=131072
MEMLOCK=82000
DAEMON_OPTS="-a :80 \
             -T :6082 \
             -f /etc/varnish/default.vcl \
                -s malloc,4g
                -p thread_pools=8 \
                -p thread_pool_max=4000 \
                -p thread_pool_min=100 \
                -p thread_pool_add_delay=2 \
                -p default_grace=300 \
                -p default_ttl=300 \
                -p ban_lurker_sleep=0.01"

Paramètres à modifier :

  • NFILES : maximum openfiles (utilisé pour faire un ulimit -n au démarrage)
  • MEMLOCK : mémoire partagée maximum pour les cores/threads (utilisé pour faire un ulimit -l au démarrage)
  • -a : port d’écoute de Varnish
  • -T : port d’écoute de l’administration
  • -f : fichier de configuration des routines et des backends
  • -s malloc : cache en ram avec une taille (en octets)
  • -p thread_pools : nombre de core
  • -p thread_pool_min : 800/nombre de core
  • -p thread_pool_max : nombre maximum de thread
  • -p thread_pool_add_delay : temps d’attente qu’un thread se libère avant d’en démarrer un supplémentaire (en ms)
  • -p default_grace : temps que les objets reste en cache après le ttl si le ou les backends ne sont pas disponibles
  • -p default_ttl : temps de rafraichissement des objets par défaut
  • -p ban_lurker_sleep : temps entre chaque passage du ban lurker pour nettoyer les vieux objets en cache et ainsi nettoyer la liste des bans
Mar 062012
 

Vous pouvez limiter l’accès à un site ou une partie du site avec Varnish.
C’est utile car les limitations par IP au niveau Apache2 ne fonctionne pas avec Varnish, car les IPs clients détectées sont celle du Varnish.
Ajoutez une acl avec la liste de vos IPs autorisées.

acl iplimit {
        {"1.2.3.4"};
        {"9.8.7.6"};
}

Ensuite ajoutez dans le vcl_recv par exemple :

if (!(client.ip ~ iplimit)) {
        return(error);
}
Mar 062012
 

Ajoutez dans vcl_recv :

if(req.http.cookie !~ "wordpress_logged_in" ) {
        set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-(1|2)=[^;]+(; )?", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-(1|2)=[^;]+(; )?", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "comment_author_[a-z0-9]+=[^;]+(; )?", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "comment_author_email_[a-z0-9]+=[^;]+(; )?", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "comment_author_url_[a-z0-9]+=[^;]+(; )?", "");
        if (req.http.cookie ~ "^$") {
                unset req.http.cookie;
        }
}