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.
# 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
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
oui c’est un serveur web et qui utilise des adresses IP statiques.
Merci de votre aide. Je vous tiendrai au courant lorsque le serveur sera en production avec dual stack IPv4et IPv6 séparement.