mardi 9 juin 2009

Contrer une attaque DDOS de type SYN flood sous Linux

Une attaque par déni de services SYN flood est une technique visant à saturer un serveur en envoyant une multitude de paquets TCP, avec le flag SYN. Les connexions sont alors établies vers la machine, mais restent à moitié ouvertes, car le client malveillant (hacker) ne renvoie pas de confirmation (ACK).

Le serveur attend pendant un certain délai la réponse et la connexion semi-ouverte consomme alors un certain nombre de ressources. En multipliant ce type de connexions, le hacker peut arriver à créer un déni de service qui rendra la machine inopérante.

1. Détection d'une l'attaque DDOS SYN flood

Pour détecter la présence de l'attaque, il faut utiliser la commande netstat et repérer la présence des connexions de type SYN_RECV :

# netstat -an | grep SYN
tcp 0 0 10.xxx.xxx.xxx 237.177.154.8:25882 SYN_RECV -
tcp 0 0 10.xxx.xxx.xxx 236.15.133.204:2577 SYN_RECV -
tcp 0 0 10.xxx.xxx.xxx 127.160.6.129:51748 SYN_RECV -
tcp 0 0 10.xxx.xxx.xxx 230.220.13.25:47393 SYN_RECV -

2. Contrer une attaque DDOS SYN flood

La dernière commande renvoie plusieurs dizaines de résultats. L'attaque par SYN flood est donc confirmée. Pour la contrer une solution consiste à modifier quelques paramètres du noyau Linux à chaud. Voici les commandes à utiliser en root uniquement :

echo "1" > /proc/sys/net/ipv4/tcp_syncookies
echo "1024" > /proc/sys/net/ipv4/tcp_max_syn_backlog
echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter

Quelques explications :

  • La première ligne fait en sorte que la machine ne garde pas en mémoire les demandes de connexion semi-ouverte tant qu'elle n'a pas reçu la confirmation ACK
  • La deuxième commande positionne à 1024 le nombre maximum de SYN_WAIT
  • Enfin, la variable rp_filter permet de vérifier qu'un paquet arrive bien par l'interface sur laquelle il devrait arriver

Il est possible de paramétrer ses valeurs de façon permanente en modifiant le fichier /etc/sysctl.conf :

# Protection SYN flood
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_max_syn_backlog = 1024

On pourra ensuite recharger la configuration avec la commande :

sysctl -p /etc/sysctl.conf

Ajouter une ligne au début ou à la fin d’un fichier texte sous Linux

Cet article explique comment insérer une chaîne de caractères au début ou à la fin d’un fichier texte. Cette astuce sera particulièrement utile lors d’un développement de script shell par exemple.

1. Ajouter une ligne en début de fichier

Pour insérer une ligne au début d'un fichier, il faudra utiliser la commande sed. Voici un exemple d'utilisation :

[sbilbeau@localhost ~]$ cat test.txt
ligne2
[sbilbeau@localhost ~]$ sed -i '1iLigne1' test.txt
[sbilbeau@localhost ~]$ cat test.txt
ligne1
ligne2

On notera l'utilisation du code 1i au début de la chaîne à insérer. Le chiffre 1 indique à sed d'insérer cette phrase sur la première ligne.


2. Ajouter une ligne en fin de fichier

Ajouter une ligne à la fin d'un fichier est une opération beaucoup plus simple sous Linux. Il suffit d'utiliser l'opérateur ">>" pour réaliser ceci. Voici un exemple d'utilisation :

[sbilbeau@localhost ~]$ cat test.txt
ligne1
[sbilbeau@localhost ~]$ echo "ligne2" >> test.txt
[sbilbeau@localhost ~]$ cat test.txt
ligne1
ligne2

Développer son propre module noyau sous Linux

Cet article explique comment coder son propre module noyau sous Linux. Il s’adresse aux débutants et ne nécessite pas forcément beaucoup de connaissances en programmation.

1. Les pré-requis

Pour pouvoir développer son propre module noyau, il vous faudra disposer du paquet kernel headers et d'un compilateur de langage c comme gcc par exemple.

Pour installer ces différents composants, ouvrez un terminal en root et lancez la commande suivante pour une distribution à base de rpm :

yum install kernel-headers gcc

Ou celle-ci pour une distribution à base de Debian :

sudo aptitude install linux-headers-`uname -r` build-essential


2. Le développement d'un module noyau

Voici un exemple assez simple de code source d'un module noyau. Celui-ci affiche simplement un "Hello world" à l'initialisation et un "Goodbye world" lors du déchargement du module. Le nom du fichier contenant ce code s'intitulera hello.c :

#include
#include

#define DRIVER_AUTHOR "Sebastien Bilbeau"
#define DRIVER_DESC "My First module"

int init_module(void) {
printk(KERN_INFO "Hello world.\n");
return 0;
}

void cleanup_module(void) {
printk(KERN_INFO "Goodbye world\n");
}

MODULE_LICENSE("GPL"); // La licence du module
MODULE_AUTHOR(DRIVER_AUTHOR); // L'auteur du module
MODULE_DESCRIPTION(DRIVER_DESC); // La description du module


3. La compilation du module

Pour compiler le module, lancez la commande suivante. Si tout se passe bien, un fichier hello.ko sera alors créé :

chmod 755 hello.c
make -C `ls -d /lib/modules/$(uname -r)/build` M=`pwd` modules


4. L'utilisation du module

Attention, pour manipuler un module, il faut nécessairement avoir les droits root. Pour le charger, il faudra utiliser la commande insmod comme ceci :

insmod hello.ko

On pourra vérifier qu'il est bien chargé en utilisant lsmod :

lsmod | grep hello

Si vous souhaitez afficher les informations relatives au module :

[root@localhost ~]# modinfo hello.ko
filename: hello.ko
description: My First module
author: Sebastien Bilbeau
license: GPL

Dans le code de hello.c, nous avons utilisé la fonction printk, qui permet d'écrire un message dans le fichier /var/log/message. Nous allons donc maintenant observer le résultat de notre petit programme :

[root@localhost ~]# cat /var/log/messages | grep -i hello
Jan 19 23:21:03 localhost kernel: Hello world.

Enfin, on pourra décharger le tout avec la commande rmmod :

rmmod hello.ko

Vous connaissez désormais les bases du développement des modules noyau pour Linux.