Utilisation de base de iptables

Introduction

Cet article vise les gens qui ont déjà une légère base de connaissances sous linux en shell et une base en réseautique et dans les pare-feu (firewall) en général.  Il a pour but d’aider a comprendre et être capable d’utiliser quelques commandes de base de iptables qui vous permetterons de sécuriser une bonne partie de votre serveur.  Cet article implique que vous ayez déjà iptables d’installé sur votre système.

Les exemples sont basés sur un serveur web avec Apache, MySQL, SSH, ProFTPD, Bind, SendMail sur CentOS.  Notez que les commandes iptables sont aussi fonctionnelles sur d’autres distributions de linux et que vous pouvez modifier ces règles pour les adapter à d’autres logiciels (ex.: vsftpd, pureftpd, powerdns, etc.).  Notez que les commandes shell ci-dessous sont exécutées en tant que root.

Créer un fichier de configuration initial

Avant de tout commencer, sauvegardez le fichier de configuration actuel si vous en avez un :

# cp -p /etc/sysconfig/iptables /etc/sysconfig/iptables.backup

Une façon simple de créer le fichier de configuration iptables est d’entrer une première commande iptables à la volée en shell et ensuite demander à iptables de créer le fichier de configuration lui-même.  Tapez les commandes suivantes, même si vous ne les comprenez pas pour l’instant (on accepte toute communication provenant de l’extérieur, question de ne pas se bloquer nous-même en partant) :

# iptables -A INPUT -j ACCEPT
# iptables-save > /etc/sysconfig/iptables

Ensuite, ouvrez votre fichier /etc/sysconfig/iptables avec votre éditeur texte favori.  Vous devriez y voir quelque chose qui ressemble à ceci :

# Generated by iptables-save v1.3.5 on Fri May 28 20:34:23 2010
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [41:3804]
-A INPUT -j ACCEPT
COMMIT
# Completed on Fri May 28 20:34:23 2010

C’est ici que le plaisir débute!

DNS avec Bind

Débutons par enlever la ligne que nous avons ajouté pour créer le fichier iptables (-A INPUT -j ACCEPT).  Ensuite, attaquons nous au service DNS de Bind.  Voici les commandes de base que j’entre pour laisser passer Bind (j’aime bien apposer des commentaires pour me comprendre plus tard si j’y reviens, ils sont précédés d’un #) :

# DNS TCP et UDP et RNDC
-A INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 953 -j ACCEPT

Dans la première ligne, le « -A INPUT » veut dire d’ajouter (append) à la chaine nommée INPUT, ce qui a pour but d’ajouter une commande pour vérifier les paquets qui tentent d’entrer dans le serveur.

Le « -m state » veut dire qu’il faut que le paquet concorde « match » un état « state ».

Le « –state NEW » veut dire que l’état « state » qui doit concoder doit être une nouvelle communication « NEW ».

Le « -m tcp » veut dire que le paquet doit concorder avec le protocole tcp.

Le « -p tcp » veut dire que le protocole du paquet doit être tcp.

Le « –dport 53 » veut dire que le paquet doit être destiné au port 53.

Le « -j ACCEPT » veut dire que l’action à effectuer si toutes les vérifications précédentes sont véridictes est d’accepter le paquet.

Les deux règles suivantes sont similaires et acceptent les paquets sur le port 53 en udp et sur le port 953 en tcp.

Emails avec sendmail, ipop3d et imapd

# 25 SMTP, 110 POP3, 143 IMAP, 465 SMTPS, 993 IMAPS, 995 POP3S
-A INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 110 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 143 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 465 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 993 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 995 -j ACCEPT

Pas très compliqué…  Exactement la même commande mais pour les ports ayant trait aux emails (SMTP, POP3, IMAP, SMTPS, IMAPS et POP3S).  Notez que certaines configurations SMTPS utilisent aussi le port 587.

FTP avec ProFTPD

-A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 60000:60199 --syn -j ACCEPT

Ici on accepte les connexions sur le port 21 ainsi que les connexions de type « syn » qui permettent d’initier des nouvelles connections en tcp.  Nous acceptons les nouvelles connexions tcp sur les ports 60000 à 60199 (ça aurait pu être d’autres ports, plus de ports ou moins de ports).  Je configure ensuite ProFTPD pour accepter les connexions passives dans ces mêmes ports donc les transferts FTP fonctionnent normalement en mode passif et il n’y a pas plein de ports ouverts à toutes les requêtes en tout temps.

HTTP avec Apache

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

Ici nous acceptons simplement les requêtes sur les ports HTTP et HTTPS normaux.

ICMP Ping

-A INPUT -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT

Il est toujours intéressant de pouvoir faire des « ping » sur le serveur pour diverses raisons telles que vérifier si le serveur réponds, s’il réponds assez rapidement ou pour générer des rapports de disponibilité.

MySQL

#-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
-A INPUT -s 127.0.0.1 -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
#-A INPUT -s 10.10.10.10 -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT

La première ligne est déconseillée puisqu’elle ouvre MySQL pour n’importe qui.  L’utiliser seulement si c’est bien le but et que vous comprenez les risques.

La deuxième ligne donne accès à MySQL localement (pour toute requête venant du serveur lui-même), ce qui est nécessaire.

La troisième ligne est un exemple si vous voulez ouvrir MySQL pour l’IP d’une personne en particulier ou de vos bureaux par exemple.

SSH

# Local
-A INPUT -s 127.0.0.1 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
# Adresses connues
-A INPUT -s 10.10.10.10 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

Simplement ajouter les IPs desquelles vous vous connecter.  Si vous n’avez pas d’IP statique, enlevez la partie « -s 10.10.10.10 » et vous pourrez vous connecter de n’importe ou.  Il est aussi toujours préférable d’accepter les connections SSH seulement avec des clés et non pas par mot de passe.  Par contre, cette configuration ne touche pas iptables et sort du contenu de cet article.

Pour boucler la boucle

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -j DROP

Ici, la première ligne accepte tous les paquets provenant de connexions déjà établies ou reliées.

La deuxième ligne laisse tomber tous les paquets n’ayant pas trouvé de règle les acceptant.  Ainsi, tout ce qui n’est pas un service accepté ou une IP acceptée sera automatiquement laissé de côté sans même une réponse comme quoi il est refusé, ce qui est plus sécuritaire.

Le résultat complet

Une fois tout réuni, le fichier devrait maintenant avoir l’air de ceci :

# Generated by iptables-save v1.3.5 on Fri May 28 20:34:23 2010
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [41:3804]

#######
# DNS #
#######

# DNS TCP et UDP et RNDC
-A INPUT -m state --state NEW -m tcp -p tcp --dport 53 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 953 -j ACCEPT

#########
# EMAIL #
#########

# 25 SMTP, 110 POP3, 143 IMAP, 465 SMTPS, 993 IMAPS, 995 POP3S
-A INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 110 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 143 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 465 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 993 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 995 -j ACCEPT

#######
# FTP #
#######

-A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 60000:60199 --syn -j ACCEPT

########
# HTTP #
########

-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

########
# ICMP #
########

-A INPUT -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT

#########
# MySQL #
#########

-A INPUT -s 127.0.0.1 -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT

#######
# SSH #
#######

# Local
-A INPUT -s 127.0.0.1 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
# Adresses connues
-A INPUT -s 10.10.10.10 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

##########
# GLOBAL #
##########

# Accept everything related or already established, drop everything that did not match
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -j DROP

COMMIT
# Completed on Fri May 28 20:34:23 2010

Activation de iptables au démarrage

Vérifiez si iptables est déjà activé en tapant « chkconfig –list iptables ».  Si vous voyez quelques « on », c’est qu’il est actif.  Sinon, tapez « chkconfig iptables on ».

Conclusion

Vous savez maintenant comment faire une protection minimaliste de votre serveur web et ainsi éviter d’avoir des trous béants de sécurité.  J’espère que ceci vous aura aidé!

Be Sociable, Share!

Une réflexion au sujet de « Utilisation de base de iptables »

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *