Comment configurer un pare-feu à l'aide d'Iptables sur Ubuntu 14.04

De Get Docs
Aller à :navigation, rechercher

Introduction

La mise en place d'un bon pare-feu est une étape essentielle à franchir pour sécuriser tout système d'exploitation moderne. La plupart des distributions Linux sont livrées avec quelques outils de pare-feu différents que nous pouvons utiliser pour configurer nos pare-feu. Dans ce guide, nous couvrirons le pare-feu iptables.

Iptables est un pare-feu standard inclus dans la plupart des distributions Linux par défaut (une variante moderne appelée nftables commencera à le remplacer). Il s'agit en fait d'un frontal des crochets netfilter au niveau du noyau qui peuvent manipuler la pile réseau Linux. Cela fonctionne en comparant chaque paquet qui traverse l'interface réseau à un ensemble de règles pour décider quoi faire.

Dans le guide précédent, nous avons appris comment les règles iptables fonctionnent pour bloquer le trafic indésirable. Dans ce guide, nous allons passer à un exemple pratique pour montrer comment créer un ensemble de règles de base pour un serveur Ubuntu 14.04. Le pare-feu résultant autorisera le trafic SSH et HTTP.

Remarque : Ce tutoriel couvre la sécurité IPv4. Sous Linux, la sécurité IPv6 est maintenue séparément d'IPv4. Par exemple, "iptables" ne gère que les règles de pare-feu pour les adresses IPv4, mais il a un équivalent IPv6 appelé "ip6tables", qui peut être utilisé pour maintenir les règles de pare-feu pour les adresses réseau IPv6.

Si votre VPS est configuré pour IPv6, n'oubliez pas de sécuriser vos interfaces réseau IPv4 et IPv6 avec les outils appropriés. Pour plus d'informations sur les outils IPv6, reportez-vous à ce guide : Comment configurer les outils pour utiliser IPv6 sur un VPS Linux


Conditions préalables

Avant de commencer à utiliser ce didacticiel, vous devez disposer d'un compte de superutilisateur non root séparé (un utilisateur avec des privilèges sudo) configuré sur votre serveur. Si vous avez besoin de le configurer, suivez ce guide : Configuration initiale du serveur avec Ubuntu 14.04.

Commandes iptables de base

Maintenant que vous avez une bonne compréhension des concepts d'iptables, nous devrions couvrir les commandes de base qui seront utilisées pour former des ensembles de règles complexes et pour gérer l'interface iptables en général.

Tout d'abord, vous devez savoir que les commandes iptables doivent être exécutées avec les privilèges root. Cela signifie que vous devez vous connecter en tant que root, utiliser su ou sudo -i pour obtenir un shell root, ou faire précéder toutes les commandes de sudo. Nous allons utiliser sudo dans ce guide car c'est la méthode préférée sur un système Ubuntu.

Un bon point de départ consiste à répertorier les règles actuelles configurées pour iptables. Vous pouvez le faire avec le drapeau -L :

sudo iptables -L
Output: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

Comme vous pouvez le voir, nous avons nos trois chaînes par défaut (INPUT, OUTPUT et FORWARD). Nous pouvons également voir la politique par défaut de chaque chaîne (chaque chaîne a ACCEPT comme politique par défaut). Nous voyons également des en-têtes de colonne, mais nous ne voyons aucune règle réelle. C'est parce qu'Ubuntu n'est pas livré avec un ensemble de règles par défaut.

Nous pouvons voir la sortie dans un format qui reflète les commandes nécessaires pour activer chaque règle et stratégie en utilisant à la place l'indicateur -S :

sudo iptables -S
Output:-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

Pour répliquer la configuration, il nous suffirait de taper sudo iptables suivi de chacune des lignes de la sortie. (Selon la configuration, cela peut en fait être un peu plus compliqué si nous sommes connectés à distance afin de ne pas instituer une politique de suppression par défaut avant que les règles ne soient en place pour attraper et autoriser notre connexion actuelle.)

Si vous avez avez des règles en place et souhaitez les supprimer et recommencer, vous pouvez vider les règles actuelles en tapant :

sudo iptables -F

Encore une fois, la politique par défaut est importante ici, car, bien que toutes les règles soient supprimées de vos chaînes, la politique par défaut ne changera pas avec cette commande. Cela signifie que si vous êtes connecté à distance, vous devez vous assurer que la politique par défaut sur vos chaînes INPUT et OUTPUT est définie sur ACCEPT avant de vider vos règles. Vous pouvez le faire en tapant :

sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F

Vous pouvez ensuite redéfinir la stratégie de suppression par défaut sur DROP après avoir établi des règles qui autorisent explicitement votre connexion. Nous verrons comment faire cela dans un instant.

Créez votre première règle

Nous allons commencer à construire nos politiques de pare-feu. Comme nous l'avons dit plus haut, nous allons travailler avec la chaîne INPUT puisque c'est l'entonnoir par lequel le trafic entrant sera envoyé. Nous allons commencer par la règle dont nous avons parlé un peu plus haut : la règle qui accepte explicitement votre connexion SSH actuelle.

La règle complète dont nous avons besoin est la suivante :

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

Cela peut sembler incroyablement compliqué, mais la plupart auront un sens lorsque nous passerons en revue les composants :

  • -A INPUT : Le drapeau -A ajoute une règle à la fin d'une chaîne. C'est la partie de la commande qui indique à iptables que nous souhaitons ajouter une nouvelle règle, que nous voulons que cette règle soit ajoutée à la fin de la chaîne et que la chaîne sur laquelle nous voulons opérer est la chaîne INPUT.

  • -m conntrack : iptables possède un ensemble de fonctionnalités de base, mais également un ensemble d'extensions ou de modules qui fournissent des fonctionnalités supplémentaires.

    Dans cette partie de la commande, nous indiquons que nous souhaitons avoir accès aux fonctionnalités fournies par le module conntrack. Ce module donne accès à des commandes qui peuvent être utilisées pour prendre des décisions en fonction de la relation du paquet avec les connexions précédentes.

  • –ctstate : C'est l'une des commandes rendues disponibles en appelant le module conntrack. Cette commande nous permet de faire correspondre les paquets en fonction de leur relation avec les paquets que nous avons vus auparavant.

    Nous lui transmettons la valeur de ESTABLISHED pour autoriser les paquets qui font partie d'une connexion existante. Nous lui transmettons la valeur RELATED pour autoriser les paquets associés à une connexion établie. Il s'agit de la partie de la règle qui correspond à notre session SSH actuelle.

  • -j ACCEPT : Ceci spécifie la cible des paquets correspondants. Ici, nous disons à iptables que les paquets qui correspondent aux critères précédents doivent être acceptés et autorisés à passer.

Nous mettons cette règle au début car nous voulons nous assurer que les connexions que nous utilisons déjà sont appariées, acceptées et retirées de la chaîne avant d'atteindre les règles DROP.

Nous pouvons voir les changements si nous listons les règles :

sudo iptables -L
Output:Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Maintenant que vous connaissez la syntaxe générale, continuons en ajoutant quelques cas supplémentaires où nous voulons accepter la connexion.

Accepter les autres connexions nécessaires

Nous avons demandé à iptables de garder ouvertes toutes les connexions déjà ouvertes et d'autoriser les nouvelles connexions liées à ces connexions. Cependant, nous devons créer des règles pour établir quand nous voulons accepter de nouvelles connexions qui ne répondent pas à ces critères.

Nous voulons garder deux ports ouverts en particulier. Nous voulons garder notre port SSH ouvert (nous allons supposer dans ce guide qu'il s'agit du port 22. Si vous avez changé cela dans votre configuration SSH, modifiez votre valeur ici). Nous allons également supposer que cet ordinateur exécute un serveur Web sur le port par défaut 80. Si ce n'est pas le cas pour vous, vous n'avez pas à ajouter cette règle.

Les deux lignes que nous allons utiliser pour ajouter ces règles sont :

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Comme vous pouvez le voir, celles-ci sont très similaires à notre première règle, mais peut-être plus simples. Les nouvelles options sont :

  • -p tcp : cette option correspond aux paquets si le protocole utilisé est TCP. Il s'agit d'un protocole basé sur la connexion qui sera utilisé par la plupart des applications car il permet une communication fiable.
  • –dport : cette option est disponible si le drapeau -p tcp est donné. Il donne une exigence supplémentaire de faire correspondre le port de destination pour le paquet correspondant. La première règle correspond aux paquets TCP destinés au port 22, tandis que la seconde règle correspond au trafic TCP pointé vers le port 80.

Il existe une autre règle d'acceptation dont nous avons besoin pour nous assurer que notre serveur peut fonctionner correctement. Souvent, les services de l'ordinateur communiquent entre eux en s'envoyant des paquets réseau. Pour ce faire, ils utilisent une pseudo interface réseau appelée loopback device, qui redirige le trafic vers lui-même plutôt que vers d'autres ordinateurs.

Ainsi, si un service souhaite communiquer avec un autre service qui écoute les connexions sur le port 4555, il peut envoyer un paquet au port 4555 du périphérique de bouclage. Nous voulons que ce type de comportement soit autorisé, car il est essentiel au bon fonctionnement de nombreux programmes.

La règle que nous devons ajouter est la suivante :

sudo iptables -I INPUT 1 -i lo -j ACCEPT

Cela semble un peu différent de nos autres commandes. Passons en revue ce qu'il fait :

  • -I INPUT 1' : le drapeau -I indique à iptables dinsérer une règle. Ceci est différent du drapeau -A qui ajoute une règle à la fin. Le drapeau -I prend une chaîne et la position de la règle où vous voulez insérer la nouvelle règle.

    Dans ce cas, nous ajoutons cette règle comme toute première règle de la chaîne INPUT. Cela renversera le reste des règles. Nous voulons cela au sommet car c'est fondamental et ne devrait pas être affecté par les règles ultérieures.

  • -i lo : ce composant de la règle correspond si l'interface utilisée par le paquet est l'interface "lo". L'interface "lo" est un autre nom pour le périphérique de bouclage. Cela signifie que tout paquet utilisant cette interface pour communiquer (paquets générés sur notre serveur, pour notre serveur) doit être accepté.

Pour voir nos règles actuelles, nous devrions utiliser le drapeau -S. C'est parce que l'indicateur -L n'inclut pas certaines informations, comme l'interface à laquelle une règle est liée, qui est une partie importante de la règle que nous venons d'ajouter :

sudo iptables -S
Output:-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT

Implémentation d'une règle de suppression

Nous avons maintenant quatre règles distinctes qui acceptent explicitement les paquets en fonction de certains critères. Cependant, notre pare-feu ne bloque actuellement rien.

Si un paquet entre dans la chaîne INPUT et ne correspond pas à l'une des quatre règles que nous avons définies, il est transmis à notre politique par défaut, qui consiste à accepter le paquet de toute façon. Nous avons besoin de changer ça.

Il existe deux manières différentes de procéder, avec quelques différences assez importantes.

La première façon de procéder consiste à modifier la politique par défaut de notre chaîne INPUT. Nous pouvons le faire en tapant:

sudo iptables -P INPUT DROP

Cela interceptera tous les paquets qui passent par notre chaîne INPUT et les supprimera. C'est ce que nous appelons une politique de suppression par défaut. L'une des implications de ce type de conception est qu'elle revient à abandonner des paquets si les règles sont vidées.

Cela peut être plus sûr, mais peut également avoir de graves conséquences si vous n'avez pas d'autre moyen d'accéder à votre serveur. Avec DigitalOcean, vous pouvez vous connecter via notre console Web pour accéder à votre serveur si cela se produit. La console Web agit comme une connexion locale virtuelle, les règles iptables ne l'affecteront donc pas.

Vous aimeriez peut-être que votre serveur abandonne automatiquement toutes les connexions dans le cas où les règles seraient vidé. Cela empêcherait votre serveur d'être laissé grand ouvert. Cela signifie également que vous pouvez facilement ajouter des règles au bas de la chaîne tout en laissant tomber les paquets comme vous le souhaitez.

L'approche alternative consiste à conserver la stratégie par défaut pour la chaîne en tant qu'acceptation et à ajouter une règle qui supprime chaque paquet restant au bas de la chaîne elle-même.

Si vous avez modifié la stratégie par défaut pour la chaîne INPUT ci-dessus, vous pouvez la rétablir pour suivre en tapant :

sudo iptables -P INPUT ACCEPT

Maintenant, vous pouvez ajouter une règle au bas de la chaîne qui supprimera tous les paquets restants :

sudo iptables -A INPUT -j DROP

Le résultat dans des conditions de fonctionnement normales est exactement le même qu'avec une stratégie de suppression par défaut. Cette règle fonctionne en faisant correspondre chaque paquet restant qui l'atteint. Cela empêche qu'un paquet jamais soit abandonné tout au long de la chaîne pour atteindre la politique par défaut.

Fondamentalement, cela est utilisé pour conserver la politique par défaut pour accepter le trafic. De cette façon, s'il y a des problèmes et que les règles sont vidées, vous pourrez toujours accéder à la machine via le réseau. C'est un moyen d'implémenter une action par défaut sans modifier la politique qui sera appliquée à une chaîne vide.

Bien sûr, cela signifie également que toute règle que toute règle supplémentaire que vous souhaitez ajouter à la fin de la chaîne devra être ajoutée avant la règle de suppression. Vous pouvez le faire en supprimant temporairement la règle de suppression :

sudo iptables -D INPUT -j DROP
sudo iptables -A INPUT new_rule_here
sudo iptables -A INPUT -j DROP

Ou, vous pouvez insérer les règles dont vous avez besoin à la fin de la chaîne (mais avant la chute) en spécifiant le numéro de ligne. Pour insérer une règle à la ligne numéro 4, vous pouvez taper :

sudo iptables -I INPUT 4 new_rule_here

Si vous rencontrez des difficultés pour savoir à quel numéro de ligne correspond chaque règle, vous pouvez indiquer à iptables de numéroter les règles en tapant :

sudo iptables -L --line-numbers
Output:Chain INPUT (policy DROP)
num  target     prot opt source               destination         
1    ACCEPT     all  --  anywhere             anywhere            
2    ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
3    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
4    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http

Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

Cela peut être utile pour vous assurer que vous ajoutez votre règle à la position appropriée.

Liste et suppression des règles Iptables

Si vous souhaitez en savoir plus sur la liste et la suppression des règles iptables, consultez ce didacticiel : Comment répertorier et supprimer les règles de pare-feu Iptables.

Enregistrement de votre configuration Iptables

Par défaut, les règles que vous ajoutez à iptables sont éphémères. Cela signifie que lorsque vous redémarrez votre serveur, vos règles iptables auront disparu.

Il s'agit en fait d'une fonctionnalité pour certains utilisateurs, car cela leur donne un moyen de revenir s'ils se sont accidentellement verrouillés hors du serveur. Cependant, la plupart des utilisateurs voudront un moyen d'enregistrer automatiquement les règles que vous avez créées et de les charger au démarrage du serveur.

Il existe plusieurs façons de procéder, mais la plus simple consiste à utiliser le package iptables-persistent. Vous pouvez le télécharger depuis les dépôts par défaut d'Ubuntu :

sudo apt-get update
sudo apt-get install iptables-persistent

Lors de l'installation, il vous sera demandé si vous souhaitez enregistrer vos règles actuelles pour qu'elles soient automatiquement chargées. Si vous êtes satisfait de votre configuration actuelle (et que vous avez testé votre capacité à créer des connexions SSH indépendantes, vous pouvez choisir d'enregistrer vos règles actuelles.

Il vous demandera également si vous souhaitez enregistrer les règles IPv6 que vous avez configurées. Ceux-ci sont configurés via un utilitaire séparé appelé ip6tables qui contrôle le flux de paquets IPv6 presque de la même manière.

Une fois l'installation terminée, vous aurez un nouveau service appelé iptables-persistent qui est configuré pour s'exécuter au démarrage. Ce service chargera vos règles et les appliquera au démarrage du serveur.

Enregistrement des mises à jour

Si jamais vous mettez à jour votre pare-feu et souhaitez conserver les modifications, vous devez enregistrer vos règles iptables pour qu'elles soient persistantes.

Enregistrez vos règles de pare-feu avec cette commande :

sudo invoke-rc.d iptables-persistent save

Conclusion

Vous devriez maintenant avoir un bon point de départ pour développer un pare-feu qui répond à vos besoins. Il existe de nombreux autres utilitaires de pare-feu et certains peuvent être plus faciles, mais iptables est un bon outil d'apprentissage, ne serait-ce que parce qu'il expose une partie de la structure sous-jacente de netfilter et parce qu'il est présent dans de nombreux systèmes.

Pour en savoir plus sur la sécurisation de votre réseau avec iptables, consultez ces tutoriels :