Configurer des règles de filtrage réseaux

Retour à la liste des tutoriels

Explication des fonctionnalités principales d'iptables et création d'un script de configuration.
Utilisation d'IPv4 et IPv6
Prérequis
  • Aucun prérequis pour ce tutoriel.


Préambule

Afin de sécuriser un serveur, il faut effectuer un filtrage au niveau des connexions réseau : la meilleure manière de se protéger contre une attaque est qu'elle n'atteigne pas la machine !

Plus d'une personne conseille d'analyser les logs en temps réel de la machine (avec un logiciel spécialisé) afin de bannir les machines tentant de pirater notre serveur.

Cette idée n'est pas optimale : en plus d'utiliser des ressources en permanence afin d'analyser les logs, elle ne fait que post-traiter l'attaque.

Une bonne sécurisation est dans la prévention de l'attaque.

Une mauvaise configuration d'iptables peut rendre votre serveur totalement in-opérationnel !
Important à savoir : si vous rendez votre serveur in-opérationnel à cause d'une erreur de configuration, redémarrez le : iptables ne conserve pas sa configuration !

Iptables IPv4

Programmes à autoriser

Quels sont les services dont nous avons toujours besoin ?

  • Apache pour le serveur web, donc le port 80
  • SSH pour gérer à distance notre serveur, donc le port 22
  • Ping pour pouvoir vérifier que notre serveur est bien en ligne
  • Toutes les connexions internes au système d'exploitation (lancées automatiquement au démarrage)

Gestion des droits

Je vais utiliser une gestion des droits dite par liste blanche :

  • Interdiction de toutes les connexions
  • Autorisation au cas par cas.

Cette manière me semble être la plus adaptée à notre besoin de sécurité.

Notions théoriques

3 types de flux réseaux sont gérés par iptables : * ceux qui entrent : INPUT (du visiteur vers le serveur), * ceux qui sortent : OUTPUT (du serveur vers le visiteur), * ceux qui ne font que passer : FORWARD (d'un visiteur, vers un autre serveur / visiteur / …).

Je vais travailler uniquement sur les flux entrants.

Schéma explicatif

Commandes d'iptables

Une liste de valeurs données entre crochets ([]) signifie qu'une des valeurs est à choisir.

Je met plusieurs possibilités afin de vous donner un aperçu des commandes possibles.

Afficher les règles actuellement appliquées

iptables -L

Version “verbose” (plus d'informations)

iptables -L -v

Ajouter une règle globale

Il est possible de définir une règle globale sur un des trois types de flux :

iptables -P [INPUT/OUTPUT/FORWARD/...] [ACCEPT/DROP]

Ajouter une règle

iptables -A [INPUT/OUTPUT/FORWARD/...] -p [tcp/udp/...] --dport [www/ssl/80/...] -j [ACCEPT/DROP]
  • -A précise le type de flux
  • -p précise le type de protocole (le plus souvent TCP)
  • –dport précise le numéro du port concerné, ou son nom
  • -j définit la politique du pare-feu

Supprimer une règle

Afficher les règles en vigueur :

iptables -L --line-numbers

Relever le n° et le type de la règle que l'on souhaite supprimer

iptables -D [INPUT/OUTPUT/FORWARD/...] [1/2/...]
  • -D précise la suppression
  • puis on donne le type de flux concerné
  • et l'id de la règle

Règles de configuration

Voici les règles que je vais appliquer * Supprimer les configurations d'iptables pouvant exister

iptables -t filter -F
iptables -t filter -X
  • Autoriser le trafic entrant d'une connexion déjà active
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  • Autoriser le trafic entrant SSH
iptables -A INPUT -p tcp -i eth0 --dport ssh -j ACCEPT
  • Autoriser le trafic entrant web
iptables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT
  • Autoriser le ping
iptables -A INPUT -p icmp -j ACCEPT
  • Autoriser toutes les connexions en loopback (connexion locale)
iptables -I INPUT 2 -i lo -j ACCEPT
  • Restriction de tout le reste du trafic entrant
iptables -P INPUT DROP
Si vous possédez un serveur BIND (DNS) pensez à ajouter également :
iptables -A INPUT -p udp -i eth0 --dport 53 -j ACCEPT

Bien entendu ceci est adapté dans mon cas, et est à réfléchir avant de l'appliquer sur un autre serveur !

Je vous laisse trouver les configurations optimales pour votre serveur !

Pérenniser

Explication

Je vais vous expliquer comment créer un script qui sera exécuté automatiquement au lancement de votre serveur, et configurera donc iptables.

J'ai lu des tutoriels recommandant de sauvegarder (automatiquement) la configuration d'iptables à l'extinction du serveur, et de la réinsérer au redémarrage. Je désapprouve cette idée : en cas de configuration erronée, le seul moyen de récupérer le serveur sera de le réinstaller !

Création du script

Les scripts associés aux services sont stockés dans /etc/init.d.

nano /etc/init.d/iptables

Voici le contenu de mon fichier :

iptables
#!/bin/bash
# vider les tables de filtrage existantes
iptables -t filter -F
iptables -t filter -X
 
# autoriser le trafic entrant d'une connexion déjà active
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# autoriser le trafic entrant SSH
iptables -A INPUT -p tcp -i eth0 --dport ssh -j ACCEPT
# autoriser le trafic entrant web
iptables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT
# autoriser le ping
iptables -A INPUT -p icmp -j ACCEPT
# autoriser toutes les connexions en loopback (connexion locale)
iptables -I INPUT 2 -i lo -j ACCEPT
 
# restriction de tout le trafic entrant
iptables -P INPUT DROP

Statut exécutable

Pour rendre le script exécutable, il faut faire :

chmod +x /etc/init.d/iptables

Automatiser le lancement

cd /etc/init.d/
update-rc.d iptables defaults
FIXME Un warning s'affiche parlant du LSB du fichier… Ceci n'empêche en rien sa bonne exécution !
Infos sur LSB

Ip6tables IPv6

Si votre serveur possède une adresse IPv4 ainsi qu'une adresse IPv6, il convient de protéger correctement votre serveur sur les deux réseaux.

Sinon cela reviendrait à mettre une porte blindée devant votre maison, mais laisser la porte de service grande ouverte… inutile !

IPv6, suis-je concerné ?

Pour déterminer si votre serveur possède une adresse IPv6 :

ifconfig

Que faut-il lire ?

eth0      Link encap:Ethernet  HWaddr c8:0a:a9:03:25:78  
          inet adr:88.191.122.115  Bcast:88.191.122.255  Masque:255.255.255.0
          adr inet6: 2a01:e0b:1:122:ca0a:a9ff:fe03:2578/64 Scope:Global
          adr inet6: fe80::ca0a:a9ff:fe03:2578/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:210192407 errors:0 dropped:0 overruns:0 frame:0
          TX packets:97773119 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000 
          RX bytes:143351720634 (133.5 GiB)  TX bytes:89455408641 (83.3 GiB)
          Interruption:28 Mémoire:feae0000-feb00000 

La ligne nous intéressant est adr inet6.

Si une seule ligne est présente, et commence par fe80, votre serveur ne possède pas de connectivité internet IPv6.

Sinon, votre serveur est accessible en IPv6.

ip6tables

Le pare-feu est ip6tables. Je vais réutiliser les mêmes configurations que pour l'IPv4.

L'autorisation de l'ICMPv6 est obligatoire pour que vos sites web soient accessibles aujourd'hui !

Je rajoute dans mon script /etc/init.d/iptables :

iptables
# ----------------------------------- I P v 6 -----------------------------------------
 
# vider les tables de filtrage existantes
ip6tables -t filter -F
ip6tables -t filter -X
 
# autoriser le trafic entrant d'une connexion déjà active
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# autoriser le trafic entrant SSH
ip6tables -A INPUT -p tcp -i eth0 --dport ssh -j ACCEPT
# autoriser le trafic entrant web
ip6tables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT
# autoriser le ping
ip6tables -A INPUT -p icmpv6 -j ACCEPT
# autoriser toutes les connexions en loopback (connexion locale)
ip6tables -I INPUT 2 -i lo -j ACCEPT
 
# restriction de tout le trafic entrant
ip6tables -P INPUT DROP


Liens