Iptables
Présentation
Iptables est un moyen de configurer netfilter (pare-feu au niveau du noyau linux) en utilisant différentes tables : INPUT, FORWARD et OUTPUT. Il est cependant aussi possible de créer ses propres tables. Voici un visuel très bien fait, permettant de comprendre les différentes étapes
Configuration de base
La seule bonne manière de faire est de tout bloquer puis de configurer ce que l'on souhaite accepter en entrée/sortie. Bien lire ce paragraphe jusqu'au bout pour éviter les blocages. Pour ce faire il faut commencer par vider les tables avec la commande :
iptables -t filter -F
Puis supprimer toutes les chaînes que l'utilisateur a pu rentrer :
iptables -t filter -X
Et enfin bloquer toutes les entrées/sorties :
iptables -t filter -P INPUT DROP iptables -t filter -P FORWARD DROP iptables -t filter -P OUTPUT DROP
À partir de ce moment là votre ordinateur n'acceptera plus aucune données venant de l'extérieur et interdira également toute sortie. S'il s'agit d'un ordinateur distant auquel vous accédez via ssh, votre connexion sera coupé !! Pour éviter que cela n'arrive il faut ajouter les lignes :
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
qui permettent de ne pas casser les connexions déjà établies.
Ouvrir un port
Maintenant que la base est là, on peut autoriser certaines connexions.
Pour tout le monde
Prenons l'exemple de ssh. Si vous souhaitez autoriser l'accès à une machine, il faut ajouter les lignes :
#autorisation d'entrer iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT #autorisation de sortir iptables -t filter -A OUTPUT -p tcp --sport 22 -j ACCEPT
Pour une seule ip
Si vous voulez qu'un seul ordi de votre réseau puisse se connecter en ssh, on peut restreindre l'accès qu'a une seule addresse :
#autorisation d'entrer iptables -t filter -A INPUT -s 192.168.1.42 -p tcp --dport 22 -j ACCEPT #autorisation de sortir iptables -t filter -A OUTPUT -d 192.168.1.42 -p tcp --sport 22 -j ACCEPT
Pour un sous-réseau
Ou alors autoriser à un sous réseau :
#autorisation d'entrer iptables -t filter -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT #autorisation de sortir iptables -t filter -A OUTPUT -d 192.168.1.0/24 -p tcp --sport 22 -j ACCEPT
Redirection de ports
En plus de gérer les autorisation d'entrées et sorties iptables permet de faire du routage en redirigeant certains ports en entrée vers une autre adresse ip et/ou un autre port. La première étape sera de changer la destination du paquet, ce qui se fait en modifiant la chaîne PREROUTING :
#redirection du port 25 vers le serveur courriel iptables -t nat -A PREROUTING -p tcp --dport 25 -j DNAT --to-destination 192.168.1.42:25
Cependant cela ne suffit pas, car suite à cette modification, le paquet ne sera plus destiné à la machine qui vient de le recevoir. Si vous regardez le schéma vous comprendrez que le paquet va alors devoir traverser la chaîne FORWARD
iptables -A FORWARD -p tcp --dport 25 -j ACCEPT
Il reste tout à fait possible de combiner les options de source et de destination afin de limiter les adresse ip autorisées à passer cette redirection.
Passerelle
Jusqu'à présent les règles décrites ne s'occupe que des paquets voyageant dans un seul sens. Suite à la redirection la source des paquets n'a pas changé et il est possible que la machine recevant ce paquet soit dans l'incapacité de contacter directement la source. Ce qui empêchera l'envoie d'une réponse. Regardons comment créer une vraie passerelle qui aura pour rôle de faire communiquer deux réseaux distincts.
Contexte
Ordi 1 et Ordi 2 sont sur des réseaux différents et ne peuvent donc pas communiquer directement. Passerelle étant sur les deux réseaux elle pourra jouer le rôle d'intermédiaire.
Ordi 1 veut contacter Ordi 2
Dans ce cas il faut que Ordi 1 envoie ses paquets à Passerelle et Passerelle doit effectuer une redirection en changeant les chaînes PREROUTING et FORWARD comme vu précédemment
iptables -t nat -A PREROUTING -p tcp --dport 25 -j DNAT --to-destination 192.168.1.2:25 iptables -A FORWARD -p tcp --dport 25 -j ACCEPT
Ordi 2 recevra effectivement les paquets, mais ils auront pour source : 192.168.0.2, qui est un réseau inaccessible pour Ordi 2. La réponse sera donc perdu ... Il faut donc faire croire à Ordi 2 que le paquet provient de Passerelle. Pour cela deux solutions SNAT et MASQUERADE
SNAT
SNAT est l'acronyme pour Source Network Address Translation. Qui est très simple à comprendre, on va simplement modifier l'adresse source du paquet.
iptables -t nat -A POSTROUTING -p tcp --dport 25 -j SNAT --to-source 192.168.1.1
Grâce à ça les paquets qui se présenteront à Passerelle et qui sont à destination du port 25 seront redirigé vers Ordi 2 sur le port 25 et la source sera changé pour 192.168.1.1, l'adresse de Passerelle que Ordi 2 peut contacter. Mais les plus malins d'entre vous auront sans doute une question : "Si pour une raison ou une autre je change l'adresse de ma passerelle, faut-il que je change la configuration ?", la réponse est oui. C'est pour cela qu'on va aborder également la deuxième façon de faire : MASQUERADE
MASQUERADE
Le masquerading fait exactement la même chose que SNAT, à la différence qu'il faut lui fournir l'interface par laquelle le paquet va sortir.
iptables -t nat -A POSTROUTING -p tcp --dport 25 -o eth0 -j MASQUERADE
Avec cette ligne de commande, les paquets sortant auront pour source la même ip que l'interface eth0. Dans ce cas, si l'adresse de Passerelle change, pas besoin de refaire la configuration.
Chaînes personnalisées
Il peut être très intéressant d'utiliser des chaînes personnalisées.
Création d'une chaîne
Pour créer une nouvelle chaîne il suffit de taper :
iptables -N nom_de_la_chaine
Par défaut cette chaîne sera vide et n'aura donc aucune utilité.
Remplissage
On peut ajouter des règles à cette chaîne avec :
iptables -A nom_de_la_chaine -p tcp --dport 22 -j ACCEPT
Qui aura donc pour but d'accepter les paquets entrant à destination du port 22 Cependant aucun paquet n'atteindra cette règle ...
Où se trouve une chaîne personnalisée dans le diagramme ?
Bonne question. Pour l'instant, nul part ! Pour associer notre nouvelle chaîne au diagramme il faut utiliser ce genre de commande :
iptables -A INPUT -j nom_de_la_chaine
Ce qui aura pour effet qu'un paquet rentrant passera en premier lieu aux travers des règles INPUT. Mais si aucune correspondance n'est trouvé, à la sortie de INPUT, le paquet sera dirigé vers la chaîne : nom_de_la_chaine. Une chaîne personnalisée peut donc se retrouver n'importe où dans le diagramme suivant les associations qui seront faite.
Suppression d'une chaîne
Dans un premier temps il faut vider la chaîne avec :
iptables -F nom_de_la_chaine
Puis la supprimer avec :
iptables -X nom_de_la_chaine
Blocage d'adresse ip
Cas général
Lorsqu'on a un serveur il arrive que l'on voit des adresses essayant de se connecter, souvent à des fin malveillantes. Pour les bloquer il suffit d'ajouter cette ligne :
iptables -I INPUT -s 155.133.82.146 -j DROP
L'option -I spécifie que cette règle doit passer avant toutes les autres dans la table INPUT, de cette manière on s'assure que même s'il existe une règle permettant l'accès elle ne sera pas appliqué pour cette adresse ip.
Cas de Docker
Avec Docker la règle modifiant la table INPUT n'aura aucun effet, car Docker crée sa propre table pour gérer les entrées/sorties des conteneurs. Par défaut il ouvre les ports spécifiés des conteneurs vers le monde extérieurs sans aucune restriction. Pour en limiter l'accès il faut alors utiliser :
iptables -I DOCKER -s 155.133.82.146 -j DROP
Qui va modifier la table créée par Docker et bloquer l'adresse ip qui tente de se connecter sans cesse.
Automatisation des blocages
fail2ban est un logiciel permettant d'ajouter automatiquement des adresses ip à la liste noire lorsque trop de tentative infructueuse de connexion ont eu lieu.