Généralités
Iptables est un utilitaire avec une interface en ligne de commande permettant de configurer le firewall (pare-feu) Netfilter intégré dans le noyau Linux.
Il permet de filtrer, rediriger et contrôler le trafic réseau (entrant, sortant, local).
Installation
Il suffit d’installer le paquet.
apt install iptables
Déclaration des règles
Fonctionnement
Le trafic est traité selon des tables (filter, nat, mangle, raw).
Chaque table contient des chaînes (chains).
Une chaîne est composée de règles, qui sont évaluées séquentiellement.
Chaque règle applique une action (target) : ACCEPT, DROP, REJECT, LOG, DNAT, SNAT, etc.
Exemple de schéma :
Paquet réseau → Chaîne → Liste de règles → Action finale
Tables principales
Table | Usage principal | Chaînes principales |
---|---|---|
filter | Filtrage classique des paquets | INPUT, OUTPUT, FORWARD |
nat | Traduction d’adresses | PREROUTING, POSTROUTING, OUTPUT, CHAIN |
mangle | Modification des paquets | PREROUTING, OUTPUT, FORWARD, INPUT |
raw | Configuration avancée | PREROUTING, OUTPUT |
Notes :
filter : utilisée pour accepter ou bloquer les paquets.
nat : utilisée surtout pour les serveurs qui font du routage/NAT.
mangle : permet de marquer ou modifier certains champs des paquets avant routage.
raw : permet de configurer certains paquets pour qu’ils ne passent pas par le suivi de connexion
INPUT → paquets entrants destinés au serveur local.
OUTPUT → paquets sortants générés par le serveur local.
FORWARD → paquets qui transitent par le serveur (routeur/NAT).
PREROUTING → règles appliquées avant le routage, utile pour NAT et marquage.
POSTROUTING → règles appliquées après le routage, souvent pour SNAT/MASQUERADE.
Actions principales
Action / Target | Description |
---|---|
ACCEPT | Accepter le paquet et le laisser passer. |
DROP | Bloquer le paquet silencieusement (pas de réponse). |
REJECT | Bloquer le paquet et envoyer un message d’erreur au client. |
LOG | Journaliser le paquet dans syslog (ne le bloque pas). |
RETURN | Arrêter de traiter la chaîne courante et revenir à la chaîne précédente. |
SNAT | (dans nat) Modifier l’adresse source (Source NAT). |
DNAT | (dans nat) Modifier l’adresse de destination (Destination NAT). |
MASQUERADE | (dans nat) Variante de SNAT pour IP dynamique (ex. Internet partagé). |
MARK | (dans mangle) Marquer le paquet pour traitement ultérieur (QoS, routage). |
Exemple simple de pare-feu
Pour plus de souplesse, nous allons écrire nos règles sous forme de script bash.
Créons le script.
nano /etc/init.d/firewall
Et on y écrit.
#!/bin/bash
On efface toutes les règles précédentes pour partir sur de bonnes bases.
# Vider les règles existantes : Table filter (règles classiques)
iptables -t filter -F
iptables -t filter -X
On bloque par défaut tout le trafic.
# Politique par défaut : tout bloquer (entrant, sortant, transité)
iptables -t filter -P INPUT DROP
iptables -t filter -P OUTPUT DROP
iptables -t filter -P FORWARD DROP
On ne ferme pas les connexions déjà établies ou liées.
# Autoriser les connexions établies ou liées (entrant, sortant)
iptables -t filter -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
On autorise les connexions locales (on ne va pas se bloquer nous-mêmes !).
# Autoriser les connexions locales (loopback)
iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT
Note : lo signifie localhost (le serveur lui-même).
Tout est bloqué, il ne nous reste plus qu’à ouvrir les ports utilisés.
Ouvrir des ports
À partir de maintenant, observons plus en détail les paramètres de iptables.
-t : sert à sélectionner la table (par défaut : filter)
-A : sert à indiquer le sens du trafic (INPUT (entrant) ou OUTPUT (sortant))
-p : sert à spécifier le protocole (TCP ou UDP en principe)
–sport et –dport : servent à spécifier les ports source ou destination (nous utiliserons principalement –dport)
-j : sert à indiquer l’action à appliquer (nous nous servirons de ACCEPT et de DROP pour respectivement accepter et refuser le paquet).
Plus nous serons précis, plus nous serons sécurisés. Renseigner ces quelques règles est donc le minimum.
Ainsi, une règle simple aura la forme suivante.
iptables -t filter -A INPUT/OUTPUT -p protocole –dport port_a_ouvrir -j ACCEPT
Notez que si vous voulez un échange, il faut toujours ouvrir le port dans les deux sens (INPUT et OUTPUT), logique.
Exemple si l’on a un serveur web (port 80).
iptables -t filter -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
ou (sans -t filter)
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
Les deux commandes fonctionnent exactement de la même manière, car par défaut, si tu ne précises pas de table, iptables utilise la table filter, qui est la table principale.
Il ne vous reste qu’à spécifier toutes les règles nécessaires.
Voici un petit tableau pour vous aider (il s’agit de données par défaut).
service | port d’écoute | protocole |
SSH | 22 | tcp |
HTTP | 80 | tcp |
FTP | 20 et 21 | tcp |
SMTP | 25 | tcp |
POP3 | 110 | tcp |
IMAP | 143 | tcp |
DNS | 53 | tcp et udp |
Cas particulier du ping
Le ping est basé sur un protocole particulier (ICMP) qui n’a pas de port prédéfini. Mais il faut absolument autoriser le ping car c’est la méthode la plus couramment utilisée pour savoir si votre serveur est en vie. Voici donc les règles.
iptables -A INPUT -p icmp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT
Allez un peu plus loin
Outre que c’est l’outil de base de tout système de sécurité, Iptables permet des manipulations plus poussées que filtrer des ports. Je vais vous montrer quelques exemples.
Flood ou déni de service
Ce genre d’attaque vise à surcharger la machine de requête. Il est possible de s’en prémunir directement au niveau du firewall.
iptables -A INPUT -p tcp --syn -m limit --limit 15/second -j ACCEPT
Le flags TCP –syn engendre des demandes de connexions, et le but de cette règle est donc de les limiter à 10 par seconde (champs limit).
Il est cependant déconseillé de descendre en dessous de certaines limites (sous peine de bloquer des utilisateurs légitimes).
Il est aussi déconseillé de monter au dessus de certaines limites (sous peine de réduire la protection contre les SYN flood).
On peut faire de même avec les protocoles UDP et ICMP.
iptables -A INPUT -p udp -m limit --limit 30/second -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/second -j ACCEPT
Notez cependant que ce type d’attaque permet de faire tomber le serveur, mais pas d’en prendre l’accès.
Scan de ports
On peut aussi limiter un tant soit peu le scan de ports (qui consiste à tester tous vos ports afin de détecter ceux qui sont ouverts). Pour cela, une règle de ce genre irait.
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 5/s -j ACCEPT
C’est un peu le même principe que ci-dessus. Sachant qu’une connexion TCP en bon et due forme requiert trois paquets avec trois flags différents, on voit tout de suite la finesse de cette règle qui peut travailler paquet par paquet.
Notez que cette règle basique n’est pas très efficace, c’est une protection de base.
Bannir une IP
Si vous repérez dans les logs ou autre une adresse IP suspecte, vous pouvez la bannir aisément au niveau du firewall via la commande :
iptables -A INPUT -s adresse_ip -j DROP
Notez cependant qu’il n’est pas conseillé de bannir les IP à tour de bras.
Exemple de script
Ci-dessous, je vous montre un exemple de script basique autorisant le minimum pour un serveur HTTP, FTP, SSH, MAIL et résolution de DNS. Je vous encourage à lire des docs et des tutos plus complets si vous voulez aller plus loin dans le paramétrage de votre firewall.
Créer un nouveau fichier nommé /etc/init.d/firewall.
nano /etc/init.d/firewall
Et ajouter le script ci-dessous dedans.
#!/bin/sh
### BEGIN INIT INFO
# Provides: firewall
# Required-Start: $network $syslog
# Required-Stop: $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: firewall iptables
# Description: Script firewall de configuration des regles iptables
### END INIT INFO
RETVAL=0
case "$1" in
'start')
echo -e "\nChargement des regles du firewall…\n"
# Vider toutes les règles actuelles de la table filter
iptables -t filter -F
iptables -t filter -X
echo "Vidage des regles de la table filter : [OK]"
# Vider toutes les règles actuelles de la table nat
iptables -t nat -F
iptables -t nat -X
echo "Vidage des regles de la table nat : [OK]"
# Vider toutes les règles actuelles de la table mangle
iptables -t mangle -F
iptables -t mangle -X
echo "Vidage des regles de la table mangle : [OK]"
# Vider toutes les règles actuelles de la table raw
iptables -t raw -F
iptables -t raw -X
echo "Vidage des regles de la table raw : [OK]"
# Interdire toutes les connexions entrantes et transitants
iptables -P INPUT DROP
iptables -P FORWARD DROP
echo "Interdire toutes les connexions entrantes et transitants : [OK]"
# Interdire toutes les connexions sortantes
iptables -P OUTPUT DROP
echo "Interdire toutes les connexions sortantes : [OK]"
# Chargement du module ip_conntrack_ftp pour gérer correctement les connexions FTP
modprobe ip_conntrack_ftp
echo "Chargement du module : [OK]"
# Autoriser les connexions établies ou liées
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
echo "Autoriser les connexions etablies ou liees : [OK]"
# Autoriser les connexions localhost (loopback)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -i lo -j ACCEPT
echo "Autoriser loopback : [OK]"
# Autoriser ICMP (Ping)
iptables -A INPUT -p icmp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT
echo "Autoriser ping : [OK]"
# IP a blacklister
# iptables -A INPUT -s ADRESSE_IP -j DROP
echo "Mise a jour des IP blacklistees : [OK]"
# Limiter le Syn-Flood (TCP, UDP et ICMP)
iptables -A INPUT -p tcp --syn -m limit --limit 15/second -j ACCEPT
iptables -A INPUT -p udp -m limit --limit 30/second -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/second -j ACCEPT
echo "Limiter le Syn-Flood : [OK]"
# Limiter le scan de ports
iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 5/s -j ACCEPT
echo "Limiter le scan de ports : [OK]"
# Bloquer le Spoofing
iptables -N SPOOFED
iptables -A SPOOFED -s 127.0.0.0/8 -j DROP
iptables -A SPOOFED -s 169.254.0.0/12 -j DROP
iptables -A SPOOFED -s 172.16.0.0/12 -j DROP
iptables -A SPOOFED -s 192.168.0.0/16 -j DROP
iptables -A SPOOFED -s 10.0.0.0/8 -j DROP
iptables -A INPUT -j SPOOFED
iptables -A FORWARD -j SPOOFED
echo "Bloquer le Spoofing : [OK]"
# Forcer la vérification des paquets SYN
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
echo "Bloquer les paquets non SYN : [OK]"
# Forcer la vérification des paquets fragmentés
iptables -A INPUT -f -j DROP
echo "Bloquer les paquets fragmentes : [OK]"
# Supprimer les paquets mal formés XMAS
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
echo "Bloquer les paquets XMAS : [OK]"
# Supprimer les paquets mal formés NULL
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
echo "Bloquer les paquets NULL : [OK]"
# Supprimer les paquets non valides
iptables -A INPUT -m state --state INVALID -j DROP
echo "Bloquer les paquets non valides : [OK]"
# Autoriser SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
echo "Autoriser SSH : [OK]"
# Autoriser HTTP
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
echo "Autoriser HTTP : [OK]"
# Autoriser HTTPS
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
echo "Autoriser HTTPS : [OK]"
# Autoriser FTP
iptables -t raw -A PREROUTING -p tcp --dport 21 -j CT --helper ftp
iptables -A OUTPUT -p tcp --dport 20:21 -j ACCEPT
iptables -A INPUT -p tcp --dport 20:21 -j ACCEPT
echo "Autoriser FTP : [OK]"
# Autoriser DNS
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
echo "Autoriser DNS : [OK]"
# Autoriser NTP
iptables -A OUTPUT -p udp --dport 123 -j ACCEPT
echo "Autoriser NTP : [OK]"
# Autoriser SMTP
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 25 -j ACCEPT
echo "Autoriser SMTP : [OK]"
# Autoriser POP3
iptables -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 110 -j ACCEPT
echo "Autoriser POP3 : [OK]"
# Autoriser IMAP
iptables -A INPUT -p tcp --dport 143 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 143 -j ACCEPT
echo "Autoriser IMAP : [OK]"
echo -e "\nConfiguration iptables terminee\n"
RETVAL=$?
;;
'stop')
echo -e "\nRegles par defaut du firewall..\n"
# Vider toutes les règles
iptables -t filter -F
iptables -t filter -X
echo "Vidage des regles de la table filter : [OK]"
iptables -t nat -F
iptables -t nat -X
echo "Vidage des regles de la table nat : [OK]"
iptables -t mangle -F
iptables -t mangle -X
echo "Vidage des regles de la table mangle : [OK]"
iptables -t raw -F
iptables -t raw -X
echo "Vidage des regles de la table raw : [OK]"
# Politique par défaut ACCEPT
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
echo "Autoriser toutes les connexions : [OK]"
echo -e "\nConfiguration iptables terminee\n"
RETVAL=$?
;;
'status')
echo ""
iptables -L -n --line-numbers
echo ""
RETVAL=$?
;;
*)
echo -e "\nUsage: $0 { start | stop | status }\n"
RETVAL=1
;;
esac
exit $RETVAL