Règles de firewall pour un pont IPv6

Certains d’entre-vous ont installé un firewall linux en IPv4 et l’ont également configuré pour transmettre le trafic IPv6 de leur freebox avec un pont tel que je l’avais décrit dans l’article DHCPv6 et Freebox. Je n’y décrivais pas comment configurer le service de filtrage de paquets ip6tables pour appliquer quelques règles de firewall à ce pont. Voici donc une configuration simple qui pourra vous servir de base pour commencer.

Elle ne constitue pas une protection absolue mais elle vous explique la philosophie du système avec ce que l’on peut filtrer et ce qui ne doit pas être filtré pour le bon fonctionnement d’IPv6. Les règles présentées ici permettent à tout le trafic IPv6 sortant de l’intranet d’atteindre l’internet mais interdit tout le trafic émis de l’internet d’atteindre le firewall et l’intranet.

Prérequis

Firewall/routeur en mode pont IPv6 avec un noyau linux 2.6, les outils ip6tables. Je suppose que le pont IPv6 a pour nom br0.

Firewall Linux avec pont logiciel pour traiter les flux IPv6

# Interface pont IPv6
EXTIF=br0

# Préfixe local (à compléter selon votre configuration
LOCAL=2xxx:xxxx:xxxx:xxxx::/64

# Toute adresse IPv6
ANY=::/0

# Adresses de lien local
LINK=fe80::/10

# Adresses multicast
MULTICAST=ff00::/8

Trafic à destination du firewall

Le trafic provenant de l’internet est interdit (sauf réponses DNS), le trafic de l’intranet est autorisé :

# Trafic autorisé en interne
ip6tables -t filter -A INPUT -s ${LOCAL} -j ACCEPT
ip6tables -t filter -A INPUT -s ${LINK} -j ACCEPT
ip6tables -t filter -A INPUT -d ${MULTICAST} -j ACCEPT
ip6tables -t filter -A INPUT -i lo -j ACCEPT

# Seul le trafic UDP pour la résolution DNS est autorisé
ip6tables -t filter -A INPUT -i $EXTIF -p udp -m udp --sport 53 -j ACCEPT
ip6tables -t filter -A INPUT -i $EXTIF -p udp -j DROP

# Trafic TCP sur les ports < 1024 interdit
ip6tables -t filter -A INPUT -i $EXTIF -p tcp -m tcp --dport 0:1023 -j DROP

# Accepter le trafic des connexions etablies
ip6tables -t filter -A INPUT -i $EXTIF -m state --state ESTABLISHED,RELATED -j ACCEPT

# Connexions TCP entrantes interdites
ip6tables -t filter -A INPUT -i $EXTIF -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j DROP

# Autorisations icmpv6 sauf ping entrant
ip6tables -t filter -A INPUT -i $EXTIF -p icmpv6 --icmpv6-type echo-request -j DROP
ip6tables -t filter -A INPUT -i $EXTIF -p icmpv6 -j ACCEPT

# Tout le reste est refusé, on trace
ip6tables -t filter -A INPUT -i $EXTIF -j DROP

Trafic traversant le firewall

Le trafic initié de l’internet est interdit, le trafic de l’intranet vers l’internet est autorisé :

# Retransmission des adresses locales (entre la freebox et l'intranet par exemple)
ip6tables -t filter -A FORWARD -s ${LINK} -j ACCEPT

# Retransmission des paquets ICMP sauf ping de l'internet vers l'intranet
ip6tables -t filter -A FORWARD ! -s ${LOCAL} -p icmpv6 --icmpv6-type echo-request -j DROP
ip6tables -t filter -A FORWARD -p icmpv6 -j ACCEPT

# Accepter le trafic des connexions établies
ip6tables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

# Accepter les flux sortants (a vous d'affiner)
ip6tables -t filter -A FORWARD -s ${LOCAL} -j ACCEPT

# Accepter les flux sortant locaux
ip6tables -t filter -A FORWARD -s ::1 -j ACCEPT

# Interdire tout le reste
ip6tables -t filter -A FORWARD -j DROP

Tracer les paquets indésirables

Comme le but d’un firewall est aussi de tracer les tentatives de connexions j’ai encapsulé le tout dans un script d’initialisation utilisable dans la séquence d’init qui remplace les habituelles règles DROP et REJECT par des chaines utilisateur qui tracent l’évènement dans la log système avant de réaliser le véritable DROP/REJECT. Cette règle limite également le nombre de messages écrits dans la log car en cas d’attaque sévère par dénis de service la machine pourrait voir sa CPU à 100% rien que de devoir tout écrire dans la log.

Par exemple pour les paquets DROP de la chaine INPUT :

# Chaine utilisateur (INDROP: Réception refusée, pas de réponse)
ip6tables -t filter -N INDROP
ip6tables -t filter -A INDROP -m limit --limit 1/s --limit-burst 10 -j LOG --log-level info --log-prefix "TENTATIVE InputDrop6 "
ip6tables -t filter -A INDROP -j DROP

Il suffit alors d’utiliser -j INDROP à la place de -J DROP dans les règles de la chaine INPUT

Tout ensemble

Voici un script qui englobe l’ensemble de ce qui été vu et un peu plus encore. Le script est exécutable et accepte un paramètre parmi :

  • start : établir les règles de firewall IPv6
  • stop : établir les règles IPv6 par défaut du système (plus de firewall)
  • panic : couper tout le trafic IPv6
  • status : visualiser les règles actuellement en cours d’utilisation
  • save : enregistrer la configuration en cours dans un fichier /etc/sysconfig/ip6tables

Vous pouvez télécharger ce fichier dans un tar.gz en suivant ce lien : Télécharger “ip6tables.sh” ip6tables-rgc.tar.gz – 1,99 Ko

# Trafic autorisé en interne
ip6tables -t filter -A INPUT -s ${LOCAL} -j ACCEPT
ip6tables -t filter -A INPUT -s ${LINK} -j ACCEPT
ip6tables -t filter -A INPUT -d ${MULTICAST} -j ACCEPT
ip6tables -t filter -A INPUT -i lo -j ACCEPT

# Seul le trafic UDP pour la résolution DNS est autorisé
ip6tables -t filter -A INPUT -i $EXTIF -p udp -m udp –sport 53 -j ACCEPT
ip6tables -t filter -A INPUT -i $EXTIF -p udp -j INDROP

# Trafic TCP sur les ports < 1024 interdit
ip6tables -t filter -A INPUT -i $EXTIF -p tcp -m tcp –dport 0:1023 -j INDROP

# Accepter le trafic des connexions etablies
ip6tables -t filter -A INPUT -i $EXTIF -m state –state ESTABLISHED,RELATED -j ACCEPT

# Connexions TCP entrantes interdites
ip6tables -t filter -A INPUT -i $EXTIF -p tcp -m tcp –tcp-flags SYN,RST,ACK SYN -j INDROP

# Autorisations icmpv6 sauf ping entrant
ip6tables -t filter -A INPUT -i $EXTIF -p icmpv6 –icmpv6-type echo-request -j INDROP
ip6tables -t filter -A INPUT -i $EXTIF -p icmpv6 -j ACCEPT

# Tout le reste est refusé, on trace
ip6tables -t filter -A INPUT -i $EXTIF -j INDROP

19 réflexions sur « Règles de firewall pour un pont IPv6 »

    • Non, plus de NAT en IPv6. Toutes les adresses sont publiques, le NAT n’a plus de raison d’exister. Les espaces d’adresses privées IPv4 ont été crées pour retarder la pénurie d’adresses. C’est leur utilisation qui imposait le NAT. Je sais c’est déstabilisant et ça va obliger les administrateurs qui pensaient être bien à l’abris dans leur espace privé à bien savoir ce qu’ils font dans leur réglage de firewall en IPv6.

  1. Bonjour
    j’ai pas bien compris dans le shéma ci-dessus le pont IPv6, est-ce que sont des interfaces réseau ETH ?

    et dans les règles c’est quoi $EXTIF .

    Merci pour votre réponse.

    • Physiquement il y a bien deux interface réseau : eth0 connecté à l’intranet et eth1 connecté à l’internet. En utilisant la commande brctl on réalise un pont entre ces deux interfaces. Ca revient à créer un switch à deux ports mais qui ne laisse passer que l’IPv6 grâce à la commande ebtables.
      Une interface virtuelle est alors crée qui se nomme br0 et qui représente le pont. C’est comme un troisième port du switch mais en interne au firewall. C’est cette interface que doit utiliser le firewall pour dialoguer en IPv6 car le pont saura vers quelle interface physique émettre le paquet (intranet, internet, les deux ou même aucune).
      Dans les règles décrites ici, la variable EXTIF contient le nom de cette interface virtuelle, donc br0 dans mon exemple. Le but est de ne pas manipuler cette interface directement par son nom système car chacun peut lui donner le nom qu’il veut avec la commande brctl.

      Pour le détail de la création du pont, voir cet autre article : DHCPv6 et Freebox.

  2. Bonjour

    Merci pour les deux réponse,
    maintenant j’ai un autre question, concerne la configuration des serveurs FTP, MAIL, SSH, LDAP …etc, est-ce qu’il prennent en charge IPv6 sans aucun configuration supplémentaires ?

    • Ce n’est pas si simple. FTP, MAIL, SSH et LDAP prennent en charge IPv6 à condition d’utiliser une version assez récente des produits assurant ces services (client et serveur). Parfois il faudra modifier le fichier de configuration du service pour lui dire d’écouter sur l’interface IPv6. Certains produits, comme DHCP de l’ISC, ne fonctionnent qu’en IPv4 ou IPv6 mais pas les deux simultanément. Il faut alors lancer deux fois le service avec deux fichiers de configuration différents.

    • Non, pour ces deux là c’est simple. Par défaut ils seront à l’écoute sur les interfaces IPv6. A vérifier dans leur fichier de configuration au cas où une restriction d’adresse soit présente mais par défaut je ne crois pas.

  3. Bonjour,

    Je ne sais pas si vous pouvez répondre à ma question, mais je tente quand meme..
    Je suis en train de voir comment configurer le serveur web Apache avec dual stack (IPv6/IPv4)sur une application. J’ai regardé des infos sur le site d’apache.org, il m’indique que par défaut le serveur apache traduit les adresses IPv6 en adresses IPv4. Cependant, il est possible de désactiver ce paramètre sur le serveur web. J’ai fait pas mal de recherche sur le net, j’ai pas trouvé la commande sous débian, qui permet de vérifier si le serveur web gère séparément les connexions IPv6/IPv4.
    C’est pour quoi je voudrais vous demander pour Debian squeeze, Apache peut gérer séparemment les connexions IPv6 et les connexions IPv4 ? Y a-t-il des risques ?

    • Sur un système à double pile, apache travaille en IPv6 et traduit les adresses IPv4 en IPv6. Par défaut il écoute sur toutes les IP (v4 et v6) à moins de le restreindre à l’aide du paramètre Listen dans son fichier de configuration. Exécuter la commande suivante pour connaitre les interfaces d’écoute :
      # netstat -anp | grep httpd
      tcp 0 0 :::80 :::* LISTEN xxxx/httpd
      tcp 0 0 :::443 :::* LISTEN xxxx/httpd

      La deuxième ligne (sur port 443) n’apparait que si le support SSL a été activé dans apache. Ici le « :: » signifie « ANY » donc toutes les IP (v4 et v6 si apache n’a pas été compilé avec l’option –disable-v4-mapped).
      Il est tout à fait possible de dire à apache de n’utiliser que IPv4, modifiez la directive Listen du fichier de configuration (httpd.conf) :
      Listen 0.0.0.0:80
      Pour n’utiliser que IPv6 il faut avoir compilé apache avec l’option –disable-v4-mapped et préciser dans le fichier httpd.conf:
      Listen [::]:80
      Sinon il est possible de donner la liste exhaustive des IP sur lesquelles on souhaite que apache réponde :
      Listen 192.168.0.10:80
      Listen 127.0.0.1:80
      Listen [2001:DB8::1234]:80

      Si SSL est activé, il faut répéter la configuration pour le port 443.
      Pour aller plus loin, avec un seul serveur apache et en configurant des serveurs virtuels (VirtualHost) il est possible de définir une gestion séparée des accès IPv4 et IPv6. Par exemple : présenter un site web différent en IPv4 et en IPv6.

  4. Merci de votre réponse.
    Dans ce cas, où est-ce que je peux trouver le script configure qui permet d’utiliser l’option –disable-v4-mapped sur Débian ?

    • Ce n’est pas un script que vous pouvez télécharger et utiliser dans une distribution linux. Vous devez télécharger les sources de apache httpd et les recompiler avec cette option. Si vous utilisez une distribution Linux vous pouvez télécharger le package de sources de cette distribution pour reprendre les patchs et options de compilation qui ont été utilisée dans votre distribution (debian). Vous ajouterez –-disable-v4-mapped lors de l’appel du script configure avant la compilation. Puis installez les binaires compilés. Sauvegardez tout votre système car vous risquez de le corrompre. Vous ne pourrez plus utilisez de packages pour mettre à jour apache.

  5. … Alors il est préférable que j’installe un serveur web dédié en IPv6 ? Puisque cette méthode présente des risques. Sachant que c’est un serveur web en production d’une école.

    • Pourquoi ne pas utiliser le serveur apache existant mais avec deux fichiers de configuration? Dans l’un IPv4 est le seul protocole utilisé et dans l’autre seul IPv6. On peut alors lancer deux serveurs apache httpd en précisant à chacun quel fichier de configuration utiliser. Il faut veiller à éviter les conflits : ne pas utiliser les mêmes fichiers de log, par exemple.

  6. Vous voulez dire configurer deux un pour IPv4 et IPv6 ? J’ai déjà vu cette méthode, mais je pensais que l’option –-disable-v4-mapped est obligatoire pour rendre les connexions IPv6 et IPv4 séparément.

    • Par exemple :
      Dans le fichier de conf pour IPv4 utilisez Listen 0.0.0.0:80
      Dans le fichier de conf pour IPv6 utilisez Listen [votre:adress::ipv6]:80
      Il n’est pas nécessaire de préciser l’IPv4 pour restreindre le serveur à ce seul protocole pour IPv6 vous devrez le préciser. C’est une serveur, non ? Avec des IP fixes ?

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *