| Accueil | FAQ | Statistiques | Divers | Contact |
Sécurité : Linux : Floodmon (surveillance, alerte et mitigation des attaques SYN flood)
Floodmon est un petit daemon pour surveiller, alerter et mitiger les attaques SYN flood. Son but principal est de permettre à un serveur de continuer à accepter les connexions légitimes (HTTP, POP3 etc) malgré l'attaque en cours. Il dispose d'un système de défense à la fois passif et actif s'adaptant automatiquement à l'ampleur du flood.
Floodmon fonctionne essentiellement en manipulant les variables de la pile TCP/IP. Cela concerne l'activation/désactivation de certaines d'entre-elles, la modification de la taille des files d'attente, des timeout et retransmissions etc. Ces éléments sont modifiés en temps réel dans le pseudo-système de fichiers '/proc' tout au long d'une attaque SYN flood et suivant l'ampleur de celle-ci. Il dispose d'autres possibilités de défense comme null-router des blocs entiers d'adresses IP (/8, /16 ou /24). Il fonctionne avec 4 niveaux de protection, chaque niveau ayant sa propre configuration et peut se montrer relativement aggressif en cas de nécessité. Enfin, il peut alerter l'administrateur de toute éventuelle attaque par email et/ou SMS, envoyer un rapport détaillé de celle-ci et même y joindre une capture des segments SYN reçus pour analyse.
Le daemon, floodmon, doit être installé dans le répertoire '/usr/sbin/', rendu exécutable (chmod 0700) et accessible à 'root' uniquement (chown root:root). Son fichier de configuration 'floodmon.conf' doit être copié dans '/etc/'. Deux autres scripts sont inclus l'un pour munin-node, l'autre pour lancer floodmon automatiquement au démarrage du serveur (cf le fichier 'LISEZMOI' pour leur installation).
Modules Perl :
Le fichier de configuration 'floodmon.conf' doit être édité puis copié dans le répertoire '/etc/'.
Il contient certaines variables que vous devez configurer immédiatement après l'installation pour le bon fonctionnement du daemon. Les autres variables concernent essentiellement les niveaux d'alerte et sont configurées par défaut.
Ces variables concernent les niveaux d'alerte de floodmon. Elle sont codées par défaut dans le daemon mais peuvent être modifiées si nécessaire dans le fichier de configuration. Modifiez-les uniquement si vous êtes sûr de ce que vous faites car elles ont été optimisées et testées sous attaques réelles et simulées et se sont avérées relativement efficaces.
* Apache v1.x utilise la même variable depuis la version 1.3 mais nommée DEFAULT_LISTEN_BACKLOG et dont la longueur est fixée à 512 (cf httpd.h). Elle peut elle-aussi être modifiée par la directive ListenBacklog.
On trouve de nombreuses règles sur internet pour iptables afin de 'lutter' contre les SYN flood dont certaines sont absolument à proscrire, notamment si vous utilisez floodmon. Par exemple :
Visualiser le fichier floodmon
Si Floodmon vous a été utile et si vous souhaitez participer à son développement, vous pouvez :
Dernière version : v0.9.4 (07-01-2010) - changelog
I - Présentation :
II - Installation :
Floodmon créé un fichier log '/var/log/floodmon.log' et effectue la sauvegarde de votre configuration système avant toute modification dans le répertoire '/var/cache/floodmon/'.
III - Programmes & modules nécessaires :
- Debian : # apt-get install libtime-hires-perl
- RH/CentOS : # yum install perl-Time-HiRes
- Debian : # apt-get install libnet-pcap-perl
- RH/CentOS : # yum install perl-Net-Pcap
Programmes :
Floodmon n'utilise aucune autre commande ou utilitaire. Il n'utilise pas iptables, ni même la commande netstat puisque pour une plus grande rapidité il récupère lui-même les données de connexion directement dans '/proc/net' et '/proc/sys/net' (tout comme le fait d'ailleurs netstat).
- Debian : # apt-get install iproute
- RH/CentOS : # yum install iproute
IV - Paramètres :
floodmon :
Commandes :
--help : affiche cet écran.
--debug : exécution en mode debug, sans lancer le daemon.
--daemon : lance le daemon.
--reload : recharge le ficher de configuration (/etc/floodmon.conf).
--stop : quitte et rétablit la configuration originale (défaut).
--stop-save : quitte et laisse les modifications effectuées
(pile TCP/IP, table de routage).
--stats : affiche les statistiques réseau.
--munin-node : statistiques pouvant être utilisées avec munin-node.
--sms-test : test l'envoi d'une alerte par SMS.
--capture <num> : capture <num> paquets SYN.
--version : vérifie si une nouvelle version est disponible
* ces 5 dernières options peuvent être exécutées quel que soit le statut de floodmon (actif ou non).
V - Fichier de configuration :
Si vous effectuez des changements dans le fichier de configuration lorsque floodmon tourne, utilisez la commande # floodmon --reload afin que les changements soient pris en compte sans devoir redemarrer le daemon.
VI - Variables à configurer après l'installation :
VII - Variables facultatives :
Important : si vous utilisez floodmon avec un VPS openVZ ou Virutozzo, seules les parties MAX_SYN, LOOP_DELAY et NULLROUTE_SUBNET vous concernent. Il n'est pas possible de modifier les paramètres de la pile TCP/IP de ces VPS car ils ne disposent que d'un seul et unique kernel partagé par tous les conteneurs. Floodmon fonctionnera en mode 'light', c'est à dire monitoring, alerte et blocage des IPs.
Par défaut, 350 SYN sont tolérés (1er niveau) avant le déclenchement de l'alerte. Même si cette valeur ne semble pas très élevée, vous ne devriez pas à avoir à la modifier, sauf bien sûr si vous recevez trop de fausses alertes.
Pour les autres niveaux, le nombre de SYN_RECV tolérés est par défaut : 500 pour le 2e et 1,000 pour le 3e. Dans le 4e, la valeur de 'MAX_SYN' n'a pas d'importance puisqu'il s'agit du dernier niveau d'alerte, mais elle doit bien évidemment être supérieure à celle du 3e niveau.
Floodmon les désactive au démarrage et ne les activera que lorsqu'une attaque aura été détectée. Il faut aussi noter que même lorsqu'ils sont activés, les syncookies ne sont pas automatiquement utilisés. Ils le sont lorsque les files d'attente (tcp_max_syn_backlog et listen() ) sont presque pleines. Enfin, Linux est un OS solide ayant intégré depuis l'invention des syncookie certains mécanismes permettant de réduire considérablement l'effet d'une attaque SYN flood (minisock etc).
Cette valeur est aujourd'hui très faible comparativement à la puissance des serveurs et les débits ADSL. Floodmon l'ajuste entre 10,000 et 200,000 suivant son niveau d'alerte.
Lorsqu'une application appelle la fonction listen(), elle lui passe 2 arguments : sockfd (socket précédemment ouverte) et backlog (nombre maximal de connexions pouvant être mises en attente). Si backlog a une taille supérieure à SOMAXCONN, elle sera réduite à la valeur de SOMAXCONN.
Lors d'une attaque SYN flood, SOMAXCONN a autant d'importance que tcp_max_syn_backlog : si la file d'attente demandée par l'application est pleine et qu'il y a déjà un grand nombre de SYN dans tcp_max_syn_backlog, toute nouvelle connexion sera rejetée (cf tcp_ipv4.c).
Sous Linux, la taille de SOMAXCONN est fixée par défaut à un niveau très bas : 128 (cf socket.h). Heureusement, cette valeur est modifiable dans '/proc/sys/net/core/somaxconn'. Floodmon l'ajuste entre 10,000 et 60,000 suivant les niveaux.
Important : vous devez aussi modifier la backlog de votre serveur HTTP (Apache, Nginx etc). Pour ça, reportez-vous au paragraphe "VIII - Préparation du serveur" ci-dessous.
Lors de la réception d'un SYN, le serveur retournera un SYN/ACK. S'il n'obtient aucune réponse du client, comme dans le cas d'une attaque SYN flood, il va le retransmettre plusieurs fois. Par défaut, sous Linux, un SYN/ACK est retransmis 5 fois (cf tcp.h) : une première retransmission 3s après l'envoi du premier, puis 6s après l'envoi de la première retransmission, puis 12s après la 2e, puis 24s après la 3e et enfin 48s après la 4e. Cette dernière retransmission attendra encore 96s avant d'abandonner. Cela représente un total de 189 secondes. C'est pour cette raison que lors d'une attaque, la commande netstat affiche autant de SYN_RECV, leur time-out étant très élevé.
Pour pallier à ce problème, floodmon dès son démarrage ajuste le nombre de retransmissions à 3 (45s), valeur largement suffisante de nos jours, puis la baissera encore plus à chaque niveau d'alerte supérieur pour enfin, au dernier niveau, supprimer toute retransmission. Même si la suppression totale de retransmission peut sembler un peu rude, celle-ci est tout simplement identique à l'utilisation des syncookies qui, eux aussi, empêchent toute retransmission du paquet SYN/ACK.
Lors de son lancement, floodmon s'adaptera en fonction de la table utilisée c'est à dire soit ip_conntrack soit nf_conntrack (la première gère l'IPv4 et la deuxième l'IPv4 et l'IPv6). Si vous ne souhaitez pas utiliser la table, activez la variable NO_CONNTRACK.
Floodmon gère 3 variables relatives à cette table :
Si floodmon gère ces valeurs c'est tout simplement pour s'assurer que les SYN soient rapidement supprimés de la table afin d'éviter son débordement. Ces valeurs sont simplement ajustées en fonction de MAX_SYNACK_RETRY.
Notez que l'augmentation de cette variable et de la précédente entraine aussi une augmentation de la mémoire RAM utilisée. Au niveau 4, floodmon leur donne une valeur de 131072 ce qui représente environ 38Mo de RAM. Enfin, si vous souhaitez modifier ces valeurs, utilisez de préférence des puissances de 2 : 65536 (2^16), 131072 (2^17) etc.
Notez que floodmon récupère les données de connexion directement dans '/proc/net/' et '/proc/sys/net' sans faire appel à un programme tiers et de ce fait, même si LOOP_DELAY a une valeur très basse, il utilise peu de CPU et de RAM en dehors d'une alerte (env. 2Mo en veille).
Les IP ne sont pas bloquées individuellement, mais plutôt par bloc entier en faisant un masque de sous réseau /8, /16 ou /24 (cf la variable NETMASK). La valeur par défaut est 16, ce qui correspond à une classe B (255.255.0.0 ou, en notation CIDR, /16). S'il y a plus de NULLROUTE_SUBNET IP de cette même classe, toute la classe sera null-routée. Par exemple, si NETMASK == 16 et NULLROUTE_SUBNET = 200 et qu'il y a plus de 200 SYN provenant d'adresses IP 200.10.xx.xx, floodmon bloquera toutes les IPs de 200.10.0.0 à 200.10.255.255
Au niveau 1, cette variable est désactivée et par défaut les IP bloquées sont supprimées toutes les 10mn (variable FLUSH_FREQ du fichier 'floodmon.conf').
Pour avoir des infos sur chacune des variables, utilisez la commande # man tcp .
VIII - Préparation du serveur :
Afin de tirer le maximum de floodmon lors d'une attaque, vous devez impérativement faire attention aux points suivant :
Cette disparité des valeurs par défaut Apache/Linux est plutôt problématique : lors d'une attaque SYN flood sur le port 80, très rapidement Apache ne semble plus répondre. En fait, ce n'est pas Apache mais le kernel qui rejette les nouvelles connexions, puisque la file d'attente des SYN et celle de l'application sont toutes les deux directement liées pour la gestion des nouvelles connexions et leur rejet. Il est important de comprendre que durant toute l'attaque, Apache n'est pas sollicité (il ne sait même pas qu'il y a une attaque en cours) car, et c'est le principe du SYN flood, aucune connexion n'est établie. Les SYN restent dans la file d'attente des connexions incomplètes du kernel.
Heureusement, DEFAULT_LISTENBACKLOG peut être modifiée grace à la directive ListenBacklog qui doit être ajoutée au fichier apache2.conf (ou httpd.conf). Etant donné que floodmon donne des valeurs généreuses à SOMAXCONN et tcp_max_syn_backlog (minimum 10,000), il vous est conseillé d'augmenter largement la valeur de la backlog d'Apache tant que vous utilisez floodmon. Celle-ci dépendra de la puissance de votre serveur, du nombre de visiteurs et bien entendu d'une éventuelle attaque. Une valeur minimale de 5000 semble être assez confortable pour faire face à une attaque de moyenne envergure sur le port 80.
Editez votre fichier apache2.conf ou httpd.conf et ajoutez la valeur que vous souhaitez utiliser. Exemple avec une backlog de 5000 :
ListenBacklog 5000
Modifiez la valeur de SOMAXCONN (uniquement si floodmon ne tourne pas !) :
echo 5000 > /proc/sys/net/core/somaxconn
Puis relancez Apache.
backlog=5000
Pour plus d'info, consultez l'aide en ligne de Nginx.
Changez cette valeur, modifiez SOMAXCONN (uniquement si floodmon ne tourne pas !) et relancez Nginx.
if (-1 == listen(srv_socket->fd, 128 * 8)) {
log_error_write(srv, __FILE__, __LINE__, "ss", "listen failed: ", strerror(errno));
return -1;
}
Changez cette valeur, recompilez puis modifiez SOMAXCONN et relancez Lighttpd.
Si vous êtes victime d'une attaque sur un autre port (serveur POP3, FTP, SMTP...) consultez la documentation de ce serveur afin de voir s'il est aussi possible de changer la taille de la backlog. Dans le cas contraire, vous pouvez toujours modifier sa valeur dans le code source et recompiler (il suffit de chercher l'appel à la fonction listen() ).
Depuis la version 0.9.4, floodmon n'utilise plus iptables.
iptables -N syn-flood
iptables -A INPUT -p tcp --syn -j syn-flood
iptables -A syn-flood -m limit --limit 5/s -j RETURN
iptables -A syn-flood -j DROP
Cette règle a pour effet de limiter les nouvelles connexions TCP à 5 par secondes.
Même si un site n'accueille qu'une centaine de visiteurs uniques par jour, cette règle ne fait que leur porter préjudice, ralentissant leur connexion et nécessitant le renvoi fréquent de nouveaux paquets SYN pour tenter de se connecter et, lors d'une attaque, ces renvois incessants de paquets ne feront qu'aggraver le flood en cours. Sans oublier que la limitation du SYN ne concerne pas que le serveur HTTP mais tout le protocole TCP (POP3, SMTP, FTP etc). Un attaquant pourrait simplement envoyer un flux de 10 SYN par seconde, soit une bande passante ridicule d'environ 80bits/s, pour monopoliser totalement l'accès au serveur et vous n'auriez même plus la possibilité de vous y connecter en SSH. En d'autres termes, un script-kiddie pourrait 'flooder' le firewall du serveur avec son iPhone...
Vous devez supprimer cette règle si vous l'utilisez, floodmon gèrera l'attaque bien mieux qu'elle tout en essayant de laisser les visiteurs accéder au site. Et s'il n'est plus en mesure de le faire en cas d'attaque beaucoup trop violente, aucun script ou logiciel ne pourra le faire non plus et le dernier mot reviendra à votre hébergeur : null-router l'IP de votre serveur. Sauf si vous disposez de plus de puissance et de bande passante que l'attaquant, mais généralement, ce n'est jamais le cas :(
IX - Téléchargement :
floodmon.tgz - v0.9.4 - 26 Ko - (changelog)
X - Listing du code du daemon :
XI - Utilisateurs de Floodmon :
- configuration de votre serveur (CPU, RAM, bande passante etc)
- l'ampleur de l'attaque subie (nombre de Kbits/s ou Mbits/s)
- joindre le fichier log (/var/log/floodmon.log)
- vos commentaires et/ou problèmes rencontrés
![]()