Table des matières Page précédente Page suivante

III-10 Autres astuces

III-10-1 Règles par défaut ("Policy")

Jusqu'à présent, nous avons vu que nous devions initialiser et définir les règles par défaut de ta table "Filter", et parfois celles de la table "NAT". En fait, ce n'est pas tout à fait la bonne manière de faire. A supposer par exemple que vous voulez faire uniquement du filtrage (option "-t filter"), vous pouvez très bien avoir laissé quelques règles de PREROUTING ou de POSTROUTING activées dans la table NAT. Dans ce cas, vous ne savez pas forcément ce que fait Netfilter, et il se peut qu'avec de telles configurations, il laisse passez des trames sans que vous ne vous en doutiez.

Donc il est est primordial que la première chose que vous fassiez dans un script Netfilter, c'est d'initialiser toutes les tables ("Filter", "NAT" et "Mangle") :
[root@phoenix /]# iptables -t filter -F
[root@phoenix /]# iptables -t filter -X
[root@phoenix /]# iptables -t filter -P INPUT   DROP
[root@phoenix /]# iptables -t filter -P FORWARD DROP
[root@phoenix /]# iptables -t filter -P OUTPUT  DROP
[root@phoenix /]# iptables -t nat -F
[root@phoenix /]# iptables -t nat -X
[root@phoenix /]# iptables -t nat -P PREROUTING  ACCEPT
[root@phoenix /]# iptables -t nat -P OUTPUT      ACCEPT
[root@phoenix /]# iptables -t nat -P POSTROUTING ACCEPT
[root@phoenix /]# iptables -t mangle -F
[root@phoenix /]# iptables -t mangle -X
[root@phoenix /]# iptables -t mangle -P PREROUTING  ACCEPT
[root@phoenix /]# iptables -t mangle -P INPUT       ACCEPT
[root@phoenix /]# iptables -t mangle -P FORWARD     ACCEPT
[root@phoenix /]# iptables -t mangle -P OUTPUT      ACCEPT
[root@phoenix /]# iptables -t mangle -P POSTROUTING ACCEPT
Vous remarquerez que l'on définie à "ACCEPT" les règles par défaut des tables "NAT" et "Mangle". Cela n'a pas trop d'influence sur la sécurité, du moment que vos règles de FORWARD sont bien écrites. Sinon, vous pouvez les mettre à "DROP", mais cela rallongera énormément le code et le temps de développement de votre script Netfilter.

Ce n'est pas non plus une mauvaise chose que de désactiver en début de script, au moins temporairement, le NAT (on ne sait jamais, des fois que vous l'ayez oublié) :
echo 0 > /proc/sys/net/ipv4/ip_forward

III-10-2 Chaînes utilisateurs

Nous avons peu parlé des chaînes utilisateurs, aussi nous allons y jeter un oeil. Lorsque vous écrivez vos règles Netfilter, il y a parfois des morceaux de code que vous aimeriez mettre en commun. Par exemple, supposons que vous voudriez interdire le "ping" de certaines machines du réseau local ainsi que du réseau externe, mais que vous vouliez aussi "logger" toute utilisation du "ping". Vous auriez alors à écrire quelque chose comme :
[root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.2 -p icmp -j LOG
[root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.2 -p icmp -j DROP
[root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.3 -p icmp -j LOG
[root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.3 -p icmp -j DROP
[root@phoenix /]# iptables -t filter -A INPUT -i eth1 -p icmp -j LOG
[root@phoenix /]# iptables -t filter -A INPUT -i eth1 -p icmp -j DROP
Dans ces cas, les règles utilisateurs sont là pour simplifier la vie. Commençons par écrire notre propre règle "LogDrop" qui comme son nom l'indique, va "logger" les trames, puis les supprimer :
[root@phoenix /]# iptables -t filter -N LogDrop
[root@phoenix /]# iptables -t filter -A LogDrop -j LOG --log-prefix LogDrop
[root@phoenix /]# iptables -t filter -A LogDrop -j DROP
Puis, appelons la pour nos pings sur les réseaux locaux :
[root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.2 -p icmp -j LogDrop
[root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.3 -p icmp -j LogDrop
Et les réseaux externes :
[root@phoenix /]# iptables -t filter -A INPUT -i eth1 -p icmp -j LogDrop
On note au passage que notre chaîne "LogDrop" peut être appelée à n'importe quelle occasion, avec une règle "parente" ayant ou non beaucoup d'options. Le script vu ci-dessus se trouve ici.

III-10-3 Script final d'exemple

Nous avons vu jusqu'à présent un bon nombre de fonctionnalités de Netfilter grâce aux commandes "iptables". J'ai donc écrit un script qui regroupe toutes ces fonctionnalités en un seul script que vous pouvez utiliser chez vous. Ce script est téléchargeable ici.

Avant toute chose, il faudra que vous le configuriez à votre usage. Pour cela, le début du script contient un certain nombre de variables globales, qui définissent le comportement du script :
  • LAN_* (Local Area Network) : ces variables définisent le réseau local. Dans notre exemple, il s'agit du réseau "sky.net".
  • WAN_* (Wan Area Network) : là, il s'agit des variables définissant le réseau Internet. Elles sont spécialement conçues pour un réseau connecté par l'intermédiaire d'une passerelle. Or, vous devez plutôt avoir un modem RTC/RNIS/ADSL pour vous connecter, non ? Dans ce cas, il vous faudra donc décommenter le 2nd paquet de lignes "WAN_*", qui définirons vos paramètres de connexions Internet. La seule variable qu'il faudra bien vérifier est "WAN_INTERFACE=ppp0", mais à priori, vous ne vous connectez à Internet que par l'interface "ppp0". Dans le doute, et une fois que votre connexion Internet est activé, les commandes "/sbin/ifconfig" et "/sbin/route" vous donnerons plus d'informations.
  • NAT (Network Adress Translation) : cette variable définie si ou non vous voulez autorisez les machines de votre réseau interne à se connecter à Internet.
  • PF_* (Port Forwarding) : ces variables définissent si ou non vous voulez faire du port forwarding. Notez que j'ai pris ici l'exemple le plus simple : le HTTP ne demande en effet qu'un seul port omnidirectionnel. Si vous voulez faire du port forwarding sur du FTP, ce sera un peu plus compliqué, car il faut laisser passer le canal de données (FTP-DATA) qui utilise le port 20 du coté client. Pour le P2P, c'est votre port de connexion (par exemple, "4660") qu'il faudra laisser passer en entrée.
Quelques remarques à propos de ce script :
  • Toutes les règles Netfilter qui contrôlent l'accès à Internet utilisent l'adresse IP externe de la machine ("WAN_IP"). C'est une manière de faire, qui je l'admets est contestable. Beaucoup de scripts que vous trouverez sur Internet n'utilisent pas ces options ("-d $WAN_IP" pour les règles "INPUT" et "-s $WAN_IP" pour les règles "OUTPUT"), et ne restreignent tout simplement pas les connexions externes à l'adresse IP externe. Par exemple, au lieu d'écrire :
    [root@phoenix /]# iptables -t filter -A OUTPUT -o $WAN_INTERFACE -s $WAN_IP -d $WAN_NETWORK \
                               -p all -m state --state ! INVALID           -j ACCEPT
    [root@phoenix /]# iptables -t filter -A INPUT  -i $WAN_INTERFACE -s $WAN_NETWORK -d $WAN_IP \
                               -p all -m state --state RELATED,ESTABLISHED -j ACCEPT
    
    Ces autres scripts écriraient :
    [root@phoenix /]# iptables -t filter -A OUTPUT -o $WAN_INTERFACE -d $WAN_NETWORK \
                               -p all -m state --state ! INVALID           -j ACCEPT
    [root@phoenix /]# iptables -t filter -A INPUT  -i $WAN_INTERFACE -s $WAN_NETWORK \
                               -p all -m state --state RELATED,ESTABLISHED -j ACCEPT
    
    C'est effectivement plus simple à écrire, mais personnellement je n'ai pas confiance en ce type d'écriture "courte". Et ce, pour 2 raisons :
    • On peut toujours craindre une attaque malicieuse où un intrus nous enverrait un paquet mal formé, avec une adresse IP qui n'est pas la nôtre. C'est spécialement faisable si l'intrus se trouve être chez notre propre fournisseur d'accès. Ce paquet n'étant pas du tout normal, il n'a aucune raison de rentrer dans notre machine. On peut aussi imaginer qu'il indique comme adresse de destination une adresse de notre réseau interne. Ce type de paquet n'est pas du tout supposé pouvoir pénétrer dans notre machine, mais les techniques d'intrusion évoluant sans cesse, qui sait si un jour une telle technique ne sera pas capable de contourner les protections de Netfilter ?
    • "Iptables" permet d'être très "fin" au niveau de ses règles de filtrages, je trouve donc tout simplement regrettable de ne pas exploiter au maximum ses possibilités, et donc de ne pas faire des règles "ACCEPT" les plus restrictives possibles.
    Conclusion : dans le doute, je m'abstiens, et j'utilise la "WAN_IP"... Smiley

    Mais ce choix a un désavantage important : pour que ce script soit fonctionnel, il faut le lancer à chaque fois que la configuration réseau change, c'est à dire à chaque connexion à Internet. Et c'est la commande (barbare ?) "/sbin/ifconfig | grep "P-t-P" | sed "s/^[: a-z]*\([.0-9]*\).*/\1/g"" qui va se charger de trouver l'adresse IP internet de votre machine. Mais plutôt que de le lancer manuellement, vous pouvez laisser Linux s'en occuper pour vous. En effet, à chaque fois que la connexion ppp est initialisée, Linux exécute le script "/etc/sysconfig/network-scripts/ifup-ppp" (*). Vous n'avez donc qu'à rajouter une ligne lançant ce script au début de ce fichier. Par exemple, quelque chose comme "/usr/local/sbin/iptables-final-1.sh".

    Pour des raisons de sécurité, je vous conseille de donner la propriété de ce fichier au root, et de le laisser en écriture uniquement pour le super utilisateur.
    Exemple :
    [root@phoenix /]# chown root:root /usr/local/sbin/iptables-final-1.sh
    [root@phoenix /]# chroot 755 /usr/local/sbin/iptables-final-1.sh
    
    (*): en fait, ce n'est pas une obligation absolue. Et cela dépend en partie de l'outil que vous utilisez pour vous connecter sur Internet. Par exemple, pour ma connexion modem j'utilise l'interface graphique "/usr/bin/kppp". Et ce programme propose de lancer un script une fois la connexion Internet établie. C'est là que l'on pourrait mettre le "/usr/local/sbin/iptables-final-1.sh"
  • Dans ce script, vous pouvez voir que les règles de port forwarding sont situées avant celles d'IP masquerading. Simple effet de style de ma part ? Non, pas du tout. Un paquet venant d'Internet et à destination du port 80 de la machine satisfait à 2 règles de la chaîne "FORWARD" :
    iptables -t filter -A FORWARD -i $WAN_INTERFACE -o $LAN_INTERFACE -s $WAN_NETWORK -d $LAN_NETWORK \
                       -p $PF_PROTO --dport $PF_PORT -m state --state ! INVALID           -j ACCEPT
    iptables -t filter -A FORWARD -i $WAN_INTERFACE -o $LAN_INTERFACE -s $WAN_NETWORK -d $LAN_NETWORK \
                       -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
    
    De même que pour les paquets sortants de la machine et ayant pour source le port 80 :
    iptables -t filter -A FORWARD -i $LAN_INTERFACE -o $WAN_INTERFACE -s $LAN_NETWORK -d $WAN_NETWORK \
                       -p $PF_PROTO --sport $PF_PORT -m state --state ESTABLISHED,RELATED -j ACCEPT
    iptables -t filter -A FORWARD -i $LAN_INTERFACE -o $WAN_INTERFACE -s $LAN_NETWORK -d $WAN_NETWORK \
                       -p all -m state --state ! INVALID           -j ACCEPT
    
    Dans les 2 cas, la 1ère règle est une règle de port forwarding et la 2nd d'IP masquerading. Mais comme les 2nd règles sont plus générales que les premières, les statistiques de Netfilter (commande "iptables -L -n -v -t filter") sont faussées si les règles d'IP masquerading sont placées avant les règles de port forwarding.

    Cet exemple est intéressant, car c'est un des fameux cas où l'ordre des commandes "iptables" a une certaine importance. Comment cela je chipote ? Et bien oui... Smiley
  • Notez enfin que les différents modules de Netfilter ("iptable_nat", "ip_nat_ftp", etc ...) ne sont chargés que si c'est nécessaire. On aurait par contre pu tous les charger "en bloc" au début du script.

III-10-4 Autres scripts

A titre d'informations, vous pouvez télécharger quelques scripts supplémentaires :
Nom du scriptDescription
iptables-extrem-accept.sh Ce script vide toutes les chaînes prédéfinies et supprime toute les chaînes utilisateurs de toutes les tables. C'est utile si vous voulez revenir à une configuration de Netfilter complètement vierge, et aussi complètement insécurisée. Bref, c'est la configuration que vous avez probablement actuellement !
iptables-extrem-drop.sh Ce script est pour les ultra paranoïaques, car contrairement à son prédécesseur, il interdit toute connexion (après avoir au préalable supprimé toutes les règles et toutes les chaînes utilisateurs). Avec une telle configuration, il ne vous reste plus qu'à débrancher les câbles réseaux de votre machine, et en faire des colliers. Au moins, ils vous seront utiles à quelque chose ! Smiley

III-10-5 Tests d'intrusion

Une fois que toutes vos règles iptables sont écrites, il vous faut vous-même tester la sécurité de votre Linux en pratiquant des tests d'intrusions. Une première approche est d'utiliser "nmap", et de contrôler chacun de vos ports. Cette pratique est très efficace (lisez "man nmap" afin d'utiliser au mieux les options très variées de Nmap), et doit être fait depuis les machines de votre réseau. Pendant vos "attaques" lancées par "nmap", n'oubliez pas de garder un oeil sur votre "/var/log/messages" (par exemple avec un "tail -f /var/log/messages") ou le fichier qui stocke les logs de Netfilter, afin de suivre la progression de l'attaque.

Dans le cadre du réseau proposé ici, il m'a été facile de tester les 2 interfaces réseaux de Phoenix, en lançant les tests depuis Paradise et Pirate. Cependant, dans le cadre d'une utilisation personnelle, il est beaucoup plus difficile de tester l'interface réseau externe ("ppp0" par exemple). En effet, si par exemple depuis Phoenix vous lancez un "nmap phoenix1.internet.net", vous ne ferez que tester les règles de "loopback/localhost", comme nous l'avons déjà vu précédemment. Pour que vous obteniez un résultat correct, il vous faut donc changer vos règles de "loopback" par celles que vous avez définies pour "ppp0". Mais cette solution n'est pas forcément très représentative de la réalité, et le mieux serait de tester réellement les paquets arrivant sur "ppp0".

Il vous faut donc faire confiance à une personne externe à votre réseau, situé sur Internet, pour tester vos règles de Firewall. Pour cela, 3 possibilités :
  • Vous avez un accès en "telnet" ou en "SSH" (ce qui est mieux, car plus sécurisé) sur une machine situé sur Internet. Vous vous connectez alors dessus, et vous lancez un "nmap" sur l'adresse IP de votre machine. Attention de ne pas vous tromper d'adresse IP, sinon vous iriez tester les ports d'une autre machine, et son propriétaire pourrait ne pas être très content...
  • Vous demandez à un de vos amis de faire ce test pour vous. Encore faut il qu'il sache ce qu'est "nmap" !
  • Enfin, vous faire faire ce test par un site web. Certains sites proposent gratuitement ce genre de prestation, entre autre pour vous proposer des solutions de firewall ... Windows® Smiley
J'ai testé certains de ces sites, et voici les résultats :
Site de testRésultat
PcFlankPcFlank
DSLreportsDSLreports
Shields UP!Shields UP!
AuditMyPc.comLe site a refusé de tester la machine, ce qui est
apparemment dût à la présence du proxy transparent
de mon fournisseur d'accès à Internet
Sans surprise, non ? Smiley

En fait, tout le mérite en revient au suivi de connexion, qui fait passer notre machine pour un "trou noir". Comme le veut la définition de ce terme, c'est "un corps qui absorbe tout, et qui ne rejette rien"...

Quelques soit ces sites, leurs tests ne sont souvent pas très poussés, et se limitent parfois qu'aux seuls ports ouverts par défaut sous Windows®. De plus, un simple test de "port scanning" n'est pas forcément suffisant, et d'autres outils de tests d'intrusion peuvent être utilisés en complément. Mais à ce niveau là, la limite entre tests de sécurité et piratage est très tenue, donc je vous laisserai chercher par vous-même des moyens de tester un peu plus en profondeur votre système...

III-10-6 Sauvegarde des règles Netfilter

Supposons que vous n'écriviez pas votre adresse IP Internet dans vos règles Netfilter de "ppp0" (comme décrit ci-dessus), vous avez alors des règles de ce type :
[root@phoenix /]# iptables -t filter -A OUTPUT -o ppp0 -d 0.0.0.0/0 \
                           -p all -m state --state ! INVALID           -j ACCEPT
[root@phoenix /]# iptables -t filter -A INPUT  -i ppp0 -s 0.0.0.0/0 \
                           -p all -m state --state RELATED,ESTABLISHED -j ACCEPT
Dans ce cas, vos règles Netfilter sont génériques, et elles n'ont pas besoin d'être modifiées à chaque connexion Internet. Donc vous pouvez écrire vos règles une fois pour toute, et laisser Linux les charger automatiquement au démarrage de votre machine. Pour cela, écrivez vos règles Netfilter dans un script, puis (pour les possesseurs de distributions Mandrake) tapez la commande :
[root@phoenix /]# /etc/rc.d/init.d/iptables save
Enfin, pour que le Netfilter soit opérationnel à chaque démarrage, il faut créer les liens symboliques adéquates dans le /etc/rc.d/ :
[root@phoenix /]# cd /etc/rc.d/rc3.d/
[root@phoenix /]# ln -s ../init.d/iptables s03iptables
[root@phoenix /]# cd /etc/rc.d/rc5.d/
[root@phoenix /]# ln -s ../init.d/iptables s03iptables
Au démarrage, votre Linux lancera le script /etc/rc.d/init.d/iptables qui chargera les règles Netfilter précédemment sauvées.
Si à un moment vous avez besoin d'arrêter la protection de Netfilter, vous n'avez qu'à lancer la commande suivante :
[root@phoenix /]# /etc/rc.d/init.d/iptables stop

Table des matières Page précédente Page suivante
Valid XHTML 1.0! Valid CSS!
Site de référence : http://olivieraj.free.fr/ Last modified: Mon Jul 21 22:56:27 CEST 2003