Gentoo Logo

[ << ] [ < ] [ Sommaire ] [ > ] [ >> ]


12. Pare-feu

Table des matières :

12.a. Un pare-feu

La plupart des gens pensent qu'un pare-feu est la réponse ultime aux problèmes de sécurité. Ils ont tort. Dans la majorité des cas, avoir un pare-feu mal configuré présente plus de dangers de sécurité que de ne pas en avoir du tout. Un pare-feu est un logiciel et doit donc être traité comme tout autre service, tout simplement car il est susceptible d'avoir des bogues, au même titre que les autres programmes.

Réfléchissez donc bien avant de mettre en placce un pare-feu ! En avez-vous vraiment besoin ? Si vous le pensez, écrivez une politique sur son utilité, son type et qui doit s'en occuper. Mais tout d'abord, lisez ce guide.

Les pare-feu sont utilisés dans deux situations :

  • Pour garder des utilisateurs (vers/attaquants) à l'extérieur.
  • Pour garder des utilisateurs (employés/enfants) à l'intérieur.

Il existe globalement 3 types de pare-feu :

  • Filtrage de paquets
  • Relais de circuit
  • Passerelle d'application

Un pare-feu devrait être une machine dédiée sans aucun service (ou uniquement sshd) et sécurisée de la façon qui est recommandée dans ce guide.

12.b. Filtrage de paquets

Tout le trafic réseau se fait sous forme de paquets. Une grande partie du trafic est découpée en petits paquets pour une gestion plus simple. Ils sont ensuite réassemblés une fois arrivés à leur destination. L'en-tête de chaque paquet contient des informations sur comment et où il devrait être délivré. Ces informations sont très exactement ce qu'un pare-feu filtrant les paquets utilise. Le filtrage se base sur :

  • Autorisation ou interdiction des paquets en se basant sur l'adresse IP source/destination.
  • Autorisation ou interdiction des paquets en se basant sur un port source/destination.
  • Autorisation ou interdiction des paquets selon le protocole.
  • Autorisation ou interdiction des paquets selon les options établies à l'intérieur d'un protocole.

En d'autres mots, le filtrage se fait sur les données contenues dans l'en-tête d'un paquet et non pas sur son contenu.

Faiblesses :

  • L'adresse IP d'un paquet peut être contrefaite ou, comme le veut le terme dédié, spoofée par son envoyeur.
  • Les données ou requêtes contenues dans le paquet peuvent contenir des données indésirables que l'attaquant peut utiliser pour exploiter des bogues connus dans les services qui sont sur ou derrière le pare-feu.
  • Est généralement un point faible pouvant causer une panne globale.

Avantages :

  • Simple et facile à implémenter.
  • Peut donner des avertissements sur une attaque possible avant qu'elle n'arrive (en détectant les scanneurs de ports).
  • Bonne méthode pour arrêter les attaques de type SYN.

Voici quelques exemples de filtreurs de paquets gratuits sous Linux :

Note : nous recommandons d'utiliser iptables. ipchains est obsolète.

12.c. Relais de circuit

Aussi appelé passerelle de niveau circuit, ce type de pare-feu valide les connexions avant d'autoriser l'échange de données. Cela signifie qu'il n'autorise et ne refuse pas les paquets en fonction de leur en-tête mais détermine plutôt si une connexion entre les deux parties est valide, en consultant un ensemble de règles configurables, avant d'autoriser l'ouverture d'une session de transfert de données. Le filtrage est basé sur :

  • Adresse de destination/source
  • Port de destination/source
  • Un certain laps de temps
  • Protocole
  • Utilisateur
  • Mot de passe

Tout le trafic est validé et surveillé, et peut être bloqué lorsqu'il ne correspond pas aux règles.

Faiblesse :

  • Opère sur la couche de transport et peut nécessiter des modifications substantielles des programmes fournissant habituellement les fonctions de transport.

12.d. Passerelle d'applications

La passerelle de niveau application est un mandataire pour les applications, échangeant des données avec un système distant selon les demandes de ses clients. Elle est gardée à l'abri du public, en sécurité derrière une DMZ (zone démilitarisée, la portion de réseau privé visible à travers le pare-feu) ou un pare-feu sans connexion vers l'extérieur. Le filtrage est basé sur :

  • L'autorisation ou l'interdiction selon les adresses IP source/destination.
  • Le contenu des paquets.
  • Limitation de l'accès aux fichiers en fonction du type ou de l'extension.

Avantages :

  • Peut mettre des fichiers en cache, améliorant ainsi les performances réseau.
  • Journal complet et détaillé de toutes les connexions.
  • S'adapte bien aux changements d'échelle (certains serveurs mandataires peuvent « partager » les données en cache).
  • Aucun accès direct depuis l'extérieur.
  • Peut même modifier le contenu des paquets en temps réel.

Faiblesses :

  • Sa configuration est compliquée.

Les passerelles d'applications sont considérées comme les solutions les plus sécurisées étant donné qu'elles ne doivent pas fonctionner sous root et que leurs hôtes ne sont pas accessibles depuis Internet.

Un exemple de passerelle d'applications est Squid.

12.e. Iptables

Vous devez activer iptables dans le noyau pour pouvoir l'utiliser. Je l'ai ajouté en tant que modules (la commande iptables les chargera lorsqu'elle en a besoin), puis j'ai recompilé mon noyau. (Toutefois, si vous souhaitez désactiver l'option Loadable Kernel Modules tel que discuté plus tôt, vous devrez ajouter iptables directement dans le noyau.) Pour plus d'informations sur la configuration du noyau pour iptables, consultez le Iptables Tutorial Chapter 5: Preparations. Après la compilation de votre nouveau noyau (ou pendant sa compilation), vous devez installer la commande iptables. Il suffit d'exécuter emerge iptables, et cela devrait fonctionner.

Testez à présent si tout fonctionne avec la commande iptables -L. Si cette dernière échoue, c'est que quelque chose ne va pas ; vérifiez à nouveau votre configuration.

Iptables est le nouveau filtreur de paquets du noyau Linux 2.4.x. Il a été considérablement amélioré par rapport à son prédécesseur, ipchains, le filtreur de paquets du noyau Linux 2.2.x. Une des principales améliorations est le filtrage de paquets par état. Grâce à cette fonction, il est possible de garder une trace de chaque connexion TCP établie.

Une connexion TCP est composée d'une série de paquets contenant des informations sur les adresses IP et les ports de la source et du destinataire, ainsi qu'une séquence permettant de réassembler les paquets par la suite, sans perte de données. TCP est un protocole qui établit une connexion, contrairement à UDP.

En examinant les en-têtes des paquets, un filtre de paquets par état peut déterminer si un paquet TCP reçu fait partie d'une connexion établie ou non, et ainsi accepter ou rejeter le paquet.

Avec un filtre de paquets sans état, il est possible de leurrer le filtre en lui faisant accepter des paquets qui devraient être rejetés. Cela se fait en manipulant les en-têtes des paquets TCP. En modifiant le drapeau SYN (ou d'autres drapeaux) de l'en-tête TCP, on peut déguiser un paquet mal intentionné pour qu'il semble faire partie d'une connexion déjà établie (car le filtre de paquets ne garde pas de trace des connexions). Avec un filtrage par état, il est possible de rejeter de tels paquets, étant donné qu'ils ne font pas partie d'une connexion déja établie. Cela empêchera aussi les « scans invisibles », un type de scanneur de ports qui envoie des paquets dont les drapeaux sont moins susceptibles d'être consignés par un pare-feu que ceux des paquets SYN standards.

Iptables propose beaucoup d'autres fonctionnalités comme le NAT (Network Address Translation - traduction d'adresses réseau) et la limitation de flux. La limitation de flux est très utile quand on essaie de prévenir certaines attaques de type déni de service (DoS) comme les « SYN floods ».

Une connexion TCP est établie en trois temps (N.D.T. : « three-way handshake » en anglais). Quand on établit une connexion TCP, le client envoie un paquet au serveur avec le drapeau SYN levé. Quand le serveur reçoit le paquet SYN, il répond en envoyant un paquet SYN+ACK au client. Quand le paquet SYN+ACK est reçu par le client, il répond avec un troisième paquet ACK qui a pour effet d'établir la connexion.

Un attaque « SYN floods » est effectuée en envoyant le paquet SYN mais en ne répondant pas au paquet SYN+ACK. Le client peut créer un paquet avec une adresse IP source falsifiée car il n'a pas besoin de réponse. Le serveur ajoute une entrée dans la queue de connexions semi-ouvertes quand il reçoit le paquet SYN et attend ensuite le paquet ACK final avant de supprimer cette entrée de la queue. La queue a un nombre de places limité et, si toutes les places sont occupées, le serveur ne peut plus ouvrir de connexions. Si le paquet ACK n'est pas reçu avant un délai spécifié, l'entrée va être automatiquement supprimée de la queue. Le délai varie, mais se situe typiquement entre 30 et 60 secondes, voire plus. Le client initie l'attaque en créant une énorme quantité de paquets SYN avec des adresses IP sources différentes et les envoie vers l'IP cible avec le plus haut débit possible. Cela a pour effet de remplir la queue des connexions semi-ouvertes et empêche les autres clients d'établir des connexions légitimes avec le serveur.

C'est là que la limitation de flux devient utile. Il est possible de limiter le flux de paquets SYN acceptés en utilisant -m limit --limit 1/s. Cela limitera le nombre de paquets SYN acceptés à un par seconde et réduira donc l'efficacité du « SYN floods ».

Note : les cookies SYN sont une autre option permettant de prévenir les « SYN floods ». Ils permettent à votre ordinateur de répondre aux paquets SYN sans remplir l'espace dans la queue de connexion. Les cookies SYN peuvent être activés dans la configuration de noyau Linux, mais ils sont encore, pour l'instant, considérés comme une fonctionnalité expérimentale.

Maintenant un peu de pratique !

Lorsque iptables est chargé dans le noyau, il contient 5 sections dans lesquelles vous pouvez placer vos règles : INPUT, OUTPUT, FORWARD, PREROUTING et POSTROUTING. Ces sections sont appelées chaînes car elles consistent en une liste de règles. Chaque règle indique ce qu'il faut faire en fonction de l'en-tête du paquet. Si une règle ne correspond pas à un paquet, la règle suivante est consultée.

Vous pouvez ajouter des règles directement dans une des 5 chaînes ou créer des chaînes de règles et les ajouter aux chaînes existantes. Iptables supporte les options suivantes :

Option : Description :
-A Append (ajoute)
-D Delete (efface)
-I Insert (insère)
-R Replace (remplace)
-L List (liste)
-F Efface toutes les règles dans la ou les chaînes
-Z Remet les compteurs à zéro dans une ou plusieurs chaînes
-C Teste ce paquet sur une chaîne
-N Crée une chaîne définie par l'utilisateur
-X Efface une chaîne définie par l'utilisateur
-P Change le comportement d'une chaîne sur une cible
-E Change le nom d'une chaîne
-p Protocole
-s Adresse/masque de source
-d Adresse/masque de destination
-i Nom d'entrée (nom ethernet)
-o Nom de sortie (nom ethernet)
-j Saute (cible de règle)
-m Correspondance étendue (peut utiliser des extensions)
-n Sortie numérique de ports et d'adresses
-t Table à manipuler
-v Mode bavard
-x Vérifications étendues (affiche les valeurs exactes)
-f Prends uniquement en compte le second fragment ou ceux d'après
-V Version du paquet
--line-numbers Affiche les numéros de ligne

Nous allons d'abord essayer de bloquer tous les paquets ICMP sur notre machine, juste dans le but de se familiariser avec les commandes.

Exemple de code 5.1 : blocage de tous les paquets ICMP

# iptables -A INPUT -p icmp -j DROP

On spécifie tout d'abord la chaîne à laquelle notre règle devrait appartenir, ensuite le protocole des paquets qui nous intéressent, et, enfin, la cible. La cible peut être le nom d'une chaîne spécifiée par l'utilisateur ou une des cibles spéciales ACCEPT, DROP, REJECT, LOG, QUEUE, MASQUERADE. Dans cet exemple, nous utilisons DROP, qui va ignorer le paquet sans répondre au client.

Note : la cible LOG est qualifiée de « non-terminatrice » : si un paquet correspond à une règle utilisant la cible LOG, l'évaluation des règles n'est pas interrompue ; elle se poursuit plutôt avec la règle suivante. Cela permet de consigner certains paquets sans influer sur leur gestion.

Essayez à présent de faire ping localhost. Vous n'obtiendrez aucune réponse car iptables ignorera tous les messages ICMP entrants. Vous ne pourrez pas non plus utiliser ping vers d'autres machines, car les paquets de réponse ICMP seront également ignorés. Maintenant, vidons la chaîne pour donner à nouveau libre cours au trafic ICMP.

Exemple de code 5.2 : supprimer toutes les règles

# iptables -F

Regardons maintenant le filtrage par état dans iptables. Si nous désirons activer l'inspection des paquets entrants sur eth0, la commande à utiliser est la suivante :

Exemple de code 5.3 : accepter les paquets qui proviennent d'une connexion déjà établie

# iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Cela acceptera tous les paquets provenant d'une connexion déjà établie ou ayant un rapport avec la chaîne INPUT. Vous pourriez ignorer tous les paquets qui ne sont pas dans la table des états en faisant iptables -A INPUT -i eth0 -m state --state INVALID -j DROP juste avant la commande précédente. Cela active le filtrage par état dans iptables en chargeant l'extension nommée « state ». Si vous voulez qu'une machine de l'extérieur puisse se connecter à votre machine, vous pouvez utiliser --state NEW. Iptables contient des modules correspondant à différentes fonctions. En voici quelques-uns :

Module Description Options étendues
mac Vérifie que l'extension correspond pour les paquets entrants sur une adresse mac. --mac-source
state Active l'inspection des états --state (les états sont ESTABLISHED,RELATED, INVALID, NEW)
limit Définit une limite sur le flux --limit, --limit-burst
owner Essaie de trouver des correspondances dans le créateur du paquet --uid-owner userid --gid-owner groupid --pid-owner processid --sid-owner sessionid
unclean Plusieurs tests de vérification aléatoires du bon état des paquets

Essayons à présent de créer une chaîne définie par l'utilisateur et de l'appliquer sur une chaîne existante :

Exemple de code 5.4 : création d'une chaîne définie par l'utilisateur

(Crée une nouvelle chaîne avec une seule règle.)
# iptables -X machaine
# iptables -N machaine
# iptables -A machaine -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
(La politique par défaut est d'accepter tout le trafic sortant. Tout le
trafic entrant est ignoré.)
# iptables -P OUTPUT ACCEPT
# iptables -P INPUT DROP
(Et on ajoute cela à la chaîne INPUT.)
# iptables -A INPUT -j machaine

En ajoutant cette règle, tout paquet sortant est autorisé et le trafic entrant est ignoré.

Pour plus d'informations, consultez la documentation sur iptables.

Voyons à présent un exemple complet. Dans ce cas précis, il s'agit de mes règles de pare-feu/passerelle :

  • Connexions au pare-feu uniquement autorisées via SSH (port 22).
  • Le réseau local doit avoir accès à HTTP, HTTPS et SSH (DNS est également autorisé).
  • Le trafic ICMP peut être nocif et devrait être interdit. Évidemment, nous devons autoriser un peu de trafic ICMP.
  • Les scanneurs de ports doivent être détectés et leur actions consignées.
  • Les attaques SYN doivent être évitées.
  • Tout autre trafic doit être ignoré et consigné.

Exemple de code 5.5 : /etc/init.d/firewall

#!/sbin/runscript
IPTABLES=/sbin/iptables
IPTABLESSAVE=/sbin/iptables-save
IPTABLESRESTORE=/sbin/iptables-restore
FIREWALL=/etc/firewall.rules
DNS1=212.242.40.3
DNS2=212.242.40.51
#interne
IIP=10.0.0.2
IINTERFACE=eth0
LOCAL_NETWORK=10.0.0.0/24
#externe
OIP=217.157.156.144
OINTERFACE=eth1

opts="${opts} showstatus panic save restore showoptions rules"

depend() {
  need net
}

rules() {
  stop
  ebegin "Paramétrer les règles internes"

  einfo "On ignore tout par défaut"
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP

  # Règles par default
  einfo "Créer les chaînes d'état"
  $IPTABLES -N allowed-connection
  $IPTABLES -F allowed-connection
  $IPTABLES -A allowed-connection -m state --state ESTABLISHED,RELATED -j ACCEPT
  $IPTABLES -A allowed-connection -i $IINTERFACE -m limit -j LOG --log-prefix \
      "Bad packet from ${IINTERFACE}:"
  $IPTABLES -A allowed-connection -j DROP

  # Trafic ICMP
  einfo "Créer la chaîne icmp"
  $IPTABLES -N icmp_allowed
  $IPTABLES -F icmp_allowed
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \
      time-exceeded -j ACCEPT
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \
      destination-unreachable -j ACCEPT
  $IPTABLES -A icmp_allowed -p icmp -j LOG --log-prefix "Bad ICMP traffic:"
  $IPTABLES -A icmp_allowed -p icmp -j DROP

  # Trafic entrant
  einfo "Créer la chaîne de trafic ssh entrant"
  $IPTABLES -N allow-ssh-traffic-in
  $IPTABLES -F allow-ssh-traffic-in
  # Protection anti Flood
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
      ALL RST --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
      ALL FIN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
      ALL SYN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -p tcp --dport ssh -j ACCEPT

  # Trafic sortant
  einfo "Créer la chaîne de trafic SSH sortant"
  $IPTABLES -N allow-ssh-traffic-out
  $IPTABLES -F allow-ssh-traffic-out
  $IPTABLES -A allow-ssh-traffic-out -p tcp --dport ssh -j ACCEPT

  einfo "Créer la chaîne de trafic DNS sortant"
  $IPTABLES -N allow-dns-traffic-out
  $IPTABLES -F allow-dns-traffic-out
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS1 --dport domain \
      -j ACCEPT
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS2 --dport domain \
     -j ACCEPT

  einfo "Créer la chaîne de trafic HTTP/HTTPS sortant"
  $IPTABLES -N allow-www-traffic-out
  $IPTABLES -F allow-www-traffic-out
  $IPTABLES -A allow-www-traffic-out -p tcp --dport www -j ACCEPT
  $IPTABLES -A allow-www-traffic-out -p tcp --dport https -j ACCEPT

  # Détecter les scanneurs de ports.
  einfo "Créer la chaîne de détection de portscan"
  $IPTABLES -N check-flags
  $IPTABLES -F check-flags
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -m limit \
      --limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -m limit --limit \
      5/minute -j LOG --log-level 1 --log-prefix "XMAS:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \
      -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -m limit \
      --limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -m limit \
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit \
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

  # Applique et ajoute les chaînes invalides.
  einfo "Appliquer les chaînes a INPUT"
  $IPTABLES -A INPUT -m state --state INVALID -j DROP
  $IPTABLES -A INPUT -p icmp -j icmp_allowed
  $IPTABLES -A INPUT -j check-flags
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A INPUT -j allow-ssh-traffic-in
  $IPTABLES -A INPUT -j allowed-connection

  einfo "Appliquer les chaînes au FORWARD"
  $IPTABLES -A FORWARD -m state --state INVALID -j DROP
  $IPTABLES -A FORWARD -p icmp -j icmp_allowed
  $IPTABLES -A FORWARD -j check-flags
  $IPTABLES -A FORWARD -o lo -j ACCEPT
  $IPTABLES -A FORWARD -j allow-ssh-traffic-in
  $IPTABLES -A FORWARD -j allow-www-traffic-out
  $IPTABLES -A FORWARD -j allowed-connection

  einfo "Appliquer les chaînes à l'OUTPUT"
  $IPTABLES -A OUTPUT -m state --state INVALID -j DROP
  $IPTABLES -A OUTPUT -p icmp -j icmp_allowed
  $IPTABLES -A OUTPUT -j check-flags
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  $IPTABLES -A OUTPUT -j allow-ssh-traffic-out
  $IPTABLES -A OUTPUT -j allow-dns-traffic-out
  $IPTABLES -A OUTPUT -j allow-www-traffic-out
  $IPTABLES -A OUTPUT -j allowed-connection

  # Autoriser les clients à router via le NAT (« Network Address Translation »).
  $IPTABLES -t nat -A POSTROUTING -o $OINTERFACE -j MASQUERADE
  eend $?
}

start() {
  ebegin "Démarrage du pare-feu"
  if [ -e "${FIREWALL}" ]; then
    restore
  else
    einfo "${FIREWALL} n'existe pas. Utilisation des règles par defaut."
    rules
  fi
  eend $?
}

stop() {
  ebegin "Arrêt du pare-feu"
  $IPTABLES -F
  $IPTABLES -t nat -F
  $IPTABLES -X
  $IPTABLES -P FORWARD ACCEPT
  $IPTABLES -P INPUT   ACCEPT
  $IPTABLES -P OUTPUT  ACCEPT
  eend $?
}

showstatus() {
  ebegin "Statut"
  $IPTABLES -L -n -v --line-numbers
  einfo "Statut NAT"
  $IPTABLES -L -n -v --line-numbers -t nat
  eend $?
}

panic() {
  ebegin "Mise en place des règles de panique"
  $IPTABLES -F
  $IPTABLES -X
  $IPTABLES -t nat -F
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  eend $?
}

save() {
  ebegin "Enregistrement des règles de pare-feu"
  $IPTABLESSAVE > $FIREWALL
  eend $?
}

restore() {
  ebegin "Rétablissement des règles précédentes"
  $IPTABLESRESTORE < $FIREWALL
  eend $?
}

restart() {
  svc_stop; svc_start
}

showoptions() {
  echo "Usage: $0 {start|save|restore|panic|stop|restart|showstatus}"
  echo "start)      Restaure les paramètres s'ils existent, sinon force les règles."
  echo "stop)       Efface toutes les règles et autorise tout accès."
  echo "rules)      Force les paramètres des nouvelles règles."
  echo "save)       Sauve les paramètres dans ${FIREWALL}."
  echo "restore)    Récupère les paramètres depuis ${FIREWALL}."
  echo "showstatus) Affiche le statut."
}

Quelques conseils pour la création d'un pare-feu :

  1. Créez la politique de votre pare-feu avant de l'implémenter.
  2. Faites quelque chose de simple.
  3. Connaissez le fonctionnement de chaque protocole. (Lisez le RFC (Request For Comments) approprié.)
  4. Gardez en tête que votre pare-feu n'est qu'un logiciel qui fonctionne sous root.
  5. Testez votre pare-feu.

Si vous pensez que iptables est difficile à comprendre ou vous prendra trop de temps à configurer, vous pouvez utiliser Shorewall. Il utilise iptables pour générer des règles de pare-feu, mais se concentre sur les règles et pas les protocoles spécifiques.

12.f. Squid

Squid est un serveur mandataire très puissant. Il peut filtrer le trafic en fonction de l'heure, d'une expression rationnelle sur le chemin/URI, d'une adresse IP source/destination, du domaine, du navigateur, de l'utilisateur, d'un type MIME ou bien d'un numéro de port (protocole). J'en ai sans doute oublié d'autres, mais il serait difficile de les énoncer dans leur ensemble ici.

Dans l'exemple suivant, j'ai ajouté un filtre de bannières plutôt qu'un filtre basé sur du contenu pornographique. La raison pour cela est que Gentoo.org ne devrait pas être listé comme site à caractère pornographique, et je ne veux pas perdre mon temps à essayer de vous trouver de bonnes adresses de sites.

Dans cet exemple précis, mes règles sont les suivantes :

  • Le surf (HTTP/HTTPS) est autorisé pendant les heures de bureau (du lundi au vendredi de 8 à 17 heures, et le samedi de 8 à 13 heures), mais si les employés restent plus tard, c'est pour travailler et pas pour surfer.
  • Le téléchargement de fichiers est interdit (.exe, .com, .arj, .zip, .asf, .avi, .mpg, .mpeg, etc.).
  • N'aimant pas les bannières publicitaires, nous les filtrons et les remplaçons par un gif transparent. (C'est ici que vous devenez créatif !)
  • Toute autre connexion venant d'Internet ou vers Internet est interdite.

Cela se fait en 4 étapes simples :

Exemple de code 6.1 : /etc/squid/squid.conf

# Liaison à une adresse IP et un port
http_port 10.0.2.1:3128

# Configuration standard
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY

# Contrôle d'accès standard
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255

# Machines autorisées à accéder à ce serveur
acl localnet src 10.0.0.0/255.255.0.0

# Et les ports
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl purge method PURGE

# Liste d'accès basée sur les expressions rationnelles
acl archives urlpath_regex "/etc/squid/files.acl"
acl url_ads url_regex "/etc/squid/banner-ads.acl"

# Liste d'accès basée sur les horaires
acl restricted_weekdays time MTWHF 8:00-17:00
acl restricted_weekends time A 8:00-13:00

acl CONNECT method CONNECT

# Autorise l'administrateur à se connecter depuis la machine locale.
http_access allow manager localhost
http_access deny manager

# Nettoyage de cache autorisé uniquement localement.
http_access allow purge localhost
http_access deny purge

# Refuse les requêtes vers des ports inconnus.
http_access deny !Safe_ports

# Refuse les connexions en dehors du port SSL.
http_access deny CONNECT !SSL_ports

# Mes règles

# Affiche une page quand un bandeau est supprimé.
deny_info NOTE_ADS_FILTERED url_ads

# Puis les refuse.
http_access deny url_ads

# Refuse toutes les archives.
http_access deny archives

# Restreint l'accès aux heures de bureau.
http_access allow localnet restricted_weekdays
http_access allow localnet restricted_weekends

# Refuse le reste.
http_access deny all

Indiquez ensuite les fichiers dont vous ne voulez pas autoriser le téléchargement. J'ai ajouté : zip, viv, exe, mp3, rar, ace, avi, mov, mpg, mpeg, au, ra, arj, tar, gz et z.

Exemple de code 6.2 : /etc/squid/files.acl

\.[Zz][Ii][pP]$
\.[Vv][Ii][Vv].*
\.[Ee][Xx][Ee]$
\.[Mm][Pp]3$
\.[Rr][Aa][Rr]$
\.[Aa][Cc][Ee]$
\.[Aa][Ss][Ff]$
\.[Aa][Vv][Ii]$
\.[Mm][Oo][Vv]$
\.[Mm][Pp][Gg]$
\.[Mm][Pp][Ee][Gg]$
\.[Aa][Uu]$
\.[Rr][Aa]$
\.[Aa][Rr][Jj]$
\.[Tt][Aa][Rr]$
\.[Gg][Zz]$
\.[Zz]$

Note : notez les [] avec une majuscule et une minuscule pour chaque lettre. Cela permet de ne pas pouvoir tromper notre filtre en téléchargeant un fichier dont l'extension est AvI plutôt que avi.

On ajoute ensuite les expressions rationnelles pour identifier les bannières. Vous serez sans doute plus créatif que moi :

Exemple de code 6.3 : /etc/squid/banner-ads.acl

/adv/.*\.gif$
/[Aa]ds/.*\.gif$
/[Aa]d[Pp]ix/
/[Aa]d[Ss]erver
/[Aa][Dd]/.*\.[GgJj][IiPp][FfGg]$
/[Bb]annerads/
/adbanner.*\.[GgJj][IiPp][FfGg]$
/images/ad/
/reklame/
/RealMedia/ads/.*
^http://www\.submit-it.*
^http://www\.eads.*
^http://ads\.
^http://ad\.
^http://ads02\.
^http://adaver.*\.
^http://adforce\.
adbot\.com
/ads/.*\.gif.*
_ad\..*cgi
/Banners/
/SmartBanner/
/Ads/Media/Images/
^http://static\.wired\.com/advertising/
^http://*\.dejanews\.com/ads/
^http://adfu\.blockstackers\.com/
^http://ads2\.zdnet\.com/adverts
^http://www2\.burstnet\.com/gifs/
^http://www.\.valueclick\.com/cgi-bin/cycle
^http://www\.altavista\.com/av/gifs/ie_horiz\.gif

Et, enfin, on veut afficher un fichier lorsque l'on retire une bannière. Il s'agit ici d'un fichier html partiel contenant une image gif transparente de taille 4x4.

Exemple de code 6.4 : /etc/squid/errors/NOTE_ADS_FILTERED

<HTML>
<HEAD>
<META HTTP-EQUIV="REFRESH" CONTENT="0; URL=http://localhost/images/4x4.gif">
<TITLE>Erreur, l'URL que vous avez demandée est indisponible</TITLE>
</HEAD>
<BODY>
<H1>Publicité filtrée !</H1>

Note : ne fermez pas les balises <HTML> <BODY>. Squid s'en chargera pour vous.

Comme vous pouvez le constater, Squid a beaucoup de possibilités et est très efficace dans le filtrage de contenu ainsi qu'en tant que mandataire. Vous pouvez même utiliser plusieurs serveurs Squid dans des configurations réseau de grande taille. Le type de configuration que j'ai listé ici devrait convenir à un réseau de petite taille (entre 1 et 20 utilisateurs).

Cependant, combiner le filtrage de paquets (iptables) et un serveur d'applications (Squid) est probablement la meilleure solution, même si Squid est situé dans un endroit sécurisé non accessible de l'extérieur. Gardez en tête que les attaques peuvent aussi venir de l'intérieur.

Vous devez maintenant configurer les navigateurs de vos clients pour qu'ils utilisent le serveur mandataire. La passerelle empêchera les utilisateurs d'avoir un contact avec l'extérieur, à moins qu'ils n'utilisent le mandataire.

Note : dans Mozilla Firefox, vous pouvez modifier le mandataire dans Edition->Préférences->Avancées->Réseau.

Vous pouvez aussi le faire de façon transparente en utilisant iptables pour renvoyer tout le trafic vers le mandataire Squid. Il suffit pour cela d'ajouter des règles de pré-routage/« forward » sur la passerelle :

Exemple de code 6.5 : autoriser le « forwarding » de ports vers notre serveur mandataire

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to proxyhost:3128
# iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to proxyhost:3128

Note : si le mandataire fonctionne sur l'hôte s'occupant du filtrage des paquets (Bien que ce ne soit pas recommandé, cela peut être nécessaire si vous ne disposez pas d'assez de machines pour faire autrement.), utilisez la cible REDIRECT plutôt que DNAT (REDIRECT dirige les paquets vers l'hôte local).

12.g. Conclusion de cette leçon

Nous avons appris ce qui suit :

  1. Qu'un pare-feu peut représenter un risque s'il est mal configuré et qu'il vaut mieux, dans ce cas, n'en avoir aucun.
  2. Comment paramétrer un serveur mandataire transparent et une passerelle de base.
  3. Que la clé d'un bon pare-feu est de connaître le protocole que vous voulez autoriser.
  4. Que le trafic IP ne contient pas que des données anodines. Des paquets ICMP peuvent révéler des informations importantes sur le réseau.
  5. Comment éviter des attaques SYN.
  6. Comment filtrer le trafic HTTP en retirant le chargement d'images ou de virus.
  7. Que la combinaison pare-feu/serveur mandataire donne le meilleur contrôle.

Si vous en avez vraiment besoin, vous pouvez à présent créer un pare-feu qui répondra à vos besoins.


[ << ] [ < ] [ Sommaire ] [ > ] [ >> ]


Imprimer

Voir tout

Dernière mise à jour le 2 avril 2010

Résumé : Filtrez les paquets qui passent sur le réseau.

Kim Nielsen
Auteur

John P. Davis
Correcteur

Eric R. Stockbridge
Correcteur

Carl Anderson
Correcteur

Jorge Paulo
Correcteur

Sven Vermeulen
Correcteur

Benny Chuang
Correcteur

Sune Jeppesen
Correcteur

Tiemo Kieft
Correcteur

Zack Gilburd
Correcteur

Dan Margolis
Correcteur

FRLinux
Traducteur

Matthieu Montaudouin
Traducteur

Olivier Fisette
Traducteur

Clément Varaldi
Traducteur

Xavier Neys
Traducteur

José Fournier
Traducteur

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.