2.3. Ajustements système

2.3.1. Sysctl

sysctl permet de modifier le comportement du système en ajustant certains paramètres du noyau. Ces paramètres sont disponibles :

  • soit sous /proc/sys/

  • soit grâce à l'outil sysctl

A titre d'exemple, mettre le paramètre ip_forward à la valeur 1 peut se faire de deux manières :

  • via sysctl : sysctl -w net.ipv4.ip_forward=1

  • en modifiant le fichier : echo 1 > /proc/sys/net/ipv4/ip_forward

Pour que ces paramètres soient appliqués au démarrage du système, on met généralement les valeurs à configurer dans le fichier /etc/sysctl.conf.

sysctl permet aussi d'afficher la valeur d'un paramètre actuellement en vigueur (sysctl param), voire la totalité des paramètres (sysctl -a).

oper@ubuntu:~$ sudo sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
oper@ubuntu:~$ sudo sysctl -a
...
net.ipv4.ip_forward = 0
...
oper@ubuntu:~$ 

Certaines valeurs sont parfois disponibles sous les variables all, default, ou un nom d'interface. Par exemple, rp_filter existe dans les variables net.ipv4.conf.all.rp_filter, net.ipv4.conf.default.rp_filter, net.ipv4.conf.eth0.rp_filter, etc... all permet de fixer la valeur pour toutes les interfaces. Si un interface reçoit une valeur explicite via, par exemple, net.ipv4.conf.eth0.xyz, c'est cette dernière qui sera utilisée. default permet de définir une valeur par défaut qui sera utilisée si une nouvelle interface est créée dynamiquement (carte PCMCIA ou dispositif USB par exemple).

D'une manière générale, il conviendra, lorsque une valeur est donnée pour all, d'appliquer la même valeur à default.

Quelques optimisations intéressantes sont décrites ci-dessous. Même si la valeur par défaut est donnée pour chacune d'entre elles, il vaut mieux ne pas présumer des valeurs par défaut et renseigner systématiquement /etc/sysctl.conf.

2.3.1.1. SYN protection

Pour établir une connexion TCP, les deux parties doivent passer par le « three-way handshake » : le client envoie un paquet TCP vide avec le drapeau SYN, le serveur répond avec un paquet contenant les flags ACK (pour acquitter le premier SYN) et SYN (son propre drapeau de SYNchronisation). Le client achève l'établissement de la connexion en envoyant le troisième et dernier paquet contenant simplement un acquittement (ACK) du SYN serveur.

Tout cela fonctionne bien tant que le processus d'établissement de connexion va à son terme. Si le « 3-way handshake » n'est pas complété, la connexion reste à moitié ouverte. Aux débuts de TCP/IP, ce n'était pas perçu comme un problème : il n'y avait pas de malveillance. La plupart des piles TCP/IP se contentaient alors d'avoir une queue de SYN (« SYN backlog ») de quelques entrées, généralement autour de 8. En clair, le système ne pouvait maintenir que 8 connnexions en cours d'établissement.

Il est apparu rapidement que cette manière de fonctionner était problématique. Effectuer un déni de service était particulièrement trivial en remplissant le « backlog » de connexions à moitié ouvertes (« SYN flooding »).

Pour résoudre ce problème, plusieurs techniques sont utilisées sous Linux. Par défaut, Linux utilise une FIFO (« SYN backlog »). Lorsque la file de connexions en attente est pleine, les plus anciennes sont supprimées. Si la réponse (ACK) du client arrive après que la demi-connexion ait été supprimée, un paquet RST sera émis et la connexion sera (normalement) retentée par le client. Le backlog sous Ubuntu est de 1024 entrées.

L'autre possibilité est d'activer les « syncookies ». Les « syncookies » désignent un mécanisme permettant de générer un numéro de séquence initial (ISN) dans la réponse au client (SYN+ACK). Cet ISN est construit de telle sorte qu'il n'est pas nécessaire de conserver l'information du SYN initial afin de valider que le dernier paquet du 3-way handshake est correct (voir [SynDJB] et [SynWiki]).

Beaucoup d'encre et de sang (voir « SYN cookie monsters » dans [SynWiki]) ont coulé autour des syncookies, en particulier concernant leur utilisation sur des serveurs chargés. Cependant, il vaut probablement mieux les activer en toutes circonstances. A part dans des cas de congestion extrème, il sont probablement la meilleure réponse au problème du « syn flooding ».

Les syncookies sont pilotés par la variable net.ipv4.tcp_syncookies. Elle est à 0 par défaut, il faut donc ajouter la ligne suivante dans /etc/sysctl.conf.

net.ipv4.tcp_syncookies = 1

2.3.1.2. ICMP echo

Il est possible d'empécher la pile IP de répondre aux ICMP echo requests. Il est probablement préférable d'utiliser netfilter pour limiter le volume d'icmp echo requests (c'est ce qui sera implémenté dans la section dédiée au filtrage, Section 2.4.2, « Résolution DNS »). En effet Supprimer complètement l'émission d'icmp echo replies viole la RFC 792 (voir [RFC792]) :


3.2.2.6  Echo Request/Reply

            Every host MUST implement an ICMP Echo server function that
            receives Echo Requests and sends corresponding Echo Replies.

ainsi que la RFC 1812 ([RFC1812]) au choix, selon que net.ipv4.ip_forward soit à 1 ou non :


4.3.3.6 Echo Request/Reply

A router MUST implement an ICMP Echo server function that receives
Echo Requests sent to the router, and sends corresponding Echo
Replies. 

Par ailleurs, cela n'apporte absolument rien en terme de sécurité. L'époque des « ping de la mort » est révolue. Ignorer les paquets ICMP ne règle pas les problèmes de saturation réseau, de pile IP bogguée ou de trou de la couche d'ozone... Enfin, se cacher ne résoud pas les problèmes de sécurité... Si malgré tout, le blocage complet est requis, il suffit de mettre la variable net.ipv4.icmp_echo_ignore_all à la valeur 1.

[Attention]Variable net.ipv4.icmp_echo_ignore_all

Mettre net.ipv4.icmp_echo_ignore_all à 1 viole les RFC 792 et 1812 ! Il est très fortement conseillé de recourir au rate limiting ICMP à la place.

2.3.1.3. ICMP redirects

Le paquets ICMP redirects permettent aux routeurs de prévenir des hôtes qu'une meilleure route est disponible et qu'ils peuvent l'utiliser. Un paquet ICMP redirect contient la nouvelle gateway que l'hôte doit utiliser.

Sur un réseau bien configuré, l'ICMP redirect est inutile. De plus, l'utilisation de l'ICMP redirect pourrait permettre d'injecter des routes dans les tables de routages des hôtes. Il est donc conseillé de supprimer l'acceptation (net.ipv4.conf.all.accept_redirects) et l'émission (net.ipv4.conf.all.send_redirects) de paquets ICMP redirect.

Enfin, la variable net.ipv4.conf.all.secure_redirects, lorsqu'elle est à 1, permet d'accepter les ICMP redirect depuis une gateway listée comme telle. Il est aussi conseillé de passer cette valeur à 0. Attention : la configuration par défaut fait exactement l'inverse pour toutes ces variables.

2.3.1.4. ICMP echo broadcasts

Les paquets ICMP echo request envoyés en broadcast permettent de facilement « pinguer » toutes les machines d'un sous réseau. Même si cette fonctionnalité (qui tient tout de même de l'effet de bord) peut sembler pratique, il est déconseillé de l'activer. L'effet d'amplification induit peut poser des problèmes de déni de service « smurf attacks » (voir http://en.wikipedia.org/wiki/Smurf_attack). Il est donc préférale de mettre la variable net.ipv4.icmp_echo_ignore_broadcasts à 1.

2.3.1.5. Bogus ICMP

Le noyau, par défaut, loggue les paquets ICMP malformés (code d'erreur inconnu). Logguer ces paquets induit une écriture sur le disque. Cela peut permettre à un attaquant d'effectuer un déni de service en remplissant les logs de messages

kernel: XX.XX.XX.XX sent an invalid ICMP type T, code C...

L'accumulation de ces messages peut finir par remplir le filesystem et accueillant les logs. Il est donc préférable de simplement ignorer ces erreurs en affectant 1 à net.ipv4.icmp_ignore_bogus_error_responses. Si nécessaire, on pourra traiter ces messages avec d'autres applications plus spécialisées.

2.3.1.6. Source routing

Le « source routing » permet de spécifier (à l'intérieur même d'un paquet IP) les passerelles par lesquelles doit transiter ce paquet. C'est à proscrire. Les implications en termes de sécurité sont multiples (spoofing, network ingerprinting, etc...). net.ipv4.conf.all.accept_source_route doit donc être à 0.

[Avertissement]Source routing

Il n'y a aucune raison valable d'utiliser le « source routing ». Le laisser activé est extrèmement dangereux. Si l'on désire vraiment s'affranchir de la topologie de routage, on utilisera un VPN.

2.3.1.7. Défragmentation IP

Si la machine configurée doit servir de passerelle NAT (masquerading ou SNAT), il faut activer l'option net.ipv4.ip_always_defrag. Cette dernière force la passerelle à effectuer le réassemblage de paquets pour ses clients. Comme la passerelle maitient une table de correspondance qui s'appuie sur les ports source/destination des paquets, un fragment (en dehors du premier) ne pourra pas être dé-NATé, puisqu'il contient une portion du paquet qui ne contient plus ces informations.

2.3.1.8. Spoofing

La variable net.ipv4.conf.all.rp_filter permet de vérifier qu'un paquet arrive bien par l'interface sur laquelle il devrait arriver. Par exemple, si mon interface eth0 est 192.168.0.1/24 et que je recois un paquet avec l'IP source 192.168.0.34 sur eth1, ce paquet sera rejeté puisqu'il ne peut arriver sur cette interface. De même, 127.0.0.1 est une adresse source invalide pour un paquet arrivant sur une interface autre que la loopback (lo).

Par défaut, cette fonction est désactivée. Il faut donc activer net.ipv4.conf.all.rp_filter en mettant sa valeur à 1 dans /etc/sysctl.conf.

2.3.1.9. Logguer les martiens

Les « martiens » sont des paquets ayant des adresses sources ou destination invalides (voir [RFC1812], « 5.3.7 Martian Address Filtering », p.96) . Les paquets source routés (Section 2.3.1.6, « Source routing ») et spoofés (Section 2.3.1.8, « Spoofing ») refusés seront aussi loggés grâce à cette règle. Linux permet de logguer les martiens en mettant la valeur 1 dans la variable net.ipv4.conf.all.log_martians.

2.3.1.10. Fichier sysctl.conf

Le fichier ci-dessous donne une exemple de base de fichier sysctl.conf, à ajuster au besoin en fonction de la machine sur laquelle il sera implanté.

## On loggue le trafic bizare
#
# Log des martiens
#
net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.log_martians = 1

## Source routing
#
# Refus des paquets source-routés
# 
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_source_route = 0

#
# On n'envoie pas de paquets avec 
# des options de source routing
#
net.ipv4.conf.default.mc_forwarding = 0
net.ipv4.conf.all.mc_forwarding = 0

## ICMP
#
# Ignorer les paquets ICMP redirect
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
#
# Pas d'envoi d'ICMP redirect
#
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.send_redirects = 0

## IP forwarding
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !! Ajuster au besoin         !!
# !! Un routeur doit forwarder !!
# !! Un hôte non               !!
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#
net.ipv4.conf.default.forwarding = 0
net.ipv4.conf.all.forwarding = 0
net.ipv4.ip_forward = 0

## Divers
#
# Reverse path : vérification de la cohérence
# interface d'entrée / table de routage
#
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1

#
# Par de relais bootp/dhcp
#net.ipv4.conf.default.bootp_relay = 0
net.ipv4.conf.all.bootp_relay = 0

## ARP
#
# Pas de proxying ARP
# 
net.ipv4.conf.default.proxy_arp = 0
net.ipv4.conf.all.proxy_arp = 0

#
# Taille maximum de la table ARP
# 
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !! Ajuster au besoin         !!
# !! En fonction de la taille  !!
# !! Du subnet occupé          !!
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#
net.ipv4.neigh.default.gc_thresh3 = 256

#
# Limite au dela de laquelle le nettoyage de la table ARP
# sera engagé
#
net.ipv4.neigh.default.gc_thresh2 = 256

#
# Limite en dessous de laquelle le nettoyage de la table ARP
# sera stoppé
#
net.ipv4.neigh.default.gc_thresh1 = 32

#
# Intervalle de nettoyage de la table ARP
#
net.ipv4.neigh.default.gc_interval = 30

2.3.2. IPv6

2.3.2.1. Un peu tôt ?

IPv6 est installé et activé par défaut sur toutes les distributions. Son intérêt est cependant limité. Il n'y a aucune raison d'activer IPv6 tant que le site n'a pas de connectivité IPv6 ou que ce site n'expérimente pas IPv6 explicitement.

[Note]Epuisement des adresses IPv4

L'épuisement des adresses IPv4 est annoncé depuis longtemps. En particulier par les promoteurs d'IPv6. Mais aujourd'hui, la date semble plus proche que jamais : plusieurs études ([Potaroo2007], [Hain2007]) s'accordent sur mars 2010. D'ici là, il faudra maitriser les masques sur 64 bits et les adresses sur 128 !

Laisser IPv6 activé c'est prendre le risque de s'exposer à de nouveaux problèmes. Ce protocole étant relativement nouveau, les problèmes d'implémentation ou même de design apparaîssent progressivement ([v6SrcRoute]).

Si malgré tout IPv6 reste activé, il faudra se poser la question de son filtrage périmétrique (sur le périmètre réseau) et sur chaque machine. En effet, par défault, il n'y a aucun filtrage. Chaque interface IPv6 ayant (ou pouvant avoir) plusieurs adresses (link local, site scope, global scope) le filtrage est plus délicat à mettre en œuvre.

2.3.2.2. Désactiver IPv6

IPv6 peut être désactivé dans le fichier /etc/modprobe.d/aliases. Il faut remplacer la ligne :

alias net-pf-10 ipv6

par

alias net-pf-10 off

IPv6 ne sera alors plus activé au prochain redémarrage.

Une autre possibilité consiste à ajouter la ligne

blacklist ipv6

dans un fichier que l'on mettra dans /etc/modprobe.d/. Cette option est plus propre : si nous devons effectuer un upgrade du package module-init-tools, le fichier /etc/modprobe.d/aliases ne sera pas mis à jour si nous l'avons modifié. Cela peut être ennuyeux si la mise à jour nécessite d'introduire des alias pour les pilotes.

oper@ubuntu:~$ sudo -i
Password:****
root@ubuntu:~# cat > /etc/modprobe.d/blacklist-perso
blacklist ipv6
blacklist pcspkr^D
root@ubuntu:~# cat /etc/modprobe.d/blacklist-perso
blacklist ipv6
blacklist pcspkr
root@ubuntu:~# logout
oper@ubuntu:~$