Iptables et ip6tables sont utilisés pour configurer des règles de filtrage de paquets IPv4 et IPv6 dans le noyau Linux. Il existe plusieurs tables différentes pouvant être définies et contenir des règles de filtrage qui leur sont propres.
IPtatbles in a nutshell
Les tables
Il existe 5 tables dans IPtables, la table filter,nat, mangle, security et raw et chacune possède un rôle spécifique.
filter : la table utilisé par défaut quand l’option -t n’est pas précisée, contient les chaînes :
INPUT (packets destined to local sockets)
FORWARD (packets being routed through the box)
OUTPUT (for locally-generated packets).
nat : consulté lorsqu’un paquet créant une nouvelle connexion est rencontré, contient les chaînes :
PREROUTING (for altering packets as soon as they come in)
INPUT (for altering packets destined for local sockets)
OUTPUT (for altering locally-generated packets before routing)
POSTROUTING (for altering packets as they are about to go out).
mangle : utilisé pour la modification de paquets spécialisés, contient les chaînes :
PREROUTING (for altering incoming packets before routing)
OUTPUT (for altering locally-generated packets before routing).
FORWARD (for altering packets being routed through the box)
POSTROUTING (for altering packets as they are about to go out).
raw : pour configurer des dispenses de suivi de connexion, priorité plus élevée, contient les chaînes :
PREROUTING (for packets arriving via any network interface)
OUTPUT (for packets generated by local processes)
security : utilisé pour les règles MAC (Mandatory Access Control), appelé après filter, contient :
INPUT (for packets coming into the box itself)
OUTPUT (for altering locally-generated packets before routing)
FORWARD (for altering packets being routed through the box).
Le man d’iptables contient toutes les précisions et informations nécessaires
Les chaînes
Il existe 3 chaines dans IPtables INPUT, FORWARD et OUPUT.
INPUT (en entrée)
FORWARD (cas d’un routage réseau)
OUPUT (en sortie)
Les actions
Les actions à entreprendre sur chaque chaîne de chaque table peuvent être ACCEPT, DROP, QUEUE et RETURN
ACCEPT (accepter le paquet)
DROP (le jeter)
QUEUE
RETURN
Les options utilisées pour ces actions peuvent être :
i : interface d’entrée (input)
o : interface de sortie (output)
t : table (par défaut filter contenant les chaînes INPUT, FORWARD, OUTPUT)
j : règle à appliquer (Jump)
A : ajoute la règle à la fin de la chaîne (Append)
I : insère la règle au début de la chaîne (Insert)
R : remplace une règle dans la chaîne (Replace)
D : efface une règle (Delete)
F : efface toutes les règles (Flush)
X : efface la chaîne
P : règle par défaut (Policy)
lo : localhost (ou 127.0.0.1, machine locale)
Les ports
Il existe l’option sport et dport :
sport : source port
dport : destination port
Lister les règles
Sans aucune règle, les tables d’Iptables sont vides, il en existe 5, la table filter,nat, mangle, security et raw
Il est également possible de lister les tables avec les options suivantes :
# iptables -nvL
Le résultat pour chaque table devrait ressembler à ça :
Chain INPUT (policy ACCEPT 661 packets, 42512 bytes) pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 556 packets, 38218 bytes) pkts bytes target prot opt in out source destination
Comment vider complètement IPtables ?
⚠ * BIG WARNIG * ⚠
⚠ Le serveur pourrait être inaccessible ⚠
⚠ Avant de vider complètement les tables il est très important de vérifier si les politiques par défaut des chaînes INPUT, FORWARD et OUTPUT de la table filter sont à ACCEPT ⚠
Si jamais vous décidez de vider les tables avec l’option -F en ayant les politiques par défaut des chaînes à DROP alors le firewall vous éjectera du serveur et vous ne pourrez plus vous y connecter car cette configuration fonctionne par liste blanche et donc personne n’est autorisé à se connecter sauf si vous correspondez aux règles édictées dans Iptables, mais si vous décidez de vider ces mêmes règles qui vous autorisent à vous connecter, vous serez tout simplement éjecté du serveur.
Pour vérifier vos politiques par défaut faites iptables -t filter -L ou si vous avez déjà de nombreuses règles qui rendent la lecture difficile :
Si vous souhaitez vider complètement les tables et effacer toutes les règles les commandes sont les suivantes, <NomDeVotreTable> peut être filter,nat, mangle, security ou raw :
# iptables -t <NomDeVotreTable> -F
Les commandes
WARNING : Faut vraiment VRAIMENT savoir ce que l’ont fait pour tester ça sur un serveur, voilà c’est dit.
# Vider les tables actuelles iptables -t filter -F # Vider les tables de la table nat (translation) iptables -t nat -F # Vider les règles personnelles iptables -t filter -X
Normalement (Si vous n’avez pas merdé et que votre serveur est toujours accessible) en faisant un iptables -L tout sera vide :
# Remetre la numérotation des chaînes à zéro iptables -t filter -Z iptables -t nat -Z iptables -t mangle -Z iptables -t raw -Z iptables -t security -Z
# ------------------------------------------------- # # --- Politique par défaut des tables --- # # ------------------------------------------------- # # Fonctionnement par liste blanche iptables -t filter -P INPUT DROP iptables -t filter -P FORWARD DROP iptables -t filter -P OUTPUT DROP
# ------------------------------------------------- # # --- Politique des autres tables --- # # ------------------------------------------------- # # Les tables nat, mangle, raw et security sont ici # laissées par défaut, c'est à dire toutes à ACCEPT
# ------------------------------------------------- # # --- Règles générales --- # # ------------------------------------------------- # # Conserver les connexions en attente (SSH, Ftp, ...) iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Autoriser loopback iptables -t filter -A INPUT -i lo -j ACCEPT iptables -t filter -A OUTPUT -o lo -j ACCEPT
# ------------------------------------------------- # # --- Exception : IP à ne jamais bannir --- # # ------------------------------------------------- # # Note : Ne sert à rien si utilisation de Fail2Ban # Dans ce cas, configurer l'exception dans Fail2Ban iptables -A INPUT -s 88.44.22.11 -j ACCEPT iptables -A OUTPUT -d 88.44.22.11 -j ACCEPT
# ------------------------------------------------- # # --- Réponse du script --- # # ------------------------------------------------- # echo -e ' \e[0;31m ┌───────────────────────────────────────────────────┐ \e[0;31m │ \e[1;33m Vos règles IPtables ont bien été prises en compte \e[0;31m│ \e[0;31m └───────────────────────────────────────────────────'
Explications de la configuration
Réinitialisation des tables
Vider les tables actuelles
Normalement, les tables filter et nat devraient suffire..
C’est le principe du fonctionnement par liste blanche, on bloque absolument tout et, au besoin, on autorisera les accès.
iptables -t filter -P INPUT DROP iptables -t filter -P FORWARD DROP iptables -t filter -P OUTPUT DROP
Table nat
La table nat n’accepte pas que la politique prenne la valeur DROP
Error : The "nat" table is not intended for filtering, the use of DROP is therefore inhibited
Les autres tables : mangle, security et raw
Ces tables n’étant pas destinées à filtrer, on ne devrait pas définir leur politiques à DROP
*Il est cepedant possible de le faire, en passant les politiques par défaut de mangle, security et raw à DROP, par contre, pour avoir accès au serveur, il faudra également autoriser les accès pour ces mêmes tables.
Par exemple si filter et mangle sont par défaut à DROP et que l’on souhaite accéder au serveur en SSH il faudra créer une règle pour ces deux tables :
Sans cette règle une tentative de connexion en SSH sera par exemple impossible car state permet d’accéder à l’état de suivi de connexion pour des paquets.
# Conserver les connexions en attente (SSH, Ftp, ...) iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEP
ESTABLISHED : signifie que le paquet est associé à une connexion qui a vu des paquets dans les deux directions.
NEW : signifie que le paquet a démarré une nouvelle connexion ou est associé à une connexion qui n’a pas vu de paquets dans les deux directions.
RELATED : signifie que le paquet démarre une nouvelle connexion, mais est associé à une connexion existante, telle qu’un transfert de données FTP ou une erreur ICMP.
Autoriser loopback
Le loopback est important pour la communication interne du serveur, comme un serveur DNS, une connexion interne à une BDD, …
# Autoriser loopback iptables -t filter -A INPUT -i lo -j ACCEPT iptables -t filter -A OUTPUT -o lo -j ACCEPT
Ouvertures de ports
Autoriser le ping
Dans ce cas on autorise toute les connexions ICMP, ce qui n’est pas forcément prudent.
iptables -t filter -A INPUT -p icmp -j ACCEPT iptables -t filter -A OUTPUT -p icmp -j ACCEPT
Le mieux serait de restreindre la connexion au type echo-reply/echo-request.
# autoriser ping ICMP intérieur vers extérieur iptables -t filter -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
# autoriser ping ICMP extérieur vers intérieur iptables -t filter -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
Cependant là encore la méthode n’est pas bonne car de nombreux protocoles utilisent ICMP et ses caractéristiques, parfois très utiles comme debug, le flag DF, les MTU/MSS… Pour plus de détails sur les types ICMP : http://www.informit.com/articles/article.aspx?p=26557&seqNum=5
Doit-on bloquer ICMP ?
Selon les recommandations de ce site http://shouldiblockicmp.com/ il faudrait obligatoirement autoriser les types suivants afin que le réseau fonctionne correctement :
# Autoriser certain type ICMP (comme le ping) iptables -t filter -A INPUT -p icmp --icmp-type 0 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 2 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 2 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 3 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 3 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 8 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 11 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 11 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 128 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 128 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 129 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 129 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 133 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 133 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 135 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 135 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 136 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 136 -j ACCEPT iptables -t filter -A INPUT -p icmp --icmp-type 137 -j ACCEPT iptables -t filter -A OUTPUT -p icmp --icmp-type 137 -j ACCEPT
Connexion SSH
Les options --dport et --sport sont un raccourcis pour --destination-port et --source-port