Ubuntu - Sécuriser votre serveur dédié ou VPS via Iptables

Page 1 / 1
  • Publié le : 28 février 2014 à 20:59
  • Par Lionel Eppe

Si vous avez acheté un VPS sur Internet, vous vous rendrez vite compte que les pirates risquent de chercher des failles sur vos serveurs. Surtout, si celui-ci devient connu.
Pour le sécuriser, nous allons donc fermer toutes les portes que vous n'utiliserez pas sur votre serveur.

  1. Explications à propos de iptables
  2. Les 2 politiques de gestion d'un pare-feu
  3. Création d'un script de configuration du pare-feu
  4. Exécuter le script à chaque démarrage

Pour cela, nous allons utiliser "iptables" qui est une interface en ligne de commande permettant de configurer le pare-feu "Netfilter".

 

1. Explications à propos de iptables

Pour commencer, lister les règles de votre pare-feu en tapant la commande suivante :

Code : Bash

iptables -L

Vous remarquerez que par défaut, tout le traffic est autorisé. Ce qui est la plus mauvaise configuration car dans cette configuration, ce pare-feu ne sert strictement à rien.

Code : Bash

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 remarquer, il y a 3 catégories de traffic :

  1. Le traffic entrant (Chain INPUT) :
    C'est à dire, ce qui arrive au serveur. Par exemple : Une requête HTTP sur le port 80 pour demander une page à notre serveur web "Apache".
  2. Le traffic sortant (Chain OUTPUT) :
    C'est à dire, ce que le serveur envoi (aux clients ou à d'autres serveurs). Par exemple : Le contenu de la page web qu'un visiteur avait demandé tout à l'heure.
  3. Le traffic redirigé (Chain FORWARD) :
    En résumé, c'est ce que votre routeur effectue chez vous. Le routeur est une passerelle qui redirige les données (entrantes et sortantes) d'une interface réseau vers une autre (d'un réseau à un autre).
    C'est grâce à ce système que l'on peut brancher plusieurs ordinateurs sur une seule connexion Internet (arrivant au modem) et distribuer les bons paquets réseau aux bons ordinateurs.
    Vous aurez donc compris que cette catégorie ne nous intéressera pas à moins de vouloir créer une passerelle réseau. Nous le bloqueront donc complètement.

 

2. Les 2 politiques de gestion d'un pare-feu

Pour configurer un pare-feu, en l'occurrence "Netfilter" dans notre cas, il y a 2 façons :

  1. Soit vous autoriser tout le traffic et vous bloquer le traffic non désiré
  2. Soit vous bloquer tout le traffic et vous autoriser seulement le traffic d'on vous avez besoin.

Dans notre cas, nous allons choisir la 2ème possibilité qui est la meilleure et la plus simple à mettre en place.

 

3. Création d'un script de configuration du pare-feu

Alors pourquoi créer un script de configuration plutôt que de tapez directement ces commandes "iptables" ?
La raison est simple, lorsque vous tapez des commandes iptables, celles-ci ont un effet immédiat et nous serions donc bloqués lorsque l'on commencerait par interdire tout le traffic.
La 2ème raison, c'est simplement le fait que le pare-feu est réinitialisé lors du redémarrage de votre machine Ubuntu. Un redémarrage volontaire ou non exposerait donc votre serveur à tous les pirates présents sur le net.

Maintenant que cette question est réglée, commençons notre script.

Pour commencer, vous devez obligatoirement indiqué le langage utilisé dans votre script en ajoutant cette ligne :

Code : Bash

#!/bin/sh

Ensuite, pour éviter les futurs "warning" dans les logs, vous devez ajouter le petit en-tête que voici :

Code : Bash

### BEGIN INIT INFO
# Provides:          Mon Firewall
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:
# Default-Stop:
# X-Interactive:     false
# Short-Description: Mon Firewall
### END INIT INFO
echo "Configuration du pare-feu ..."

Maintenant que les informations obligatoires sont indiquées, commençons notre script à proprement parlé.

Pour éviter que des précédentes règles n'interfères avec les nôtre, nous allons réinitialiser notre pare-feu

Code : Bash

# Mise à 0
iptables -t filter -F
iptables -t filter -X
echo "Pare-feu remis à 0"

Ensuite, comme nous avons choisi la 2ème politique de gestion d'un pare-feu, nous allons commencer par bloquer tout le traffic entrant et redirigé.

Code : Bash

# On bloque le traffic entrant et redirigé
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
echo "Traffic entrant et redirigé bloqué"

Par simplicité, nous vous conseillons d'autoriser tout le traffic sortant. Etant donné qu'il s'agit de notre serveur. Le traffic sortant ne pourra théoriquement par être dangereux.
A moins que n'importe qui puisse utiliser votre serveur comme il le veut.

Code : Bash

# On autorise le traffic sortant
iptables -t filter -P OUTPUT ACCEPT
echo "Traffic sortant autorisé"

Toujours par simplicité, nous allons autoriser les connexions établies. Etant données que ces connexions sont en état "établies", c'est qu'elles ont été autorisé par une des règle de traffic entrant du pare-feu.
Dans le cas contraire, cette connexion sera de type "NEW" et sera donc bloquée par le pare-feu.

Code : Bash

# On ne casse pas les connexions établies
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
echo "Connexions établies autorisées"

Nous allons autoriser tout le traffic entrant et sortant sur l'interface de bouclage réseau
Il s'agit des requêtes effectuées sur le serveur lui-même. Etant donné qu'il se demande des informations à lui-même, il n'y a aucun risque à autoriser ce traffic.

Code : Bash

# Autorise le traffic entrant et sortant sur l'interface de bouclage réseau (loopback) (IP : 127.0.0.1)
iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT
echo "Traffic de loopback autorisé"

Nous allons aussi autoriser le ping sur et depuis le serveur.
Info : Le ping est une commande utilisée pour tester la connexion entre 2 périphériques réseaux et il est donc intéressant de le laisser passer. Cela permet de diagnostiquer les problèmes réseaux que vous pourriez rencontrer.

Code : Bash

# ICMP (le ping)
iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A OUTPUT -p icmp -j ACCEPT
echo "Ping autorisé"

Le reste des règles concerne les divers protocoles qui existent sur votre serveur.
Quelques petites informations sur les commandes qui suivent :

  • dport = port de destination
  • sport = port source
  • On sait uniquement le port de destination pour le traffic entrant (il s'agit du port sur lequel le serveur écoute)
  • On sait uniquement le port source pour le traffic sortant (car il s'agit encore une fois du port sur lequel le serveur travaille)

Exemple :
Un visiteur envoi une requête HTTP au serveur web sur le port 80.
Cette requête vient de l'adresse IP xxx.xxx.xxx.xxx du client depuis le port x (aléatoirement alloué par le système d'exploitation du client) et arrive sur le port 80 du serveur (vu que le protocole utilisé est HTTP).
Lorsque le serveur lui envoi la réponse (le contenu de la page demandée dans ce cas-ci), il utilise son port 80 (qui est donc le port source pour le traffic sortant) et envoi la réponse à l'adresse IP du client xxx.xxx.xxx.xxx sur le port que le client avait lors de l'envoi de sa requête.
Note : Vu qu'il s'agit du protocole TCP qui est un mode connecté, le serveur sait l'adresse IP et le port du client. Il sait donc lui répondre de cette façon.

Code : Bash

# SSH entrant/sortant
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 22 -j ACCEPT
echo "SSH autorisé"

# DNS entrant/sortant
# Requêtes DNS effectuées par le serveur (TCP et UDP)
iptables -t filter -A OUTPUT -p tcp --sport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p udp --sport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT
# Requêtes DNS envoyées par les clients et donc reçues par le serveur (TCP et UDP)
iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT
echo "DNS autorisé"

# NTP sortant (serveur de temps)
iptables -t filter -A OUTPUT -p udp --sport 123 -j ACCEPT
echo "ntp ok"

# HTTP + HTTPS entrant/sortant (Serveur Web : HTTP (80) et HTTPS sécurisé par SSL (443 ou 8443)
iptables -t filter -A OUTPUT -p tcp --sport 80 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 443 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 8443 -j ACCEPT

# Mail SMTP:25 (Protocole d'envoi d'e-mails)
iptables -t filter -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 25 -j ACCEPT

# Mail POP3:110 (Protocole de récupération d'e-mail)
iptables -t filter -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 110 -j ACCEPT

# Mail POP3S:995 (Protocole de récupération d'e-mail)
# POP3S est un protocole POP3 sécurisé via SSL (POP3 Over SSL)
iptables -t filter -A INPUT -p tcp --dport 995 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 995 -j ACCEPT

# Mail IMAP:143 (Protocole permettant de consulter ses mails via un système de dossiers distants)
iptables -t filter -A INPUT -p tcp --dport 143 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 143 -j ACCEPT
echo "Protocoles e-mails autorisés"

Et pour terminer, le protocole FTP qui est assez compliqués quand on ne connait pas son fonctionnement.
Notez que nous avons activé la plage de ports passifs (50000-50100) dans la configuration du serveur FTP pour savoir quelle plage de ports autoriser.

En réalité, avec le protocole FTP, vous n'utilisez pas uniquement le port 21 comme on pourrait le croire.
Car si vous installez un serveur FTP sur votre ordinateur et que vous regardez vos connexions réseau (via TCP View par exemple), vous remarquerez que les transferts de fichiers ne se font pas via le port 21 mais via un des ports passif configurés sur le serveur.
Le port 21 ne servant principalement qu'à la connexion (ou authentification) ainsi que l'envoi de commande

Voici le schéma d'un transfert de fichiers via FTP :

  • Connexion au serveur FTP sur le port 21
  • Demande de transfert d'un fichier (envoi ou réception)
  • Le serveur FTP choisi un port parmi sa plage de ports passif, et il commence le transfert du fichier
  • Une fois le transfert terminé, cette connexion supplémentaire est coupée
  • Si vous transférez un autre fichier, une nouvelle connexion s'effectuera le temps de ce transfert, ...

Il faut donc autoriser les ports suivants :

  • Port 20 : Transfert de données (en mode direct). Le client aura dans ce cas un avertissement provenant de son pare-feu (il est donc recommandé de configurer les ports passifs pour éviter ce problème chez les clients)
  • Port 21 : Envoi des commandes et réception des réponses (connexion ok, ...)
  • Plage de ports 50000:50100 (dans notre cas) : Transfert de données via les ports passif du serveur.

Code : Bash

# FTP sortant
iptables -t filter -A OUTPUT -p tcp --sport 21 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --sport 20 -j ACCEPT
# FTP entrant
iptables -t filter -A INPUT -p tcp --dport 20 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 21 -j ACCEPT
echo "FTP autorisé"

# FTP Passive
iptables -t filter -A OUTPUT -p tcp --sport 50000:50100 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 50000:50100 -j ACCEPT
echo "Port passifs du serveur FTP autorisés"

Indiquez ensuite cette ligne à la fin du fichier

Code : Bash

echo "Configuration du pare-feu terminée"

Et enregistrer le fichier avec comme nom "parefeu" et activer l'exécution du script comme ceci :

Code : Bash

chmod +x parefeu

Si vous vous demandez pourquoi nous avons ajouté des lignes "echo" pour chaque bloc de règles, c'est simplement pour débugger plus facilement le script, le jour où une erreur se produira (si tel est le cas).
Lorsque le script s'exécutera (et donc aussi au démarrage de la machine quand on l'y aura ajouté), cette série de message s'affichera.

Pour exécuter ce script, tapez simplement la commande suivante :

Code : Bash

./parefeu

 

4. Exécuter le script à chaque démarrage

Avant de programmé ce script au démarrage de votre machine, assurez-vous que tout fonctionne correctement.
Testez votre connexion SSH, vos transfert de fichiers par FTP, vos protocoles de messageries (SMTP, POP3, IMAP, ...), ...
Si vous n'avez plus accès à votre serveur, demandez un redémarrage de votre serveur dédié ou VPS depuis votre compte chez votre hébergeur.

Si tout fonctionne toujours, alors vous pouvez le mettre au démarrage de votre machine.
Pour cela, commencez par copier le fichier "parefeu" dans le dossier "/etc/init.d" (où se trouvent d'ailleurs les autres services comme apache, postfix, ...)

Code : Bash

cp parefeu /etc/init.d

Puis ajouter le script au démarrage de la machine, utilisez la commande "update-rc.d" :

Code : Bash

update-rc.d parefeu defaults