IPtables

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

# iptables -t filter -L (équivalent à iptables -L)
# iptables -t nat -L
# iptables -t mangle -L
# iptables -t security -L
# iptables -t raw -L

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 :

# iptables -t filter -L | grep -i \(policy   
Chain INPUT (policy DROP)
Chain FORWARD (policy DROP)
Chain OUTPUT (policy DROP)

Si vos politiques sont à DROP il faut les passer à ACCEPT avant de vider les tables

# iptables -t filter -P INPUT ACCEPT
# iptables -t filter -P FORWARD ACCEPT
# iptables -t filter -P OUTPUT ACCEPT

Vérification :

# iptables -t filter -L | grep -i \(policy
Chain INPUT (policy ACCEPT)
Chain FORWARD (policy ACCEPT)
Chain OUTPUT (policy ACCEPT)

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 :

$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Configuration de base

Cette configuration de base d’IPtables ouvre le strict minimum.

#!/bin/sh

# ------------------------------------------------- #
# --- Réinitialisations des tables --- #
# ------------------------------------------------- #
# Vider les tables actuelles
iptables -t filter -F
iptables -t nat -F
iptables -t mangle -F
iptables -t raw -F
iptables -t security -F

# Vider les règles personnalisées
iptables -t filter -X
iptables -t nat -X
iptables -t mangle -X
iptables -t raw -X
iptables -t security -X

# 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

# ------------------------------------------------- #
# --- Ouvertures de ports --- #
# ------------------------------------------------- #
# Autoriser certain type ICMP
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

# SSH In/Out
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 22 -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..

iptables -t filter -F
iptables -t nat -F
iptables -t mangle -F
iptables -t raw -F
iptables -t security -F

Vider les règles personnalisées

Normalement, les tables filter et nat devraient suffire.

iptables -t filter -X
iptables -t nat -X
iptables -t mangle -X
iptables -t raw -X
iptables -t security -X

Remettre la numérotation des chaînes à zéro

Normalement, les tables filter et nat devraient suffire.

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

Table filter

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 :

iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 22 -j ACCEPT
iptables -t mangle -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t mangle -A OUTPUT -p tcp --sport 22 -j ACCEPT

Sinon on ne passera pas.

Règles générales

Conserver les connexions en attente

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

iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 22 -j ACCEP

Mémo ports/services

Un petit résumé des ports à ouvrir pour faire fonctionner les services de base.

# SSH In/Out
iptables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
# DNS In/Out
iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT
# NTP Out (Serveur de temps)
iptables -t filter -A OUTPUT -p udp --dport 123 -j ACCEPT
# ---Si vous hébergez un sevreur web :
# HTTP + HTTPS Out
iptables -t filter -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 443 -j ACCEPT
# HTTP + HTTPS In
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT
# Tomcat
iptables -t filter -A INPUT -p tcp --dport 8443 -j ACCEPT
# --- FTP ----------------------------------:
iptables -t filter -A INPUT -p tcp --dport 20 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 20 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 21 -j ACCEPT
# --- FTPS ---------------------------------:
iptables -t filter -A INPUT -p tcp --dport 990 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 990 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 989 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 989 -j ACCEPT
# --- FTPS range for passive mode -----------
iptables -I INPUT -p tcp --destination-port 10090:10100 -j ACCEPT
# GlassFish
iptables -t filter -A INPUT -p tcp --dport 8080 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 4848 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 8080 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 4848 -j ACCEPT
# --- MAILS ----------------------------------:
# Mail SMTP:25
iptables -t filter -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 25 -j ACCEPT

# Mail POP3:110
iptables -t filter -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 110 -j ACCEPT

# Mail IMAP:143
iptables -t filter -A INPUT -p tcp --dport 143 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 143 -j ACCEPT

# Mail IMAPS:993
iptables -t filter -A INPUT -p tcp --dport 993 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 993 -j ACCEPT

# Mail POP3S:995
iptables -t filter -A INPUT -p tcp --dport 995 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 995 -j ACCEPT

# --- POSTFIX ADMIN ----------------------------------:
iptables -t filter -A INPUT -p tcp --dport 10042 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 10042 -j ACCEPT

# --- OpenDKIM ----------------------------------:
#iptables -t filter -A INPUT -p tcp --dport 8891 -j ACCEPT
#iptables -t filter -A OUTPUT -p tcp --dport 8891 -j ACCEPT
# Note : Pas la peine aparement

# --- AMAVIS ----------------------------------:
iptables -t filter -A INPUT -p tcp --dport 10025 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 10025 -j ACCEPT
# --- TELNET ------------------------------------- :
iptables -t filter -A INPUT -p tcp --dport 23 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 23 -j ACCEPT
# --- Wowza Streaming  ----------------------------------:
#iptables -t filter -A INPUT -p tcp --dport 10025 -j ACCEPT
#iptables -t filter -A OUTPUT -p tcp --dport 10025 -j ACCEPT
# --- OwnCloud collaboration ----------------------------------: 
iptables -t filter -A INPUT -p tcp --dport 9980 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 9980 -j ACCEPT
#  --- IRC  ----------------------------------:
iptables -t filter -A INPUT -p tcp --dport 6667 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 6667 -j ACCEPT
#  --- Hexo   ----------------------------------
iptables -t filter -A INPUT -p tcp --dport 4000 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 4000 -j ACCEPT
# --- ELK -------------------------------------------------------
# - Elasticksearch
iptables -t filter -A INPUT -p tcp --dport 9200 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 9200 -j ACCEPT
# - Kibana
iptables -t filter -A INPUT -p tcp --dport 5601 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 5601 -j ACCEPT
# - Logstash
iptables -t filter -A INPUT -p tcp --dport 5044 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 5044 -j ACCEPT
#iptables -t filter -A INPUT -p udp --dport 5044 -j ACCEPT
#iptables -t filter -A OUTPUT -p udp --dport 5044 -j ACCEPT
iptables -I INPUT -p tcp --destination-port 9600:9700 -j ACCEPT
# --- Grafana -------------------------------------------------------
iptables -t filter -A INPUT -p tcp --dport 3000 -j ACCEPT
# MYSQL 
iptables -t filter -A INPUT -p tcp --dport 3306 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 3306 -j ACCEPT
# Boulets
#iptables -I INPUT -s 5.101.7.162 -j DROP

IPtables persistant ?

WARNING
Pour un IPtptable persistant. Pour ne pas avoir à reload les règles a chaque reboot.
En cas de problème on ne pourra plus acceder au serveur. Réinstalaltion obligatoire du système
https://www.thomas-krenn.com/en/wiki/Saving_Iptables_Firewall_Rules_Permanentl

Documentations

https://www.booleanworld.com/depth-guide-iptables-linux-firewall/
http://www.informit.com/articles/article.aspx?p=26557&seqNum=5
http://shouldiblockicmp.com/
https://inetdoc.net/guides/iptables-tutorial/
https://github.com/trimstray/iptables-essentials
https://gist.github.com/jirutka/3742890

> Partager <