Créer un firewall avec Iptables

configurer firewall iptables

Etape importante de la configuration réseau, nous allons voir comment installer et configurer un firewall linux via iptables et ip6tables, avec comme objectif d’être le seul à pouvoir utiliser la machine.

Pourquoi limiter le firewall à notre seul usage ?
L’idée ici est d’installer notre pare-feu sur un serveur VPS de test. L’équivalent d’une machine de test locale mais… Sur le web.
Autant en local on ne se souci pas de la sécurité, des risques d’intrusions ou même de qui se connecte à notre machine, autant sur un serveur public, en ligne, ce n’est pas pareil.

L’esprit est donc de restreindre tout le trafic entrant et d’autoriser que notre ou nos IPs à se connecter au serveur.
Ce n’est pas ici une question de paranoïa ou de sécurité, c’est juste une question d’être tranquille et de garder nos contenus et publications pour nous sans avoir à nous inquiéter de ce qui est visible ou non par tous (et Google pour le web).

Le firewall est configuré sous forme de script et une succession de règles iptables et ip6tables.
Je ne vais pas détailler ici le fonctionnement de ces deux programmes, mais juste la logique de filtrage.
L’idée est de comprendre comment cela fonctionne et d’adapter en fonction de vos besoins.

Comment fonctionne notre firewall Linux ?

Dans les grandes lignes on commence par supprimer toutes les règles existantes pour repartir de zéro avec une configuration vierge.

Ensuite on applique la stratégie globale sur les 3 tables INPUT, FORWARD et OUTPUT.
On bloque tout le trafic sur les tables INPUT et FORWARD et on autorise le trafic sur la table OUTPUT.
Donc le serveur communique vers l’extérieur sans problème mais rien ne rentre.

Enfin, on défini des exceptions sur les stratégies globales si besoin.
Comme par exemple autoriser les mails entrants qui sont de fait bloqués par défaut.

Le cas de iptables et ip6tables

On aborde maintenant une notion fondamentale du firewalling ou du réseau.

IPV6 est là et il faut absolument en tenir compte.
Jusqu’à peu, on ne se souciait que de IPV4 et on filtrait avec le logiciel ad hoc : iptables. Mais maintenant sur les serveurs dédiés et les VPS vous avez systématiquement une adresse IPV6 en plus.

Pour gérer notre par-feu nous utiliserons donc 2 programmes :

  • iptables pour IPV4
  • ip6tables pour IPV6. Notez bien le « 6 ».

Ce qu’il faut bien retenir c’est que iptables ne gère pas le filtrage IPV6 tout comme ip6tables ne gère pas le filtrage IPV4.
Donc on doit tout faire en double. Et surtout en double !!! Chaque règle, chaque stratégie sera écrite deux fois pour chaque type d’IP.
Car on peut construire le meilleur parfeu, s’il ne tient pas compte d’IPV6, n’importe qui avec une IP en v6 passera complètement à travers toutes les règles définies en IPV4 !

Bien compris ?

Cela ne vaut bien sûr que si IPV6 est activé sur votre réseau/serveur.
Si vous n’en avez absolument pas besoin, vous pouvez toujours désactiver IPV6 si le cœur vous en dit.

Un script firewall automatique

Nous allons placer toutes nos règles dans un fichier de service qui sera exécuté automatiquement au démarrage de notre serveur.
On pourra également gérer le firewall à la demande via 3 fonctions. On le lance, on l’arrête et on regarde les règles en cours.

Pour plus d’infos sur les scripts de démarrage, allez jetez un œil au tutos sur la gestion des services.

Création et configuration du parfeu

Copier les règles ci-dessous et collez-les dans un fichier nommé firewall dans le dossier /etc/init.d.
Prenez bien le temps de lire la configuration et surtout d’adapter les variables en début de fichier.

#! /bin/sh
### BEGIN INIT INFO
# Provides:          PersonalFirewall
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Personal Firewall
# Description:
### END INIT INFO

# programme iptables IPV4 et IPV6
IPT=/sbin/iptables
IP6T=/sbin/ip6tables

# Les IPs
IPMAISON=xx.xx.xx.xx
IPBUREAU=xx.xx.xx.xx

# fonction qui démarre le firewall
do_start() {

    # Efface toutes les règles en cours. -F toutes. -X utilisateurs
    $IPT -t filter -F
    $IPT -t filter -X
    $IPT -t nat -F
    $IPT -t nat -X
    $IPT -t mangle -F
    $IPT -t mangle -X
    #
    $IP6T -t filter -F
    $IP6T -t filter -X
    # Il n'y a pas de NAT en IPV6
    #$IP6T -t nat -F
    #$IP6T -t nat -X
    $IP6T -t mangle -F
    $IP6T -t mangle -X

    # stratégie (-P) par défaut : bloc tout l'entrant le forward et autorise le sortant
    $IPT -t filter -P INPUT DROP
    $IPT -t filter -P FORWARD DROP
    $IPT -t filter -P OUTPUT ACCEPT
    #
    $IP6T -t filter -P INPUT DROP
    $IP6T -t filter -P FORWARD DROP
    $IP6T -t filter -P OUTPUT ACCEPT

    # Loopback
    $IPT -t filter -A INPUT -i lo -j ACCEPT
    $IPT -t filter -A OUTPUT -o lo -j ACCEPT
    #
    $IP6T -t filter -A INPUT -i lo -j ACCEPT
    $IP6T -t filter -A OUTPUT -o lo -j ACCEPT

    # Permettre à une connexion ouverte de recevoir du trafic en entrée
    $IPT -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    #
    $IP6T -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    # ICMP depuis les ips autorisées des serveur de monitoring d'OVH
    $IPT -t filter -A INPUT -p icmp -s 37.187.37.250 -j ACCEPT
    $IPT -t filter -A INPUT -p icmp -s 5.39.111.9 -j ACCEPT

    # DNS:53
    # /!\ Il faut autoriser le DNS AVANT de déclarer des hosts sinon pas de résolution de nom possible
    $IPT -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
    $IPT -t filter -A INPUT -p udp --dport 53 -j ACCEPT
    #
    $IP6T -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
    $IP6T -t filter -A INPUT -p udp --dport 53 -j ACCEPT

    # accepte tout d'une ip en TCP
    $IPT -t filter -A INPUT -p tcp -s $IPMAISON -j ACCEPT
    $IPT -t filter -A INPUT -p tcp -s $IPBUREAU -j ACCEPT

    #
    echo "firewall started [OK]"
}

# fonction qui arrête le firewall
do_stop() {

    # Efface toutes les règles
    $IPT -t filter -F
    $IPT -t filter -X
    $IPT -t nat -F
    $IPT -t nat -X
    $IPT -t mangle -F
    $IPT -t mangle -X
    #
    $IP6T -t filter -F
    $IP6T -t filter -X
    #$IP6T -t nat -F
    #$IP6T -t nat -X
    $IP6T -t mangle -F
    $IP6T -t mangle -X

    # remet la stratégie
    $IPT -t filter -P INPUT ACCEPT
    $IPT -t filter -P OUTPUT ACCEPT
    $IPT -t filter -P FORWARD ACCEPT
    #
    $IP6T -t filter -P INPUT ACCEPT
    $IP6T -t filter -P OUTPUT ACCEPT
    $IP6T -t filter -P FORWARD ACCEPT

    #
    echo "firewall stopped [OK]"
}

# fonction status firewall
do_status() {

    # affiche les règles en cours
    clear
    echo Status IPV4
    echo -----------------------------------------------
    $IPT -L -n -v
    echo
    echo -----------------------------------------------
    echo
    echo status IPV6
    echo -----------------------------------------------
    $IP6T -L -n -v
    echo
}

case "$1" in
    start)
        do_start
        # quitte sans erreur
        exit 0
    ;;

    stop)
        do_stop
        # quitte sans erreur
        exit 0
    ;;

    restart)
        do_stop
        do_start
        # quitte sans erreur
        exit 0
    ;;

    status)
        do_status
        # quitte sans erreurs
        exit 0
    ;;

    *)
        # Si on ne tape ni "start" ni "stop"... on affiche une erreur
        echo "Usage: /etc/init.d/firewall {start|stop|restart|status}"
        # quitte le script avec un etat "en erreur"
        exit 1
    ;;

esac

Ensuite on rend le fichier exécutable :

chmod +x /etc/init.d/firewall

Maintenant on peut le tester :

service firewall start

Pour regarder les règles en cours :

service firewall status

Et pour l’arrêter :

service firewall stop

Maintenant un point très important.
Si au lancement du firewall vous ne vous êtes pas fait éjecter du terminal : c’est un bon point.
Mais il faut aussi tester la connexion nouvelle.
Avec le firewall lancé, quittez votre session ssh et re-loguez vous. Si vous y arrivez vous pouvez automatisez le démarrage du firewall.
Si ce n’est pas le cas il faut vérifier les règles.

Si tout est bon et que vous n’avez pas de soucis de connexion vous pouvez automatiser le démarrage avec la commande suivante :

update-rc.d firewall defaults

A partir de là le par-feu sera lancé automatiquement au démarrage de la machine. Vous n’avez plus rien à faire.

Vous pouvez maintenant vérifier les ports ouverts avec Netstat et Nmap.

Vous avez aimé cet article ? Réagissez !

Votre email ne sera pas publié. Les champs requis sont marqués d'une astérisque *