Nous avons un accès à l'Internet ! Malheureusement, il n'y a qu'un ordinateur qui peut y accéder. Nous voulons que toutes les autres machines du réseau puissent y accéder également et en particulier, le portable sous Windows, avec RealPlayer G2, Macromedia, ICQ et plein d'autres plugins. Bref, il faut que les machines puissent aller sur le Net en même temps.
Qu'est-ce qu'il nous faut ?
- Un PC sous Linux avec une connexion à l'Internet.
- Au moins un autre PC (oui, sinon ça ne sert vraiment à rien).
- Un réseau Ethernet (TCP/IP) correctement configuré...
Première méthode (la plus simple ? Peut-être pas...)
Elle consiste à faire tourner des logiciels proxy spécifiques...
Ainsi, notre machine agit comme un proxy HTML, FTP, RealAudio, etc.
Dans le principe, ce n'est pas trop mal, mais il y a quelque chose qui n'est pas pratique dans l'histoire : si je veux jouer à Quake (mauvais exemple...) sur le Net, à Civilization ou encore si je veux accéder à un service qui n'est pas sur la machine proxy, comment faire ? En entreprise, la réponse serait « tu ne le fais pas car ce n'est pas la politique de la maison ». Mais là, on est chez soi(?). Il faut donc trouver autre chose...
Deuxième méthode : Ipchains
(Certes, je fais abstraction d'un certain nombre de choses, mais l'article ne porte pas sur l'utilisation d'un proxy...)
Apparu avec les nouveaux noyaux 2.2.x, Ipchains est l'outil de référence pour le masquage de paquets IP. Une fois correctement installé sur la machine Linux (et le reste du réseau correctement configuré), toutes les applications des autres machines n'y verront que du feu !!
Ceci implique simplement que lorsque vous allez vous placer devant votre machine cliente (pas la fameuse sous Linux), vous n'aurez pas à vous soucier de savoir qui est qui, vous aurez juste à penser que votre boîte, là, devant vous, est connectée directement à l'Internet. N'est-ce pas génial ?
Faisons à présent retomber un peu la joie qui vous étreint, je vais vous donner un avant-goût de la réalité (en ligne de commande) :
ipchains -A output -d 199.95.207.0/24 -j REJECT
Mais qu'est-ce que cela veut dire ? Simplement que la machine n'a pas le droit de se connecter aux adresses 199.95.207.xxx (c'est-à-dire la moitié de doubleclick.net... Oui, c'est un exemple type du HowTo...)
Comme vous êtes intelligents et donc pensez comme moi, la solution retenue est Ipchains.
Étape 1 : Configuration et compilation du noyau
- Avant toute chose, lisez le Kernel-Howto !
- Placez-vous dans /usr/src/linux (dans la plupart des cas, c'est là qu'il se trouve, sauf pour certaines distributions qui rajoutent toujours des numéros de version dans le nom des répertoires).
- Tapez make config, make menuconfig ou make xconfig (dans le cas d'une exécution sous X-Window).
- Lisez encore une fois le Kernel-Howto
- Faites votre marché parmi les options... N'oubliez pas d'intégrer au noyau (et non pas en module) la reconnaissance de l'ext2 (par défaut) ou le système de fichier utilisé pour la partition racine, c'est capital.
- Configurer les options suivantes :
CONFIG_FIREWALL (ou Network Firewall) Yes
CONFIG_IP_FIREWALL (ou IP: Firewall) Yes
Je vous conseille fortement d'activer tout ce qui a un rapport avec le masquerading... histoire de créer les modules nécessaires à certains masquages particuliers comme le FTP...
Essayez de mettre le plus d'options (générales) possibles sous forme de modules. Evitez toutefois de le faire avec ce qui a trait au port parallèle.
N'oubliez pas non plus d'activer tout ce qui concerne le loadable modules support
Si vous avez du SCSI, activez l'initrd...
Le marché est fait, faisons la cuisine :
- Tapez make dep pour créer les dépendances (un peu comme étaler les ingrédients)
- make clean pour nettoyer l'arborescence (indispensable, comme nettoyer les ustensiles de cuisine)
- make zImage pour compiler le noyau (sans commentaire)
- make modules pour compiler les modules
- make modules_install pour...installer les modules
En cas de problème... lisez le Kernel-Howto
Dernier point de l'étape, configurez Lilo pour qu'il charge ce nouveau noyau. Relancez la machine...
Étape 2 : Configuration d'Ipchains
Une fois le noyau prêt, on peut passer aux choses sérieuses...
4 La théorie made in HowTo ou comment fonctionne Ipchains...
Dans chaque paquet de données, il y a toujours un en-tête précisant qui l'envoie, où il va, de quelle nature il est, etc.
Dans le protocole TCP, pour que quelqu'un puisse commencer à envoyer des paquets, il faut s'assurer que le récepteur est prêt à les recevoir, c'est-à-dire qu'il accepte la connexion. D'où la nécessité d'envoyer certains paquets « en mission diplomatique ».
La cible peut alors soit les refuser (les ignorer, en envoyant aucune réponse du tout), soit les accepter (et envoyer une réponse positive) ou soit alors les rejeter (en envoyant une réponse négative).
Mais lorsqu'une machine fait office de passerelle avec Ipchains vers un autre réseau (du vôtre, vers l'Internet), elle doit être capable de faire transiter ces fameux paquets au travers de ses interfaces (modem et carte Ethernet ou tout simplement deux cartes Ethernet différentes...).
Pour ce faire, il faut préciser certaines règles qu'un paquet doit respecter pour avoir le droit de passer. Ces règles se présentent sous forme de chaînes (d'où le nom "IP Chains”). Un tel dialogue peut se résumer grossièrement à quelque chose comme : «tu es un paquet de ce type, ok, test suivant, tu ne vas pas à tel endroit, ok, tu vas à cet endroit, ah non pas d'accord».
Un paquet qui arrive sur la machine «passerelle» va subir, au minimum, trois règles : la règle input (entrée), la règle output (sortie) et la règle forward (transmission).
Le paquet va donc vérifier en premier la règle d'entrée (input). Si ce paquet est accepté, il va soit être démasqué (si c'est une réponse à un paquet masqué), soit être transmis directement à la machine concernée (la même ou une autre). Dans ce dernier cas, il y a encore une règle à passer : forward. Enfin, avant de repartir dans une direction quelconque, ce pauvre paquet subit une dernière règle de sortie (output).
Nous avons vu qu'il y a trois chaînes indélébiles que sont forward, input et output. Mais, bien sûr, vous pouvez en ajouter d'autres (vous allez voir...)
4 la pratique théorique (j'adore ce paradoxe !)
En fait, ceci peut se résumer à un test sur l'interface loopback qui n'est, en fait, que votre machine sur son réseau propre (c'est-à-dire seule).
Faisons un ping d'un seul paquet :
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=0.2 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.2/0.2/0.2 ms
Appliquons maintenant la règle suivante à la chaîne input :
Je refuse les paquets de type ICMP envoyés par 127.0.0.1
# ipchains -A input -s 127.0.0.1 -p icmp -j DENY
Recommençons le ping :
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
Tiens, on a plus le droit... Conclusion : ça marche
Assez rigolé, remettons tout dans l'ordre en supprimant cette règle arbitraire :
# ipchains -D input 1
ou encore :
# ipchains -D input -s 127.0.0.1 -p icmp -j DENY
Cette dernière ligne est surtout utile au cas où vous avez des tonnes de règles et que vous ne connaissez pas leur numéro par coeur. Si je veux refuser toutes les sources SAUF 127.0.0.1, j'utilise «!». Ce qui donnera :
4 La pratique
Là, j'ai triché. Je suis allé sur Internet et j'ai téléchargé le Gtk+ firewall control center 0.63 (GFCC, merci à Koo Kyoseon).
Méthode X Window :
Après avoir compilé et lancé GFCC, faites :
Host--> edit host and network.
Ajustez les zones user_defined par rapport à votre système.
Un éclaircissement s'impose... Que veulent dire les /24 ou /32 après les adresses IP ? Quand vous avez un réseau d'adresses IP, ces adresses varient selon un masque précis. Exemple :
192.168.1.xxx
xxx sont les seuls nombres à varier, les trois premiers sont invariables. 255.255.255.0 est donc le masque de sous-réseau correspondant...
Si nous avons 192.168.xxx.xxx, le masque est 255.255.0.0.
La valeur 255 correspond à 8 bytes. Ainsi, le réseau respectant la règle de formation précédente s'écrit aussi bien 192.168.0.0/255.255.0.0 que 192.168.0.0/16
Ma machine, qui a l'adresse 192.168.1., ne change pas d'adresse IP, donc son masque sera 255.255.255.255. Voilà pourquoi le réseau qu'elle forme s'appelle 192.168.1.1/255.255.255.255 ou 192.168.1.1/32...
Je crée la valeur «local» pour lui attribuer la valeur de mon réseau (donc 192.168.1.0/24). Je crée une valeur «passerelle» pour lui attribuer la valeur de la passerelle (192.168.1.1/32). Normalement, le serveur et la passerelle ne sont pas la même machine, mais je n'ai pas 36 ordinateurs chez moi. Enfin, je charge la règle ppp-masquerade.rule, je remplace tous les localnet par local et tous les firewallhost par passerelle...
J'applique le tout au système et voilà !
Il reste toutefois encore deux problèmes :
Si j'éteins mon PC, toutes ces règles vont disparaître.
En effet, les paquets IP de mon réseau ne vont pas forcément par défaut vers la passerelle.
Pour résoudre le problème du rappel des règles de filtrage, voici un script assez avancé qui établira des règles assez sûres pour un masquage d'IP d'un réseau local vers une connexion PPP
(si vous n'avez pas X-Window, contentez-vous de recopier ce script) :
#!/bin/sh # Generated by Gtk+ firewall control center (Hé oui, ce n'est pas moi qui l'ai fait !!!) IPCHAINS=/sbin/ipchains Local= »192.168.0.0/16 » passerelle= »192.168.1.9/32 » Any= »0.0.0.0/0 » $IPCHAINS -P input ACCEPT $IPCHAINS -P forward DENY $IPCHAINS -P output ACCEPT $IPCHAINS -F $IPCHAINS -X $IPCHAINS -N ppp-in $IPCHAINS -N ppp-out # input rules $IPCHAINS -A input -s $local -d $local -j ACCEPT $IPCHAINS -A input -s $Any -d $Any -i lo -j ACCEPT $IPCHAINS -A input -s $local -d $Any -j ACCEPT $IPCHAINS -A input -s $Any -d $Any -i ppp0 -j ppp-in # forward rules $IPCHAINS -A forward -s $local -d $local -j ACCEPT $IPCHAINS -A forward -s $passerelle -d $Any -j ACCEPT $IPCHAINS -A forward -s $local -d $Any -j MASQ # output rules $IPCHAINS -A output -s $local -d $local -j ACCEPT $IPCHAINS -A output -s $Any -d $Any -i lo -j ACCEPT $IPCHAINS -A output -s $local -d $Any -j ACCEPT $IPCHAINS -A output -s $Any -d $Any -i ppp0 -j ppp-out # ppp-in rules $IPCHAINS -A ppp-in -p tcp -s $Any -d $Any 1433 -j DENY $IPCHAINS -A ppp-in -p udp -s $Any -d $Any 1433 -j DENY $IPCHAINS -A ppp-in -p tcp -s $Any -d $Any 2049 -j DENY $IPCHAINS -A ppp-in -p udp -s $Any -d $Any 2049 -j DENY $IPCHAINS -A ppp-in -p tcp -s $Any -d $Any postgres -j DENY $IPCHAINS -A ppp-in -p udp -s $Any -d $Any postgres -j DENY $IPCHAINS -A ppp-in -p tcp -s $Any -d $Any 5999:6003 -j DENY $IPCHAINS -A ppp-in -p udp -s $Any -d $Any 5999:6003 -j DENY $IPCHAINS -A ppp-in -p tcp -s $Any -d $Any 31337 -j DENY $IPCHAINS -A ppp-in -p udp -s $Any -d $Any 31337 -j DENY $IPCHAINS -A ppp-in -p tcp -s $Any -d $Any 12345:12346 -j DENY $IPCHAINS -A ppp-in -p udp -s $Any -d $Any 12345:12346 -j DENY $IPCHAINS -A ppp-in -p tcp -s $Any -d $Any auth -j ACCEPT $IPCHAINS -A ppp-in -p tcp -s $Any -d $Any 1023:65535 -j ACCEPT $IPCHAINS -A ppp-in -p udp -s $Any -d $Any 1023:65535 -j ACCEPT $IPCHAINS -A ppp-in -p icmp -s $Any -d $Any -j ACCEPT $IPCHAINS -A ppp-in -p tcp -s $Any -d $Any smtp -j ACCEPT $IPCHAINS -A ppp-in -s $Any -d $Any -j REJECT # ppp-out rules $IPCHAINS -A ppp-out -p tcp -s $Any -d $Any -t 0x01 0x10 $IPCHAINS -A ppp-out -p tcp -s $Any -d $Any telnet -t 0x01 0x10 $IPCHAINS -A ppp-out -p tcp -s $Any -d $Any ftp -t 0x01 0x10 $IPCHAINS -A ppp-out -p tcp -s $Any -d $Any ftp-data -t 0x01 0x08 |
Voilà qui est bien pratique mais pour partager deux interfaces Ethernet, il faudra remplacer ppp0 par votre interface eth(x).
Pour lancer ce script au démarrage, faites-le appeler par le fichier rc.local (/etc/rc.d).
Normalement, quelque soit votre niveau de lancement, les règles seront mises à jour.
Résolvons maintenant l'ultime problème, le routage.
Dites à toutes vos machines (sauf la passerelle) que la route par défaut passe par la passerelle.
Dans mon cas, un appel de la commande suivante est nécessaire :
# /sbin/route sur la passerelle me renvoie
192.168.178.0 * 255.255.255.0 U 0 0 0 vmnet1
192.168.0.0 * 255.255.0.0 U 0 0 0 eth0
127.0.0.0 * 255.0.0.0 U 0 0 0 lo
# cat /proc/sys/net/ipv4/ip_forward
1
Ce dernier appel sert à vérifier si la machine est prête à transmettre des paquets...
Si la valeur retournée est 0, alors elle ne l'est pas. Activez dans ce cas la transmission en tapant :
echo 1 > /proc/sys/net/ipv4/ip_forward
Ou alors, entrez :
FORWARD_IPV4= yes
dans le fichier /etc/sysconfig/network
Exemple concret...
- Passerelle : Linux
- Hôtes : Windows, Linux, OS x
La configuration de la passerelle a déjà été vue ; voyons maintenant la partie client.
4 Sous Windows
Voici ce qu'il faut mettre dans les propriétés réseau TCP/IP de la carte Ethernet :
Passerelle : adresse de la passerelle
DNS : hôte : ce que vous voulez
Domaine : celui du fournisseur
Adresse : l'adresse DNS du fournisseur
Adresse IP : une adresse respectant le formatage de votre réseau
Masque de
réseau : celui de votre réseau (généralement 255.255.0.0 ou 255.255.255.0)
Il faudra rebooter. Bien sûr, si la passerelle n'est pas connectée au Net, votre Windows risque de planter lors de la résolution d'un nom de réseau.
4 Sous Linux
Pour la passerelle, deux solutions : soit utiliser LinuxConf, soit éditer le fichier /etc/sysconfig/network et y écrire :
GATEWAYDEV= eth0 (généralement)
GATEWAY= adresse IP de la passerelle
Vous n'aurez pas besoin de rebooter mais seulement de relancer les démons de réseau. Si la passerelle n'est pas connectée, il n'y a aucune raison que Linux plante.
Voyons à présent les paramètres d'Ipchains. Je prends le HowTo dans ma main gauche et je recopie :
Ipchains +arguments :
les arguments sont :
N pour ajouter une nouvelle chaîne
X pour supprimer une chaîne vide
P pour changer la police d'une chaîne (en clair : refus, rejet ou acceptation)
L pour lister les règles d'une chaîne (ou de toutes si vous ne précisez pas)
F pour supprimer les règles d'une chaîne
Z pour mettre les compteurs de paquets d'une chaîne à zéro
A pour ajouter une nouvelle règle à une chaîne
I pour insérer une nouvelle règle à une position quelconque de la chaîne
R pour remplacer une règle d'une chaîne par une autre
D pour supprimer une règle (ciblée par son numéro) d'une chaîne (souvenez-vous «-D input 1») -D pour supprimer la première règle d'une chaîne
s pour spécifier le réseau ou l'adresse IP de la source (et si l'on veut son port)
p pour spécifier le protocole
j pour spécifier l'action (DENY, REJECT ...)
! pour spécifier le contraire de l'argument ( ex : -s ! 127.0.0.1, toutes les adresses IP SAUF 127.0.0.1)
i pour spécifier l'interface (ppp0, eth0, eth1...)
Pour spécifier des intervalles de ports, on prend le premier puis le dernier et, au milieu, on met un «:».
Exemple : 600:650 => tous les ports du 600 inclus
au 650 inclus...
Si l'on ne précise pas la borne inférieure, elle est remplacée par 0 et si l'on ne précise pas la borne supérieure, elle est remplacée par la valeur maximum (65535). Fort de cette information, nous pouvons donc dire que :100 équivaut à 0:100 et 100: équivaut à 100:65535.
Heureusement pour nous, les intervalles « standards » sont « littéralisés ». Donc, pour les ports de l'Internet, il n'y a qu'à mettre www ou pour le ftp, ftp-data, ftp, etc.
Revoyons une dernière fois la syntaxe :
# ipchains -(NXPLFZAIRD) nom_de_la_chaîne -p protocole -s réseau_ou_adresse_de_la_source intervalle_port -d réseau_ou_adresse_dune_machine_du_réseau_local port -j action
Cet article est le résultat d'expérimentations pratiques, je tiens donc à remercier ceux sans qui je n'y serais jamais arrivé.
Romain Chantereau
REMERCIEMENT
Paul Russel
(qui a non seulement participé au développement mais qui a en plus écrit l'howto !)
Arnaud Launay
(ho, merci, merci à toi qui a traduit l'howto !)
Koo Kyoseon (Génial le GFCC !)
Et merci à l'équipe de Vmware, sans qui tous les tests de dernière minute n'auraient pas été possibles.