Outils pour utilisateurs

Outils du site


Ceci est une ancienne révision du document !


IPtables

Pour manipuler les poignées de Netfilter, les outils «iptables» ont été développés à partir du noyau Linux 2.4, à partir de 1998. Avant ça, il y a eu d'abord «ipfwadm» avec les noyaux 2.0, très rudimentaire, puis «ipchains» avec les noyaux 2.2.

Bien que frappé d'obsolescence au profit de Nftables», cette suite d'outils (au 29/03/2025) a vu sa dernière révision en novembre 2024. À ce jour, de très nombreux firewalls en exploitation sont encore construits avec ces outils ou avec des surcouches de ces outils, si bien qu'il faut encore en parler.

Des règles de base pour IPv4

Pour cette étude, comme d'habitude, une maquette virtuelle fera l'affaire. Reprenons celle utilisée pour l'exposé sur DHCP: Maquette virtuelle La station qui fait office de routeur/DHCP/DNS va en plus devoir assurer la protection du LAN en vert, autant en IPv4 d'abord.

Protection du serveur lui-même

  1. Étant serveur DNS et DHCP pour le LAN 192.168.61.0/24, il doit accepter toutes les requêtes entrant par enp7s0 sur les ports concernés à savoir:
    • port 53 pour DNS;
    • port 67 pour DHCP.
  2. En revanche, ces requêtes ne doivent pas être acceptées venant du LAN 192.168.60.0/24.
  3. l'accès à Telnet ne doit être autorisé qu'à 192.168.61.254, station de l'administrateur
  4. Rien ne doit entrer sur enp1s0 hormis les réponses aux connexions que lui-même a initiées, ce qui inclut le nécessaire pour ses mises à jour et pour le bon fonctionnement du cache DNS.

Nous pouvons faire ceci de suite:

iptables -t filter -A INPUT -i enp7s0  -p udp -m multiport --dports 53,67 -j ACCEPT
  • -t filter indique que l'on charge dans la table «Filter», mais ceci est optionnel parce qu'implicitement, c'est cette table qui est choisie;
  • -A INPUT Ajoute à la chaîne «INPUT» ce qui suit:
    • -i enp7s0 «input» enp7s0
    • -p udp «protocol» UDM
    • -m multiport «match» multiport. C'est pour signaler que l'on a besoin d'un module de test additionnel, ici un module capable de tester si un port dans le paquet se trouve dans la liste (53,67)
    • -j ACCEPT Alors si un paquet entrant par enp7s0 contient un datagramme udp avec un port (source ou destination) égal à 53 ou 67, il faut laisser passer.
iptables -A INPUT -i enp7s0 -p tcp --dport 23 -s 192.168.61.254 -j ACCEPT

Si, en entrant par enp7s0, ça vient de la source 192.168.61.254 (-s 192.168.61.254) à destination du port 23 (–dport 23) On accepte, car c'est le port Telnet ouvert exclusivement pour la station de l'administrateur.

iptables -A INPUT -i enp1s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Cette fois-ci nous nous occupons de ce qui entre par enp1s0

  • -m conntrack ici nous faisons appel au module conntrack pour vérifier si l'état d'un paquet qui entre est dû à une connexion déjà établie ou en relation avec une connexion déjà établie. Si c'est le cas, le paquet est accepté.

Un exemple: le routeur/DHCP/DNS a envoyé une requête à un DNS «SOA». C'est un paquet sortant autorisé par défaut ici. La réponse à ce paquet est considérée par le module conntrack comme faisant partie d'une connexion déjà établie. C'est facile à faire en TCP, moins en UDP mais il est fort, ce module…

En revanche, quelqu'un de l'extérieur enverrait une requête DNS sur enp1s0, elle serait considérée comme «NEW» et donc rejetée par cette règle.

Nous allons tout de même accepter ICMP sur les deux interfaces:

iptables -A INPUT -p ICMP -j ACCEPT

Pour finir, la règle par défaut qu'il vaut mieux définir en dernier, de manière à ce que l'administrateur ait déjà l'autorisation d'accéder à la machine depuis sa station de travail:

iptables -P INPUT DROP

Concernant le LAN 192.168.61.0/24

Il ne faut permettre dans le sens enp1s0 → enp7s0 que les connexions établies ou relatives à des connexions établies. On sait déjà faire, il suffit de l'appliquer ici à la chaîne FORWARD. C'est toujours sous-entendu du filtrage. Donc:

iptables -A FORWARD -i enp1s0 -o enp7s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

-i comme «input» et -o comme «output». Ce qui entre pas enp7s0 pour ressortie par enp1s0 n'a à priori aucune raison d'être filtré ici. Mais nous avons appris dans l'exercice de routage qu'il fallait faire du masquage d'adresses dans ce sens pour assurer le chemin de retour depuis l'internet vers 192.168.61.0/24 en passant par 192.168.60.0/24:

iptables -t nat -A POSTROUTING  -o enp1s0 -j MASQUERADE

Dans la table «nat», il faut ici le spécifier, dans la chaîne POSTROUTING , ce qui sort par enp1s0

Et maintenant pour IPv6

Toujours la même maquette, mais avec les adresses IPv6 suivantes pour le serveur:

  • enp1s0 dans le LAN orange:
    • 2a01:e0a:875:b1d0:5054:ff:fe74:45f2 lien global
    • fe80::5054:ff:fe74:45f2 lien local
  • enp7s0 dans le LAN vert:
    • 2a01:e0a:875:b1d2::1 lien global
    • fe80::5054:ff:fe78:2d7e lien local

Protection du serveur:

Depuis l'extérieur, l'idée reste la même que pour IPv4:

ip6tables -A INPUT -i enp1s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Cependant, il faut ajouter icmp pour les annonces et découvertes des voisins, aussi bien du côté orange que du côté vert:

ip6tables -A INPUT -p ipv6-icmp -j ACCEPT

En ce qui concerne les adresses de lien local, nous n'allons pas être paranoïaques au point de suspecter l'entourage immédiat du serveur:

ip6tables -A INPUT -s fe80::/64 -j ACCEPT

Avant d'appliquer la règle par défaut sur les entrées, il faut autoriser les membres du LAN vert à interroger le serveur DNS:

ip6tables -A INPUT -p udp --dport 53 -j ACCEPT

Et enfin:

ip6tables -P INPUT DROP

Concernant la délégation 2a01:e0a:875:b1d2::/64

Ici plusieurs options sont possibles. Avec IPv4, les nouvelles connexions depuis l'internet vers le LAN vert sont naturellement impossibles puisque les IP 192.168.61.0/24 ne sont pas routables, mais avec des adresses lien-global routables, le problème est différent.

Le plus simple est juste d'interdire aux nouvelles connexions entrant pas enp1s0 de traverser le routeur

ip6tables -A FORWARD -i enp1s0 -m conntrack --ctstate NEW -j REJECT
ip6tables -A FORWARD -i enp1s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Ainsi comme pour IPv4 seules les connexions initiées depuis l'intérieur de la délégation ouvriront le pare-feu pour laisser passer les réponses.

Ici en revanche, il n'est pas nécessaire de faire du marquage d'adresse puisque les adresses lien-global IPv6 dans la délégation sont routables et que le routeur de la Freebox sait y accéder.

Il n'y a à priori plus rien à faire en fonction du cahier des charges initial

Vérifications

Depuis 192.168.61.0/24 vers l'internet

Lors du démarrage d'un client du LAN vert, Nous pouvons vérifier sa configuration IPv4:

ip -4 addr
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: enp1s0:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet 192.168.61.102/24 brd 192.168.61.255 scope global dynamic enp1s0
       valid_lft 2799sec preferred_lft 2799sec

ip -4 route 
default via 192.168.61.1 dev enp1s0 
192.168.61.0/24 dev enp1s0 proto kernel scope link src 192.168.61.102 
La configuration est correcte, preuve que le dialogue avec DHCP se passe bien.
host www.debian.org 192.168.61.1

Using domain server:
Name: 192.168.61.1
Address: 192.168.61.1#53
Aliases: 

www.debian.org has address 194.177.211.216
www.debian.org has address 130.89.148.77
www.debian.org has IPv6 address 2001:648:2ffc:deb:216:61ff:fe2b:6138
www.debian.org has IPv6 address 2001:67c:2564:a119::77

Le client peut interroger le DNS 192.168.61.1 et recevoir la réponse.

telnet 192.168.61.1
Trying 192.168.61.1...
...
telnet: Unable to connect to remote host: Connexion terminée par expiration du délai d'attente
Car la cible DROP réagit ainsi: Elle jette le paquet dans un puits sans fond, sans renvoyer de notification à la source. Telnet n'est donc pas accessible à cette station.

Un client d'adresse 192.168.61.101 fait un ping sur 194.177.211.216

ping -c1 194.177.211.216

PING 194.177.211.216 (194.177.211.216) 56(84) bytes of data.
64 bytes from 194.177.211.216: icmp_seq=1 ttl=57 time=65.6 ms

--- 194.177.211.216 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 65.622/65.622/65.622/0.000 ms
Le routage masqué fonctionne et les clients verts accèdent bien à l'internet.

Pour tester la solidité du serveur depuis l'extérieur, c'est-à-dire depuis le LAN orange, nous n'allons pas prendre des gants, mais plutôt l'outil «Nmap» Qui ne doit JAMAIS être utilisé en dehors des réseaux dont on a la charge!!! C'est un outil de vérification à l'usage des administrateurs de réseaux.

Voici le résultat:

nmap -sT -sU 192.168.60.200

Starting Nmap 7.93 ( https://nmap.org ) at 2025-03-31 15:14 CEST
Nmap scan report for 192.168.60.200
Host is up (0.00017s latency).
All 2000 scanned ports on 192.168.60.200 are in ignored states.
Not shown: 1000 filtered tcp ports (no-response), 1000 open|filtered udp ports (no-response)
MAC Address: 52:54:00:74:45:F2 (QEMU virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 42.29 seconds
Nmap n'a rien trouvé d'ouvert, ni en TCP ni en UDP. Réconfortant.

Voyons maintenant avec IPv6. D'abord la configuration du client:

ip -6 addr ls
1: lo:  mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: enp1s0:  mtu 1500 state UP qlen 1000
    inet6 2a01:e0a:875:b1d2:5054:ff:feb7:6681/64 scope global dynamic mngtmpaddr 
       valid_lft 86379sec preferred_lft 14379sec
    inet6 fe80::5054:ff:feb7:6681/64 scope link
       valid_lft forever preferred_lft forever
       
ip -6 route ls
2a01:e0a:875:b1d2::/64 dev enp1s0 proto kernel metric 256 expires 86371sec pref medium
fe80::/64 dev enp1s0 proto kernel metric 256 pref medium
default via fe80::5054:ff:fe78:2d7e dev enp1s0 proto ra metric 1024 expires 151sec hoplimit 64 pref medium
Les adresses sont correctes, la route par défaut est correcte aussi.

Depuis la station dans le LAN vert il faut vérifier qu'une nouvelle connexion IPv6 peut en sortir et que les réponses peuvent entrer en chargeant par exemple la page html par défaut de [2001:41d0:305:2100::2cd5]:

wget http://[2001:41d0:305:2100::2cd5]/index.html

--2025-03-31 18:54:54--http://[2001:41d0:305:2100::2cd5]/index.html
Connexion à [2001:41d0:305:2100::2cd5]:80… connecté.
requête HTTP transmise, en attente de la réponse… 200 OK
Taille : 16 [text/html]
Sauvegarde en : « index.html »

index.html                       100%[==========================================================>]      16  --.-KB/s    ds 0s      

2025-03-31 18:54:54 (682 KB/s) — « index.html » sauvegardé [16/16]
Tout va bien mais n'essayez pas de faire la même chose avec la même adresse. Moi je peux mais pas vous 8-)

Essayons maintenant d'ouvrir une connexion Telnet (port 23) depuis justement 2001:41d0:305:2100::2cd5 vers 2a01:e0a:875:b1d2:5054:ff:feb7:6681:

telnet 2a01:e0a:875:b1d2:5054:ff:feb7:6681
Trying 2a01:e0a:875:b1d2:5054:ff:feb7:6681...
telnet: Unable to connect to remote host: Connection refused
Comme c'était prévu. Mais nous savons que

IPtables: Dernière modification le: 31/03/2025 à 17:14 par prof