Configuration du firewall sous Debian

Bonjour à tous,

j’ai un petit souci avec la configuration du script du firewall sous Linux Debian. En fait, je dois bloquer tous les ports mais laisser le port internet ouvert (dans le sens où le pc Debian puisse accéder au net), ainsi que, si possible (ce n’est pas ça qui soit vraiment primordial), permettre de se connecter sur le pc Debian en ssh depuis un pc du réseau local.

Le petit problème, c’est que ça ne fonctionne pas tout à fait… Soit tous les ports sont bloqués, soit ils sont tous débloqués : je n’arrive pas à laisser ouvert que ces deux ports.

Voici mon script :

#!/bin/bash
INTERNET="eth1"
LOCAL="eth0"
Iptables –F
Iptables –t nat –F
Iptables –A OUTPUT –p tcp –i eth1 –-dport 80 –j ACCEPT
Iptables –A INPUT –p tcp –i eth0 –-dport ssh –j ACCEPT
Iptables –P INPUT –j DROP
Iptables –P FORWARD –j DROP
Iptables –P OUTPUT –j DROP

Voilà, qu’en dîtes-vous ?

Merci d’avance pour vos réponses,
Tom

Mes observations.

  • La description de la situation est insuffisante. Notamment il faut lire le script pour découvrir que la machine a deux interfaces. Elle fait routeur ?
  • “Le port internet”, ça ne veut rien dire. Je vais supposer qu’il s’agit du port 80 pour l’accès aux sites web (accès non sécurisé seulement, ajouter le port 443 pour HTTPS si besoin). S’il s’agit d’autre chose, merci de préciser.
  • C’est bien la peine de définir des jolies variables pour les noms des interfaces si elles ne servent pas dans les règles.
  • Ecrire “Iptables” avec I majuscule dans les commandes du script, ça risque de beaucoup moins bien marcher.
  • En règle générale et à moins de savoir exactement ce qu’on fait, il est souhaitable d’autoriser le trafic interne sur l’interface de loopback. On ne sait jamais quel processus local pourrait en avoir besoin.
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
  • Dans la chaîne OUTPUT, spécifier l’interface d’entrée (-i) n’a pas de sens. En revanche on peut spécifier l’interface de sortie (-o).
iptables -A OUTPUT -o $INTERNET -p tcp --dport 80 -j ACCEPT
  • Pour se connecter à un serveur web, il faut connaître son adresse IP, et pour ça il faut généralement faire une requête DNS. Donc il faut autoriser les requêtes DNS en sortie. Je suppose que les serveurs DNS interrrogés sont côté internet.
iptables -A OUTPUT -o $INTERNET -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -o $INTERNET -p tcp --dport 53 -j ACCEPT
  • Autoriser les requêtes (DNS, HTTP, SSH…), ce n’est pas suffisant. Il faut aussi autoriser les réponses.
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

En fait, là c’est ma seconde semaine d’alternance en première année de BTS IG. On m’a demandé de faire ce travail seulement je n’avais encore jamais utilisé Linux de ma vie ! Autant dire que je suis un grand débutant dans le domaine… :frowning:

Donc, déjà (par exemple), comment aurais-je pu savoir qu’il ne fallait pas mettre de « I » majuscules dans les commandes du script ? Tout le monde n’est pas un expert de Linux…

J’essaye tant bien que mal de comprendre le fonctionnement en faisant des recherches sur le net, mais à chaque fois je tombe sur des explications différentes (je fais bien attention qu’il s’agit d’une explication pour la version Debian *). Déjà - par exemple - rien que sur l’endroit où l’on doit enregistrer le script : à chaque fois il est indiqué un endroit différent -_-‘

Salut,

Lis bien la suite - par bien j’entends loupes pas un mot :wink:

Sous GNU/Linux, la casse est importante, une majuscule est une majuscule. Ainsi tu peux avoir dans un même répertoire les fichiers : README, readme, ReadMe (etc.)

[quote]
Déjà - par exemple - rien que sur l’endroit où l’on doit enregistrer le script : à chaque fois il est indiqué un endroit différent -_-‘[/quote]
Tu es libre de mettre ton fichier qui lance les commandes iptables où tu veux, et de l’appeler comme tu veux, mais une façon plus “pro” et Debianisée de le faire est la suivante :

Squelette du script

#!/bin/bash

IPTABLES="/sbin/iptables"
#tes autres variables ici

case "$1" in
start)
  $IPTABLES -P INPUT DROP
  $IPTABLES -P OUTPUT DROP
  $IPTABLES -P FORWARD DROP
  $IPTABLES -F
 
  #tes autres règles ici, comme te l'a indiqué PascalHambourg

  echo "Firewall Started."
  #le ';;' est à laisser et doit representer la dernière ligne de la config
  #parefeu
;;

stop)
  $IPTABLES -F
  $IPTABLES -P INPUT ACCEPT
  $IPTABLES -P OUTPUT ACCEPT
  $IPTABLES -P FORWARD ACCEPT
  echo "Firewall Stopped."
;;

*)
  echo "Usage : $0 {start|stop}"
  exit 1
;;

esac

Pourquoi un tel script ? Un script qui se lance au démarrage de la machine devrait toujours avoir un start/stop (c’est requis chez Debian pour les paquets officiels). Ensuite, si tu te trompes dans une règle, ça te permet d’annuler l’erreur rapidement.

Tu sauvegardes le fichier avec tes règles dans un fichier, appelons-le rc.firewall mais ça pourrait être autrement. Donc ensuite il faut qu’il soit executable : chmod +x rc.firewall Pour démarrer le pare-feu (en root bien sûr) : ./rc.firewall start Pour l’arrêter ./rc.firewall stop

La tu crées et testes tes règles de pare feu. Une fois tes régles bien définies, t’intégres ton script dans le système. Les scripts de démarrage sont dans /etc/init.d donc, toujours en root :

mv rc.firewall /etc/init.d chown root:root /etc/init.d/rc.firewall chmod 700 /etc/init.d/rc.firewall

Le chown et le chmod permettent de s’assurer qu’un utilisateur normal ne peut pas lire les régles, donc note bien qu’a l’avenir tu devras être root pour accéder au contenu du script. Maintenant que ton script est considéré comme script de démarrage, on va indiquer au système de lancer systématiquement le pare-feu au démarrage, toujours en root :

Et l’intégration au système est terminée (41, parce que 40 c’est le démarrage du réseau, S= quelque soit le mode de démarrage choisi, en très simplifié, et discutable). Le script démarrera automatiquement à chaque démarrage.

Si t’as des questions sur une commande : man nom_dela_commande contient la réponse :stuck_out_tongue: Tout ce que je viens d’expliquer peut te paraître complexe, mais dans la mesure où tu débutes prends ton temps pour comprendre l’intégralité de la manoeuvre.

Bon courage :smiling_imp:

[size=50][TROLL=ON]PF est plus user friendly que iptables[/TROLL][/size]

Salut,

Utiliser /etc/init.d n’est plus considéré comme une méthode « pro » qui plus est en le lançant après le réseau. :wink:

Depuis plusieurs années il est recommandé de placer le script de lancement (ou le script appelant les règles) dans /etc/network/if-pre-up.d/ ainsi il se lancera avant le réseau. Et de la même manière d’utiliser /etc/network/if-post-down.d/ pour le script d’arrêt.

En quoi n’est-ce plus une méthode pro ?
Evidemment il faut le lancer le script de pare-feu avant d’activer les interfaces réseau, en spécifiant un numéro de séquence inférieur à 40.

Je ne suis pas d’accord avec cette méthode. Si je ne m’abuse, les scripts placés dans ces répertoires sont exécutés lors de l’activation ou de la désactivation de chaque interface individuelle, et non une fois pour toutes au démarrage et à l’arrêt du réseau. Par conséquent s’il y a plusieurs interfaces le script d’activation du pare-feu est exécuté plusieurs fois, et dès qu’une des interfaces est désactivée le script de désactivation du pare-feu est exécuté, laissant les interfaces actives restantes sans protection. Ce n’est pas adapté à un script de pare-feu global.

Une bonne solution est probablement entre les deux : une script global dans /etc/init.d/ exécuté une seule fois avant le démarrage (resp. après l’arrêt) du réseau, et des scripts spécifiques dans /etc/network/if-*.d/ exécutés lors de l’activation (resp. désactivation) d’une interface et ne s’occupant que des règles spécifiques à cette interface le cas échéant.

J’ai volontairement exagéré eut égard à l’ordre de lancement du script qui était proposé.
Néanmoins cette méthode n’est plus conseillée depuis Sarge il me semble car elle est aussi souple qu’un parpaing et n’est pas vraiment dans « l’esprit » Debian.

/etc/network/* est l’endroit où gérer ce qui a trait au réseau et les services qui lui sont associés (wifi, etc) et offre tout ce qu’il faut pour.

[quote=“PascalHambourg”]Si je ne m’abuse, les scripts placés dans ces répertoires sont exécutés lors de l’activation ou de la désactivation de chaque interface individuelle, et non une fois pour toutes au démarrage et à l’arrêt du réseau[/quote].
Oui.

Rien ne t’oblige à faire un script bête et méchant qui ne tiendrait pas compte de l’état des interfaces… :wink:

Tout cela peut ce gérer dans /etc/network/if-*.d/ sans oublier /etc/network/interfaces et les commandes pre-up, etc.
Maintenant oui, cette méthode peut être plus, voire beaucoup plus complexe à mettre à place dans une configuration où plusieurs interfaces sont exposées mais elle est très souple et permet de faire des choses très fines tout en restant cohérente. :smiley: