Bonjour à tous,
Sur suggestion de Ricardo, j’ouvre un nouveau fil pour proposer une mise à jour de pare-feu basique présenté ici. Le principe reste le même, l’idée était simplement d’unifier un peu toutes les nouveautés liées à l’IPv6 et de proposer une version bureau et serveur.
Ce fil est destiné aux débutants, et j’accepterai bien volontiers toutes les modifications proposées par des personnes plus compétentes que moi (elles sont nombreuses ).
#Le principe
##iptables
Sur Debian, iptables
et ip6tables
(tous deux empaquetés dans le paquet iptables
) vous permettront de mettre assez facilement en place un pare-feu basique pour IPv4 et IPv6.
Après installation, le pare-feu ne pare rien du tout, il est ouvert à tous les vents, il va donc falloir le configurer. Et il faudra également prendre soin de lancer le pare-feu, avec sa configuration, dès le démarrage de la machine.
##Bureau/serveur
La configuration d’un pare-feu diffère évidemment beaucoup selon les besoins de la machine concernée. Sur votre machine de bureau, par exemple, vous pouvez faire simple et choisir de bloquer toute communication entrante venant de l’extérieur. En revanche, un serveur doit pouvoir répondre à des sollicitations sur certains ports, au moins 80 et 443 si vous hébergez un serveur HTTP/HTTPS. On sera donc obligés d’être plus fins dans le cas d’un serveur. Deux versions du script seront donc proposées dans ce fil.
##IPv4/IPv6
Une adresse IP sert à identifier une machine dans un réseau. Pendant longtemps les adresses IPv4 ont été suffisantes pour ça, elles sont de type 104.28.12.4 (au hasard). Seulement, il semblerait qu’avec l’augmentation du nombre de machines et de babioles d’objets connectés, on arrive à saturation de ce système d’adressage. Une nouvelle norme a donc été mise en place : IPv6. À ce jour, les deux normes coexistent et il convient donc de se protéger sur les deux fronts, en tenant compte en plus certaines spécificités d’IPv6.
#La mise en place
##Installation d’iptables
Ce n’est pas le plus compliqué, et vous pouvez utiliser votre gestionnaire de paquets favori. Par exemple : # aptitude install iptables
.
##Création d’un script d’init
Comme introduit plus haut, il faut s’assurer que le pare-feu soit lancé lors de la phase de boot du système. Pour ça, on crée un fichier nommé par exemple init_firewall
dans /etc/init.d/
.
#!/bin/sh
### BEGIN INIT INFO
# Provides: init_firewall
# Required-Start: $local_fs
# Should-Start:
# Required-Stop: $local_fs
# Should-Stop:
# X-Start-Before: $network
# X-Stop-After: $network
# Default-Start: S
# Default-Stop: 0 6
# Short-description: iptables-based firewall
### END INIT INFO
case "$1" in
'start')
iptables-restore < /etc/config_parefeu_IPv4
ip6tables-restore < /etc/config_parefeu_IPv6
echo "Starting firewall"
RETVAL=$?
;;
'stop')
iptables-save > /etc/config_parefeu_IPv4
ip6tables-save > /etc/config_parefeu_IPv6
RETVAL=$?
;;
'clean')
# clean le parefeu pendant que la machine tourne
# ça peut être une faille de sécurite si on l'exécute lors de l'extinction avant l'arrêt des interfaces
# pensez à refaire un start après sinon la sauvegarde se fera automatiquement à l'extinction
#### IPv4 ####
iptables -t filter -F
iptables -t nat -F
iptables -t mangle -F
iptables -t raw -F
iptables -t filter -P INPUT ACCEPT
iptables -t filter -P OUTPUT ACCEPT
iptables -t filter -P FORWARD ACCEPT
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P INPUT ACCEPT
iptables -t nat -P OUTPUT ACCEPT
iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P OUTPUT ACCEPT
iptables -t mangle -P POSTROUTING ACCEPT
iptables -t mangle -P FORWARD ACCEPT
iptables -t mangle -P INPUT ACCEPT
iptables -t raw -P OUTPUT ACCEPT
iptables -t raw -P PREROUTING ACCEPT
#### IPv6 ####
# Attention : la table nat IPv6 n'existe pas sous Wheezy (noyau 3.2)
ip6tables -t filter -F
ip6tables -t nat -F
ip6tables -t mangle -F
ip6tables -t raw -F
ip6tables -t filter -P INPUT ACCEPT
ip6tables -t filter -P OUTPUT ACCEPT
ip6tables -t filter -P FORWARD ACCEPT
ip6tables -t nat -P PREROUTING ACCEPT
ip6tables -t nat -P POSTROUTING ACCEPT
ip6tables -t nat -P INPUT ACCEPT
ip6tables -t nat -P OUTPUT ACCEPT
ip6tables -t mangle -P PREROUTING ACCEPT
ip6tables -t mangle -P OUTPUT ACCEPT
ip6tables -t mangle -P POSTROUTING ACCEPT
ip6tables -t mangle -P FORWARD ACCEPT
ip6tables -t mangle -P INPUT ACCEPT
ip6tables -t raw -P OUTPUT ACCEPT
ip6tables -t raw -P PREROUTING ACCEPT
RETVAL=$?
;;
'restart')
$0 stop && $0 start
RETVAL=$?
;;
*)
echo "Usage: $0 { start | stop | restart | clean}"
RETVAL=1
;;
esac
exit $RETVAL
Ne pas oublier de rendre le script exécutable : chmod +x /etc/init.d/init_firewall
. Puis, pour permettre au gestionnaire de boot de prendre en charge ce nouveau script, on lance update-rc.d init_firewall defaults
.
##Configuration
À ce stade, votre pare-feu accepte toutes les connexions. Il reste donc à le configurer. Pour cela, il “suffit” de faire appel à iptables
et ip6tables
pour définir les règles du pare-feu une à une. En pratique, je me suis fait un script /usr/local/sbin/config_firewall
qui regroupe toutes mes règles “de base”. Cette organisation est flexible et me permet toujours d’entrer une règle iptable
à la main le jour où j’en ai besoin. Et inversement, de revenir à mon jeu de règles de base en lançant config_firewall
. Pensez à restreindre les droits sur ce script, chown root:root
et chmod 740
feront l’affaire.
###Pour une machine de bureau
#!/bin/sh
/etc/init.d/init_firewall clean
##################
# IPv4 #
##################
# droper l'input et le forward par défaut, accepter l'output
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# laisser l'interface lo (loop) tranquille
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# maintenir les connexions établies
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# accepter en entrée le ping (icmp) et les
# connexions sur les ports nécessaires
iptables -A INPUT -p icmp --icmp-type echo-request -m conntrack --ctstate NEW -m limit --limit 1/s --limit-burst 1 -j ACCEPT
iptables -A INPUT -p tcp --dport xxxx -j ACCEPT
iptables -A INPUT -p udp --dport xxxx -j ACCEPT
###################
# IPv6 #
###################
# droper l'input et le forward par défaut, accepter l'output
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT
# laisser l'interface lo (loop) tranquille
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# maintenir les connexions établies
ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# NDP pour toute interface de type broadcast
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT
# accepter en entrée le ping (icmpv6), les
# connexions sur les ports nécessaires.
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -m conntrack --ctstate NEW -m limit --limit 1/s --limit-burst 1 -j ACCEPT
ip6tables -A INPUT -p tcp --dport xxxx -j ACCEPT
ip6tables -A INPUT -p udp --dport xxxx -j ACCEPT
/etc/init.d/init_firewall restart
###Pour un serveur
#!/bin/sh
/etc/init.d/init_firewall clean
###################
# IPv4 #
###################
# tout droper par défaut
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT DROP
# laisser l'interface lo (loop) tranquille
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# maintenir les connexions établies
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# accepter en entrée le ping (icmp), et les
# connexions sur les ports nécessaires.
iptables -A INPUT -p icmp --icmp-type echo-request -m conntrack --ctstate NEW -m limit --limit 1/s --limit-burst 1 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport xxxx -j ACCEPT
iptables -A INPUT -p udp --dport xxxx -j ACCEPT
# accepter en sortie le ping, les requêtes HTTP(S), DNS,
# et les connexions sur les ports nécessaires.
iptables -A OUTPUT -p icmp --icmp-type echo-request -m conntrack --ctstate NEW -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp --dport xxxx -j ACCEPT
iptables -A OUTPUT -p udp --dport xxxx -j ACCEPT
###################
# IPv6 #
###################
# tout droper par défaut
ip6tables -t filter -P INPUT DROP
ip6tables -t filter -P FORWARD DROP
ip6tables -t filter -P OUTPUT DROP
# laisser l'interface lo (loop) tranquille
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# maintenir les connexions établies
ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# NDP pour toute interface de type broadcast
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-solicitation -m hl --hl-eq 255 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-advertisement -m hl --hl-eq 255 -j ACCEPT
ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT
ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbour-solicitation -j ACCEPT
ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbour-advertisement -j ACCEPT
ip6tables -A OUTPUT -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT
# accepter en entrée le ping (icmpv6), les
# connexions entrantes déjà établies et les connexions sur les ports nécessaires.
ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -m conntrack --ctstate NEW -m limit --limit 1/s --limit-burst 1 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
ip6tables -A INPUT -p tcp --dport xxxx -j ACCEPT
ip6tables -A INPUT -p udp --dport xxxx -j ACCEPT
# accepter en sortie le ping, les requêtes HTTP(S), DNS,
# et les connexions sur les ports nécessaires.
ip6tables -t filter -A OUTPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport 80 -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport 443 -j ACCEPT
ip6tables -A OUTPUT -p udp --dport 53 -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport 53 -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport xxxx -j ACCEPT
ip6tables -A OUTPUT -p udp --dport xxxx -j ACCEPT
/etc/init.d/init_firewall restart
##Démarrage
Une fois votre script de configuration lancé, votre pare-feu devrait être en place ! Grâce au restart
à la fin du script config_firewall
, les règles IPv4 et IPv6 ont été sauvegardées et seront remises en place à chaque démarrage.
##Vérification
Et voilà ! Maintenant, vérification importante : le pare-feu a-t-il bien été configuré ? Vous pouvez pour ça utiliser deux commandes différentes qui donnent les mêmes informations, simplement formatées différemment :
-
iptables -vL --line-numbers
etip6tables -vL --line-numbers
, ou bien -
iptables-save
etip6tables-save
, dont la sortie est plus facilement comparable avec le scriptconfig_firewall
.
Dans les deux cas, vous devriez voir les règles globales (policy) et ciblées en place.
#À l’usage
- Pour ajouter une règle, c’est soit à la main dans un terminal, soit ajout dans le script
config_firewall
. Si vous le faites à la main, veillez à bien lancer un restart du script d’init (voir ci-dessus) si vous voulez que la règle soit enregistrée pour les prochains boots. - En cas de doute ou après chaque modification, ne pas hésiter à vérifier l’état du pare-feu (voir §Vérification ci-dessus).
#Fils à consulter
#Merci à
- Ricardo, pour son post initial.
- PascalHambourg, PengouinPdt et Ricardo pour leurs conseils avisés.