Serveur Debian - Iptables
Par Seza le mercredi 23 mai 2007, 10:54 - Serveur Debian - Lien permanent
CHAPITRE 1 : IPTABLES
Si vous ne connaissez pas encore « iptables »
, c'est LA commande pour gérer les connexions réseau, faire des redirections de port, blacklister une adresse IP ou tout simplement ouvrir ou fermer des ports. C'est ce que l'on appelle un pare-feu ou firewall.
Par défaut « iptables »
laisse tout ouvert et ne filtre rien. Notre but c'est de fermer un peu tout ça et de garder le minimum ouvert.
Je ne rentrerai pas dans le détails de l'utilisation de « iptables »
car bien trop de choses sont à voir mais nous allons l'utiliser d'une manière simple et efficace ce qui vous donnera les bases minimales pour commencer à appréhender « iptables »
.
Nous allons paramétrer « iptables »
de manière à l'utiliser que pour nos besoins. A l'heure actuelle, seul « apt »
(la gestion des paquets Debian) et « ntpdate »
(synchronisation de l'heure) font des connexions réseau. Nous allons donc tout bloquer puis ouvrir un passage à « apt »
et « ntpdate »
.
D'abord on supprime toutes les règles existante (des fois qu'ils y en aurait de rentrées) :
ALBAN@bebeserv:~$ sudo iptables -t filter -F INPUT ALBAN@bebeserv:~$ sudo iptables -t filter -F OUTPUT
Maintenant on ferme les portes :
ALBAN@bebeserv:~$ sudo iptables -t filter -P INPUT DROP ALBAN@bebeserv:~$ sudo iptables -t filter -P OUTPUT DROP
Un reflex qu'il faut avoir c'est de toujours autoriser la boucle locale (et ceci doit être toujours la première règle) :
ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i lo -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o lo -j ACCEPT
Dorénavant nous sommes totalement fermé de l'extérieur. Configurons « iptables »
pour laisser « apt »
.
« apt »
aura déjà besoin de faire des requêtes DNS (port 53 en UDP et TCP) pour résoudre les noms tel que « ftp.debian.fr »
afin de pouvoir récupérer les listes et les paquets.
Normalement un client DNS n'a besoin que du protocole UDP mais ce dernier est laxiste sur sa spécification et autorise aussi le TCP (qui est normalement réservé au transfert de zone DNS)
Ouvrons le port DNS en TCP et UDP pour l'entrée et la sortie :
ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -p tcp --sport 53 -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -p udp --sport 53 -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p tcp --dport 53 -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p udp --dport 53 -j ACCEPT
Si vous posséder un serveur DNS ouvrez vous aurez besoin d'ouvrir les ports dans l'autre sens :
ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -p tcp --dport 53 -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -p udp --dport 53 -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p tcp --sport 53 -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p udp --sport 53 -j ACCEPT
De même ouvrons le port 80 en TCP pour que « apt »
puisse télécharger les paquets :
ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -p tcp --sport 80 -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p tcp --dport 80 -j ACCEPT
De même pour un serveur web ouvrez les ports dans l'autre sens :
ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -p tcp --dport 80 -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p tcp --sport 80 -j ACCEPT
Maintenant autorisons « ntpdate »
qui lui utilise le port 123 en UDP :
ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -p udp --sport 123 -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p udp --dport 123 -j ACCEPT
A ce stade nous pourrions nous arrêter là tout es fonctionnel. Mais allons plus loin.
Maintenant ajoutons une règle qui dira que toute connexion déjà établie avec le serveur donc déjà autoriser par « iptables »
sera elle aussi autorisée (même sur un port fermé par exemple). Cette règle est facultative mais bien utile quand vous tester votre configuration vous permettant de tester avec la règle de log (voir ci-dessous) les paquets qui sont rejetés qui devrait être acceptés.
ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -m state --state RELATED,ESTABLISHED -j ACCEPT ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -m state --state RELATED,ESTABLISHED -j ACCEPT
Dernière ces règles nous allons loguer dans le fichier « /var/log/debug »
tout les paquets que nous allons bloquer avant de les bloquer :
ALBAN@bebeserv:~$ sudo iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -j LOG --log-prefix "Iptables INPUT dropped : " --log-level debug ALBAN@bebeserv:~$ sudo iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -j LOG --log-prefix "Iptables OUPUT dropped : " --log-level debug
Il est est terminer des règles. Maintenant voyons quelques commandes utiles. Sauver votre configuration :
ALBAN@bebeserv:~$ sudo iptables-save > ~/iptables-sauvegarde
Restaurer votre configuration :
ALBAN@bebeserv:~$ sudo iptables-restore ~/iptables-sauvergade
Voir votre configuration complète :
ALBAN@bebeserv:~$ sudo iptables -L -v --line-numbers
Vérifier le log en temps réel (paquets rejetés) : (tapez « [CTRL + C] »
pour sortir)
ALBAN@bebeserv:~$ sudo tail -f /var/log/debug
Quand le serveur redémarre vos règles « iptables »
seront perdues, il faut donc automatiser la mise en place de ces règles.
Allez dans « /etc/network »
:
ALBAN@bebeserv:~$ cd /etc/network ALBAN@bebeserv:/etc/network$
Créez le fichier « iptables »
à côté du fichier « interface »
:
ALBAN@bebeserv:/etc/network$ sudo nano iptables
Entrez les mêmes lignes que nous avons du taper pour configurer « iptables »
(attention aux fautes de frappes !) :
# A modifier en fonction de votre adresse IP MYIP=10.0.0.2 iptables -t filter -F INPUT iptables -t filter -F OUTPUT iptables -t filter -Z INPUT iptables -t filter -Z OUTPUT iptables -t filter -P INPUT DROP iptables -t filter -P OUTPUT DROP iptables -t filter -A INPUT -i lo -j ACCEPT iptables -t filter -A INPUT -i eth0 -d $MYIP -p tcp --sport 53 -j ACCEPT iptables -t filter -A INPUT -i eth0 -d $MYIP -p udp --sport 53 -j ACCEPT iptables -t filter -A INPUT -i eth0 -d $MYIP -p tcp --sport 80 -j ACCEPT iptables -t filter -A INPUT -i eth0 -d $MYIP -p udp --sport 123 -j ACCEPT iptables -t filter -A INPUT -i eth0 -d $MYIP -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -t filter -A INPUT -i eth0 -d $MYIP -j LOG --log-prefix "Iptables INPUT dropped : " --log-level debug iptables -t filter -A OUTPUT -o lo -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -s $MYIP -p tcp --dport 53 -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -s $MYIP -p udp --dport 53 -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -s $MYIP -p tcp --dport 80 -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -s $MYIP -p udp --dport 123 -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -s $MYIP -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -s $MYIP -j LOG --log-prefix "Iptables OUPUT dropped : " --log-level debug
Enregistrez le fichier « [CTRL + O] »
et quittez « [CTRL + X] »
:
Créez le fichier de démarrage,
ALBAN@bebeserv:/etc/network$ cd /etc/init.d/ ALBAN@bebeserv:/etc/init.d$ sudo nano iptables-conf
Entrez ceci :
#! /bin/sh set -e iptables_start() { if [ -f /etc/network/iptables ]; then . /etc/network/iptables fi } iptables_stop() { iptables -t filter -F INPUT iptables -t filter -F OUTPUT iptables -t filter -P INPUT ACCEPT iptables -t filter -P OUTPUT ACCEPT } case "$1" in start) echo -n "Apply Iptables configuration" iptables_start echo "." ;; stop) echo -n "Clear Iptables configuration" iptables_stop echo "." ;; restart) echo -n "Reloading Iptables configuration" iptables_stop iptables_start echo "." ;; *) echo "Usage: /etc/init.d/iptables-conf {start|stop|restart}" exit 1 esac exit 0
Donnons les bons droits à notre fichier :
ALBAN@bebeserv:/etc/init.d$ sudo chmod +x iptables-conf
Enregistrez et quittez. Rajoutez le script de démarrage dans le mode voulu avec la priorité voulue :
ALBAN@bebeserv:/etc/init.d$ sudo update-rc.d iptables-conf start 99 2 3 4 5 . stop 20 0 1 6 . [...]
Testons le tout, affichons la configuration actuelle :
ALBAN@bebeserv:/etc/init.d$ sudo iptables -L -v --line-numbers [...]
Stoppez le firewall :
ALBAN@bebeserv:/etc/init.d$ sudo /etc/init.d/iptables-conf stop [...]
Vérifiez que tout est vide et autorisé :
ALBAN@bebeserv:/etc/init.d$ sudo iptables -L -v --line-numbers [...]
Démarrons le firewall :
ALBAN@bebeserv:/etc/init.d$ sudo /etc/init.d/iptables-conf start [...]
Vérifions que toutes les règles sont bien présentes :
ALBAN@bebeserv:/etc/init.d$ sudo iptables -L -v --line-numbers [...]
Modifions nous même la configuration actuelle :
ALBAN@bebeserv:/etc/init.d$ sudo iptables -F INPUT [...] ALBAN@bebeserv:/etc/init.d$ sudo iptables -L -v --line-numbers [...]
Redémarrons le firewall pour vérifier que tout revient comme nous l'avions configuré :
ALBAN@bebeserv:/etc/init.d$ sudo /etc/init.d/iptables-conf restart [...] ALBAN@bebeserv:/etc/init.d$ sudo iptables -L -v --line-numbers [...]
Voilà c'est terminé pour ce chapitre !
ALBAN@bebeserv:/etc/init.d$ cd ~ ALBAN@bebeserv:~$
Commentaires
Bonjour,
Tout d'abord je tiens à te dire que ton tutos est génial j'ai réussi à config mon iptables.
Par contre j'ai un soucis lorsque je redémarre mon serveur je ne peut plus accéder en ssh à ma machine ...
J'ai pourtant ajouté :
iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -p tcp --dport 22 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -d 10.0.0.2 -p udp --dport 22 -j ACCEPT
Dans les règles du fichier iptables ...
Cordialement.
Bonjour,
Merci pour tes compliments. La première chose que je remarque c'est l'adresse IP dans ta ligne de commande. Es-tu sûr de celle-ci ?
Sinon seul le proto TCP est nécessaire tu peux enlever la seconde ligne avec le proto UDP pour le SSH. Une dernière chose si tu filtres en entrant et en sortant comme dans mes exemples. N'oublies pas d'autoriser SSH à sortir avec cette ligne :
iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p tcp --dport 22 -j ACCEPT
J'espère que je t'aurais aidé.
Bonjour,
Pour se qui est de l'IP j'ai mit celle de mon serveur et j'ai aussi supprimé le proto UDP.
Par contre cela ne marche toujours pas, je dois toujours redémarrer iptables-conf pour que ma règle 22 soit prise en compte... ?
Cordialement.
Ton ssh est bien sur le port 22 ? Tu n'a pas changer le port pour le sécuriser par hasard ?
Rien changé car comme dit plus haut, il me suffit de redémarrer iptables pour que cela marche ...
La règle n'est pas prise en compte lors du redémarrage du serveur, mais que lorsque je redémarre iptables ...
Bizarre non ?
Je n'ai jamais eu ce genre de problème. As-tu vérifié que les règles étais bien lancée au démarage ? J'imagine que oui. Et ça ne te le fait que pour SSH ou pour toutes les règles entrées ?
Désolé de poser autant de questions mais il faut des infos pour cerner le problème (quand on y arrive).
La règle qu'il faut ajouter en OUTPUT n'est pas
iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p tcp --dport 22 -j ACCEPT
mais
iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -p tcp --sport 22 -j ACCEPT
(il suffit de changer dport en sport), en effet, les connexions quittant le serveur SSH ont pour ORIGINE le port 22 mais pour DESTINATION un port arbitraire, déterminé par le client.
Oui ! Exact dans la précipitation je n'ai pas fait attention.
Néanmoins cette ligne n'est pas obligatoire si les connexions déjà établies sont autorisées par la ligne :
iptables -t filter -A OUTPUT -o eth0 -s 10.0.0.2 -m state --state RELATED,ESTABLISHED -j ACCEPT
La ligne que j'ai indiqué avec le --dport permet à la machine distante d'utiliser sont client ssh pour se connecter elle-même à une machine.
EDIT : J'ai fait une petite mise à jour du tuto pour que ça soit plus clair.
Salut Seza
Je "prends" maintenant "le taureau par les cornes". J'ai commencé par le comencement. Seulement je suis toujours confronté à l'accès à Internet quand je demarre IPTABLES. Les règles que j'ai recopié de ton tuto sont ceci(etc/network/iptables):
"
## MYIP=192.168.0.169
MYIP=99.178.171.119
iptables -t filter -F INPUT
iptables -t filter -F OUTPUT
iptables -t filter -Z INPUT
iptables -t filter -Z OUTPUT
iptables -t filter -P INPUT DROP
iptables -t filter -P OUTPUT DROP
iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A INPUT -i eth0 -d $MYIP -p tcp --sport 53 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -d $MYIP -p udp --sport 53 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -d $MYIP -p tcp --sport 80 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -d $MYIP -p udp --sport 123 -j ACCEPT
iptables -t filter -A INPUT -i eth0 -d $MYIP -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A INPUT -i eth0 -d $MYIP -j LOG
log-prefix "Iptables INPUT dropped : "log-level debugiptables -t filter -A OUTPUT -o lo -j ACCEPT
iptables -t filter -A OUTPUT -o eth0 -s $MYIP -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o eth0 -s $MYIP -p udp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -o eth0 -s $MYIP -p tcp --dport 80 -j ACCEPT
iptables -t filter -A OUTPUT -o eth0 -s $MYIP -p udp --dport 123 -j ACCEPT
iptables -t filter -A OUTPUT -o eth0 -s $MYIP -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A OUTPUT -o eth0 -s $MYIP -j LOG
log-prefix "Iptables OUPUT dropped : "log-level debug## Champ pour ssh :
## iptables -t filter -A OUTPUT -o eth0 -s $MYIP -p tcp --dport 22 -j ACCEPT"
Que j'utilise mon adresse ip locale ou publique (comme inidiqué par les deux valeurs de la variable MYIP) en exécutant le script " sudo /etc/init.d/iptables-conf start" ma connexion à Internet reste bloquée. Le port 80 est quand meme ouvert à travers une règle, non?Je ne sais pas si je dois rajouter une ou des règle(s) supplementaire(s). Je signale juste que j'ai un routeur auquel j'ai pas touché encore. (Cest un D-LINK! ça va être chaud pour configurer ça aussi si ça devait...)
Merci d'avance pour ton aide.
Salut
Je pense que j'ai résoud le problème. "La nuit portant conseil"!. En fait comme j'arrive à acceder à Internet avant d'activer IPTABLES, j'ai tout somplement commenté les lignes :
"## iptables -t filter -F INPUT
## iptables -t filter -F OUTPUT
## iptables -t filter -Z INPUT
## iptables -t filter -Z OUTPUT
## iptables -t filter -P INPUT DROP
## iptables -t filter -P OUTPUT DROP "
qui remettent à plat toute connexion. Vu que IPTABLES (à travers une de tes régles) laisse continuer toutes connexions établies, alors j'ai plus de problème. C'est tout bête en fait.
J'espère que ça tiendra comme ça. Est-ce est une bonne idée d'avoir procédé ainsi? Je ne me dis pas que l'important est que ça marche! C'est la sécurité des données avant tout. Qu'en penses-tu?
Bonne journée.
Salut bekabeka:
Excuse moi de te répondre si tard, mais mon pc m'a laché durant les fêtes de noël ! Le temps d'en racheter et de me refaire un petit nid, me revoilà !
Donc concernant ton premier commentaire, si j'ai bien suivant, tu essaie iptables sur un pc chez toi. Dans ce cas de figure ton pc est relié à un réseau local donc c'est l'ip local que tu dois utilisé pour iptables. À noter que le script utilise eth0 comme interface, ceci peut varier d'un pc à l'autre surtout si ton pc est relié en wifi tu devrais donc remplacer alors eth0 par un wlan0 ou un truc du genre.
Concernant le deuxième commentaire, non je ne suis pas d'accord. En commentant les premières lignes, certes iptables n'est plus remis à 0 mais surtout tu ne places plus la policy de iptables en DROP donc les paquets qui ne sont pas matcher par des règles ne sont plus rejetés ce qui revient à dire j'accepte tout, c'est à dire à ne pas avoir d'iptables du tout.