Pare-feu IPv4/IPv6, versions bureau serveur

En fait, il faut que tu lances ton script pour appliquer tes règles iptables, puis tu lances la configuration de iptables-persistant. C’est comme ça que je fais à chaque fois.

oui d’accord mais les règles de mon script (https://www.debian-fr.org/t/pare-feu-ipv4-ipv6-versions-bureau-serveur/77003 )sont-elles correctes? Peut-on les utiliser avec iptables-persistant?

iptables-persistent se fiche de ton script et des règles qu’il met en place. Il se contente de les rendre persistantes.
Quant à savoir si elles sont “correctes”, ça dépend de ce que tu veux qu’elles fassent.

La configuration est destinée à une machine bureau. C’est pour cela que j’ai simplement recopié le script “Pour une machine de bureau” du tuto “Pare-feu IPV4/IPv6, versions bureau et serveur” (https://www.debian-fr.org/t/pare-feu-ipv4-ipv6-versions-bureau-et-serveur/68665 )car je n’ai pas besoin de plus.
La seule question que je me pose est pour la première partie du script, celle dédiée au “nettoyage” du firewall: est-il indispensable de rajouter ces règles? D’habitude, je me contentai seulement de “ipatbles -F” et “iptables -X”.

Il est évident que des séquences comme

iptables -t filter -P INPUT ACCEPT
iptables -P INPUT DROP

où la seconde commande fait l’inverse de la première, sont absurdes.
D’autre part, si le but est d’effacer toute trace du jeu de règles antérieur, il manque les commandes -X pour effacer les éventuelles chaînes utilisateur.

En revanche la réinitialisation de toutes les tables, même celles que tu n’utilises pas, a du sens : en effet un jeu de règles enregistré par iptables-save (utilisé par iptables-persistent) ne réinitialise que les tables présentes lors de la sauvegarde.

Donc, je dois commencer le script par:
sudo iptables -L
sudo iptables -X

Et ensuite, je réinitialise toutes les tables, c’est bien ça?

Je comprends que les 2 commandes soient absurdes mais pourquoi sont-elles présentes dans le fil https://www.debian-fr.org/t/pare-feu-ipv4-ipv6-versions-bureau-et-serveur/68665 ?

  1. On n’utilise pas sudo dans un script.
  2. Il faut faire la même chose pour toutes les autres tables (la table par défaut est “filter”).

“Ensuite” ? Les commandes ci-dessus font déjà partie des opérations ayant pour but de réinitialiser une table.

Je ne suis pas responsable de ce que les autres écrivent.

1 J'aime

Petite erreur de frappe dans mon poste précédent. Ce n’était iptables -L mais iptables -F .

Voici le script rectifié:

#table filter
iptables -t filter -F
iptables -t filter -X
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT ACCEPT

#table NAT
iptables -t nat -F
iptables -t nat -X
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT

#table mangle
iptables -t mangle -F
itpables -t mangle -X
ptables -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

#table raw
iptables -t raw -F
itpables -t raw -X
iptables -t raw -P OUTPUT ACCEPT
iptables -t raw -P PREROUTING ACCEPT


#autorise lo
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


#accepte ping 
iptables -A INPUT -p icmp --icmp-type echo-request -m conntrack --ctstate NEW -m limit --limit 1/s --limit-burst 1 -j ACCEPT


# On log les paquets en entrée.
iptables -A INPUT -j LOG

# On log les paquets forward.
iptables -A FORWARD -j LOG

Je n’avais même pas remarqué la coquille -L/-F.

  • Table nat (et non NAT, le nom des tables est en minuscule) : il manque la définition de la politique par défaut de la chaîne INPUT, pourtant présente dans ton script initial. Tu a peut-être été influencé par la lecture de scripts écrits avant que la chaîne INPUT soit ajoutée à la table nat (c’est relativement récent comparativement à l’âge d’iptables).

    iptables -t nat -P INPUT ACCEPT

  • Table mangle : faute de frappe à une commande.

    ptables -t mangle -P PREROUTING ACCEPT

  • Règles de filtrage :

iptables -A OUTPUT -o lo -j ACCEPT

Cette règle est redondante puisque la politique par défaut de la chaîne OUTPUT est déjà ACCEPT.

iptables -A INPUT -p icmp --icmp-type echo-request -m conntrack --ctstate NEW -m limit --limit 1/s --limit-burst 1 -j ACCEPT

Quel est la limitation précise que cette règle est supposée imposer ?

Il faut avoir à l’esprit que tous les paquets ICMP echo-request et echo-reply d’une même séquence sont considérés comme appartenant à la même “connexion” (au sens de netfilter), un séquence étant par exemple l’ensemble des paquets émis et reçus lors de l’exécution continue d’une commande ping. Par conséquent si le destinataire répond au ping, seul le premier paquet ICMP echo-request d’une séquence a l’état NEW, les suivants ont l’état ESTABLISHED.

La conséquence sur ton jeu de règles, qui accepte tous les paquets entrants dans l’état ESTABLISHED, est que le nombre de requêtes appartenant à une même séquence par seconde n’est pas limité ; seul le nombre de séquences différentes par seconde l’est. Est-ce bien ce que tu souhaites ?

1 J'aime

Merci d’avoir rectifié le script.

Oui c’est vrai, j’ai lu plusieurs tutos qui datent d’années différentes.

Mon idée de départ était de bloquer les requêtes ICMP car je pense que cela n’a aucune utilité pour moi. Je n’ai jamais utilisé la commande ping et je ne le ferais sans doute jamais.

Les règles que je mettais étaient celles-ci :

iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j DROP

Grâce à ces deux commandes, mon PC ne répond plus aux requêtes « ping ». Mais me permettent-elles quand même d’effectuer des pings ? Peut-être qu’un jour j’aurais besoin de vérifier si un serveur est joignable !

La seconde règle est inutile car si les requêtes echo-request sont bloquées, aucune réponse echo-reply n’est émise.

Note qu’il y a un autre moyen plus simple d’empêcher ta machine de répondre au ping :

net.ipv4.icmp_echo_ignore_all=1

dans /etc/sysctl.conf ou dans un fichier /etc/sysctl.d/*.conf pour désactiver la réponse au ping.

Ces deux règles n’empêchent pas le ping sortant qui fait intervenir des paquets ICMP echo-request ayant l’état NEW ou ESTABLISHED dans la chaîne OUTPUT et des paquets ICMP echo-reply ayant l’état ESTABLISHED (dans le cas d’un ping unicast) ou INVALID (dans le cas d’un ping broadcast ou multicast, le suivi de connexion de netfilter ne gérant pas ces modes de communication) dans la chaîne INPUT.

Je vais alors plutôt modifier le fichier systctl.conf.
J’ai donc réécrit le script :

#table filter
iptables -t filter -F
iptables -t filter -X
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT ACCEPT

#table nat
iptables -t nat -F
iptables -t nat -X
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P INPUT ACCEPT
iptables -t nat -P OUTPUT ACCEPT

#table mangle
iptables -t mangle -F
itpables -t mangle -X
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

#table raw
iptables -t raw -F
itpables -t raw -X
iptables -t raw -P OUTPUT ACCEPT
iptables -t raw -P PREROUTING ACCEPT


#autorise lo
iptables -A INPUT -i lo -j ACCEPT

#maintenir les connexions établies
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# On log les paquets en entrée.
iptables -A INPUT -j LOG

# On log les paquets forward.
iptables -A FORWARD -j LOG

Quelques dernières questions :

Du point de vue de la sécurité, ne serait-il pas plus prudent de droper aussi l’OUTPUT de la table filter et ensuite de maintenir les connexions établies et d’accepter en sortie lo…

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack ! --ctstate INVALID -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -i lo -j ACCEPT (enfin, peut-être que cette règle est superflue vu que je maintiens les connexions établies en OUTPUT)

J’ai aussi lu qu’il fallait autoriser tout le trafic loopback et droper tout le trafic vers 127/8 qui n’utilise pas lo.
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i lo -d 127.0.0.0/8 -j DROP

Pour ce qui est de se protéger des scans XMAS et NULL:

iptables -A INPUT -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

J’ai mentionné le fichier sysctl.conf car c’est l’emplacement historique où on plaçait ce genre de réglage. Cependant il est géré en “conffile” (fichier de configuration) du paquet procps par dpkg, donc si une mise à jour du paquet fournit une nouvelle version du fichier, le système détectera que le fichier d’origine a été modifié localement et il faudra choisir entre conserver le fichier ou le remplacer par la nouvelle version. La tendance actuelle est plutôt de créer un fichier *.conf dans /etc/sysctl.d/. Avantages : on peut créer des fichiers distincts pour différentes catégories de réglages (réseau, gestion de la mémoire, du noyau…), ce qui facilite la maintenance, et ces fichiers ne sont pas affectés par les mises à jour de procps. La même tendance existe pour les fichiers de configuration de modprobe et X.org.

Bof. Ça ne fera que bloquer les paquets ayant l’état INVALID émis par la machine. Et je ne vois pas le rapport avec l’interface de loopback. Il n’y a pas plus de paquets INVALID émis sur l’interface de loopback que sur les autres interfaces. Au passage la première règle est superflue puisque la seconde accepte la même chose et plus encore. La troisième règle est en doublon avec un règle déjà présente dans le script.

Contre quel type de menace veux-tu protéger ta machine en filtrant dans OUTPUT ? Si tu veux vraiment filtrer dans OUTPUT, il faut n’accepter que les flux dont tu as besoin, comme en INPUT. La difficulté étant de lister exhaustivement ces flux.

Ton script le fait déjà, pas besoin d’en rajouter.

Oui. Il me semble que la pile IP de Linux le fait déjà nativement, mais il y a longtemps que j’ai étudié ce genre de choses. Ça ne coûte pas cher d’ajouter une règle pour être tranquille.

Pourquoi pas, mais ces combinaisons de drapeaux TCP sont invalides et les paquets devraient être classés dans l’état INVALID par le suivi de connexion.

OK merci.

J’ai l’impression que les sites se recopient les uns les autres. Ils ont tous les mêmes règles et donc les mêmes fautes. La preuve, leurs règles sont identiques aux miennes !! Ils expliquent surtout comment faire des scans XMAS et NULL mais nullement comment s’en protéger.
J’ai trouvé un site qui expliquait bien les flags et qui proposait une protection plus élargie.

# DROP paquets autres que SYN
iptables -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

# DROP paquets invalides
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# DROP paquets incomplets
iptables -A INPUT -f -j DROP

# DROP NULL
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# DROP XMAS
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# DROP SYNFIN
iptables -A INPUT -p tcp --tcp-flags ALL SYN,FIN -j DROP

# DROP FIN scan
iptables -A INPUT -p tcp --tcp-flags ALL FIN -j DROP

# DROP SYN RST
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

# DROP NMAP XMAS
iptables -A INPUT -p tcp --tcp-flags ALL URG,PSH,FIN -j DROP

# DROP NMAP 
iptables -A INPUT -p tcp --tcp-flags ALL URG,PSH,SYN,FIN -j DROP

# DROP SYN FLOOD
iptables -N SYN-FLOOD
iptables -A SYN-FLOOD -m limit --limit 1/sec --limit-burst 4 -j RETURN
iptables -A SYN-FLOOD -j DROP

# DROP port scans
iptables -N PORT-SCAN
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j PORT-SCAN
iptables -A PORT-SCAN -m limit --limit 1/s --limit-burst 4 -j RETURN
iptables -A PORT-SCAN -j DROP

# Blocage IP attaque 24h
iptables -A INPUT -m recent --name DUMBASS --rcheck --seconds 86400 -j DROP

# Levée du blocage
iptables -A INPUT -m recent --name DUMBASS --remove

Le commentaire est ambigu. As-tu bien compris la portée de cette règle ?

Euh, en quoi cette chaîne est-elle censée lutter contre un SYN flood ?

Pourquoi traiter ces paquets invalides différemment des autres type de scan, et en laisser passer un par seconde au lieu de tous les bloquer ?

Je recommande la plus grande prudence avec la correspondance “recent”. Un attaquant capable d’envoyer des paquets avec une adresse source arbitraire peut non seulement se sortir du blocage mais aussi l’exploiter pour provoquer un déni de service à l’encontre de l’utilisateur légitime d’une adresse IP usurpée.

# DROP paquets autres que SYN
iptables -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

# DROP paquets invalides
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# DROP paquets incomplets
# Force la vérification des paquets fragmentés
# DROP les paquets fragmentés
iptables -A INPUT -f -j DROP

# DROP NULL
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# DROP XMAS
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

# DROP SYNFIN
iptables -A INPUT -p tcp --tcp-flags ALL SYN,FIN -j DROP

# DROP FIN scan
iptables -A INPUT -p tcp --tcp-flags ALL FIN -j DROP

# DROP SYN RST
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP

# DROP NMAP XMAS
iptables -A INPUT -p tcp --tcp-flags ALL URG,PSH,FIN -j DROP

# DROP NMAP 
iptables -A INPUT -p tcp --tcp-flags ALL URG,PSH,SYN,FIN -j DROP

# DROP port scans
iptables -N PORT-SCAN
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j PORT-SCAN
iptables -A PORT-SCAN -j DROP

Je ne sais pas si je peux supprimer la deuxième ligne et ne garder donc que ces deux règles:

    iptables -N PORT-SCAN
    iptables -A PORT-SCAN -j DROP

# DROP SYN FLOOD
#limite le nombre de connections tcp entrantes
iptables -N syn_flood
iptables -A INPUT -p tcp --syn -j syn_flood
iptables -A syn_flood -m limit --limit 1/s --limit-burst 3 -j RETURN
iptables -A syn_flood -j DROP

Je vais alors supprimer ces deux règles.

Je répète ma question : comprends-tu la portée de cette règle ?

Si tu supprimes la deuxième ligne, la chaîne utilisateur PORT-SCAN ne sera pas parcourue par les paquets entrants. Je ne vois pas l’intérêt de passer par une chaîne utilisateur juste pour ce type de paquet. Pourquoi ne pas faire comme pour les autres ?

Quels genres de connexions TCP entrante veux-tu limiter globalement à un taux aussi faible ? Ne vaudrait-il pas mieux mettre des limites individuelles dans les règles autorisant chaque type de connexion (s’il y en a) ?

Franchement non.

Tu veux dire comme ceci ?
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j DROP

J’aimerais bien mais je ne sais pas comment écrire ce genre de règles. Peux-tu me donner un exemple ?

Franchement non.

Tu veux dire comme ceci ?
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j DROP

J’aimerais bien mais je ne sais pas comment écrire ce genre de règles. Peux-tu me donner un exemple ?

L’option -f détecte les fragments de paquets IP.

Qu’est-ce qu’un fragment ?
Un fragment est un paquet IP. Mais ce n’est pas un paquet complet (parfois appelé datagramme), il ne contient qu’une partie de la charge utile.
Un fragment est un paquet valide, contrairement à un paquet tronqué dont la taille réelle ne correspond pas à la taille annoncée dans son en-tête IP.
Un paquet IP doit être fragmenté lorsqu’il doit être transmis à travers un lien réseau dont la taille maximum de paquet (MTU) est inférieure à la taille du paquet. Pour rappel, la taille maximum d’un paquet IP est 65535 octets mais la MTU typique des liaisons ethernet est de l’ordre de 1500. Le paquet est alors divisé en fragments de taille inférieure ou égale à la MTU. Comme tout paquet IP, chaque fragment a un en-tête IP comportant notamment les adresses source et destination, le protocole (TCP, UDP, ICMP…).

Pourquoi filtrer les fragments ?
Les fragments ont été exploités par divers types d’attaques ou pour contourner les pare-feux.

  • Lorsqu’un hôte reçoit un premier fragment, il doit allouer un tampon en mémoire de taille suffisante pour contenir le paquet complet et attendre de recevoir tous les autres fragments afin de compléter le paquet originel. Un attaquant peut envoyer de faux fragments pour faire consommer des ressources à la cible et provoquer un déni de service.
  • Les informations de l’en-tête du protocole transporté (ports source et destination TCP ou UDP, type de message ICMP…) ne sont pas dupliquées dans tous les fragments. Au mieux, l’en-tête complet est contenu dans le premier fragment s’il est assez grand. Au pire, il est réparti dans plusieurs fragments s’ils sont de taille très réduite. Or les pare-feux utilisent souvent ces informations pour déterminer si un paquet doit être accepté ou bloqué.

Cependant, netfilter a une fonctionnalité appelée “suivi de connexion” (connection tracking) qui est activée notamment quand on crée une règle iptables utilisant les correspondances state ou conntrack ou quand on active la table nat. Le suivi de connexion a besoin d’examiner les paquets complets, donc il intègre son propre mécanisme de réassemblage des paquets fragmentés. Le suivi de connexion en entrée s’insère entre les chaînes PREROUTING des tables raw et mangle. En sortie, il s’insère avant la chaîne OUTPUT. Par conséquent, lorsque le suivi de connexion est activé, aucun fragment ne peut être vu dans les chaînes INPUT ou FORWARD.

Donc en pratique, ta règle n’a aucun effet. Dans le cas contraire, elle bloquerait des paquets légitimes.

Oui.

Pour limiter le nombre de connexions SSH entrantes par seconde :

iptables -A INPUT -p tcp --dport 22 --state NEW -m limit --limit 1/s --limit-burst 3 -j ACCEPT

au lieu de

iptables -A INPUT -p tcp --dport 22 --state NEW -j ACCEPT
2 J'aime