Cisco a développé il y a quelques années une fonctionnalité très pratique pour ses routeurs : le Reverse Path Forwarding. Celle-ci spécifiait que chaque paquet arrviant sur une interface soit testé afin de vérifier que l'interface de réception correspondait bien au plus court chemin du routeur à la source. Dans le cas contraire, le paquet était considéré comme illégitime et rejeté. En quoi cela protège-t-il du spoofing ? Selon les critères de RPF, un paquet forgé avec pour adresse source celle d'un réseau directement connecté à la passerelle, sera vu comme illégitime, c'est-à-dire n'empruntant pas la bonne interface qui représente le chemin le plus court.

Devant l'intérêt suscité par cette fonctionnalité, il n'a pas fallu attendre longtemps pour en retrouver des équivalents dans le logiciel libre. L'importance d'une telle commande est de simplifier le travail de l'administrateur en remplaçant aisément les configurations complexes nécessaires auparavant pour atteindre le même but. En effet, sur tout firewall gérant correctement les opérateurs logiques, il sera possible d'écrire une règle empêchant tous paquets marqués d'une certaine adresse de passer par autre chose que l'interface à laquelle cette adresse est normalement attachée. Par exemple, en suivant une syntaxe type IPF (ou PF), la configuration serait telle que ci-dessous (avec extif l'interface externe et subnet le réseau privé) :

block drop in on !$extif inet from $subnet to any

Depuis Linux 2.4, vous pouvez activer une telle fonctionnalité par interface via les variables disponibles dans /proc/sys/net/ipv4/conf/. Pour Linux, si l'interface par laquelle le paquet analysé est censé sortir ne correspond pas à celle par lequel il rentre, alors il est considéré comme invalide et rejeté. Concrètement, cela revient à vérifier dans la table de routage si ce paquet entre bien par l'interface directement connectée à son réseau d'origine.

Pour l'activer dans une interface donnée, exécutez la ligne suivante :

# echo "1" > /proc/sys/net/ipv4/conf/<interface>/rp_filter

Où 'interface' est à remplacer par le nom de l'interface. Pour étendre cette configuration à l'ensemble de vos interfaces, remplacez 'interface' par 'default“ ou 'all'. Enfin, pour la rendre persistante, il vous faudra ajouter cette commande sous forme de script à /etc/rc.d/init.d/.

Pour détecter quels paquets sont effectivement rejetés, afin de corriger éventuellement une configuration indésirable, ajoutez également cette entrée :

# echo "1" > /proc/sys/net/ipv4/conf/<interface>/log_martians

Pour étendre cette configuration, suivez les mêmes instructions que pour rp_filter. Plus de détails dans le Linux Advanced Routing & Traffic Control (LARTC) Howto.

Pour ce qui est de FreeBSD, la ré-implémentation d'IPFW, sous le nom IPFW2, a vu l'ajout - dans FreeBSD 4.8 avec l'option IPFW2, ou dans -CURRENT avec l'option IPFW classique - du mot-clé 'verrevpath', référence directe à la commande correspondante chez Cisco. Son fonctionnement est le suivant : pour chaque paquet correspondant aux règles affublées de verrevpath, ipfw vérifie, au sein de la table de routage, si l'interface, par laquelle un paquet entre, coincide avec celle liée à la route vers le réseau d'origine du paquet. Par précaution, tous les paquets sortant ou bien ceux qui ne possèdent pas d'interface de sortie correspondante à leur adresse source (c'est-à-dire venant d'un réseau non directement connectée) passent le test.

Un règle ipfw appliquant cette sécurité à tous les paquets entrant dans un réseau ressemblera à celle qui suit, avec extif représentant l'interface d'entrée :

ipfw add 100 pass log all from any to any via ${extif} verrevpath

Le dernier à suivre ce mouvement fut OpenBSD, avec PF. Depuis la release 3.3, celui-ci dispose du mot-clé 'antispoof' sur lequel vous trouverez des informations complètes dans pf.conf(5). La commande type IPF que nous avons vu plus haut, peut désormais être remplacée, dans pf.conf, grâce à antispoof, de la façon suivante :

antispoof for $extif inet

Outre la vérification qu'aucun paquet ayant pour source une adresse du réseau auquel est attachée une certaine interface (ici extif) ne sorte pas une autre, une seconde protection, spécifique à OpenBSD, est ajoutée en rejetant complétement tout paquet ayant pour source l'adresse de l'interface protégée. Elle remplace donc aussi la règle suivante, où 192.168.0.1 correspondait à l'interface protégée :

block drop in inet from 192.168.0.1 to any

Notez que les applications qui communiquent avec les interfaces locales via l'interface loopback peuvent se trouver perturbées, comme précisé dans la man page pf.conf(5). Pensez alors à ajouter une règle autorisant explicitement les transmissions depuis l'interface de loopback. Cette complication s'applique certainement aux autres implémentations libres qui utilisent strictement le même mécanisme de décision (Linux et FreeBSD).

L'autre problème majeur que vous pouvez rencontrer avec RPF sera le rejet de paquets légitimes à cause des routes asymétriques auxquelles peuvent conduirent les protocoles de routage dynamique. Pour cette raison, il sera préférable de n'appliquer RPF que pour des adresses d'un réseau directement connecté (donc sur des interfaces privées) et d'enregistrer les paquets rejetés afin de pouvoir déteter un tel problème.

–eberkut PS subliminal : “BUGfr est ton ami, tu aimes BUGfr. Tu veux fai'e l'amou' à BUGf'.”

unix/antispoof.txt · Last modified: 2010/01/12 13:29 (external edit)