Ipchains

 




1 Pour quoi faire

Ipchains est un outil permettant de filtrer les paquets. Il est donc possible avec Ipchains de contrôler quelles machines peuvent se connecter, sur quels ports à votre machine, mais aussi quelle machine de réseau peut aller sur tel serveur extérieur. 
Ipchains est aussi utilisé pour faire du masquerading, c'est à dire permettre de partager une connexion à Internet en utilisant une seule adresse IP, et donc en masquant les machines de votre réseau local. 
Vous l'avez bien compris, l'utilité d'ipchains est de pouvoir construire un firewall, et par les temps actuels avec l'arrivée de l'ADSL et du câble qui permettent d'avoir des connexions permanentes, il est souhaitable de mettre en place ce genre de choses.
Cet outil n'est pas le plus simple à mettre en oeuvre. Il demande de bien maîtriser TCP/IP. 
Il existe un certain nombre d'outils pour vous aider à utiliser ipchains, car comme nous allons le voir les règles ne sont pas simples à mettre en oeuvre. Je pense ici à l'interface graphique gfcc entre autre. 
Ipchains remplace ipfwadm dans les versions actuelles de Linux et sera remplacé par netfilter à partir de la version 2.4 du noyau... donc prochainement.

Ce document n'a pas pour but de vous faire maîtriser toutes les possibilités d'ipchains, mais de vous permettre d'en comprendre le principe. Il existe un certain nombre de scripts que vous pouvez trouver sur Internet qui font cela pour vous. 

2 Le principe

Le principe est assez simple à comprendre, il est malheureusement moins simple à mettre en oeuvre. 
Un paquet arrive sur votre machine (on parle de paquet entrant INPUT), vous devez alors choisir ce que vous en faites. Vous pouvez l'accepter (ACCEPT), vous pouvez le rejeter (REJECT) ou le denier (DENY).
La différence entre les deux derniers modes, est de prévenir ou non l'envoyeur, que son paquet a été refusé (avec REJECT on prévient, mais pas avec DENY).
Une fois le paquet arrivé sur votre machine, il peut être forwardé (FORWARD) sur une autre carte réseau par exemple. Enfin arrivé sur cette deuxième carte réseau il peut être autorisé ou non à sortir. 
Cette dernière notion est souvent plus compliqué à comprendre, toutefois imaginé que votre machine autorise un type de paquet, un pirate arrive à prendre une partie du contrôle de votre machine, tant qu'il n'est pas en mesure de modifier les règles, il ne peut pas rebondir sur les autres machines de votre réseau.    
Enfin dans le mode FORWARD on dispose d'une option supplémentaire qui est MASQ, ce qui permet de masquer les adresses IP des machines se trouvant dans votre réseau local. Cela permet entre autre de laisser croire à votre provider que vous disposez que d'une seule machine pouvant se connecter à l'internet.

3 L'installation

L'installation ne pose aucun problème, utilisez le RPM ipchains le plus récent. Installez aussi gfcc qui va grandement vous aider dans cette épreuve. On trouve ces deux rpm dans toutes les distributions actuelles. 

4 La syntaxe

La syntaxe d'ipchains est la suivante :

ipchains -A|I chaîne -i interface -p protocole -s adresse source port -d adresse destination port -j police -l

A chaîne Ajoute une règle à la fin d'une chaîne.
chaîne peut être de type INPUT, OUTPUT, FORWARD
I chaîne Ajoute une règle au début d'une chaîne
-i interface Pour indiquer l'interface eth0, eth1, ppp0, Io
interface peut être remplacé par eth0, eth1, ppp0, Io.
-p protocole Indiquer le protocole à savoir TCP, UDP, ICMP, ALL. Si rien n'est indiqué la règle s'applique à tous. On peut aussi utiliser à la place de protocole les noms et numéros se trouvant dans le fichier /etc/protocols
-s adresse source port Indiquer l'adresse source du paquet. 
0.0.0.0/0 pour n'importe quelle origine (ou any/0)
192.168.0.0/24 pour un réseau 192.168.0.0 avec un masque sur 24 bits
Si aucun port n'est indiqué la règle s'applique à tous les ports.
Si vous souhaitez indiquer une plage de ports placer un : entre le début et la fin. 
-d adresse destination port Indiquer l'adresse destination. 
Identique à adresse source
-j police Indiquer ce que vous souhaitez faire de vos paquets
police peut être de type ACCEPT, DENY, REJECT
Si chaîne est de type forward vous disposez de MASQ 
-l Log dans /var/log/messages lorsque la règle est satisfaite

Remarques :
Vous pouvez indiquer le nom du port à la place du numéro : ainsi vous pouvez indiquer www à la place de 80.

Vous pouvez indiquer des constantes afin de rendre la lecture de votre fichier plus simple. par exemple on peut définir la constante academie="10.0.0.0/32" et ma_machine="192.168.0.1", puis utilisez la dans votre règle 

ipchains -A input -p tcp -y -s $academie -d $ma_machine www -i eth0 -j ACCEPT 
(cette règle indique que j'accepte en entrée sur eth0 tout ce qui vient de 10.0.0.0/32 sur la machine 192.168.0.1 sur le port 80).

Vous pouvez utiliser le symbole ! pour indiquer le contraire. Ainsi ! $academie indique tout sauf les adresses 10.0.0.0

L'option -y permet de vérifier les paquets d'initialisation de la connexion. 
 
Vous disposez encore d'un grand nombre d'options dont voici les principales :

-F Vider les chaînes de toutes les règles
-X Pour supprimer une chaîne
-L Lister les règles
-D Supprimer une règle
-N Crée une nouvelle règle
-C Pour tester une règle
-P Change la police d'une chaîne

Exemples :

ipchains -D input 1  Supprime la règle input 1. Faites un -L pour savoir son numéro
On peut aussi indiquer la règle comme on l'a rentrée.
ipchains -L
ipchains -L input
Affiche toutes les règles
Affiche toutes les règles de la chaîne input
ipchains -N chainepourmoi On crée ici une nouvelle règle
ipchains -X chainepourmoi Pour supprimer la chaîne que j'ai créé au dessus 
ipchains -F input Vide toutes les règles de la chaîne input
ipchains -P input deny Interdit tout par défaut

5 Avant de créer vos premières règles

Il faut savoir un minimum de choses avant de créer vos premières règles.
- Connaître les ports utilisés, quoique vous puissiez donner les ports sous la forme de nom comme ils sont indiqués dans le fichier /etc/services (on peut donc écrire telnet ou 23).
- Connaître les ports privilégiés, qui vont de 0 à 1023 et les ports sans privilèges, qui sont utilisés par le client pour établir la connexion à savoir 1024 à 65535. 
- Savoir que lorsqu'une connexion s'établit entre un serveur et un client, un port est utilisé par le client dans la zone 1024:65535 afin d'obtenir la réponse, il faut donc tenir compte de cela afin de permettre la réponse du serveur vers le client. Utiliser netstat pour constater cela. 

Ainsi je dois

  1. permettre à un client de venir sur ma machine avec un port sans privilège pour INPUT
  2. permettre à ma machine de recevoir sur un port avec privilège
  3. permettre au serveur de répondre (OUTPUT), sur un port avec privilège, à une machine sur un port sans privilège.

- Autant il est possible de connaître le port utilisé par le serveur que vous souhaitez contacter autant il n'est pas possible de connaître le port utilisé par votre station pour établir la connexion. Il est seulement situé entre 1024 et 65535.
-  Savoir que certains protocoles compliquent un peu la chose. Par exemple ftp utilise deux ports privilégiés, un pour les commandes (21) et l'établissement de la connexion, l'autre pour le transfert des données (20).
- Les serveurs de messagerie peuvent fonctionner de façon distincte. Vous utilisez un serveur SMTP pour envoyer vos messages, et vous utilisez un client POP ou un client IMAP pour les recevoir. Cela dépend de votre configuration.
- Que pour pouvoir utiliser des adresses de type www.ac-creteil.fr il vous faut pouvoir communiquer avec un serveur DNS. Là encore cela va dépendre si vous avez installé un serveur DNS sur votre réseau local. DNS interroge sur le port 53 en TCP et UDP. Mais il faut tenir compte du fait que la plupart des providers utilisent plusieurs serveurs de nom, en répartissant la charge entre plusieurs machines.
- Certain serveur nécessite l'ouverture du service AUTH (113), en output mais aussi en input. 

Cela vous donne une petite idée de la raison pour laquelle cela est plus compliqué que prévu.

6  Créer des règles

Pour créer des règles afin de protéger votre machine, il faut respecter plusieurs choses.

- Créer vos règles dans un fichier et donner lui des droits d'exécution. Ne lui donner que les droits minimum afin que le fichier ne puisse pas être lu et modifié par tout le monde. 
Pour cela commencer par lui indiquer le shell utilisé.
#!/bin/sh

- Indiquer où se trouve l'exécutable, sous la forme d'une variable (mais cela n'est pas obligatoire).
IPCHAINS=/sbin/ipchains

- Définir vos constantes (idem vous pouvez choisir de ne pas utiliser des constantes).
Cela est souvent pratique et simplifie votre travail. Il n'y a pas de norme en la matière, essayez seulement de pouvoir vous relire.
Vous les déclarez en début de fichier de la façon suivante :

localhost="127.0.0.1/32"
ip_internet="10.194.1.1"
ip_intranet="192.168.0.1"
net_intranet="192.168.0.0/24"
privports="0:1023"
unprivports="1024:65535"
interface_internet="eth0"    (cela peut être ppp0 si vous avez une connexion ADSL.)
interface_intranet="eth1"
interface_loopback="io"
Any="0.0.0.0/0"

- Effacer toutes les règles avant toute chose
Afin de partir d'une base propre et de savoir exactement ce que vous faites effacer toutes les règles qui pourraient exister sur votre machine.
$IPCHAINS -F   (j'utilise ici la variable pour appeler ipchains).

- Définir une politique par défaut
Le plus normal est de tout interdire par défaut et de n'autoriser que ce que vous souhaitez autoriser sur votre machine.
On "deny" tous les paquets entrants sans en informer l'envoyeur, on "reject" tous les paquets en sortie et en forward, afin d'être soi-même prévenu si une règle n'est pas correcte. 

$IPCHAINS -P input DENY
$IPCHAINS -P output REJECT
$IPCHAINS -P forward REJECT

Je vous conseille au départ d'accepter les output et forward, afin de ne pas compliquer la mise en place de votre protection.

Autoriser le trafic sur l'interface loopback

$IPCHAINS -A input -i $interface_loopback -j ACCEPT
$IPCHAINS -A output -i $interface_loopback -j ACCEPT 

A partir de là, cela dépend de ce que vous souhaitez mettre en place, et de la configuration de votre machine, du nombre de cartes réseau, du type de connexion, réseau local ou machine isolée, se protéger contre les autres machines du réseau ou par rapport à l'internet.

Il n'est pas possible ici de traiter tous les cas possibles, ni de donner toutes les règles permettant de protéger votre machine ou réseau contre tous les types d'attaque. La mise en place d'une bonne sécurité repose sur la mise en place de plusieurs éléments.

7 Voici quelques règles types :

  1. Autoriser telnet vers votre machine

    $IPCHAINS -A input -p tcp -s $Any $privports -d $ip_internet telnet  -i $interface_internet -j ACCEPT -l
    $IPCHAINS -A output -p tcp -s $ip_internet telnet !y -d $Any $unprivports -i $interface_internet -j ACCEPT 

    - Cette dernière ligne n'est nécessaire que si vous avez mis output REJECT, si par contre vous avez utilisé ACCEPT pour output, elle n'est pas nécessaire.
    - Any ouvre la porte telnet à tout le monde, vous pouvez préciser les machines que vous souhaitez autoriser.
    - Le -l permet de loguer les paquets entrants.
    - Cette règle ne porte que sur la carte côté internet. Vous devez avoir la même côté intranet (côté votre réseau local) avec en plus la règle pour forward.
    - !-y permet de vérifier les bits indicateurs ACK, qui sont échangés entre le serveur et le client à chaque envoi de paquet TCP.

  2. Autoriser telnet depuis votre machine (cas ou vous n'avez pas mis accept pour output) 

    $IPCHAINS -A output -i $interface_internet -p tcp -s $ip_internet unprivports -d Any telnet -j ACCEPT
    $IPCHAINS -A input -i $interface_internet -p tcp ! -y -s $Any telnet -d $ip_internet unprivports -j ACCEPT

  3. Autoriser les ping vers votre machine

    $IPCHAINS -A input -p icmp -s $Any 8 -d $ip_internet -i  $interface_internet -j ACCEPT
    $IPCHAINS -A output -p icmp -s $ip_internet 0 $Any -i $interface_internet -j ACCEPT

    Cette dernière ligne n'est nécessaire que si vous avez mis output REJECT (par contre, si vous avez utilisé ACCEPT pour output, elle n'est pas nécessaire).

Remarques : 
- Le fait d'avoir deux cartes réseau ne change pas grand chose, sauf qu'il faut écrire un peu plus de règles. De plus il faut activer le forwarding entre vos deux cartes réseau, afin de permettre au client de votre réseau local de passer par votre firewall.

8 Masquerading

Le forwarding vous donne la possibilité de router les paquets du réseau interne vers le réseau externe (ou simplement entre deux réseaux). Vous pouvez autoriser une machine et une seule de votre réseau local à utiliser telnet sur une machine de votre réseau externe (ou l'inverse ... enfin tout est possible).

Le masquerading est le fait de permettre aux machines de votre réseau interne de pouvoir sortir sur votre réseau externe en utilisant une seule adresse IP. Cette adresse officielle est mise à la place de l'adresse IP de votre machine cliente et re-remplacée au retour du paquet.

La différence entre Forwarding et Masquerading est qu'aucune de vos machines interne ne peut être atteinte par une machine de l'extérieur avec le masquerading. 

Pour pouvoir utiliser le masquerading vous devez d'abord activer le forwarding. Vérifiez que vous avez bien dans /etc/sysconfig/network la ligne suivante : forward_ipv4=yes.
Sinon pour l'activer, tapez echo "1" > /proc/sys/net/ipv4/ip_forward  (il faut redémarrer le réseau).

Il vous faut enfin ajouter la règle suivante, afin que les machines de votre réseau interne puissent en bénéficier.
$IPCHAINS -A forward -i $interface_internet -s $net_intranet -j MASQ

Si vous disposez d'une connexion ADSL pensez que l'interface est ppp0. Que cette interface n'est active que lorsque la connexion est établie, enfin que l'adresse IP obtenue peut être obtenue par dhcp.


9 Si vous êtes parano (j'en connais...!)

Pour essayer de protéger votre machine un peu mieux, il vous faut interdire un certain nombre de paquets auquel l'individu normal ne pense pas obligatoirement. Par exemple, interdire les paquets prétendant venir de vous, les paquets avec une adresse de classe A,B,C privée, les paquets qui arrivent avec comme adresse, l'adresse loopback, les paquets broadcast mal formés, une adresse multicast de classe D, une adresse réservée de la classe E, une adresse réservée par l'IANA.
Je ne peux pas ici les donner toutes. D'ailleurs je ne suis pas certain de tous les connaître. Mais il en existe encore un certain nombre.
Cela dépasse l'objet de cette formation.
Vous avez maintenant  une petite idée de la difficulté à établir correctement une sécurité.
Il existe des scripts pour faire cela. Je ne peux que vous conseillez de les utiliser.


TP 1 : Ce travail doit être réalisé par deux personnes. Lancer une connexion telnet sur la machine de votre voisin. Vérifier avec les outils dont vous disposez, les ports utilisés sur la machine locale et sur la machine distante. 
Interdire tous les ports en input (par facilité autoriser les output et forward).
Autoriser la machine de votre voisin à se connecter sur le port telnet. 
Pouvez vous faire du telnet sur la machine de votre voisin.
Autoriser les "pings" sur votre machine.
Pouvez vous pinguer depuis votre machine, que devez vous ajouter pour pouvoir le faire.
Si vous avez installé un proxy Squid sur votre machine, autoriser la machine de votre voisin à utiliser votre proxy (pensez au dns).
(On utilisera gfcc pour ce travail).


© Philippe Chadefaux - 10/10/2000 -