Ce document a pour but d'expliquer les rudiments de la sécurité d'une machine Linux placée dans un réseau local (typiquement une maison on un appartement), reliée à Internet. Il est tout particulièrement destiné aux utilisateurs néophytes, ou n'ayant pas ou peu de connaissance sur la sécurité informatique en général, et sous Linux en particulier.
Concernant ce document, il aurait été possible de le faire de manière beaucoup plus synthétique. Mais il n'était pas mon but de faire une documentation trop ardue à comprendre... Donc si vous trouvez que je suis trop long dans mes explications ou que je me répète, je vous autorise à en arrêter la lecture !
Ce document a été écrit en parallèle d'une conférence organisée par la Guilde le 2 juillet 2003. Vous pouvez télécharger les transparents de la présentation au format OpenOffice.org IMPRESS (.sxi), Powerpoint (.ppt), ou les consulter directement en ligne.
Ce document est assez long à lire (il l'a été encore plus à concevoir), aussi ne perdez pas patience au fur et à mesure des paragraphes. Le style utilisé s'est voulu le plus didactique et progressif possible, afin que les utilisateurs ayant le moins de connaissance de Linux puisse comprendre les concepts décrit ici.
Pourquoi parler de la sécurité d'un système informatique ? Cela a t' il une réelle importance ? Où n'est-ce là qu'un sujet purement théorique, issus des cerveaux fébriles de quelques paranoïaques qui voient le mal partout ?
Dans un premier temps, vous trouverez la réponse à cette question en vous posant vous même ces quelques questions. Est-ce que vous laisseriez votre maison, toutes portes et fenêtres ouvertes, à n'importe quelle heure du jour et de la nuit ? Que vous soyez ou pas présent ? Sans doute non, car votre domicile contient des biens qui pourraient tenter un voleur ou un vandale. Par contre, est-ce que vous laisseriez sur une plage votre serviette sans surveillance, pendant que vous iriez piquer une tête dans la mer ? Peut-être bien que oui ?
En informatique, et du moment que la machine que vous utilisez est connectée en réseau, c'est un peu la même chose. En fonction de votre lieu de connexion, de la machine que vous utilisez, et de l'importance des documents que vous pouvez accéder grâce à elle, vous serez plus où moins sensibilisé à ces problèmes de sécurité.
En effet, il existe sur les réseaux, et tout particulièrement sur Internet, des personnes peu scrupuleuses qui voudront atteindre, pour une multitude de raisons différentes, le contenu de votre machine. Cela va du "script kiddy" (un néophyte en terme de piratage informatique) qui a téléchargé de puissants outils de recherche de vulnérabilité, et qui, à défaut de les comprendre, les utilise afin d'épater ses amis ou rencontres sur IRC. Jusqu'à la grosse multinational du logiciel ou de la société de publicité, qui rechercheront diverses informations personnelles vous concernant, histoire de les revendre en vu d'envois massifs de publicités, ou à d'autres fins encore moins avouables...
Par contre, dans un second temps les problèmes de sécurité nous concerne tous, qui que nous soyons. En effet, que diriez vous d'une personne qui irait emprunter votre voiture, faire quelques délits, puis vous la rendrait sans que vous ne vous en aperceviez ? Dans le moindre des cas, personne (vous notamment) ne se sera rendu compte des délits. Dans le pire des cas, on viendra vous demander des comptes sur vos agissements, ou plus exactement de ceux du conducteur de votre voiture... Et vous risqueriez d'avoir du mal à expliquer la situation.
Là encore, l'informatique se trouve face aux mêmes problèmes que la vie de tout les jours. En effet, des personnes peuvent s'amuser à prendre le contrôle de votre machine, et lui faire faire des actions peu recommandables : Saturation d'une machine à distance via une attaque DOS distribuée (comme c'est régulièrement le cas avec des virus-vers qui sévicent sur Internet). Attaque par rebond d'un serveur d'une grosse société commerciale, ou d'une administration. Que sais je encore... Une chose en tout cas est sûre : Quelque soit les actions perpétrées par l'intrus, c'est vous, propriétaire d'une machine connectée sur un réseau, que l'on accusera...
Ce tableau de la situation n'est pas particulièrement réjouissant, n'est-ce pas ? Mais il n'est pas non plus inutilement alarmiste, et il n'a pas pour but de vous faire acheter au plus vite la dernière suite de logiciels de protection (firewall, anti-virus, anti-spyware, ou que sais je encore...). Ce n'est que la réalité, un peu froide et brutale de la situation. Mais maintenant que vous avez conscience de l'importance de la sécurité en informatique, nous allons pouvoir passer à la mise en place de remèdes. Car ils existent !
Afin de parler de la personne externe à votre machine qui désire y accéder sans votre autorisation, j'utiliserai dans la suite de ce document le terme d'intrus (même si celui-ci peut se révéler être du sexe féminin, ce type de comportement n'était pas réservé uniquement à la gent masculine). Je me refuse en effet à utiliser le mot de hacker, dont je préfère garder le sens premier. Quand à utiliser le mot de cracker, celui-ci a tellement de définitions différentes, qu'il n'en n'est pas une d'assez bien établi pour l'utiliser dans ce contexte. Et je préfère ne pas non plus utiliser pour les nommer, la multitude de noms d'oiseaux qui me passe par la tête...
En choisissant d'utiliser Linux comme système d'exploitation (ou OS pour "Operating System" en anglais), vous n'avez pas fait le pire choix en terme de sécurité informatique. Et surtout, contrairement à un autre OS bien connu du grand public, vous n'aurez pas à passer votre temps à vous poser l'angoissante question "Mais qu'est-ce que fait mon ordinateur ? Est-ce qu'il n'est pas entrain de diffuser des informations sans mon autorisation". De plus, sous Linux la plus grande partie des logiciels que vous utilisez sont sous la licence GPL, ce qui vous permet d'accéder à leurs codes sources, afin de savoir de quoi il en ressort exactement. Et si vous ne le pouvez / voulez pas, d'autres personnes peuvent s'en charger à votre place.
Dans les chapitres qui vont suivre, nous commencerons par un rapide rappel des notions de bases du réseau, puis nous verrons comment ne pas provoquer l'intrus, en ne l'invitant pas à passer par des portes grandes ouvertes pour commettre ses méfaits. Dans un troisième temps, nous verrons comment mettre en place le firewall de Linux (l'élément essentiel de la protection de votre machine) sur des kernels 2.4 et supérieurs, puis quelques outils permettant de faciliter son utilisation.
Installez vous confortablement, prenez un verre de votre boisson favorite à cette heure ci, et accrochez votre ceinture. C'est parti pour un plongeon dans les limbes de votre Linux !
Comme l'indique le titre de cette page, nous allons voir ici quelques notions de base sur les réseaux IP. Ici, je ne vous parlerai pas de modèle OSI, d'encapsulation de couches, de sockets, d'ARP, et de tant d'autres choses. Je me bornerai à vous expliquer les quelques rudiments de base nécessaires à la compréhension des chapitres suivants. Cet exposé se limitera au strict cadre des réseaux IP, même si il existe de nombreux autres types de réseaux (NETBeui, IPX/SPX, Transpact, etc...)
Si vous maîtrisez déjà les concepts d'adresses IP, de ports, de masque de sous-réseaux, de réseau IP, de passerelle, de type de trames, de la "handshake", et des interfaces réseaux, je vous invite à passer directement au chapitre suivant. Sinon nous allons commencer à assimiler ces notions.
Si par la suite vous désirez en apprendre un peu plus sur les réseaux IP, je vous conseille la lecture de quelques sites intéressants qui parleront de ce sujet bien plus en détail que moi. Je vous conseille tout particulièrement ceux de Christian Caleca et de CommentCaMarche.net.
Imaginez que les machines d'un réseau sont des immeubles complètement uniformes, et qu'ils forment une petite ville. Pour aller d'un immeuble à un autre, le seul moyen à votre disposition est alors d'en connaître l'adresse exacte. En France par exemple, nous utilisons un système de rues associées à un numéro, qui permettent bon an mal an, de trouver plus ou moins par hasard son lieu de destination. Aux Etats-Unis par contre, l'organisation des grandes villes se fait généralement en damier, ce qui permet d'identifier les immeubles avec une combinaison de numéros d'avenues / rues, ce qui est un poil plus pratique. Dans notre "ville réseau", chaque machine possède une adresse IP, qui l'identifie de manière unique. Cette adresse est composée de 4 chiffres numérotés de 0 à 255 séparés par des points ("."). Par exemple 62.158.78.243. L'élément le plus important d' IP, c'est que dans un même réseau, deux machines ne doivent pas avoir la même adresse IP, sinon, il serait impossible de communiquer correctement avec celles-ci. Par contre, l'inverse n'est pas vrai : Une machine peut avoir plusieurs adresses IP. Pour contacter une machine d'un réseau, il faut impérativement connaître son adresse IP. Mais comme il n'est pas très pratique de se souvenir de ces adresses, un système appelé DNS ("Domain Name Server") permet d'associer un nom de machine un peu plus facilement mémorisable (par exemple "olivieraj.free.fr") à une adresse IP (exemple : 62.158.78.243). Mais je ne rentrerai pas plus dans ces détails, car ce n'est pas nécessaire à la compréhension de la suite du document. |
Les adresses IP |
Parmi toutes les adresses IP disponibles (environ 256*256*256*256 = 4 294 967 296), il y a 3 catégories d'adresses IP très particulières. Ce sont les classes IP privées. Dans un réseau privé, comme celui d'une entreprise ou chez un particulier, on peut utiliser ces classes d'adresses IP en toute liberté, sans avoir de compte à rendre à personne. La seul condition est que les machines ayant une adresse IP d'une classe privée ne peuvent pas se connecter directement à Internet. Les classes IP privées sont : Enfin toute machine utilisant le protocole IP possède par défaut une série d'adresse IP privées, utilisable uniquement par la machine elle-même. Ainsi, toute machine peut s'adresser à elle-même en utilisant les 16 777 214 adresses IP comprises entre 127.0.0.1 et 127.255.255.255. C'est ce que l'on appelle les adresses de loopback. A noter que l'on ne parle ici que des adresses IP du protocole IPv4. A l'heure actuelle (juin 2003), une nouvelle version de ce protocole (IPv6) est entrain de se déployer, qui à terme devrait remplacer IPv4. Le principe de fonctionnement de cette nouvelle version est grosso modo le même, mais elle apporte de nombreuses fonctionnalités qui la rendent plus intéressante. Mais, les détails d'IPv6 débordent largement du cadre de ce document... |
Toujours en utilisant notre analogie ordinateur <-> immeuble, voyons maintenant la notion de ports. En bas d'un immeuble, on peut trouver un certain nombre de commerces, ouverts ou fermés, ou vides. Et dans les étages, on trouvera un certain nombre de fenêtres : certaines ouvertes ou fermées, d'autre avec des habitants entrain de parler avec leurs voisins de l'immeuble d'en face (encore faut il qu'ils aient suffisamment de voix...) Sur un ordinateur, c'est un peu la même chose. Une machine fonctionnant sur un réseau IP possède 65535 ports de connexion (numérotés de 1 à 65535), équivalents aux magasins et fenêtres de notre immeuble. Tous ces ports sont interchangeables, c'est à dire que chacun peut servir à :
Par contre, en aucun cas un port d'une même machine ne peut être utilisé par deux logiciels différents. Par analogie, on ne peut pas avoir deux habitants utilisant en même temps la même fenêtre pour parler avec ses voisins d'en face. |
Ports TCP ouverts, fermés, en cours d'utilisation |
||||||||||||
D'une manière générale :
En fait, c'est très logique car :
Pour ce qui est de la définition des termes TCP et UDP de ce fichier, vous trouverez l'explication un peu plus loin dans ce chapitre. |
Connexions entre machines |
C'est une partie un peu plus compliquée que précédemment, alors accrochez vous... Imaginez que tous les immeubles de la terre soient regroupés en une seul et même immense ville. Même avec un quadrillage précis de l'implantation des bâtiments, l'échange d'informations entre 2 immeubles éloignés seraient excessivement long, car il faudrait parcourir une grand partie de la ville pour ne serait-ce que trouver son correspondant. De plus, toutes ces connexions dans tout les sens formeraient un brouhaha insupportable, qui altérerait la qualité des communications. A la place de cela, il vaut mieux des villes plus petites (villes, villages, quartiers, lotissements), séparées par des longues routes, où les gens se regroupent par affinité ou par besoin. J'arrêterai là l'analogie, car après, le modèle de réseau IP s'éloigne un peu trop de la réalité des villes... Donc pour faire simple, les machines d'un réseau IP sont regroupées entre elles dans des mini-réseaux. Mais comment fait on pour déterminer la taille de ce réseau, et si oui ou non une machine fait parti du même réseau que nous ? La réponse est simple : Le masque de sous-réseau, appelé aussi masque IP, ou tout simplement masque. Tout comme l'adresse IP, le masque de sous-réseau est composé de 4 chiffres séparés par des points ("."). Mais contrairement aux chiffres des adresses IP, les chiffres du masque IP ne peuvent avoir que certaines valeurs : 0, 128, 192, 224, 240, 248, 252, 254, 255. Mais dans la plupart des cas, on ne trouve que les valeurs "0" et "255". Par exemple : 255.0.0.0 ou 255.255.255.0. Comme on l'a vu précédemment, chaque machine connectée à un réseau doit posséder une adresse IP unique dans le réseau. En plus de cela, toutes les machines d'un sous-réseau possèdent un masque de sous-réseau identique. C'est le couple adresse IP / masque de sous-réseau qui permet à chaque machine de s'identifier, et d'identifier les machines de son propre sous-réseau. En fait, c'est le masque IP qui va même déterminer le nombre maximum de machines pouvant se trouver dans un sous-réseau. |
Réseau sans masque : Ingérable !!! |
On a vu précédemment les 3 classes de réseaux privés, voyons maintenant quels sont les masques IP que l'on y trouve habituellement :
L'explication du pourquoi et du comment marchent les masques IP est un peu trop complexe, et sort du cadre de ce chapitre. Pour l'aborder, il faudrait utiliser des notions de logique booléenne (XOR, bit, etc...), ce qui sera trop long à traiter. Si vous désirez plus d'informations à ce sujet, je vous invite à trouver plus de documentations sur Internet, et notamment ici. |
Nous avons vu jusqu'à présent que chaque machine possédait une adresse IP et un masque de sous-réseau, permettant de définir les limites du réseau. Cela nous amène tout naturellement à parler de la notation de réseau IP. Le réseau IP définit un ensemble d'adresses IP mitoyennes, exactement comme le ferait la bordure d'une ville telle que décrit plus haut. Le réseau IP est composé de 2 séries de 4 chiffres, séparés par un "/".
Enfin, il existe une seconde notation pour les réseaux IP, tout aussi utilisée que la première, mais plus pratique car plus rapide à écrire. Il s'agit de remplacer la notation du masque de sous-réseau (dans l'exemple; 255.255.255.0) par le nombre de bits à "1" de chaque nombres qui le compose. Il faut donc utiliser la notation binaire pour trouver ce chiffre. Pour ceux qui ont la flemme de calculer, ou qui n'ont pas de calculette sous la main, voici le nombre de bits à "0" et à "1" pour les différentes valeurs des nombres composant les masques de sous-réseau :
Ce qui nous fait pour des masques de sous-réseaux que l'on trouve habituellement (les "..." indiquent qu'il y a évidement des valeurs intermédiaires) :
|
Machines groupées en réseaux IP |
Ainsi, pour les différentes classes IP privées que nous avons à notre disposition, nous pouvons écrire leur notation en réseau IP :
|
Maintenant que nous avons abordé les notions de masque IP et de réseau IP, celle de passerelle n'est qu'une formalité. En reprenant notre analogie d'une petite ville entourée d'une barrière, on va considérer maintenant que cette barrière est infranchissable, et qu'elle ne possède qu'un seul et unique point de sortie, fermée par un garde barrière. Lorsqu'un habitant d'un immeuble veut échanger des informations avec celui d'un autre immeuble, alors :
Comme vu ci-dessus, chaque machine du réseau doit connaître l'adresse IP de la passerelle. Si celle-ci n'est pas renseignée, la machine considérera qu'il n'y a pas de passerelle sur le réseau. Et donc, si elle doit accéder à une machine dont l'adresse IP n'est pas dans le réseau local, elle renverra immédiatement un message d'erreur disant que la machine n'est pas accessible. C'est le fameux message "no host reachable" en anglais. Bilan : Au point où nous en somme, nous avons appris qu'une machine dans un réseau IP,
|
La passerelle permet aux réseaux de communiquer entre eux |
Afin de s'échanger des informations, les habitants de nos immeubles ne se parlent pas directement (on dira pour simplifier que leur voix ne porte pas assez loin...), mais ils échangent des lettres. Principalement trois différents types de lettres pour être exact. Dans notre réseau IP, c'est la même chose : Les logiciels clients et serveurs vont utiliser en général 3 différents types de trames pour communiquer, TCP, UDP, et ICMP. La trame est donc un "emballage" qui va transporter les informations d'une adresse IP à une autre. Il existe d'autres type de trames, mais nous ne nous y intéresserons pas. I-6-1 TCPIl s'agit du type de trame le plus utilisé. C'est pourquoi par abus de langage, on parle très souvent de réseau TCP/IP plutôt que de réseau IP. En fait ce type de support ressemble un peu à un envoi de lettre par recommandé, où avant de commencer un échange d'information avec son interlocuteur, on enverra une lettre dont le destinataire devra lui-même envoyer une réponse disant qu'il a bien reçu le recommandé. C'est le mécanisme de la poignée de mains, qui sera expliqué un peu plus loin.La seule chose à retenir, c'est que du fait de sa robustesse, ce type de trame est utilisé aussi bien sur les réseaux éloignés que proches. Par contre, son inconvénient est qu'il rajoute une certaine "lourdeur" à la transmission d'informations, ce qui ralenti un peu les réseaux. I-6-2 UDPCe type de trame tranche franchement avec le précédent, car cette fois ci, l'expéditeur va supposer que le destinataire de l'information n'a rien d'autre à faire que de l'écouter, et donc il peut envoyer sans préavis sa requête d'information. C'est exactement le comportement de ces personnes qui, pendant que vous vous concentrez sur un sujet particulier, vous posent une question sans même commencer leur phrase par un "Je peux te poser une question ?" ou "Dis moi, est-ce que...".Ce type de communication est particulièrement adapté dans des réseaux locaux, afin de transmettre rapidement de grosses quantités d'informations. Du fait de son aspect "sans fioriture", les paquets d'informations sont plus compacts, et engorgent moins les réseaux. Cependant, le transfert par UDP est moins fiable que celui par TCP, et impose aux logiciels clients et serveurs de pouvoir se satisfaire d'une perte d'information, ou tout du moins, d'être capable de redemander une information qui aurait pu être perdue en cours de route. I-6-3 ICMPCe dernier type de trame est assez complexe, et en général uniquement utilisé par des logiciels destinés à analyser la qualité du réseau. Par exemple les commandes ping, traceroute (Unix/Linux), tracert (DOS®/Windows®), etc...Je sais que je vais faire hurler les puristes d'IP en mélangeant dans un même paragraphe un élément de la couche 2(*) (ICMP) avec d'autres de la couche 3(*) (TCP et UDP), mais en fait, cette approximation n'est pas si primordiale que cela dans le cadre de cette documentation... (*): Dans le modèle TCP/IP, et non le modèle OSI. Voir à ce sujet ces pages ici et là. Il n'est pas spécialement utile de rentrer dans les détails de ce type de trame, donc passons à la suite. |
TODO |
Lorsque deux personnes se rencontrent dans la rue, la première chose qu'elles font est de se serrer la main, de se faire une bise, de se dire bonjour ou de se présenter. C'est un moyen de commencer une discussion (ie : initialiser une communication) qui permet de mettre en confiance les deux partenaires. Pour le type de trames TCP, c'est la même chose... Et oui, les ordinateurs sont polis (même si certains plantent tout le temps !)... Supposons que la machine A veuille demander une information à la machine B :
|
La poignée de mains |
Il n'est peut-être pas très logique, pour une explication sur les réseaux, de terminer par les interfaces. Mais du fait de l'utilisation de mes analogies, c'est ce qui m'a semblé le plus efficace à faire... Les experts réseaux (y en a t' il encore à ce niveau du chapitre ?) voudront donc bien m'excuser d'avoir ainsi un peu bousculé les habitudes... Pour cette partie, nous ne parlerons donc pas d'immeubles et de personnes voulant s'échanger des informations par courrier. Un ordinateur, pour communiquer physiquement avec d'autres ordinateurs, a besoin d'au moins 2 choses : un adapteur réseau et un câble. Le câble en lui même peut être une fibre optique, une paire de fils de cuivre, un câble RJ-45, ou un câble coaxial. Bon, c'est juste un morceau de connecteur (les vendeurs de câbles, ne pas taper SVP...), donc on ne va pas en parler plus que cela... L'adapteur réseau lui est bien plus intéressant. C'est en fait un élément électronique qui peut être soit :
|
De multiples interfaces réseaux |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sous Linux, car c'est ce qui nous intéresse ici, on peut dialoguer avec ces adapteurs réseaux via :
La commande /sbin/ifconfig , lancée éventuellement en temps que root, permet d'afficher la liste des interfaces réseaux. Le plus important dans tout ceci, c'est que Linux voit de la même manière vos adapteurs réseaux, que ce soient des "eth?" ou des "ppp?" (le "?" signifie qu'il faut remplacer cette lettre par un nombre). Ainsi, dans la suite du document je vais utiliser une machines ayant 2 cartes réseaux eth0 et eth1, où eth1 simulera une connexion vers Internet. Mais chez vous, vous pourrez reprendre les exemples de configuration en remplaçant eth1 par ppp0. De ce fait vous pourrez utiliser (presque) directement les exemples de configuration pour votre propre connexion Internet via modem. A moins bien sûr que vous n'utilisiez un routeur ADSL... Ce qu'il y a d'intéressant avec Linux, c'est que même si on ne possède qu'une seule et unique carte réseau, le système peut simuler la présence d'autres cartes réseaux, mais en utilisant au final toujours la même carte physique pour dialoguer. C'est très pratique si on veut par exemple avoir 2 adresses IP sur une machine, afin de dialoguer avec 2 réseaux IP différents, mais connectés physiquement entre eux (*). Ainsi on peut avoir quelque chose comme :
Enfin, on peut rencontrer parfois, plusieurs interfaces "eth?" ou "ppp?" qui partagent la même adresse IP. Hein ? Qu'est-ce qu'il dit ? Mais je vous rassure c'est assez rare, surtout dans un réseau local. Car le but d'une telle configuration est d'augmenter la quantité d'informations passant entre 2 machines (on parle alors de multiplier la bande passante du réseau). |
Concept réseau | Analogie | Exemples |
---|---|---|
Interface réseau | Aucune analogie | eth0, eth1, ppp0,... |
Adresse IP | Immeuble | 192.168.0.1, 56.123.8.47,... |
Port | Fenêtre | 80(HTTP), 21(FTP), 25(SMTP), 110(POP3), ... |
Masque de sous-réseau | Quartier | 255.255.255.0, 255.0.0.0,... |
Réseau IP | Barrière délimitant un quartier | 192.168.0.1/255.255.255.0, 56.0.0.0/255.0.0.0,... |
Passerelle | Garde barrière | 192.168.0.255, 10.255.255.255,... |
Type de trame | Type de courrier | TCP, UDP, ICMP,... |
Poignée de mains | Établissement d'un dialogue | (SYN), (ACK, SYNC), (ACK) |
Lorsque l'on met une machine en réseau, c'est vraisemblablement pour 2 choses : accéder à de l'information, ou partager de l'information. Sinon, on utilise des supports amovibles pour transférer de l'information du ou vers le monde extérieur : disquette, CDROM, bande, clef USB,...
Lorsque cette mise en réseau se fait dans un réseau local, dont on a toute confiance envers les autres machines ou utilisateurs de ce réseau, et que cette impression est réciproque, les risques encourus sont très faibles. Par contre, du moment que l'on ne contrôle pas tout ce qu'il peut se passer sur le réseau, on peut commencer à se poser des questions sur la sécurité des données contenues dans les machines. Le fin du fin est évidement lorsque l'on connecte la machine à un réseau mondiale comme Internet, où tout utilisateur a la capacité potentielle de venir farfouiller dans vos données.
Cette introduction, bien qu'un peu sombre, n'a pas pour but de pousser le lecteur vers des solutions comme TCPA, Palladium, et le "trusted computing", car de toute façon, ce sont des projets qui ne sont pas conçu pour servir les intérêts de l'utilisateur. Et bien entendu, j'y suis complètement opposé.
Nous verrons dans ce chapitre quels sont les points sur lesquels vous, en temps qu'utilisateur, devez faire attention. Et nous verrons que même pour un système d'exploitation fraîchement installé, en générale beaucoup de choses sont à contrôler.
Dans toute la suite du document, nous allons nous intéresser à un réseau composé de 3 machines, qui a pour but de simuler le réseau que vous avez chez vous.
|
|||||||||||||||||||||||||||||||
|
Configuration du réseau |
||||||||||||||||||||||||||||||
Pour la suite du document, on notera que les machines fonctionnent sur différentes versions de Linux. Et de ce fait, l'emplacement des fichiers de configuration, des programmes, des fichiers de log, etc... peuvent être différents de votre propre machine. Pas de troll s'il vous plaît sur le choix des distributions Linux !!
|
En fait, quel que soit le rôle que l'on joue, attaquant ou défenseur, on utilise des outils similaires. Car toute personne qui voudra protéger son réseau aura à coeur de le tester lui-même !! Et tout intrus voudra d'abord se protéger lui-même, soit des gens comme lui, soit du défenseur...II-2-1 NmapC'est l'outil par excellence de l'intrus. Il rentre dans la catégorie des "scanner de ports" ("port scanner" en anglais), c'est à dire qu'il va tester un ensemble de ports sur la machine cible, et déterminer lesquels sont ouverts ou fermés. Son exécution est très rapide, et de plus il peut tester automatiquement tout un intervalle d'adresse IP. Bref, si vous avez un logiciel serveur tournant sur votre machine, cet outil le trouvera.Nmap a une seconde fonctionnalité intéressante, c'est l'identification par empreinte. C'est à dire qu'avec les quelques paquets d'informations que votre machine pourra envoyer à l'intrus, comme par exemple pour dire "ce port est fermé", nmap pourra déterminer quel est le système d'exploitation qui tourne sur votre machine. Quelle importance cela peut il avoir me direz vous ? Très simple : chaque système d'exploitation, voire chaque version de systèmes d'exploitation, possède des vulnérabilités connues ou inconnues. Ainsi, en sachant quel système tourne sur votre machine, l'intrus pourra lancer des attaques spécifiques, afin de prendre rapidement la main dessus. Donc, moins on donne d'information à l'intrus, mieux on se porte. Nmap peut être lancé ou non en temps qu'utilisateur classique. Par défaut, nmap ne teste qu'un certain nombre de ports (ceux sur lesquels il pense qu'il va trouver des choses intéressantes), et uniquement en TCP. Voyons par exemple ce que donne la commande nmap lancée depuis pirate.internet.net sur phoenix1.internet.net :
[intrus@pirate /]$ nmap phoenix1.internet.net
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Interesting ports on phoenix1.internet.net (10.0.0.1):
(The 1590 ports scanned but not shown below are in state: closed)
Port State Service
21/tcp open ftp
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
110/tcp open pop-3
111/tcp open sunrpc
139/tcp open netbios-ssn
443/tcp open https
3306/tcp open mysql
6000/tcp open X11
Nmap run completed -- 1 IP address (1 host up) scanned in 0 seconds
Hummm ça, c'est que du bonheur pour notre pirate ! Autant de ports ouverts sur une machine, il va y avoir des choses intéressantes à faire... On notera au passage que nmap est très sympathique car il nous indique quel est probablement le type de serveur (exemple : http) qui se trouve derrière chaque port (exemple : 80/tcp).Note importante à propos d'UDP : Par défaut, "nmap" ne teste que les ports TCP. Vous pouvez lui faire tester des ports UDP, mais il faut que vous lanciez "nmap" en temps que root, et en plus avec l'option "-sU". Enfin, si la machine cible est un Linux, les temps de réponses seront très long, car la cible attendra un temps de plus en plus long pour toute connexions UDP faites sur des ports fermés. Ce n'est pas un bug, c'est une mesure de protection de Linux contre le port scanner... Donc à moins que nous n'ayez le temps, ne faite pas un nmap sur tous les ports UDP d'une machine cible, mais seulement sur des ports susceptibles d'être intéressants. Par exemple : "nmap phoenix1.internet.net -sU -p 137" pour tester le port UDP de Samba / NetBIOS. II-2-2 TcpdumpTcpdump est un "sniffeur de trames réseau", c'est à dire qu'il est capable d'afficher à l'utilisateur toutes les trames réseaux qui "passent devant" une carte réseau. Et entre autre, les trames réseaux qui ne sont pas destinées à cette machine. Ce n'est pas très sympathique ce genre de choses, car cela permet par exemple de récupérer un mot de passe réseau, ou une page HTML contenant des informations sensibles (numéro de carte de crédit par exemple).Ceci est une capture par tcpdump lors de l'envoi d'une requête ping de pirate.internet.net sur phoenix1.internet.net ("ping -c 1 phoenix1.internet.net") :
[root@phoenix /]# tcpdump -i eth1
tcpdump: listening on eth1
19:31:25.170017 arp who-has phoenix1.internet.net tell pirate.0.0.10.in-addr.arpa
19:31:25.170079 arp reply phoenix1.internet.net is-at 0:4:75:df:d8:bd
19:31:25.170232 pirate.0.0.10.in-addr.arpa > phoenix1.internet.net: icmp: echo request (DF)
19:31:25.170355 phoenix1.internet.net > pirate.0.0.10.in-addr.arpa: icmp: echo reply
Comme ce type de commande est excessivement sensible pour la sécurité d'un réseau, en général elle ne peut se lancer qu'en temps que root.Enfin, il est à noter que le lancement de tcpdump demande au système de passer la carte réseau en mode "promiscuous", ce qui a pour effet de laisser une trace dans le log de Linux (le fichier "/var/log/messages"). Cela indique donc à l'administrateur de la machine que des paquets de données ont pu être récupérés illégalement...
[root@phoenix /]# grep promiscuous /var/log/messages
Jun 28 19:31:21 phoenix kernel: device eth1 entered promiscuous mode
Jun 28 19:31:28 phoenix kernel: device eth1 left promiscuous mode
|
|
II-2-3 EtherealContrairement à "tcpdump", "ethereal" est un outil en mode graphique. Mais il fait exactement le même travail que tcpdump. Dans l'exemple ci-contre, on voit la capture des trames lors d'un "nmap phoenix1.internet.net" lancé sur pirate.internet.net.Au passage cette capture nous montre des choses très intéressantes :
|
Ethereal : Capture d'un nmap |
II-2-4 Netstat"Netstat" est un outil que l'on va utiliser du coté du défenseur. Il indique l'état des connexions réseaux en cours. Expliquer toutes les options de "netstat" serait trop long, aussi ne va t'on s'intéresser qu'à quelques unes :
[root@phoenix /]# netstat -taupe | sort
Connexions Internet actives (serveurs et établies)
Proto Recv-Q Send-Q Adresse locale Adresse distante Etat Utilisatr Inode PID/Program name
tcp 0 0 *:ftp *:* LISTEN root 830048 18450/xinetd
tcp 0 0 *:http *:* LISTEN root 829583 17979/httpd2
tcp 0 0 *:https *:* LISTEN root 829580 17979/httpd2
tcp 0 0 localhost.sky.ne:domain *:* LISTEN named 835771 18847/
tcp 0 0 localhost.sky.net:rndc *:* LISTEN named 835779 18847/
tcp 0 0 localhost.sky.:webcache *:* LISTEN privoxy 587136 6407/
tcp 0 0 *:mysql *:* LISTEN root 839103 19199/
tcp 0 0 phoenix1.in:netbios-ssn *:* LISTEN root 839012 19128/smbd
tcp 0 0 phoenix1.interne:domain *:* LISTEN named 835775 18847/
tcp 0 0 phoenix.sky:netbios-ssn *:* LISTEN root 839013 19128/smbd
tcp 0 0 phoenix.sky.net:domain *:* LISTEN named 835773 18847/
tcp 0 0 *:pop3 *:* LISTEN root 830047 18450/xinetd
tcp 0 0 *:smtp *:* LISTEN root 827316 17081/
tcp 0 0 *:sunrpc *:* LISTEN root 839095 19208/
tcp 0 0 *:telnet *:* LISTEN root 830049 18450/xinetd
tcp 0 0 *:x11 *:* LISTEN root 3742 1593/X
udp 0 0 *:bootps *:* root 839078 19191/dhcpd
udp 0 0 localhost.sky.ne:domain *:* named 835770 18847/
udp 0 0 *:netbios-dgm *:* root 839024 19138/nmbd
udp 0 0 *:netbios-ns *:* root 839023 19138/nmbd
udp 0 0 phoenix1.in:netbios-dgm *:* root 839030 19138/nmbd
udp 0 0 phoenix1.interne:domain *:* named 835774 18847/
udp 0 0 phoenix1.int:netbios-ns *:* root 839029 19138/nmbd
udp 0 0 phoenix.sky:netbios-dgm *:* root 839033 19138/nmbd
udp 0 0 phoenix.sky.:netbios-ns *:* root 839031 19138/nmbd
udp 0 0 phoenix.sky.net:domain *:* named 835772 18847/
udp 0 0 *:sunrpc *:* root 839094 19208/
II-2-5 LsofPour avoir un résultat utilisable, "Lsof" (LiSt Open File) est un outil qui doit se lancer avec les droits root. Il indique quels sont les fichiers ouverts sur le système. Des fichiers ? Mais de quoi parle t'il ? On est ici pour parler de réseau, non ? Mais oui, on peut s'intéresser bien sûr aux fichiers classiques tel qu'on les connaît dans d'autres OS (comme un fichier texte, une image, une librairie, un programme, etc...) mais on peut aussi utiliser cette commande pour voir l'activité réseau. Comment ? Simple, sous Linux, tout ce que manipule l'OS est vu comme un fichier, les connexions IP entre autre. Dans notre cas, les paramètres intéressants de "lsof" sont :
[root@phoenix /]# lsof -Pi | sort
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
dhcpd 19191 root 6u IPv4 839078 UDP *:67
httpd2 17979 root 3u IPv4 829580 TCP *:443 (LISTEN)
httpd2 17979 root 4u IPv4 829583 TCP *:80 (LISTEN)
httpd2 17987 apache 3u IPv4 829580 TCP *:443 (LISTEN)
httpd2 17987 apache 4u IPv4 829583 TCP *:80 (LISTEN)
httpd2 17988 apache 3u IPv4 829580 TCP *:443 (LISTEN)
httpd2 17988 apache 4u IPv4 829583 TCP *:80 (LISTEN)
httpd2 17989 apache 3u IPv4 829580 TCP *:443 (LISTEN)
httpd2 17989 apache 4u IPv4 829583 TCP *:80 (LISTEN)
httpd2 17990 apache 3u IPv4 829580 TCP *:443 (LISTEN)
httpd2 17990 apache 4u IPv4 829583 TCP *:80 (LISTEN)
httpd2 17991 apache 3u IPv4 829580 TCP *:443 (LISTEN)
httpd2 17991 apache 4u IPv4 829583 TCP *:80 (LISTEN)
httpd2 18591 apache 3u IPv4 829580 TCP *:443 (LISTEN)
httpd2 18591 apache 4u IPv4 829583 TCP *:80 (LISTEN)
master 17081 root 11u IPv4 827316 TCP *:25 (LISTEN)
mysqld 19199 mysql 3u IPv4 839103 TCP *:3306 (LISTEN)
mysqld 19215 mysql 3u IPv4 839103 TCP *:3306 (LISTEN)
mysqld 19216 mysql 3u IPv4 839103 TCP *:3306 (LISTEN)
named 18847 named 10u IPv4 835771 TCP localhost.sky.net:53 (LISTEN)
named 18847 named 11u IPv4 835772 UDP phoenix.sky.net:53
named 18847 named 12u IPv4 835773 TCP phoenix.sky.net:53 (LISTEN)
named 18847 named 13u IPv4 835774 UDP phoenix1.internet.net:53
named 18847 named 14u IPv4 835775 TCP phoenix1.internet.net:53 (LISTEN)
named 18847 named 17u IPv4 835779 TCP localhost.sky.net:953 (LISTEN)
named 18847 named 8u IPv4 835778 UDP *:32803
named 18847 named 9u IPv4 835770 UDP localhost.sky.net:53
named 18848 named 10u IPv4 835771 TCP localhost.sky.net:53 (LISTEN)
named 18848 named 11u IPv4 835772 UDP phoenix.sky.net:53
named 18848 named 12u IPv4 835773 TCP phoenix.sky.net:53 (LISTEN)
named 18848 named 13u IPv4 835774 UDP phoenix1.internet.net:53
named 18848 named 14u IPv4 835775 TCP phoenix1.internet.net:53 (LISTEN)
named 18848 named 17u IPv4 835779 TCP localhost.sky.net:953 (LISTEN)
...
Le résultat a été tronqué, car trop long. On remarque que par rapport à la précédente commande, la liste des ports est plus longue. Bug ou erreur ? En fait, non : "lsof" affiche les forks et les threads qui utilisent les fichiers, alors que "netstat" n'affiche que les processus pères.II-2-6 Fuser"Fuser" (File user) est un peu comme "lsof", à savoir qu'il se base sur les fichiers pour déterminer les connexions IP ouvertes. Pour l'usage qui nous intéresse, nous ne verrons qu'un seul paramètre :
La commande "fuser 80/tcp" nous donne :
[root@phoenix /]# fuser -v 80/tcp
USER PID ACCESS COMMAND
80/tcp root 17979 f.... httpd2
root 17987 f.... httpd2
root 17988 f.... httpd2
root 17989 f.... httpd2
root 17990 f.... httpd2
root 17991 f.... httpd2
root 18591 f.... httpd2
Et "fuser 67/tcp 67/udp 80/tcp" nous donne :
[root@phoenix /]# fuser 67/tcp 67/udp 80/tcp
67/udp: 19191
80/tcp: 17979 17987 17988 17989 17990 17991 18591
Ici, les ports 80 en TCP et 67 en UDP sont ouverts. Par contre, le port 67 TCP n'est pas ouvert.Pour information, le port 67 est celui du DHCP, et il ne fonctionne en général qu'en UDP, et non TCP. II-2-7 PingIl est sans doute inutile de s'étendre sur la commande "ping", tellement elle est connue. "Ping" permet de vérifier la présence d'une machine en lui envoyant un paquet ICMP, auquel la machine cible doit répondre par un paquet ICMP équivalent. La commande affiche alors des informations intéressantes : Adresse IP, durée de transmission, etc...Utilisé à de mauvaises fins, "ping" peut :
[olivier@phoenix /]$ ping www.google.fr
PING www.google.com (216.239.39.99) 56(84) bytes of data.
64 bytes from 216.239.39.99: icmp_seq=1 ttl=49 time=519 ms
64 bytes from 216.239.39.99: icmp_seq=2 ttl=49 time=229 ms
64 bytes from 216.239.39.99: icmp_seq=3 ttl=49 time=229 ms
64 bytes from 216.239.39.99: icmp_seq=4 ttl=49 time=229 ms
64 bytes from 216.239.39.99: icmp_seq=6 ttl=49 time=229 ms
64 bytes from 216.239.39.99: icmp_seq=7 ttl=49 time=229 ms
64 bytes from 216.239.39.99: icmp_seq=8 ttl=49 time=219 ms
64 bytes from 216.239.39.99: icmp_seq=10 ttl=49 time=219 ms
--- www.google.com ping statistics ---
10 packets transmitted, 8 received, 20% packet loss, time 9349ms
rtt min/avg/max/mdev = 219.981/263.552/519.507/96.831 ms
Cette commande nous indique que l'adresse IP de "www.google.fr" est "216.239.39.99" (en fait, il y en a plusieurs, et ceci n'est que l'une des adresses de ce site). Par contre, Google doit filtrer une partie des paquets ICMP, ou la connexion doit être mauvaise, car seul 80% des paquets envoyés par Phoenix ont reçu une réponse... Ce sont les aléas d'IP !
II-2-8 TracerouteCette commande se base aussi sur ICMP, mais elle est plus intéressante. Elle indique le chemin utilisé par les paquets IP pour aller de votre machine à une machine cible. En plus de cela, elle affiche le temps mis par les paquets pour passer d'un réseau à un autre.Cette commande est principalement utilisée par les administrateurs réseaux. Elle sert le plus souvent à vérifier la qualité des connexions, ou à déterminer les engorgements dans les réseaux. Cependant, elle peut être aussi utilisée pour remonter la trace d'une machine, et trouver l'origine de sa source. Du fait de son caractère orienté sur la sécurité, la commande "traceroute" ne peut s'exécuter qu'en temps que root. Cependant, sur certaines OS ou distributions Linux, ce programme est dit "Set-UID root" ("man chmod" pour plus d'information). C'est à dire que lorsque qu'il est lancé, Linux donne au programme les droits de son propriétaire. Concrètement, lorsque vous lancer un programme qui a de telles capacités, vous devenez temporairement root à la place du root ! (is no good ? ) L'emplacement de ce type de programme est en général en dehors des emplacements classiques de stockages des programmes utilisateurs. Sous Linux, vous le trouverez généralement en "/usr/sbin/traceroute" : [root@phoenix /]# ls -la /usr/sbin/traceroute -rwsr-xr-x 1 root bin 18136 mai 7 2002 /usr/sbin/traceroute*Ici, c'est le caractère "s" qui indique que le programme est "Set-UID". Et on voit que le programme appartient au root. Donc ce programme est bien "Set-UID root". Exemple d'utilisation de "traceroute" sur la machine "200.165.134.194" qui a tenté aujourd'hui d'accéder illégalement à ma machine : [root@phoenix /]# traceroute 200.165.134.194 traceroute to 200.165.134.194 (200.165.134.194), 30 hops max, 38 byte packets 1 192.168.254.254 (192.168.254.254) 119.244 ms 110.262 ms 109.510 ms 2 grenoble-3k-1-a5.routers.proxad.net (213.228.10.30) 109.974 ms 109.811 ms 120.138 ms 3 cbv-6k-1-a7.routers.proxad.net (213.228.3.120) 129.695 ms 119.787 ms 130.286 ms 4 prs-b2-geth6-0.telia.net (213.248.71.13) 129.895 ms 129.943 ms 119.906 ms 5 prs-bb1-pos1-2-0.telia.net (213.248.70.5) 129.947 ms 120.188 ms 119.663 ms 6 ldn-bb1-pos0-2-0.telia.net (213.248.64.157) 130.058 ms 119.730 ms 129.883 ms 7 ldn-bb2-pos0-0-0.telia.net (213.248.64.162) 149.989 ms 150.124 ms 139.694 ms 8 nyk-bb2-pos2-3-0.telia.net (213.248.65.38) 220.042 ms 219.873 ms 219.907 ms 9 nyk-bb1-pos0-0-0.telia.net (213.248.80.1) 189.920 ms 190.519 ms 199.344 ms 10 sl-gw27-nyc-10-0.sprintlink.net (144.232.230.29) 190.289 ms 190.159 ms 189.732 ms 11 sl-bb24-nyc-15-0.sprintlink.net (144.232.7.25) 210.080 ms 199.748 ms 199.883 ms 12 sl-bb21-nyc-6-0.sprintlink.net (144.232.13.186) 189.992 ms 209.842 ms 199.948 ms 13 sl-bb21-atl-11-1.sprintlink.net (144.232.18.69) 220.024 ms 209.990 ms 219.963 ms 14 sl-bb20-orl-14-2.sprintlink.net (144.232.19.170) 239.885 ms 229.955 ms 229.944 ms 15 sl-bb21-orl-15-0.sprintlink.net (144.232.2.146) 230.250 ms 239.882 ms 230.041 ms 16 sl-st21-mia-15-1.sprintlink.net (144.232.20.13) 239.983 ms 229.887 ms 239.914 ms 17 sl-splkt1-3-0.sprintlink.net (144.223.244.78) 349.943 ms 349.903 ms 349.912 ms 18 200.187.128.69 (200.187.128.69) 350.908 ms 349.908 ms 349.933 ms 19 200.223.131.213 (200.223.131.213) 389.949 ms 399.927 ms 390.009 ms 20 PO0-0.BOT-RJ-ROTN-01.telemar.net.br (200.223.131.122) 389.862 ms 399.640 ms 389.948 ms 21 PO6-0.ASGS-BA-ROTN-01.telemar.net.br (200.223.131.73) 390.002 ms 379.775 ms 379.940 ms 22 PO4-0.BVG-PE-ROTN-01.telemar.net.br (200.223.131.17) 390.056 ms 389.770 ms 390.063 ms 23 PO10-0.BVG-PE-ROTD-02.telemar.net.br (200.223.131.22) 399.816 ms 389.723 ms 389.966 ms 24 200.164.204.198 (200.164.204.198) 399.975 ms 389.775 ms 390.692 ms 25 200.164.234.34 (200.164.234.34) 1379.447 ms 2529.793 ms 1259.899 ms 26 200.165.134.194 (200.165.134.194) 1809.956 ms 2259.911 ms 2969.929 msAnalysons tout ceci :
II-2-9 Autres informationsÉvidement, ceci n'est qu'une petite liste des outils Linux de surveillance de l'activité réseau. Il en existe beaucoup d'autres, et encore plus qui seront développés dans l'avenir. La recherche sur Internet ou sur des sites spécialisés dans la sécurité informatique vous en apprendra beaucoup plus que ces quelques lignes. Nous avons majoritairement vu ici des outils en mode ligne de commande, mais il en existe des équivalents en mode graphique.Pour ce qui est de l'utilisation plus complète de ces programmes, je vous invite à consulter leurs documentations respectives. Les commandes "man netstat", "info nmap", etc... sont vos meilleurs amis ! |
Lorsque vous démarrez votre Linux (oui je sais, c'est long...), tout un tas de programmes sont lancés. Nous allons voir un peu plus en détail de quoi il s'agit.
II-3-1 DémonsNon, nous n'allons pas parler de la Bible, ou d'une aventure de Donjons & Dragons. Sous Linux, un démon est un programme qui se charge en mémoire, attendre certains événements, et réagir en fonction d'eux. On peut citer en vrac :
Pour les utilisateurs de Windows®, un démon est l'équivalent d'un "service". II-3-2 ServeursUn serveur est un programme résident en mémoire, tout comme un démon, à la différence qu'il est tout spécialement intéressé par une activité réseau particulière. Donc un serveur va interagir avec un logiciel à distance, via par exemple le protocole IP. Que le logiciel qui dialogue avec lui soit sur une machine éloignée (connectée via "ethX" ou "pppX"), ou en local (via "lo"), cela n'a pas d'importance.Lors de la précédente commande "netstat", les programmes répondants au doux nom de "http2", "smbd", "dhcpd", etc..., étaient tous des serveurs. II-3-3 Démons de service (inetd / xinetd)Inetd et son "fils" xinetd (pour "eXtended inetd") sont deux serveurs particuliers. "Inetd" étant l'ancêtre et commençant à disparaître des configurations Linux, je ne parlerai que de "Xinetd", qui fait le même travail que "Inetd", mais en mieux...Le but d'"xinetd" est de se placer entre la couche IP et un ou plusieurs serveurs, afin de les protéger. On peut par exemple vouloir ne laisser l'accès à un serveur que depuis une certaine adresse IP, ou une certaine interface réseau, ou encore uniquement pendant une certaine fenêtre temporelle, etc... Ou alors par une combinaison de quelques unes de ces contraintes. Auquel cas, il faut que le serveur en question ait été suffisamment bien programmé, et qu'il dispose de toutes ces options de configuration. Mais développer autant de paramétrages sur autant de serveurs différents, cela demande du temps, et est la source potentielle de nombreux bugs qui peuvent compromettre la sécurité de la machine. C'est là qu'intervient "xinetd". Ce meta serveur va se charger d'attendre les requêtes venant de logiciels clients, puis d'appliquer les restrictions qu'on lui a donné, et enfin de décider ou non si la requête est valide. Si c'est le cas, il lancera le logiciel serveur à qui est destiné la requête et laissera ce dernier de débrouiller avec le client. Parmi l'ensemble de logiciels dont nous allons parler un peu plus loin certains peuvent être protégés par xinetd (pop3, proftpd, telnet,...) mais d'autres non (samba, apache, dhcpd,...). Pour ces derniers, c'est à eux de fournir tous les réglages de sécurité dont l'utilisateur peut avoir besoin. En général, ce sont de gros logiciels serveurs qui les proposent justement, et qui pour des raisons de performance, ne peuvent pas se permettre de gaspiller du temps CPU à faire analyser leur trafic IP par un meta serveur comme xinetd. Une documentation très intéressante, et en français, sur la configuration de xinetd se trouve ici. |
Faire tourner un serveur sur sa machine est certes très intéressant, mais il faut avoir conscience des risques que l'on encourt.
Et en général, c'est là que le lecteur commence à pâlir et à se dire "M.... c'est ce que j'ai fait. Ca craint....".
|
II-5-1 Un peu de bon sensLa première chose à faire, est de lancer un petit audit de votre machine. Pour cela, utilisez "nmap", "netstat" et ses petits copains pour déterminer quels sont les serveurs qui tournent sur votre machine. Rappelez vous que lancer nmap sur les ports UDP est très long, et qu'il est plus rapide d'abord de rechercher la présence des ports UDP avec "netstat", puis de les tester au cas par cas avec nmap.Bon, une fois que c'est fait, posez vous la question : "Est-ce que j'ai besoin du serveur xxxxx ?". Parfois, la réponse peut être négative, et auquel cas l'action doit être immédiate : fermer au plus tôt ce serveur !! Il n'y a rien de plus dangereux que de laisser un serveur tourner sans l'utiliser, car on fini par oublier jusqu'à sa présence, et on ne fera pas attention à le mettre à jour pour corriger ses défauts. Auquel cas, un intrus peut tomber sur ce serveur et bénéficier d'un trou de sécurité pour pénétrer dans votre machine. Dans l'exemple qui va suivre, on va chercher à supprimer le serveur Samba / NetBIOS de la machine Phoenix. Samba est un système le partage de fichiers en réseau avec les machines Windows® :
[root@phoenix /]# nmap phoenix0.sky.net -p 138,139 && nmap phoenix0.sky.net -p 137,138 -sU
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Interesting ports on phoenix.sky.net (192.168.0.1):
(The 1 port scanned but not shown below is in state: closed)
Port State Service
139/tcp open netbios-ssn
Nmap run completed -- 1 IP address (1 host up) scanned in 1 second
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Interesting ports on phoenix.sky.net (192.168.0.1):
Port State Service
137/udp open netbios-ns
138/udp open netbios-dgm
Nmap run completed -- 1 IP address (1 host up) scanned in 1 second
D'après les commandes nmap, trois ports (139/tcp, 137/udp et 138/udp) sont utilisés pour le service "netbios". Oui, ce serveur est un peu particulier, d'où l'utilisation dans cet exemple... En fait le protocole "NetBIOS" peut utiliser les ports/protocoles suivant: 137/tcp/udp, 138/tcp/udp, et 139/tcp/udp). Afin de supprimer ce serveur, il nous faut d'abord savoir quels sont les programmes qui tournent derrière ces ports :
[root@phoenix /]# netstat -taupe | sort Connexions Internet actives (serveurs et établies) Proto Recv-Q Send-Q Adresse locale Adresse distante Etat Utilisatr Inode PID/Program name tcp 0 0 phoenix1.in:netbios-ssn *:* LISTEN root 4583 2157/smbd tcp 0 0 phoenix.sky:netbios-ssn *:* LISTEN root 4584 2157/smbd udp 0 0 phoenix1.in:netbios-dgm *:* root 4599 2167/nmbd udp 0 0 phoenix1.int:netbios-ns *:* root 4598 2167/nmbd udp 0 0 phoenix.sky:netbios-dgm *:* root 4601 2167/nmbd udp 0 0 phoenix.sky.:netbios-ns *:* root 4600 2167/nmbdSeul les lignes contenant "netbios" sont affichées. On voit que les programmes qui tournent sont "smbd" et "nmbd". Bien, voila qui est intéressant. Maintenant, nous allons chercher le programme qui a lancé ces serveurs. Sous Linux, tous les programmes (en fait, ce sont des scripts shell) qui lancent des démons sont situés dans "/etc/init.d/" :
[root@phoenix /]# ls -la /etc/init.d/
-rwxr--r-- 1 root root 1838 mar 14 17:11 smb*
Seul le script qui nous intéresse est affiché. On voit donc que l'on a un script appelé "/etc/init.d/smb" qui pourrait bien correspondre à ce que nous voulons. Lançons le, histoire de voir :
[root@phoenix /]# /etc/init.d/smb
Utilisation : /etc/init.d/smb {start|stop|restart|status|condrestart}
Bon, le programme demande un paramètre. Les scripts de démons doivent en effet être lancés en leur indiquant l'opération à effectuer. Ainsi, on trouve généralement les options suivantes :
[root@phoenix /]# /etc/init.d/smb status smbd (pid 2157) est en cours d'exécution... nmbd (pid 2167) est en cours d'exécution...Bingo ! Se script contrôle le lancement de "smbd" et "nmdb" et les PID sont les mêmes que ceux de la commande "netstat" précédente. C'est donc bien ce script qui nous intéresse. Arrêtons donc le serveur Samba : [root@phoenix /]# /etc/init.d/smb stop Arrêt des services SaMBa : [ OK ] Arrêt du service NMB : [ OK ] [root@phoenix /]# /etc/init.d/smb status smbd est arrêté nmbd est arrêtéSamba semble arrêté, comme le confirme la 2nd commande. Il nous reste plus qu'à le vérifier :
[root@phoenix /]# nmap phoenix0.sky.net -p 139 && nmap phoenix0.sky.net -p 137 -sU
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
The 1 scanned port on phoenix.sky.net (192.168.0.1) is: closed
Nmap run completed -- 1 IP address (1 host up) scanned in 0 seconds
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
The 1 scanned port on phoenix.sky.net (192.168.0.1) is: closed
Nmap run completed -- 1 IP address (1 host up) scanned in 1 second
OK, "nmap" ne trouve plus rien. Et "netstat" ?
[root@phoenix /]# netstat -taupe | grep netbios | sort
Et "netstat" non plus. Victoire, nous venons de supprimer un serveur et de fermer des ports !!! Bien, plus de risque à craindre pour ce serveur. Si un intrus fait un "nmap" sur ces ports, il ne trouvera rien. Et il pourra bien tenter tout ce qu'il veut comme attaque sur Samba, rien ne se passera.Mais ce serveur n'est arrêté que tant que votre machine fonctionne. Maintenant, nous pouvons nous débrouiller pour que ce serveur ne soit plus du tout lancé aux prochains démarrages de la machine. Sous Linux, pour démarrer automatiquement un serveur il suffit de créer un lien symbolique. Suivant que votre machine démarre en mode texte ou en mode graphique, il faut créer un lien symbolique dans respectivement les répertoires "/etc/rc.d/rc3.d/" ou "/etc/rc.d/rc5.d/", vers le script du serveur qui se trouve dans le "/etc/init.d". Concrètement, voila comment cela se passe :
[olivier@phoenix /]$ ls -la /etc/rc.d/rc3.d/ /etc/rc.d/rc5.d/
/etc/rc.d/rc3.d/ :
total 8
drwxr-xr-x 2 root root 4096 jun 28 11:35 ./
drwxr-xr-x 10 root root 4096 mar 27 20:23 ../
lrwxrwxrwx 1 root root 20 mar 27 20:32 K15postgresql -> ../init.d/postgresql*
lrwxrwxrwx 1 root root 16 mar 27 20:28 K55routed -> ../init.d/routed*
lrwxrwxrwx 1 root root 23 mar 27 20:27 S01switchprofile -> ../init.d/switchprofile*
lrwxrwxrwx 1 root root 18 mai 27 19:43 S03iptables -> ../init.d/iptables*
lrwxrwxrwx 1 root root 17 mar 27 20:33 S10network -> ../init.d/network*
lrwxrwxrwx 1 root root 15 mai 4 21:02 S10ulogd -> ../init.d/ulogd*
lrwxrwxrwx 1 root root 17 mar 27 20:33 S11portmap -> ../init.d/portmap*
lrwxrwxrwx 1 root root 16 mar 27 20:33 S12syslog -> ../init.d/syslog*
lrwxrwxrwx 1 root root 14 mar 27 20:23 S17alsa -> ../init.d/alsa*
lrwxrwxrwx 1 root root 15 mar 27 20:33 S18sound -> ../init.d/sound*
lrwxrwxrwx 1 root root 16 mar 27 20:33 S20random -> ../init.d/random*
lrwxrwxrwx 1 root root 13 mar 27 20:24 S20xfs -> ../init.d/xfs*
lrwxrwxrwx 1 root root 12 mar 27 20:23 S30dm -> ../init.d/dm*
lrwxrwxrwx 1 root root 13 mar 27 20:28 S40atd -> ../init.d/atd*
lrwxrwxrwx 1 root root 19 mar 27 20:26 S40saslauthd -> ../init.d/saslauthd*
lrwxrwxrwx 1 root root 15 avr 3 23:23 S55named -> ../init.d/named*
lrwxrwxrwx 1 root root 16 mar 27 20:32 S56xinetd -> ../init.d/xinetd*
lrwxrwxrwx 1 root root 15 avr 3 20:02 S65dhcpd -> ../init.d/dhcpd*
lrwxrwxrwx 1 root root 18 mar 27 20:33 S75keytable -> ../init.d/keytable*
lrwxrwxrwx 1 root root 17 mar 27 20:26 S80postfix -> ../init.d/postfix*
lrwxrwxrwx 1 root root 15 mar 27 20:25 S85httpd -> ../init.d/httpd*
lrwxrwxrwx 1 root root 17 mar 27 20:28 S85numlock -> ../init.d/numlock*
lrwxrwxrwx 1 root root 15 mar 27 20:33 S90crond -> ../init.d/crond*
lrwxrwxrwx 1 root root 15 mai 25 17:48 S90mysql -> ../init.d/mysql*
lrwxrwxrwx 1 root root 13 mar 27 20:30 S91smb -> ../init.d/smb*
lrwxrwxrwx 1 root root 17 mar 30 22:37 S92privoxy -> ../init.d/privoxy*
lrwxrwxrwx 1 root root 17 mar 27 20:33 S95kheader -> ../init.d/kheader*
lrwxrwxrwx 1 root root 16 mar 27 20:28 S99devfsd -> ../init.d/devfsd*
lrwxrwxrwx 1 root root 11 mar 27 20:23 S99local -> ../rc.local*
/etc/rc.d/rc5.d/ :
total 8
drwxr-xr-x 2 root root 4096 jun 28 11:35 ./
drwxr-xr-x 10 root root 4096 mar 27 20:23 ../
lrwxrwxrwx 1 root root 20 mar 27 20:32 K15postgresql -> ../init.d/postgresql*
lrwxrwxrwx 1 root root 16 mar 27 20:28 K55routed -> ../init.d/routed*
lrwxrwxrwx 1 root root 23 mar 27 20:27 S01switchprofile -> ../init.d/switchprofile*
lrwxrwxrwx 1 root root 18 mai 27 19:43 S03iptables -> ../init.d/iptables*
lrwxrwxrwx 1 root root 17 mar 27 20:33 S10network -> ../init.d/network*
lrwxrwxrwx 1 root root 15 mai 4 21:02 S10ulogd -> ../init.d/ulogd*
lrwxrwxrwx 1 root root 17 mar 27 20:33 S11portmap -> ../init.d/portmap*
lrwxrwxrwx 1 root root 16 mar 27 20:33 S12syslog -> ../init.d/syslog*
lrwxrwxrwx 1 root root 14 mar 27 20:23 S17alsa -> ../init.d/alsa*
lrwxrwxrwx 1 root root 15 mar 27 20:33 S18sound -> ../init.d/sound*
lrwxrwxrwx 1 root root 16 mar 27 20:33 S20random -> ../init.d/random*
lrwxrwxrwx 1 root root 13 mar 27 20:24 S20xfs -> ../init.d/xfs*
lrwxrwxrwx 1 root root 12 mar 27 20:23 S30dm -> ../init.d/dm*
lrwxrwxrwx 1 root root 13 mar 27 20:28 S40atd -> ../init.d/atd*
lrwxrwxrwx 1 root root 19 mar 27 20:26 S40saslauthd -> ../init.d/saslauthd*
lrwxrwxrwx 1 root root 15 avr 3 23:23 S55named -> ../init.d/named*
lrwxrwxrwx 1 root root 16 mar 27 20:32 S56xinetd -> ../init.d/xinetd*
lrwxrwxrwx 1 root root 15 avr 3 20:02 S65dhcpd -> ../init.d/dhcpd*
lrwxrwxrwx 1 root root 18 mar 27 20:33 S75keytable -> ../init.d/keytable*
lrwxrwxrwx 1 root root 17 mar 27 20:26 S80postfix -> ../init.d/postfix*
lrwxrwxrwx 1 root root 15 mar 27 20:25 S85httpd -> ../init.d/httpd*
lrwxrwxrwx 1 root root 17 mar 27 20:28 S85numlock -> ../init.d/numlock*
lrwxrwxrwx 1 root root 15 mar 27 20:33 S90crond -> ../init.d/crond*
lrwxrwxrwx 1 root root 15 mai 25 17:48 S90mysql -> ../init.d/mysql*
lrwxrwxrwx 1 root root 13 mar 27 20:30 S91smb -> ../init.d/smb*
lrwxrwxrwx 1 root root 17 mar 30 22:37 S92privoxy -> ../init.d/privoxy*
lrwxrwxrwx 1 root root 17 mar 27 20:33 S95kheader -> ../init.d/kheader*
lrwxrwxrwx 1 root root 16 mar 27 20:28 S99devfsd -> ../init.d/devfsd*
lrwxrwxrwx 1 root root 11 mar 27 20:23 S99local -> ../rc.local*
Dans ces 2 répertoires, on voit donc 2 liens "S91smb -> ../init.d/smb*" qui lancent le serveur Samba lors du démarrage de la machine. Nous allons donc les supprimer, et ainsi Samba ne sera plus jamais lancé :
[root@phoenix /]# rm /etc/rc.d/rc3.d/S91smb /etc/rc.d/rc5.d/S91smb
rm: détruire lien symbolique `/etc/rc.d/rc3.d/S91smb'? y
rm: détruire lien symbolique `/etc/rc.d/rc5.d/S91smb'? y
Mais d'un autre coté, nous venons aussi d'arrêter le partage de fichiers avec les autres machines Windows® de notre réseau... Hummm, ce n'est n'est pas très bien, car nous voudrions bien que Paradise récupère sur Phoenix la dernière documentation du kernel Linux que nous avons téléchargé.Conclusion : autant arrêter des serveurs qui ne servent pas est primordiale, autant arrêter des serveurs qui sont utilisés est problématique. Non, décidément dans ce dernier cas ce n'est pas la solution. Il nous faudra faire autre chose. L'idéal serait de dire au serveur "Ne réponds qu'aux machines de sky.net, et ne répond pas aux autres". Oui, cela serait très bien. Mais comment faire ? C'est là qu'il faut plonger dans l'antre les fichiers de configuration, dans le "man" ou le "info", et paramétrer finement ses serveurs. II-5-2 Restrictions des connexions aux ports : GénéralitésPour les sections qui vont suivre, je rappelle au lecteur que l'emplacement des fichiers de configuration et/ou les options qui sont utilisés ont été testés avec une distribution Mandrake 9.1. Pour les autres distribution Linux (Debian, Red Hat, Suze, Slackware, Gentoo, etc...) ou pour des futures versions de la Mandrake, ces fichiers peuvent éventuellement être placés ailleurs, et certaines options ne sont peut-être pas les mêmes. Par contre, ce qui est important c'est la méthodologie que vous trouverez ici. Elle vous permettra de retrouver par vous mêmes les bonnes options de configuration.Dans les fichiers de configuration des divers serveurs, les "mots magiques" qui vont permettre de paramétrer le filtrage des demandes de connexion sont :
Une règle importante pour ce type de paramétrage, c'est que l'on n'est jamais trop paranoïaque. Ainsi, n'hésitez pas à utiliser en même temps les paramètres de types "bind" et "from", afin de doubler la sécurité, et de contrôler à la fois les adresse IP source et destination des requêtes. Maintenant, regardons pour certains serveurs spécifiques comment cela fonctionne. Au risque de vous déplaire, je ne parlerai que des fichiers de configuration, et non des interfaces graphiques qui permettent de saisir agréablement ces paramètres. Tout simplement parce que je ne les utilise pas, et que je travaille plus vite en configurant à la main les fichiers de configuration. Certains dirons que j'ai des pratiques de papy de l'informatique, auquel je répondrais que moi, je ne me suis pas fait greffé une sourie à la place de la main ... Mais n'entamons pas là un nouveau troll, et passons directement à la suite... II-5-3 Samba / NetBIOSOn a déjà parlé précédemment de Samba. C'est un serveur qui permet de partager des répertoire de votre disque dur avec des machines Windows®. D'ailleurs, les réseaux Microsoft et Samba utilisent le même protocole. Pour étouffer dans l'oeuf toute confusion : c'est IBM qui a inventé NetBIOS. Puis il a été implémenté dans Windows® 3.11. Et un peu plus tard par Samba.
Exemple : hosts allow = 192.168.0.0/255.255.255.0 10.0.0.0/255.0.0.0 interfaces = 192.168.0.1/26 10.0.0.1/8 bind interfaces only = yesSi vous utilisez un serveur Samba, vous devez à tout prix le sécuriser. C'est la cible privilégiée des intrus sur Internet. En effet, Windows® est fournit en standard avec un serveur NetBIOS, et bon nombre d'Internautes l'utilisent pour partager des fichiers dans leur réseau local (par exemple, avec leur portable professionnel). Et comme ils n'ont pas forcément conscience de ce problème d'ouvertures de ports, ils partagent leur répertoire sur Internet... Ainsi, tout le monde ou presque a accès en lecture, voir en écriture, sur certains de leurs répertoires, voir sur la totalité de leur disque dur... Pour information, lorsque je suis connecté sur Internet, mon Samba est sollicité environ une fois par minute par des intrus... Ne faites donc pas cette erreur de débutant, et contrôlez au plus vite l'accès à ce port ! II-5-4 ApacheNon, nous n'allons pas jouer aux cowboys et aux indiens. Apache est le nom du serveur web (HTTP) utilisé par environ 50% des serveurs Internet. Il est robuste, en continuel amélioration, mais c'est aussi une cible privilégié des intrus. Je ne parlerai ici que de la version 2.0.Ce n'est pas très habituel d'avoir un serveur Apache qui tourne sur une machine personnelle, mais qu'est-ce que c'est pratique ! Le mien sert à afficher mes pages HTML en cours de construction, exactement comme si elle étaient sur mon site sur Free. De plus, ce serveur fait tourner une version locale de l'excellent validator HTML, ce qui me permet de tester à tout moment la validité de mes pages (et d'avoir le petit logo en bas de page "Valid XHTML"). Mais ce n'est pas parce que je publie des pages HTML, que je laisse rentrer des intrus sur ma propre machine afin de les visiter avant l'heure. Et puis de toute façon, il y a des pages que je ne désire pas publier... Il convient donc de restreindre utilisation de mon serveur Apache.
Exemple : [Fichier : /etc/httpd/conf/httpd2.conf] Listen phoenix0:80 Listen phoenix1:80 [Fichier : /etc/httpd/conf/common/httpd.conf] <Directory /> AllowOverride None <IfModule mod_access.c> Order deny,allow Deny from all </IfModule> </Directory> II-5-5 XinetdOn a déjà parlé plus haut de "Xinetd". Son fichier de configuration est "/etc/xinetd.conf", mais en général il est écrit "includedir /etc/xinetd.d/" dans ce fichier. Cela veut dire que "Xinetd" lira à la fois "/etc/xinetd.conf" mais aussi les fichiers de "/etc/xinetd.d/*" pour définir sa configuration. L'idée de ce système un peu atypique est :
Exemple de configuration pour le serveur proftpd : [Fichier : /etc/xinetd.conf] defaults { instances = 60 log_type = SYSLOG authpriv log_on_success = HOST PID log_on_failure = HOST cps = 25 30 # Remarque : On n'écrit rien en paramètre, et c'est VOLONTAIRE ! Ainsi, TOUS les accès sont interdit... no_access = } includedir /etc/xinetd.d [Fichier : /etc/xinetd.d/proftpd-xinetd] # Service FTP pour phoenix0.sky.net (réseau local) service ftp { id = ftp:0 socket_type = stream wait = no user = root server = /usr/sbin/proftpd flags = REUSE log_on_failure += USERID log_on_success += USERID DURATION nice = 10 instances = 4 bind = phoenix0 only_from = 192.168.0.0/24 disable = no }Commentaire :
II-5-6 X11Lorsque vous faire un "nmap" sur votre machine, vous remarquez qu'un port est ouvert beaucoup "plus haut" que les autres. Il s'agit du port 6000, qui est associé au système graphique X11. C'est lui qui est responsable de l'affichage des beaux pixels qui s'affichent devant vous pendant que vous lisez ce document.[olivier@phoenix /]$ nmap phoenix0.sky.net Starting nmap V. 3.00 ( www.insecure.org/nmap/ ) Interesting ports on phoenix.sky.net (192.168.0.1): (The 1591 ports scanned but not shown below are in state: closed) Port State Service 21/tcp open ftp 23/tcp open telnet 25/tcp open smtp 53/tcp open domain 80/tcp open http 110/tcp open pop-3 111/tcp open sunrpc 443/tcp open https 6000/tcp open X11Pourquoi un logiciel d'affichage a t'il un port IP d'ouvert ? En fait c'est là que Linux (et les Unix/BSD en général) est génial. Avec Linux, vous pouvez lancer un programme, et afficher son résultat non pas sur votre écran, mais sur l'écran d'un autre PC, en utilisant le réseau IP. Rien d'exceptionnel me diriez vous, Windows® le fait depuis sa version 2000. Oui, mais les Unix ont eu cette technologie plus de 20 ans avant les OS de Microsoft... Il est important de fermer ce port, car des intrusions peuvent venir plus ou moins facilement dessus. Et même si ce n'est pas le cas, ce port ouvert indique très clairement à l'intrus que vous avez un système Linux / Unix / BSD. Et ce n'est pas la peine de le mettre trop rapidement sur la voie.
La méthode protection de X11 est beaucoup plus primitive que celles des autres logiciels dont nous parlons ici. En fait, elle n'a que deux options : Le port 6000 est ouvert ou fermé. En général, sur un réseau de particulier on n'utilise pas ce système d'affichage exporté ("export display" en anglais et c'est d'ailleurs le nom d'un variable d'environnement qui est justement utilisé pour cela). C'est pourquoi on peut fermer ce port en toute quiétude. C'est là que cela devient un peu plus compliqué. Le manuel ("man X11") indique que la commande "X" ("/usr/X11R6/bin/X" en fait) peut recevoir le paramètre "-nolisten tcp". Comme cela l'indique, X11 ne va plus écouter le port TCP, et donc le port sera fermé. Oui, mais en général, on ne lance pas "X" directement, car il y a d'autres couches logiciels à initialiser d'abord, comme le "Window Manager" ("gestionnaire de fenêtres" en français), le "Desktop" ("bureau" en français), etc... Ainsi :
II-5-7 Bind / NamedOn a déjà parlé de named, donc je ne m'étendrai pas dessus. Le nom du produit s'appelle "Bind", mais l'exécutable se nomme "named", c'est un peu une source de confusion... L'important si vous avez un serveur DNS sur votre réseau interne, c'est que personne de l'extérieur ne s'amuse à l'interroger, et ne devine la topologie de votre réseau (le nom et les adresses IP des machines à l'intérieur). Avec une configuration non sécurisée, c'est beaucoup plus facile à faire qu'on le croît. D'un autre coté, il est assez rare d'avoir besoin d'un serveur DNS dans un réseau personnel, sauf si on fait du NAT. Mais n'anticipons pas.
Exemple : allow-transfer { 192.168.0.0/24; }; allow-query { 192.168.0.0/24; }; listen-on { 192.168.0.0/24; }; II-5-8 Postfix"Postfix" est un serveur de mails, tout comme le célèbre "sendmail". Il est plus facile à configurer, et peut servir aussi bien à l'intérieur de réseaux modestes ou au sein des grands comptes.
Exemple : mynetworks_style = subnet mynetworks = 192.168.0.0/24 inet_interfaces = phoenix0.sky.net |
A la fin de paramétrage de chaque serveur, n'hésitez pas à utiliser "nmap" afin de vérifier que seuls les machines ou les réseaux en qui vous pouvez avoir confiance (les réseaux locaux, quoi !!) accèdent à vos ports. Remarquez bien que ces options de configurations n'assurent pas toute la sécurité de votre serveur, et encore moins celle des données qui y sont dessus. Par exemple, si vous partagez votre "/" avec Samba, NFS, ou quoi que ce soit d'autre, c'est vous qui prenez la responsabilité que l'on accède à plus d'informations que vous ne le vouliez : Il vaut mieux en effet ne partager qu'un seul petit répertoire de votre disque dur, par exemple "/home/olivier/partage". Autre exemple : Si votre serveur Apache est autorisé à exécuter des CGI-BIN, c'est encore vous qui prenez la responsabilité de ce que ces CGI-BIN peuvent faire... Donc la règle est simple : Lorsque vous lancez un serveur sur votre machine, ayez bien conscience de ce qu'il peut faire, et paramétrez le en conséquence. Bien, maintenant que nous avons bien configuré nos serveurs, et qu'un "nmap pheonix1.internet.net" n'affiche aucun port ouvert, nous nous sentons en sécurité. Oui, mais, est-ce vraiment justifié ? Oui ? Vraiment ? Et bien non !!! Dommage, hein ? Sinon, il n'y aurait pas de chapitre suivant, et ce document ne commencerait pas par "Firewall ...". Bon, trêve de palabres. Refaites le plein de boissons non alcoolisées, prenez quelques aspirines, et passez au chapitre suivant. Nous allons voir comment domestiquer les flammes de l'enfer... |
Dans le précédent chapitre, nous avons réussi à fermer tous les ports de notre machine, mais est-ce à cela que se résume la sécurité en informatique ? Même si ce point est très important, il reste insuffisant. Pourquoi ?
Netfilter est le nom d'une partie du kernel Linux qui est destinée à assurer la surveillance de tous les transferts de données réseaux. Sa tache est de faire du "Network Packet Filtering", c'est à dire du "Filtrage de Paquets Réseaux". Grosso modo, il se place entre la couche réseau du kernel Linux, et la couche applicative (c'est plus compliqué que cela en faite, mais pour les besoins de ce document, cette approximation n'est pas fausse ). Netfilter supporte actuellement les protocoles IPv4, IPv6, DECnet, et ARP, et en partie IPX via des patchs expérimentaux. Nous ne nous intéresserons ici qu'à IPv4. Comme Netfilter est un élément implanté profondément dans le kernel Linux (le "kernel space", ou "l'espace du coeur" en français), on ne peut pas le configurer aussi simplement qu'avec un jolie interface graphique doté de pleins de couleurs. On ne peut pas non plus le paramétrer directement via un fichier de configuration du "/etc/". Non, l'unique moyen que nous ayons de dialoguer avec lui est un programme appelé "iptables", que l'on lance dans le "user space" ("espace utilisateur" en français) avec les droits root. Nous verrons par la suite qu'il existe un certain nombre d'autres applications, graphiques ou non, qui servent d'interface à "iptables". Enfin, et au risque de me répéter, Netfilter / Iptables ne sont que des éléments fonctionnant avec un kernel Linux 2.4 et supérieur. Si vous utilisez un kernel Linux de type 2.2 ou inférieur, vous devez utiliser une applications appelée "ipchains". Mais cela sort malheureusement du cadre de cette documentation. Linux évolue très vite, et ses outils aussi. Pour moi, le seul fait que les kernels 2.4 et supérieurs supportent le suivi de connexion justifient totalement leur utilisation. Donc pour les utilisateurs du kernel 2.2 ou moins, mettez à jour votre kernel si vous voulez exploiter le contenu de ce chapitre. Mais la mise à jour du kernel Linux est une opération lourde. Je ne suis donc absolument pas responsable des conséquences qui pourraient en découdre ! |
Si vous utilisez une distribution Mandrake récente, tous les outils dont vous avez besoin sont disponibles. Vérifiez simplement que vous le package "iptables" est bien installé sur votre machine.
[olivier@phoenix /]$ rpm -q iptables
iptables-1.2.7a-2mdk
Le cas échéant, installez-le :
[root@phoenix /]# urpmi iptables
Pour les autres distributions, vous pouvez utiliser la technique habituelle d'installation de paquets de votre système : "rpm", "urpmi", "apt", interface graphique, etc... Mais vous devez en savoir plus que moi dans ce domaine.Pour ceux qui veulent compiler eux même leur kernel à partir des sources (Hummm, vous n'êtes pas si néophyte que cela alors ! ), vous devez utiliser les options suivantes :
Suivant vos habitudes, vous pouvez compiler certains élément dans le corps du kernel Linux (option "Y"), plutôt qu'en module ("M"). Une fois vos options sélectionnées, à vous le "make deps", "make vmlinux", "make modules", "make modules_install" et "make install", puis le reboot. Mais vous devez connaître la chanson, non ? Si ce n'est pas le cas, recherchez sur Internet comment on compile un kernel Linux. Enfin, vous devez avoir l' outil "iptables" qui soit en adéquation avec la version du kernel Linux que vous utilisez. Si vous avez tout, lancez "iptables -L" en temps que root. Vous devez avoir quelque chose ressemblant à ceci :
[root@phoenix /]# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
La commande "iptables -L" affiche l'état des tables de Netfilter. Késako tout cela ? Le paragraphe suivant va l'expliquer...
|
Je pense qu'à ce niveau là de la documentation, les utilisateurs du monde Windows® (y en a t'ils qui lisent cette documentation ?) doivent se demander dans quel monde de fous ils sont tombés ... Et bien oui, sous Windows® c'est beaucoup plus simple d'installer un firewall de type ZoneAlarm®, Tiny Firewall®, ou autre... Un double clique sur le "setup.exe", et hop cela marche du premier coup. Cela marche, oui, mais est-ce que c'est fiable ? Parce qu'à la porte de votre PC, il y a un bon nombre de virus-vers qui n'attendent qu'une erreur de votre part pour désactiver vos firewall, anti-virus et autres programmes de ce protection. En fait, on ne peut pas comparer le mode de fonctionnement des firewalls sous Windows® et sous Linux tellement ils sont différents.
Il existe plusieurs manières d'aborder l'explication de "Nerfilter" : Soit rentrer dans les détails de sa structure interne, et dans ce cas là il vaut mieux prévoir quelques boîtes d'aspirines. Soit, et c'est ce que je vais tenter de faire, expliquer les principaux composants dont l'utilisateur a besoin, puis aborder au fur et à mesure les aspects plus techniques. Pour ceux qui veulent en savoir un peu plus sur le fonctionnement de Netfilter, je les invite à consulter la documentation du développeur de Netfilter (traduite en français). Bien, êtes vous prêt pour la grande explication de Netfilter ? Oui ? OK, allons y alors. Netfilter peut intervenir en 5 endroits du système de gestion de la pile IP. Pour chacune de ces étapes (que l'on appelle des "hook", pour "crochet" en français), Netfilter peut :
Pour un non-informaticien, le hook peut s'expliquer comme suit : Lorsque vous roulez en voiture, et qu'il y a par exemple un accident sur la route, les gendarmes vont bloquer le passage, et vous faire dévier sur un itinéraire de secours. A la sortie de cet itinéraire, et si tout se passe bien, vous réintégrerez votre route initiale. Et vous aurez effectué ce que l'on appelle vulgairement "faire un crochet". Pour chacun de ces "hook", Netfilter associe une chaîne. Mais qu'est-ce qu'une chaîne ? Une chaîne est un ensemble de règles (du type "si quelque chose alors je fais ceci") concernant les paquets IP : leur origine, leur destination, leur taille, etc... En fonction des différentes règles de la chaîne, Netfilter pourra décider quoi fait du paquet IP : Le laisser passer, le supprimer ou le modifier. Reprenons notre analogie avec la route : Les paquets IP sont des voitures, qui circulent sur des routes. Si Netfilter n'est pas configuré spécialement, les voitures se déplacerons à travers les différentes routes de la pile IP, emprunteront les ronds-points de routage, puis finirons par sortir de la route IP. Par contre, si Netfilter est activé, il y aura des barrages de police en certains endroits du trajet des paquets (les fameux "hook"). En fonction des règles contenus dans ces "hook" (les fameuses chaînes, c'est à dire les signes "STOP"), le barrage décidera ou non de laisser passer le véhicule IP, voir de le modifier... D'ailleurs, c'est un peu ce qui se passe sur nos routes à nous. Il y a parfois des contrôles de police ou de gendarmerie : En fonctions de certaines règles (contrôle des papiers, de l'alcoolémie, de l'état du véhicule, du délit de "sale gueule", ...) l'officier pourra ou non décider de laisser passer le véhicule... |
Hooks et chaînes |
||||||||||||||||||
Voyons maintenant les 5 "hook" et les 5 chaînes qui y sont associées :
Le graphique ci-dessus nous montre l'implantation des différents hooks. Le sujet de ce document étant la sécurité réseau, ce qui nous intéresse le plus est la possibilité de contrôler les paquets arrivant et sortant des différents logiciels de notre machine. C'est donc au niveau des "hooks" "NF_IP_LOCAL_IN" et "NF_IP_LOCAL_OUT" que nous allons nous pencher plus précisément, via la notion de filtrage ("filter" ou "filtering" en anglais). La partie que nous venons de voir ici est une des plus technique de ce document. J'espère que vous êtes toujours là, frais et dispo pour le paragraphe suivant... |
Nous allons maintenant voir ce qu'est une table. Une table permet de définir un comportement précis de Netfilter. Une table est en fait un ensemble de chaînes, elles-mêmes composées de règles. Bref, une table va nous permettre de manipuler Netfilter, afin de lui faire faire des choses intéressantes. Mais comment manipuler ces tables ? Je vous le donnes en 1000 : Avec le programme "iptables" dont je vous parles depuis le début de ce document pardi ! Il existe pour l'instant 3 tables (Filter, NAT et Mangle), d'autres pouvant être rajoutées à l'avenir. Nous allons nous intéresser principalement à la table "Filter", puis dans un 2nd temps à la table "NAT". Nous ne ferons qu'évoquer la table "Mangle", car elle n'a pas beaucoup d'intérêt ici. III-4-1 La table FilterComme son nom l'indique, cette table sert à filtrer les paquets réseaux. C'est à dire que nous allons pouvoir trier les paquets qui passent à travers le réseau, et supprimer ceux qui ne nous intéressent pas, ou que nous trouvons dangereux. Pour cela, la table "Filter" n'utilise que 3 chaînes :
Pour cela, nous allons travailler en deux temps :
|
La table Filter : Le filtrage des paquets |
III-4-2 La table NATLa table NAT (Network Adress Translation, ou Traduction d'Adresses Réseau) nous fait sortir du cadre orienté strictement sur la sécurité de ce document. Mais ce qu'elle permet est tout bonnement essentiel pour la machine Paradise. En fait, elle va transformer notre machine Linux (Phoenix) en une passerelle Internet, ce qui permettra à Paradise de surfer sur Internet. Et dans un second temps, nous verrons comment faire suivre certains paquets arrivant sur Phoenix, pour les transmettre à Paradise.Pour faire tout ceci, nous avons besoin là encore de 3 chaînes :
|
La table NAT : Le passage de trames d'une interface à une autre |
III-4-3 La table MangleNous allons nous transformer en boucher, avide de bits à découper et à reconditionner... En effet, le terme "mangle" en anglais veut dire "mutilation"...Que diable voulons nous faire à nos braves paquets réseaux ? En fait, il s'agit de les marquer en entrée de la couche réseau, afin que d'autres programmes de l'espace kernel ("kernel space") puissent en faire quelque chose. L'idée de cette technique est par exemple de fournir à Linux la possibilité d'avoir un contrôle sur les débits des flux de données entrants et sortants de la machine, afin de rendre certains flux plus prioritaires que d'autres. Du sectarisme au niveau réseau ? Oui, c'est tout à fait cela : Certains flux vont être volontairement privilégiés, afin de garantir un meilleur confort d'utilisation à l'utilisateur. Cette technique s'appelle le QoS ("Quality of Service" ou "Qualité de Service" en français). Un exemple d'intérêt du QoS est le suivant : Pendant que vous téléchargez en FTP un gros fichier, comme une image ISO de la dernière distribution Linux à la mode, vous pouvez désirer continuer à surfer tranquillement sur Internet, sans être tout le temps pénalisé par votre gros téléchargement. Ceci sera possible avec le QoS, et rendant le contenu HTTP (port source 80) prioritaire par rapport à celui de votre téléchargement (port source 20). Mais l'application de cette technique est assez complexe, et sort complètement du cadre de cette documentation. Cela sera, peut-être, l'occasion pour moi de faire une nouvelle documentation ? Qui sait, le sujet n'est pas dénué d'intérêt... Dans les premiers kernels de la série 2.4, la table Mangle n'utilisait que 2 chaînes (PREROUTING et OUTPUT). Mais depuis le kernel 2.4.18 elle utilise toutes les chaînes de Netfilter :
|
La table Mangle : Le marquage des paquets |
Bien c'est fini pour les parties vraiment compliquées. Maintenant que nous en avons fini avec la théorie, passons à la pratique. Voyons comment nous pouvons remplir les chaînes, afin de paramétrer ces tables, et enfin sécuriser notre réseau. |
III-5-1 Les chaînes utilisateursNous avons vu précédemment qu'il existe 5 principales chaînes, appelées aussi chaînes pré-définies, (PREROUTING, INPUT, FORWARD, OUTPUT et POSTROUTING). Ce sont les fameux signes "STOP" de nos illustrations. Et nous avons aussi vu que ces chaînes sont constituées d'un certain nombre de règles, qui forment une "check list" que Netfilter parcourra afin de décider quoi faire des paquets.Ce que nous n'avons pas vu par contre, c'est qu'il est possible à l'utilisateur, au root pour être précis, de créer ses propres chaînes. Ce sont les chaînes utilisateurs. Pourquoi diable faire cela ? Nous ne sommes pas tous des programmeurs avides de milliers de ligne de code ?!?! Ne vous inquiétez pas, il ne s'agit pas là de programmer quoi que ce soit. Mais simplement de rajouter votre propre "check list" lors de l'un ou l'autre des "contrôles de gendarmerie". Ouf, vous avez eu chaud, pas vrai ? Sur le dessin ci-dessous, on voit quelques chaînes utilisateurs qui sont crées pour la table "Filter". Comme vous le voyez, les chaînes utilisateurs peuvent :
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Chaînes utilisateur : Des agents de sécurité privés |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
III-5-2 Règles et ciblesLes règles, comme leur nom l'indique, sont une série de critères auquel doivent ou non répondre les paquets. En fait, on peut associer une règle à un "délit de sale gueule". Si le paquet réseau ressemble à l'un ou l'autre des critères, alors la règle est appliquée. Les différentes règles d'une chaînes sont appliquées les unes à la suite des autres.Les critères peuvent être multiples :
Enfin, à chaque règle est associée une action (ou "CIBLE" dans la nomenclature de Netfilter) à effectuer si la règle doit s'appliquer. C'est là que Netfilter agit, qu'il fait (enfin) quelque chose avec le paquet réseau. Les principales actions sont :
III-5-3 IptablesIptables est donc une commande que seul le root peut lancer. Son but est de dialoguer avec Netfilter, afin de contrôler les règles des chaînes, dans le but de configurer les tables.Iptables est la boîte à tout faire de Netfilter. Cette commande va pouvoir :
Remarque : On trouve parfois dans la colonne "Paramètre" du tableau le paramètre "[!]". Ce paramètre peut se rajouter aux autres paramètres de l'option, afin d'indiquer la négation. Exemples :
|
Comme vous vous devez vous en douter à ce niveau du document, le paramétrage de notre firewall va se résumer à taper un certain nombre de commandes "iptables". Et comme les règles de Netfilter sont perdues à chaque arrêt de la machine, il faudra tout recommencer à chaque fois que vous démarrerez votre ordinateur. Hein ? Quoi ? Il est fou ce type ? Nannn, je vous rassure, il y a un moyen simple de d'éviter cette galère. Il s'agit des scripts. Si vous savez déjà ce qu'est un script, passez au paragraphe suivant.III-6-1 Un script ? Késako ?Un script est un ensemble de commandes que l'ordinateur va exécuter à votre place. Il s'écrit tout simplement en copiant dans un fichier texte, les commandes que vous auriez tapé. D'ordinaire, un script est un fichier ne comportant pas d'extension. Mais pour les distinguer des fichiers classiques de votre disque, il est parfois utile de leur donner un extension. Contrairement à DOS® / Windows® et leurs fichiers ".bat" ou ".cmd", n'importe quelle extension peut être utilisée. Dans ce qui va suivre, je vais donc utiliser l'extension ".sh".Voici un exemple de script très très simple :
[olivier@phoenix /]$ cat archives/scripts/exemple-01.sh
###############################################################################
# NOM : exemple-01.sh
#
# COMMENTAIRE : Simple exemple de script sh/bash
#
# Créé le : 2003/07/01 Dernière modification le : 2003/07/01
###############################################################################
# Les lignes commençant par un "#" sont des commentaires, elles ne sont donc pas
# affichées
echo "+ Bonjour lecteur"
echo "+ Nous somme le `date +%Y/%m/%d` (aaaa/mm/jj) et il est `date +%H:%M:%S`"
echo "+ Vous aimez les scripts ?"
Pour l'exécuter, il suffit de lancer la commande "sh exemple-01.sh", où "sh" est le nom du programme (on parle aussi du terme d'interpréteur), qui va exécuter ce script.
[olivier@phoenix /]$ sh archives/scripts/exemple-01.sh
+ Bonjour lecteur
+ Nous somme le 2003/07/01 (aaaa/mm/jj) et il est 15:51:32
+ Vous aimez les scripts ?
Mais taper la commande "sh ..." est un peu pénible, non ? Donc nous pouvons changer tout ceci en faisant quelques améliorations à notre script :
[olivier@phoenix /]$ cat archives/scripts/exemple-02.sh #!/bin/sh # ############################################################################### # NOM : exemple-02.sh # # COMMENTAIRE : Simple exemple de script sh/bash # # Créé le : 2003/07/01 Dernière modification le : 2003/07/01 ############################################################################### # Les lignes commençant par un "#" sont des commentaires, elles ne sont donc pas # affichées echo "+ Bonjour lecteur" echo "+ Nous somme le `date +%Y/%m/%d` (aaaa/mm/jj) et il est `date +%H:%M:%S`" echo "+ Vous aimez les scripts ?" [olivier@phoenix /]$ chmod +x archives/scripts/exemple-02.sh [olivier@phoenix /]$ archives/scripts/exemple-02.sh + Bonjour lecteur + Nous somme le 2003/07/01 (aaaa/mm/jj) et il est 16:19:04 + Vous aimez les scripts ?Remarquez que, une fois que les bits d'exécution du fichier ont été activés (via la commande "chmod"), vous pouvez fort bien le lancer en double-cliquant dessus via votre gestionnaire de fichiers favoris : Konqueror, Nautilus, ou quoi que soit d'autre. Cependant, bon nombre de scripts rendent la main immédiatement une fois exécuté, et le gestionnaire de fichiers ferme en général le programme tout de suite. Donc vous n'aurez pas le temps de voir ce qui se passe, mis à part une fenêtre noire s'affichant furtivement. Bref, la meilleure solution reste le bon vieux Xterm, la Konsole, etc... Personnellement, j'ai toujours une Konsole d'ouverte, et vous ? Reprenons notre sérieux : Le fait de changer le bit d'exécution est une opération qui peut être lourde de conséquence, surtout si vous utiliser le compte root pour lancer le script. D'une manière générale, je ne fais pas confiance aux scripts que je trouve sur Internet, à moins :
Bref, comme par la suite vous allez devoir lancer en temps que root des scripts que vous trouverez sur cette documentation, je vous encourage à vérifier auparavant qu'ils sont bien ce qu'ils sont supposés être. Si cela peut vous rassurer, j'ai lancé moi-même ces scripts sur ma machine en temps que root. Mais si vous ne voulez pas prendre le risque, je comprendrais parfaitement. Bon, je ne vais pas rentrer plus dans les détails des scripts. Les capacités des scripts sont énormes, car se sont en fait des mini programmes. Vous pouvez même en trouver sur votre Linux qui sont de belle taille (ceux de "/etc/init.d/" sont pas mal) et qui ont énormément de possibilités. J'en propose moi même un dans cette documentation, dont l'explication se trouve dans le chapitre suivant. Si vous voulez plus d'information sur les scripts, je vous conseille de rechercher sur Internet, ou tout simplement d'utiliser le "man sh" ou "man bash". Cependant, comme tout "man", la manière donc cela est écrit est un peu particulière, voir carrément pénible. Alors refaites votre stock d'aspirines ! Décidément, à force de lire ce document cela va finir par vous coûter cher, et faire la fortune de votre pharmacien ! III-6-2 Iptables basiqueNous allons commencer par travailler exclusivement sur la table filter.Bon, petit rappel sur LA règle de filtrage universellement reconnue :
Depuis Phoenix, essayez de faire un "ping phoenix.sky.net", un "ping phoenix0.sky.net", ou un "ping phoenix1.sky.net" : [olivier@phoenix /]$ ping phoenix.sky.net PING phoenix.sky.net (192.168.0.1) 56(84) bytes of data. ping: sendmsg: Operation not permitted ping: sendmsg: Operation not permitted --- phoenix.sky.net ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1010ms [olivier@phoenix /]$ ping phoenix0.sky.net PING phoenix0.sky.net (192.168.0.1) 56(84) bytes of data. ping: sendmsg: Operation not permitted ping: sendmsg: Operation not permitted --- phoenix0.sky.net ping statistics --- 2 packets transmitted, 0 received, 100% packet loss, time 1019ms [olivier@phoenix /]$ ping phoenix1.internet.net PING phoenix1.internet.net (10.0.0.1) 56(84) bytes of data. ping: sendmsg: Operation not permitted --- phoenix1.internet.net ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0msPourquoi cela ne marche t'il pas ? Aurions nous oublié quelque chose ? De toute évidence oui. Souvenez vous (recherchez le lien "plus tard") lors du 1er chapitre, nous en avions rapidement parlé. Que vous ayez sauté ce chapitre ou que vous somnoliez à ce moment n'a pas d'importance . En fait, c'est très simple : dans nos règles "iptables" de configuration de localhost, nous avons indiqué que nous autorisions uniquement les échanges sur l'interface localhost, pour les machines du réseau 127.0.0.0/8. Hors, et c'est ce que nous avions vu lors du 1er chapitre, lorsque qu'une machine accède à ses propres ressources elle ne passent pas par l'interface physique, mais uniquement par l'interface loopback. Donc au lieu de passer par les règles de l'interface eth0, ces paquets sont passés par ceux de l'interface lo, et se sont fait détruire par la règle DROP par défaut... C'est très fort, non ? Comment résoudre ce problème alors ? La solution est très simple, il suffit d'être un peu plus "tolérant" sur les 2 règles de l'interface "localhost", et retirer les options "-d 127.0.0.0/8" et "-s 127.0.0.0/8". Pour cela, nous allons supprimer les précédentes règles, et les recréer : [root@phoenix /]# iptables -t filter -L -n -v Chain INPUT (policy DROP 463 packets, 35458 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- lo * 127.0.0.0/8 127.0.0.0/8 <-- Ceci est la règle 1 0 0 ACCEPT all -- eth0 * 192.168.0.0/24 0.0.0.0/0 0 0 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp spt:80 0 0 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp spt:443 Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy DROP 71 packets, 10712 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * lo 127.0.0.0/8 127.0.0.0/8 <-- Ceci est la règle 1 0 0 ACCEPT all -- * eth0 0.0.0.0/0 192.168.0.0/24 0 0 ACCEPT tcp -- * eth1 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 0 0 ACCEPT tcp -- * eth1 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 [root@phoenix /]# iptables -t filter -D OUTPUT 1 [root@phoenix /]# iptables -t filter -D INPUT 1 [root@phoenix /]# iptables -t filter -A OUTPUT -o lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT [root@phoenix /]# iptables -t filter -A INPUT -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT [root@phoenix /]# iptables -t filter -L -n -v Chain INPUT (policy DROP 475 packets, 37048 bytes) pkts bytes target prot opt in out source destination 1 248 ACCEPT all -- eth0 * 192.168.0.0/24 0.0.0.0/0 0 0 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp spt:80 0 0 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp spt:443 274 166K ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy DROP 84 packets, 12080 bytes) pkts bytes target prot opt in out source destination 9 872 ACCEPT all -- * eth0 0.0.0.0/0 192.168.0.0/24 0 0 ACCEPT tcp -- * eth1 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 0 0 ACCEPT tcp -- * eth1 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 274 166K ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0Cette fois ci, un "ping phoenix0.sky.net" et des autres adresses IP de Phoenix marche sans problème. Ce second script corrigé est téléchargeable ici. Vous vous demandez sûrement pourquoi j'ai pris un (malin ?) plaisir à introduire cette "erreur" dans mon premier script ? C'est simple :
[intrus@pirate /]$ nmap phoenix1.internet.net
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Interesting ports on phoenix1.internet.net (10.0.0.1):
(The 1590 ports scanned but not shown below are in state: closed)
Port State Service
21/tcp open ftp
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
110/tcp open pop-3
111/tcp open sunrpc
139/tcp open netbios-ssn
443/tcp open https
3306/tcp open mysql
6000/tcp open X11
Nmap run completed -- 1 IP address (1 host up) scanned in 1 second
Maintenant, avec notre second script netfilter, non seulement il ne voit plus rien, mais en plus il suppose que Phoenix est arrêté :
[intrus@pirate /]# nmap phoenix1.internet.net Starting nmap V. 3.00 ( www.insecure.org/nmap/ ) Note: Host seems down. If it is really up, but blocking our ping probes, try -P0 Nmap run completed -- 1 IP address (0 hosts up) scanned in 30 secondsAlors que nous, nous pouvons surfer en toute tranquillité. He he he, nous avons berné l'intrus ! La vie n'est elle pas belle ? Hummmm, si si... Ahhh, que c'est beau l'insouciance de ces jeunes internautes... Mais à votre avis, pourquoi il y a encore quelques paragraphes après celui-ci ? Humm ? Je vous le donne en mille : c'est à cause du retour de l'intrus masqué ! Il revient, et il n'est pas du tout content que vous ayez essayé de l'empêcher de rentrer sur votre machine... En fait, nous avons perdu cette bataille face à lui, et nous ne le savons même pas encore... Bon, prenez fissa de quoi vous remonter, et préparez vous à vous remettre une nouvelle couche d'aspirines... |
III-7-1 Comment leurrer un firewall en une leçon...Phoenix se trouve toujours dans la configuration Netfilter définie par le script "iptables-basic-2.sh", et Pirate ne nous voit toujours pas en utilisant la commande "nmap". Oui, mais notre intrus n'est pas un petit plaisantin. Comme nous, il sait lire le "man nmap", et il connaît l'option "-g"...Notre intrus va donc se connecter en temps que root sur sa propre machine, et lancer la commande "nmap phoenix1.internet.net -g 80" :
[root@pirate /]# nmap phoenix1.internet.net -g 80
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Interesting ports on phoenix1.internet.net (10.0.0.1):
(The 1585 ports scanned but not shown below are in state: closed)
Port State Service
21/tcp open ftp
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
110/tcp open pop-3
111/tcp open sunrpc
139/tcp open netbios-ssn
307/tcp filtered unknown
404/tcp filtered nced
443/tcp open https
511/tcp filtered passgo
578/tcp filtered ipdd
607/tcp filtered nqs
3306/tcp open mysql
6000/tcp open X11
Nmap run completed -- 1 IP address (1 host up) scanned in 5 seconds
Horreur sans nom ! Contrairement à la précédente commande "nmap", non seulement notre intrus a réussi à nous retrouver, mais en plus il voit tout nos ports ouverts ! Arggggg, tout ce travail pour rien ! Netfilter ne serait il qu'un gadget inutile ? |
|
Non, en fait c'est tout à fait naturel et cela prouve la protection complètement insuffisante d'un firewall basé uniquement sur l'ouverture des ports. L'image ci-contre le montre bien. C'est une capture des connexions réseaux faite par "Ethereal" sur phoenix1.internet.net. On y voit :
|
Analyse d'un 'nmap -g 80' |
On peut se demander si un tel port scanning a un réel intérêt. Bon, l'intrus sait que nos ports sont ouverts. Oui, et alors ? La belle affaire ! Notre Netfilter est là pour nous protéger, non ? Non, malheureusement pas avec une configuration si pitoyables... Bon, notre intrus n'est pas née de la dernière pluie, et il connaît aussi le programme "nc" ("nc - TCP/IP swiss army knife", "man nc" pour plus d'informations). Avec ce programme, il va pouvoir ouvrir une connexion TCP/IP depuis son port 80, vers le port 80 de Phoenix, et envoyer toutes les commandes qu'il veut. Comme part exemple un "GET /index.html" qui permet de télécharger la page "/index.html". Cette commande est la base du protocole HTTP, et votre navigateur le fait pour ainsi dire tout le temps. [root@pirate /]# nc -p 80 phoenix1.internet.net 80 GET / <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; Linux 2.2.9-23mdk i686) [Netscape]"> <meta name="Author" content="MandrakeSoft"> <title>Welcome to the Advanced Extranet Server, ADVX!</title>La fin de la réponse a été coupée, car inutile. On voit bien ici la réponse du serveur web de Phoenix, qui affiche tout naturellement une page web de notre réseau local... Que le lecteur continue de s'inquiéter, ce qui est fait ici très simplement avec un serveur web, peut l'être tout autant avec un serveur un peu plus sensible, comme par exemple le partage de fichier "Samba" ou "NFS". Il ne faut pas grand chose en fait, juste un peu modifier les sources de programmes comme "smbmount" ou "mount"... Bon, si à ce stade je n'ai pas réussi à capter toute votre attention sur ce problème, vous pouvez définitivement arrêter la lecture de ce document, et continuer de vous faire allégrement pirater ! III-7-2 ... Et comment renvoyer l'intrus dans sa niche |
|
Toujours là ? Parfais, passons à la solution de ce problème : Bien, le problème ici est que notre intrus peut rentrer comme il veut par les différents ports que nous aurions laissé ouverts afin que nous, nous puissions aller sur Internet. En fait, il faudrait que notre firewall soit semi-perméable, c'est à dire qu'il ne laisse entrer des connexions venant du port 80, que si elles viennent en réponse de connexions qui auraient été initialisées par Phoenix. C'est justement ce que permet le module de suivi de connexion (conntrack) de Netfilter. Cette technique est vraiment une avancée en matière de firewall. Netfilter se base sur la poignée de main ("handshake", que nous avons vu au 1er chapitre), afin de déterminer si une connexion a été initialisée par Phoenix ou non. Pour toute nouvelle connexion sortante, il associe l'état "NEW" ("nouveau" en anglais) à la connexion, et stocke cette information en mémoire. Quand il verra arriver d'autres connexions venant de l'extérieur en réponse à cette connexion "NEW", il leur attribuera alors l'état "ESTABLISHED" ("établie" en anglais). Ainsi, pour une connexion rentrante et qui ne se trouve pas déjà dans la mémoire de Netfilter, celui-ci pourra en déduire qu'elle a été initialisée par l'extérieur, et lui attribuera l'état "INVALID". Dans ce cas, et si il a été configuré pour, Netfilter pourra refuser ("DROP") ou rejeter ("REJECT") cette connexion. Il existe un dernier statut intéressant pour le suivi de connexion, il s'agit du statut "RELATED" : Il existe certains protocoles, comme le FTP ou l'IRC par exemple, qui ne répondent pas toujours sur le port qui a initialisé la connexion. Au lieu de cela, ils initialisent eux-mêmes une connexion sur un autre port de la machine demandant l'information. Vous pouvez trouver une excellente explication sur le fonctionnement de ce mode particulier du protocole FTP sur ce site (la partie sur le "mode passif"). Pour certains de ces protocoles particuliers, Netfilter est capable de comprendre que cette nouvelle connexion rentrante est en fait en relation avec une autre connexion précédemment établie par la machine elle-même. Pour ce type de connexion, elle leur attribue le statut de "RELATED" (pour "relative" en anglais). |
Suivi de connexion |
Voyons maintenant comment mettre en oeuvre cette technique. Le système de suivi de connexion de Netfilter n'est pas forcément compilé dans le kernel, donc si ce n'est pas le cas, vous devez d'abord charger le module "ip_conntrack" :
[root@phoenix /]# modprobe ip_conntrack
Si vous envisagez d'utiliser vos clients FTP en mode passif, ou que vous compter utiliser l'IRC, vous avez la possibilité de charger les modules "ip_conntrack" qui supportent ces protocoles :
[root@phoenix /]# modprobe ip_conntrack_ftp [root@phoenix /]# modprobe ip_conntrack_ircEnfin, pour voir la listes des modules "ip_conntrack" qui sont installés sur votre machine : [root@phoenix /]# uname -a Linux phoenix.sky.net 2.4.21-0.13mdksmp #1 SMP Fri Mar 14 13:41:18 EST 2003 i686 unknown unknown GNU/Linux [root@phoenix /]# find /lib/modules/2.4.21-0.13mdksmp/ -iname "ip_conntrack_*" /lib/modules/2.4.21-0.13mdksmp/kernel/net/ipv4/netfilter/ip_conntrack_ftp.o.gz /lib/modules/2.4.21-0.13mdksmp/kernel/net/ipv4/netfilter/ip_conntrack_proto_gre.o.gz /lib/modules/2.4.21-0.13mdksmp/kernel/net/ipv4/netfilter/ip_conntrack_h323.o.gz /lib/modules/2.4.21-0.13mdksmp/kernel/net/ipv4/netfilter/ip_conntrack_irc.o.gz /lib/modules/2.4.21-0.13mdksmp/kernel/net/ipv4/netfilter/ip_conntrack_pptp.o.gzMaintenant, comment indiquer à Netfilter que nous ne désirons laisser passer que les connexions sortantes initialisées par la machine, mais aussi de ne laisser passer que celles qui sont en réponse avec les premières ? C'est tout simplement aussi facile que ce que nous venons de dire : [root@phoenix /]# iptables -A OUTPUT -o eth1 -s 10.0.0.1 -d 0.0.0.0/0 -p all -m state --state ! INVALID -j ACCEPT [root@phoenix /]# iptables -A INPUT -i eth1 -s 0.0.0.0/0 -d 10.0.0.1 -p all -m state --state RELATED,ESTABLISHED -j ACCEPT
Mais est-ce vraiment efficace ? On va le voir tout de suite :
[root@pirate /]# nmap phoenix1.internet.net -g 80 -P0
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
All 1601 scanned ports on phoenix1.internet.net (10.0.0.1) are: filtered
Nmap run completed -- 1 IP address (1 host up) scanned in 1721 seconds
On utilise l'option -P0 pour forcer la connexion par "nmap", vu que Phoenix refuse de répondre aux demandes les plus simples. On remarque que le scan est excessivement long (1721 secondes, soit près d'une demi heure...), car Pirate fait son scan en testant une dizaine de ports en parallèle, mais attends une dizaine de secondes pour chaque groupe de ports testés.Dans ces conditions, Nmap ne peut déterminer si Phoenix est joignable ou pas. Sur Phoenix on peut voir par contre qu'un grand nombre de paquets entrants ont été "dropés". Ce sont les tentatives de connexions de "nmap" : [root@phoenix /]# iptables -L -v -n Chain INPUT (policy DROP 6571 packets, 268K bytes) pkts bytes target prot opt in out source destination 3480 2235K ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 9 2232 ACCEPT all -- eth0 * 192.168.0.0/24 192.168.0.0/24 0 0 ACCEPT all -- eth1 * 0.0.0.0/0 10.0.0.1 state RELATED,ESTABLISHED Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy DROP 22 packets, 1716 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 3480 2235K ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 9 2232 ACCEPT all -- * eth0 192.168.0.0/24 192.168.0.0/24 97 9096 ACCEPT all -- * eth1 10.0.0.1 0.0.0.0/0 state NEW,RELATED,ESTABLISHEDLa conclusion est sans appel : notre machine est un "trou noir" qui se refuse de répondre aux sollicitations extérieures. Par contre, Phoenix arrive toujours à se connecter sur internet.net : [olivier@phoenix /]$ ping web.internet.net PING web.internet.net (10.0.0.200) 56(84) bytes of data. 64 bytes from web.0.0.10.in-addr.arpa (10.0.0.200): icmp_seq=1 ttl=64 time=2.22 ms 64 bytes from web.0.0.10.in-addr.arpa (10.0.0.200): icmp_seq=2 ttl=64 time=0.300 ms --- web.internet.net ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1010ms rtt min/avg/max/mdev = 0.300/1.263/2.227/0.964 ms [olivier@phoenix /]$ nmap web.internet.net -p 80,443 Starting nmap V. 3.00 ( www.insecure.org/nmap/ ) Interesting ports on web.0.0.10.in-addr.arpa (10.0.0.200): Port State Service 80/tcp open http 443/tcp open https Nmap run completed -- 1 IP address (1 host up) scanned in 0 secondsVictoire ? Cette fois ci, OUI !!! L'intrus ne peut nullement accéder de lui-même à notre machine, toutes ses tentatives de "nmap" échoues. Votre machine a donc été en grande partie sécurisée. Comparé à la situation au début de la lecture de ce document, vous pouvez donc être un peu plus tranquille, et vous avez un peu moins à craindre des intrus. Mais, et comme nous le verrons en conclusion de ce chapitre, ce n'est pas pour autant que vous ne risquez rien. Bien, maintenant que nous avons sécurisé l'accès à notre machine grâce à la table "Filter", passons aux autres fonctionnalités intéressantes de Netfilter : passons à l'exploitation de la table "NAT". |
|
Jusqu'à présent, la machine Paradise de notre réseau n'a pas été très utilisée. Son activité réseau est restreinte à celle du réseau sky.net. Alors que Phoenix, lui, peut se connecter au réseau internet.net. Tout cela n'est pas très juste, aussi allons nous y remédier. Comment ? En transformant tout simplement Phoenix en une passerelle entre les réseaux sky.net et internet.net. Dans tout ce qui suit, nous allons nous arranger pour que paradise.sky.net puisse se connecter au serveur web web.internet.net. Sous Windows®, ce que nous allons faire s'appelle du "partage de connexion Internet", ce qui est tout à fait vrai : Phoenix va partager sa connexion à Internet avec les machines du réseaux sky.net. Pour réaliser ceci, il nous faut réaliser plusieurs opérations :
|
|
|
Masquage d'adresse |
Le NAT étant maintenant configuré et activé, il reste à configurer les machines du réseau sky.net, afin de leur indiquer quelle est la passerelle. C'est chose faite en lançant par exemple sur paradise.sky.net :
[root@paradise /]# route add default gw phoenix0.sky.net [root@paradise /]# route Table de routage IP du noyau Destination Passerelle Genmask Indic Metric Ref Use Iface 192.168.0.0 * 255.255.255.0 U 0 0 0 eth0 127.0.0.0 * 255.0.0.0 U 0 0 0 lo default phoenix0.sky.ne 0.0.0.0 UG 0 0 0 eth0Bien, tout est en place. Voyons ce que cela donne. Depuis paradise.sky.net, tentons une connexion sur web.internet.net:
[olivier@paradise /]$ nmap web.internet.net -p 80,443
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Interesting ports on web.0.0.10.in-addr.arpa (10.0.0.200):
Port State Service
80/tcp open http
443/tcp open https
Nmap run completed -- 1 IP address (1 host up) scanned in 0 seconds
Bien ! Comme on le voit, la connexion se fait d'un réseau à l'autre, à travers Phoenix. Opération réussie donc ! Cela qui nous donne l'occasion de trouver ici le script iptables de cet exemple.Remarques : Dans tout nos exemples, nous avons systématiquement autorisé tout le réseau sky.net à accéder à internet.net. Cependant, nous aurions très bien pu limiter cet accès à uniquement quelques machines de notre réseau interne. Pour cela, il suffit de changer les options "-s" et "-d" de nos règles de "FORWARD", et d'indiquer l'adresse IP de la machine qui est autorisée à passer d'un réseau à un autre. Exemple : [root@phoenix ]# iptables -t filter -A FORWARD -i eth0 -o eth1 -s 192.168.0.2 -d 0.0.0.0/0 \ -m state --state ! INVALID -j ACCEPT [root@phoenix ]# iptables -t filter -A FORWARD -i eth1 -o eth0 -s 0.0.0.0/0 -d 192.168.0.2 \ -m state --state ESTABLISHED,RELATED -j ACCEPTEt qu'en dit la sécurité ? Est-ce que par hasard pirate.internet.net peut accéder à paradise.sky.net ? Est-ce possible ? Techniquement oui, il suffit que pirate.internet.net déclare phoenix1.internet.net comme étant sa passerelle pour le réseau internet.net : [root@pirate /]# route add default gw phoenix1.internet.net [root@pirate /]# route Table de routage IP du noyau Destination Passerelle Genmask Indic Metric Ref Use Iface 10.0.0.0 * 255.0.0.0 U 0 0 0 eth0 127.0.0.0 * 255.0.0.0 U 0 0 0 lo default phoenix1.intern 0.0.0.0 UG 0 0 0 eth0Puis, de lancer par exemple un "ping" sur l'adresse IP de paradise.sky.net : [root@pirate /]# ping -c 3 192.168.0.2 PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. --- 192.168.0.2 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2014msBien, notre machine est correctement sécurisée. Tout va donc pour le mieux ? Indéniablement, oui. Mais tel un funambule entrain de traverser le vide sur une corde tendue, il ne faut pas grand chose pour que cette état idéal se transforme en un cauchemar sans nom... En effet, regardons les traces qu'on laissé la dernière connexion de pirate.internet.net dans les statistiques de Netfilter : [root@phoenix /]# iptables -L -v -n -t nat Chain PREROUTING (policy ACCEPT 3 packets, 252 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 MASQUERADE all -- * eth1 192.168.0.0/24 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destinationCette commande nous indique que 3 paquets ont été acceptés par le comportement par défaut de la chaîne "PREROUTING" de la table "NAT". C'est tout à fait normal, ce sont nos 3 paquets de ping qui arrivent de pirate.internet.net et qui s'apprêtent à passer à travers Phoenix. Mais qui va les arrêter ? [root@phoenix /]# iptables -L -v -n -t filter Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- eth0 * 192.168.0.0/24 192.168.0.0/24 Chain FORWARD (policy DROP 3 packets, 252 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- eth0 eth1 192.168.0.0/24 0.0.0.0/0 state NEW,RELATED,ESTABLISHED 0 0 ACCEPT all -- eth1 eth0 0.0.0.0/0 192.168.0.0/24 state RELATED,ESTABLISHED Chain OUTPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- * eth0 192.168.0.0/24 192.168.0.0/24Cette commande là nous indique que 3 paquets ont été détruits par le comportement par défaut de la chaîne "FORWARD" de la table "Filter". Là encore, c'est ce à quoi nous attendions. Pourquoi ? Parce qu'aucune des autres règles de la chaîne "FORWARD" de cette table ne les ont laissé passer. Maintenant, changeons seulement le comportement par défaut de la table "FORWARD" de la table "Filter" :
[root@phoenix /]# iptables -t filter -P FORWARD ACCEPT
Juste pour information, on pourra télécharger ce méchant script iptables ici.Et relançons notre "ping" depuis pirate.internet.net : [intrus@pirate /]$ ping -c 3 192.168.0.2 PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. 64 bytes from 192.168.0.2: icmp_seq=1 ttl=254 time=0.957 ms 64 bytes from 192.168.0.2: icmp_seq=2 ttl=254 time=0.987 ms 64 bytes from 192.168.0.2: icmp_seq=3 ttl=254 time=0.957 ms --- 192.168.0.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2021ms rtt min/avg/max/mdev = 0.957/0.967/0.987/0.014 msQUOI !?!? Notre intrus peut accéder sans problème à l'intérieur de notre réseau ? Diantre, il y a un bug, et un méchant ! Et tout cela à cause d'un malheureuse règle par défaut ? Oui, exactement. Regardons les statistiques d'iptables pour la table "Filter" : [root@phoenix /]# iptables -L -v -n -t filter Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6000 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6000 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- eth0 * 192.168.0.0/24 192.168.0.0/24 Chain FORWARD (policy ACCEPT 3 packets, 252 bytes) pkts bytes target prot opt in out source destination 3 252 ACCEPT all -- eth0 eth1 192.168.0.0/24 0.0.0.0/0 state NEW,RELATED,ESTABLISHED 0 0 ACCEPT all -- eth1 eth0 0.0.0.0/0 192.168.0.0/24 state RELATED,ESTABLISHED Chain OUTPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- * eth0 192.168.0.0/24 192.168.0.0/24Voilà quelque chose de très intéressant :
[root@phoenix /]# iptables -L -v -n -t nat Chain PREROUTING (policy ACCEPT 3 packets, 252 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 3 packets, 252 bytes) pkts bytes target prot opt in out source destination 0 0 MASQUERADE all -- * eth1 192.168.0.0/24 0.0.0.0/0 Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination3 paquets sont passés par les chaînes "PREROUTING" puis "POSTROUTING" afin de sortir du réseau internet.net et atteindre le réseau sky.net. Par contre, il n'y a pas de traces des paquets de réponse de paradise.sky.net à pirate.internet.net. Ceci est dû au mécanisme interne de Netfilter qui identifie les connexions en réponse, et qui ne les fait pas passer par la table NAT. C'est pour cela, et comme vu plus haut, qu'il n'y a pas besoin d'écrire des règles spécifiques pour le "MASQUERADING rentrant". De cette (longue) explication nous pourrons en tirer 3 leçons :
|
Bien caché derrière notre firewall Phoenix, notre réseau sky.net ne craint plus grand chose. De plus, avec ce que nous avons vu au chapitre précédent, les machines de notre réseau local peuvent rejoindre le réseau internet.net. Maintenant, nous voudrions avoir un serveur (HTTP, FTP, IRC, peer-to-peer, etc...) qui puisse proposer des informations et des services non plus sur le réseau sky.net, mais carrément sur le réseau internet.net. L'emplacement d'un tel service devrait se faire en toute logique sur la machine Phoenix, qui est le seul accès que nous ayons sur le réseau internet.net. Mais ceci serait une très mauvaise idée. Pourquoi ? Parce qu'un tel accès est inévitablement une faille dans notre système de sécurité. Grâce à ce service que nous proposons, l'intrus pourrait essayer de se l'accaparer, puis d'en profiter pour prendre la main sur Phoenix, et d'enfin de court-circuiter toutes nos règles Netfilter. Notre machine se trouverait alors sans aucune protection vis à vis de l'extérieur... Inquiétant, non ? Au minimum, il faudrait configurer ce service pour fonctionner sous un utilisateur n'ayant que peu de droits, et en plus dans un chroot. Mais même avec cela, la sécurité ne pourrait pas être garantie. Alors, comment faire ? C'est là qu'intervient le suivi de port ("port fowarding" en anglais). L'idée d'un tel système est que toute connexion entrante sur un certain port de phoenix1.internet.net (par exemple le port 80, pour du HTTP), soit automatiquement redirigée vers une autre machine de sky.net : paradise.sky.net par exemple. Vu de l'extérieur, on aurait l'impression que le port 80 de phoenix1.internet.net serait ouvert, mais en fait, ce serait le port 80 de paradise.sky.net qui serait réellement ouvert, et sur lequel tournerait un serveur Apache. |
|
Est-ce réellement une "solution miracle" ? Presque, mais à condition de prendre quelques précautions :
|
DMZ pour port fowarding |
Mais revenons à un réseau un peu plus simple, et baissons d'un cran notre paranoïa. Nous allons supposer que la machine qui hébergera notre serveur HTTP est fiable, et que personne ne peut en prendre la main (ceci n'est qu'une hypothèse bien sûr !). Nous la laisserons donc dans le réseau sky.net, en compagnie des autres machines de notre réseau interne. Que devons nous faire ?
Il ne nous reste plus qu'à vérifier que pirate.internet.net a bien accès à phoenix1.internet.net : [intrus@pirate /]$ telnet phoenix1.internet.net 80 Escape character is '^]'. GET / <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; Linux 2.2.9-23mdk i686) [Netscape]"> <meta name="Author" content="MandrakeSoft"> <title>Welcome to the Advanced Extranet Server, ADVX!</title> <LINK REL="SHORTCUT ICON" HREF="/favicon.ico"> <!-- Background white, links blue (unvisited), navy (visited), red (active) --> </head> <body text="#000000" bgcolor="#FFFFFF" link="#0000FF" vlink="#000080" alink="#FF0000"> <table border=0> <tr> <td valign=top><a href=http://www.advx.org><img border=0 src=/icons/advx.png ALT="Powered by ADVX.org software" height=47 width=102 align=LEFT></a></td> <td valign=top width=100%><h2><center>Welcome to paradise.sky.net </center></h2> </td></tr>La fin de la réponse a été tronquée. Bien que l'on accède à phoenix1.internet.net, c'est paradise.sky.net qui répond. Regardons maintenant le log du serveur Apache de paradise.sky.net : [root@paradise /]# tail -1 /var/log/httpd/access_log 192.168.0.1 - - [06/Jul/2003:21:02:21 +0200] "GET /" 200 6988 "-" "-"On voit la connexion faite par pirate.internet.net, et le téléchargement de la page web. Cependant, on notera que l'adresse IP qui est logée n'est pas celle de pirate.internet.net, mais bien celle de phoenix1.internet.net, ce qui est tout à fait normal, du fait de l'utilisation de la cible "SNAT". Enfin, regardons ce que nous donne les statistiques de Netfilter sur Phoenix : [root@phoenix /]# iptables -L -v -n -t filter Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6000 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6000 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- eth0 * 192.168.0.0/24 0.0.0.0/0 0 0 ACCEPT icmp -- eth1 * 0.0.0.0/0 10.0.0.1 state NEW,RELATED, ESTABLISHED Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 8 430 ACCEPT tcp -- eth1 eth0 0.0.0.0/0 192.168.0.2 tcp dpt:80 state NEW,RELATED,ESTABLISHED 8 7412 ACCEPT tcp -- eth0 eth1 192.168.0.2 0.0.0.0/0 tcp spt:80 state RELATED,ESTABLISHED Chain OUTPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 0 0 ACCEPT all -- * eth0 0.0.0.0/0 192.168.0.0/24 0 0 ACCEPT icmp -- * eth1 10.0.0.1 0.0.0.0/0 state RELATED, ESTABLISHED [root@phoenix /]# iptables -L -v -n -t nat Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1 60 DNAT tcp -- eth1 * 0.0.0.0/0 10.0.0.1 tcp dpt:80 state NEW,RELATED, ESTABLISHED to:192.168.0.2:80 Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1 60 SNAT tcp -- * eth0 0.0.0.0/0 192.168.0.2 tcp dpt:80 state NEW,RELATED, ESTABLISHED to:192.168.0.1La requête et l'envoi de la page HTML ont demandés au total 2 fois 8 paquets, qui sont passés à travers les chaînes "FORWARD". On voit bien que les paquets entrant dans phoenix1.internet.net sont bien passés par les cibles "DNAT" et "SNAT" des chaînes "PREROUTING" et "POSTROUTING". Par contre ces statistiques ne montre pas les paquets en réponses à la demande de connexion. C'est dû à la même routine de suivi de connexion de Netfilter que pour l'IP masquerading. Nous pourrions nous arrêter ici pour le port fowarding, mais un dernier point est intéressant à soulever : que se passe t'il si nous n'incluons pas la règles SNAT, ce qui est indiqué plus haut comme étant une "méthode sale" ? Commençons par retirer cette règle :
[root@phoenix /]# iptables -D POSTROUTING 1 -t nat
Puis, indiquons à Paradise que sa passerelle est phoenix0.sky.net
[root@paradise /]# route add default gw phoenix0.sky.net [root@paradise /]# route Table de routage IP du noyau Destination Passerelle Genmask Indic Metric Ref Use Iface 192.168.0.0 * 255.255.255.0 U 0 0 0 eth0 127.0.0.0 * 255.0.0.0 U 0 0 0 lo default phoenix0.sky.ne 0.0.0.0 UG 0 0 0 eth0Et maintenant, demandons à nouveau notre page HTML depuis pirate.internet.net. Suite à cette connexion, les statistiques d'"iptables" nous donne : [root@phoenix /]# iptables -L -v -n -t nat Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1 60 DNAT tcp -- eth1 * 0.0.0.0/0 10.0.0.1 tcp dpt:80 state NEW,RELATED, ESTABLISHED to:192.168.0.2:80 Chain POSTROUTING (policy ACCEPT 1 packets, 60 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)Comme précédemment, un paquet est passé par le chaîne "PREROUTING", mais aucun n'est passé par de règles "POSTROUTING". Et pour cause, il n'y en a plus. Par contre, le paquet de retour est passé par la règle par défaut de la chaîne POSTROUTING... C'est parce que les paquets n'empruntent pas les mêmes canaux en entrée et en sortie que j'estime cette méthode comme étant "sale". Enfin ce qui est le plus intéressant c'est le log d'Apache sur paradise.sky.net : [root@paradise /]# tail -1 /var/log/httpd/access_log 10.0.0.66 - - [06/Jul/2003:22:27:43 +0200] "GET /" 200 6988 "-" "-"Cette fois ci, c'est bien l'adresse IP de la machine à distance qui est stockée, forcément, puisque Phoenix ne la dissimule plus. Vous trouverez le script de cet exemple ici, mais comme indiqué, plus haut c'est la méthode "sale" pour effectuer du port forwarding... Ceci conclue donc l'utilisation du port forwarding. Dans le cadre d'un usage personnel, cette technique est assez peu utile : qui chez lui héberge son propre serveur HTTP, FTP, IRC, etc... Pas utile donc ? En fait non, il y a bien un usage personnel fort utile où l'on peut utiliser le port forwarding, et qui est particulièrement à la mode au jour où j'écris ces lignes : il s'agit du peer-to-peer (P2P). C'est un système d'échange de fichiers à travers Internet, où toutes les machines connectées partagent des fichiers sur un morceau de son disque dur. Chaque machine agit donc à la fois comme un client et un serveur. Une grand partie des clients pour ce type d'échange se trouvant sous Windows®, et comme c'est un OS dont l'usage courant est peu orienté sur la sécurité, on peut utiliser le port forwarding de Linux pour le protéger. Avec les explications ci-dessus, vous pouvez sans difficulté écrire vos propres scripts iptables afin de renvoyer vos connexions entrantes vers la machine sur lequel tourne votre client P2P. Cependant, souvenez vous que vous ne faites que déplacer le problème de sécurité sur cette machine ci, et donc que c'est à vous d'en assurer la responsabilité. Si cette machine est par exemple sous Windows®, la présence de Netfilter en tête de votre réseau ne vous dispense pas de mettre en place un firewall logiciel sur cette machine, afin par exemple de surveiller ce que fait votre Windows®. Ceci étant, je me lave les mains de ce que vous pourriez faire de l'usage du port forwarding et du P2P. Et si je ne fournis aucun script d'exemple, c'est entre autre parce que je n'utilise pas ce type de logiciel... Enfin, je dirais que la mise en place du port forwarding n'est pas forcément ce qui se fait le plus facilement, bien qu'en fait les règles ne soit pas beaucoup plus complexes que pour l'IP masquerading. Sur Internet, vous trouverez beaucoup de bribes d'explications sur cette techniques, et beaucoup de scripts plus où moins bien fait à ce sujet. Méfiez vous donc de ce que vous trouverez. Le mieux est sans aucun doute de tester votre configuration par étape, et de regarder systématiquement les statistiques d'iptables afin de voir par où passent vos paquets. D'une manière générale, si les paquets utilisent les cibles par défaut de PREROUTING ou de POSTROUTING, c'est qu'il y a probablement une mauvaise configuration de votre script. Enfin, comme indiqué dans les 2 scripts "iptables-portforwarding-*.sh" que vous pouvez télécharger, vous avez la possibilité d'utiliser la cible LOG afin d'analyser quelles sont les paquets qui utilisent ces cibles par défaut. |
Jusqu'à présent, nous avons vu comment configurer nos règles avec Netfilter : définir les cibles par défaut, et supprimer des paquets. Mais à force de tout supprimer, il nous est difficile de connaître l'efficacité de notre firewall, et si il est intéressant de rajouter ou de supprimer des règles. D'où l'intérêt de logger certaines informations. Dans ce qui suis, nous allons utiliser l'affreux anglicisme "logger" qui décrit l'action de stocker dans un "log" une certaine information. III-9-1 LOGC'est la méthode la plus standard pour logger des trames. Il s'agit simplement de créer une règle "iptables" dont la cible ("-j [cible]") n'est pas "ACCEPT" ou "DROP", mais tout simplement "LOG". Si nous reprenons le script "iptables-conntrack-1.sh", nous pouvons par exemple rajouter une dernière règle qui va logger tout ce qui na pas été accepté par la chaîne "INPUT". C'est très pratique, car ainsi nous serons averti de tout ce qui tente d'accéder aux processus utilisateurs de notre système. Pour cela, nous rajoutons cette règle en temps que dernière règle de la chaîne "INPUT" :
[root@phoenix /]# iptables -t filter -A INPUT -j LOG
Comme Netfilter est un élément du Kernel, ses logs sont donc des logs de ce dernier. Et comme tout bon log Kernel, ils se retrouve dans le fichier "/var/log/messages". Ainsi, si pirate.internet.net fait un "nmap" sur les ports HTTP et HTTPS de Phoenix, nous aurons :
[intrus@pirate /]# nmap phoenix1.internet.net -p 80,443
Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Note: Host seems down. If it is really up, but blocking our ping probes, try -P0
Nmap run completed -- 1 IP address (0 hosts up) scanned in 30 seconds
[root@phoenix /]# tail -14 /var/log/messages Jul 8 23:04:59 phoenix nmbd[2178]: [2003/07/08 23:04:59, 0] nmbd/nmbd_packets.c:send_netbios_packet(172) Jul 8 23:04:59 phoenix nmbd[2178]: send_netbios_packet: send_packet() to IP 10.255.255.255 port 137 failed Jul 8 23:04:59 phoenix nmbd[2178]: [2003/07/08 23:04:59, 0] nmbd/nmbd_namequery.c:query_name(256) Jul 8 23:04:59 phoenix nmbd[2178]: query_name: Failed to send packet trying to query name WORKGROUP Jul 8 23:07:03 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=38 ID=41593 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=0 Jul 8 23:07:03 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 TTL=39 ID=51459 PROTO=TCP SPT=53120 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0 Jul 8 23:07:09 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=38 ID=2581 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=256 Jul 8 23:07:09 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 TTL=39 ID=27444 PROTO=TCP SPT=53121 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0 Jul 8 23:07:15 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=38 ID=29887 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=512 Jul 8 23:07:15 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 TTL=39 ID=48409 PROTO=TCP SPT=53122 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0 Jul 8 23:07:21 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=38 ID=37813 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=768 Jul 8 23:07:21 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 TTL=39 ID=17449 PROTO=TCP SPT=53123 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0 Jul 8 23:07:27 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 TTL=38 ID=57294 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=1024 Jul 8 23:07:27 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 TTL=39 ID=64622 PROTO=TCP SPT=53124 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0Grâce au log, on voit que phoenix1.internet.net reçoit une série de commandes "ping" et de requêtes sur son port 80 de la part de pirate.internet.net. Évidement, comme Phoenix ne répond pas à ces requêtes, Pirate fait plusieurs essais, et finalement ne testera même pas le port 443. Un moyen pratique de suivre ses logs en temps réel est la commande, lancé en temps que root : "tail -f /var/log/messages". Cela affichera en permanence la fin de ce fichier de log. Pour l'arrêter, il suffit d'appuyer sur CTRL+C. Mais ce fichier sert aussi (surtout !) à stocker tout les messages d'informations ou d'erreurs du Kernel. Il nous faut donc un moyen de retrouver ces messages de log Netfilter parmi tout les autres messages. On peut configurer avec le paramètre "--log-prefix=[Message de log]" la règle de log afin qu'elle rajoute systématiquement des messages en début de log. Ainsi : [root@phoenix /]# iptables -t filter -A INPUT -s 10.0.0.66 -j LOG --log-prefix="AttackPirate" [root@phoenix /]# iptables -t filter -A INPUT -s 10.0.0.200 -j LOG --log-prefix="AttackWeb"indiquera clairement les connexions faites par les machines pirate.internet.net et web.internet.net : [intrus@pirate /]$ nmap -p 80 phoenix1.internet.net [intrus@web /]$ nmap -p 80 phoenix1.internet.net [root@phoenix /]# tail -f /var/log/messages Jul 8 23:26:06 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:26:06 phoenix kernel: AttackWeb IN=eth1 OUT= SRC=10.0.0.200 DST=10.0.0.1 ... Jul 8 23:26:12 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:26:12 phoenix kernel: AttackWeb IN=eth1 OUT= SRC=10.0.0.200 DST=10.0.0.1 ... Jul 8 23:26:12 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:26:12 phoenix kernel: AttackWeb IN=eth1 OUT= SRC=10.0.0.200 DST=10.0.0.1 ... Jul 8 23:26:25 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:26:28 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:26:34 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...Cependant, cette méthode de log a l'inconvénient que même avec des "--log-prefix", il reste difficile de séparer les messages de log de Netfilter des autres messages du Kernel. Comme en témoigne d'ailleurs le premier affichage du /var/log/message, où des messages de Samba (en début de log) sont mélangés aux messages de Netfilter. Une autre méthode est de définir un "niveau de log" ("log level" en anglais), qui rajoute une autre information aux log, ce qui permet au demon de log (un programme appelé "syslogd") de stocker ces log dans un autre fichier. Par exemple, sur une Mandrake, on peut utiliser (voir "man syslogd", "man syslog.conf", "less /usr/include/sys/syslog.h" pour avoir plus d'informations sur ces commandes) : [root@phoenix /]# iptables -t filter -A INPUT -j LOG --log-level=4 [root@phoenix /]# less /usr/include/sys/syslog.h #define LOG_WARNING 4 /* warning conditions */ [root@phoenix /]# less /etc/syslog.conf kern.=warn -/var/log/kernel/warnings [intrus@pirate /]$ nmap -p 80 phoenix1.internet.net Starting nmap V. 3.00 ( www.insecure.org/nmap/ ) Note: Host seems down. If it is really up, but blocking our ping probes, try -P0 Nmap run completed -- 1 IP address (0 hosts up) scanned in 60 seconds [root@phoenix /]# tail -10 /var/log/kernel/warnings Jul 8 18:55:43 phoenix kernel: MSDOS FS: Using codepage 850 Jul 8 19:26:34 phoenix kernel: i2c-amd756.o version 2.7.0 (20021208) Jul 8 19:26:34 phoenix kernel: i2c-amd756.o: AMD768 bus detected and initialized Jul 8 19:28:37 phoenix kernel: UDF-fs: No VRS found Jul 8 23:53:58 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:54:01 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:54:07 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:54:10 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:54:13 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... Jul 8 23:54:19 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...Comme on le voit, bien que les log de Netfilter soient isolés dans un fichiers à part (/var/log/warnings), ce fichier n'en est pas moins partagé avec d'autres modules du Kernel, qui utilisent eux aussi le log Kernel de niveau 4 <=> Warning. Dans le précédent log, on voit notamment des logs de "MSDOS FS" et "i2c-amd756.0" qui n'ont rien à voir avec Netfilter. On pourrait s'imaginer utiliser une autre entrée du syslog, afin de vraiment séparer ces log. Le seul problème, c'est que les log de Netfilter sont des log du Kernel, et qu'à ce titre, on sera toujours obligé de les déclarer en temps que "kern." dans le "/etc/syslog.conf". Alors ? Stocker ces logs à part est vraiment une chose impossible sous Linux ? Non, heureusement que non ! La solution s'appelle ULOG, et nous allons la voir tout de suite. III-9-2 ULOGULOG est module du Kernel dont le développement a été fait par http://www.gnumonks.org/projects/. Il a été spécialement conçu pour recevoir les log de Netfilter. Il y a certaines (petites) contraintes à son utilisation :
|
III-10-1 Règles par défaut ("Policy")Jusqu'à présent, nous avons vu que nous devions initialiser et définir les règles par défaut de ta table "Filter", et parfois celles de la table "NAT". En fait, ce n'est pas tout à fait la bonne manière de faire. A supposer par exemple que vous voulez faire uniquement du filtrage (option "-t filter"), vous pouvez très bien avoir laissé quelques règles de PREROUTING ou de POSTROUTING activées dans la table NAT. Dans ce cas, vous ne savez pas forcément ce que fait Netfilter, et il se peut qu'avec de telles configurations, il laisse passez des trames sans que vous ne vous en doutiez.Donc il est est primordial que la première chose que vous fassiez dans un script Netfilter, c'est d'initialiser toutes les tables ("Filter", "NAT" et "Mangle") : [root@phoenix /]# iptables -t filter -F [root@phoenix /]# iptables -t filter -X [root@phoenix /]# iptables -t filter -P INPUT DROP [root@phoenix /]# iptables -t filter -P FORWARD DROP [root@phoenix /]# iptables -t filter -P OUTPUT DROP [root@phoenix /]# iptables -t nat -F [root@phoenix /]# iptables -t nat -X [root@phoenix /]# iptables -t nat -P PREROUTING ACCEPT [root@phoenix /]# iptables -t nat -P OUTPUT ACCEPT [root@phoenix /]# iptables -t nat -P POSTROUTING ACCEPT [root@phoenix /]# iptables -t mangle -F [root@phoenix /]# iptables -t mangle -X [root@phoenix /]# iptables -t mangle -P PREROUTING ACCEPT [root@phoenix /]# iptables -t mangle -P INPUT ACCEPT [root@phoenix /]# iptables -t mangle -P FORWARD ACCEPT [root@phoenix /]# iptables -t mangle -P OUTPUT ACCEPT [root@phoenix /]# iptables -t mangle -P POSTROUTING ACCEPTVous remarquerez que l'on définie à "ACCEPT" les règles par défaut des tables "NAT" et "Mangle". Cela n'a pas trop d'influence sur la sécurité, du moment que vos règles de FORWARD sont bien écrites. Sinon, vous pouvez les mettre à "DROP", mais cela rallongera énormément le code et le temps de développement de votre script Netfilter. Ce n'est pas non plus une mauvaise chose que de désactiver en début de script, au moins temporairement, le NAT (on ne sait jamais, des fois que vous l'ayez oublié) : echo 0 > /proc/sys/net/ipv4/ip_forward III-10-2 Chaînes utilisateursNous avons peu parlé des chaînes utilisateurs, aussi nous allons y jeter un oeil. Lorsque vous écrivez vos règles Netfilter, il y a parfois des morceaux de code que vous aimeriez mettre en commun. Par exemple, supposons que vous voudriez interdire le "ping" de certaines machines du réseau local ainsi que du réseau externe, mais que vous vouliez aussi "logger" toute utilisation du "ping". Vous auriez alors à écrire quelque chose comme :[root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.2 -p icmp -j LOG [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.2 -p icmp -j DROP [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.3 -p icmp -j LOG [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.3 -p icmp -j DROP [root@phoenix /]# iptables -t filter -A INPUT -i eth1 -p icmp -j LOG [root@phoenix /]# iptables -t filter -A INPUT -i eth1 -p icmp -j DROPDans ces cas, les règles utilisateurs sont là pour simplifier la vie. Commençons par écrire notre propre règle "LogDrop" qui comme son nom l'indique, va "logger" les trames, puis les supprimer : [root@phoenix /]# iptables -t filter -N LogDrop [root@phoenix /]# iptables -t filter -A LogDrop -j LOG --log-prefix LogDrop [root@phoenix /]# iptables -t filter -A LogDrop -j DROPPuis, appelons la pour nos pings sur les réseaux locaux : [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.2 -p icmp -j LogDrop [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.3 -p icmp -j LogDropEt les réseaux externes :
[root@phoenix /]# iptables -t filter -A INPUT -i eth1 -p icmp -j LogDrop
On note au passage que notre chaîne "LogDrop" peut être appelée à n'importe quelle occasion, avec une règle "parente" ayant ou non beaucoup d'options. Le script vu ci-dessus se trouve ici.
III-10-3 Script final d'exempleNous avons vu jusqu'à présent un bon nombre de fonctionnalités de Netfilter grâce aux commandes "iptables". J'ai donc écrit un script qui regroupe toutes ces fonctionnalités en un seul script que vous pouvez utiliser chez vous. Ce script est téléchargeable ici.Avant toute chose, il faudra que vous le configuriez à votre usage. Pour cela, le début du script contient un certain nombre de variables globales, qui définissent le comportement du script :
III-10-4 Autres scriptsA titre d'informations, vous pouvez télécharger quelques scripts supplémentaires :
III-10-5 Tests d'intrusionUne fois que toutes vos règles iptables sont écrites, il vous faut vous-même tester la sécurité de votre Linux en pratiquant des tests d'intrusions. Une première approche est d'utiliser "nmap", et de contrôler chacun de vos ports. Cette pratique est très efficace (lisez "man nmap" afin d'utiliser au mieux les options très variées de Nmap), et doit être fait depuis les machines de votre réseau. Pendant vos "attaques" lancées par "nmap", n'oubliez pas de garder un oeil sur votre "/var/log/messages" (par exemple avec un "tail -f /var/log/messages") ou le fichier qui stocke les logs de Netfilter, afin de suivre la progression de l'attaque.Dans le cadre du réseau proposé ici, il m'a été facile de tester les 2 interfaces réseaux de Phoenix, en lançant les tests depuis Paradise et Pirate. Cependant, dans le cadre d'une utilisation personnelle, il est beaucoup plus difficile de tester l'interface réseau externe ("ppp0" par exemple). En effet, si par exemple depuis Phoenix vous lancez un "nmap phoenix1.internet.net", vous ne ferez que tester les règles de "loopback/localhost", comme nous l'avons déjà vu précédemment. Pour que vous obteniez un résultat correct, il vous faut donc changer vos règles de "loopback" par celles que vous avez définies pour "ppp0". Mais cette solution n'est pas forcément très représentative de la réalité, et le mieux serait de tester réellement les paquets arrivant sur "ppp0". Il vous faut donc faire confiance à une personne externe à votre réseau, situé sur Internet, pour tester vos règles de Firewall. Pour cela, 3 possibilités :
En fait, tout le mérite en revient au suivi de connexion, qui fait passer notre machine pour un "trou noir". Comme le veut la définition de ce terme, c'est "un corps qui absorbe tout, et qui ne rejette rien"... Quelques soit ces sites, leurs tests ne sont souvent pas très poussés, et se limitent parfois qu'aux seuls ports ouverts par défaut sous Windows®. De plus, un simple test de "port scanning" n'est pas forcément suffisant, et d'autres outils de tests d'intrusion peuvent être utilisés en complément. Mais à ce niveau là, la limite entre tests de sécurité et piratage est très tenue, donc je vous laisserai chercher par vous-même des moyens de tester un peu plus en profondeur votre système... III-10-6 Sauvegarde des règles NetfilterSupposons que vous n'écriviez pas votre adresse IP Internet dans vos règles Netfilter de "ppp0" (comme décrit ci-dessus), vous avez alors des règles de ce type :[root@phoenix /]# iptables -t filter -A OUTPUT -o ppp0 -d 0.0.0.0/0 \ -p all -m state --state ! INVALID -j ACCEPT [root@phoenix /]# iptables -t filter -A INPUT -i ppp0 -s 0.0.0.0/0 \ -p all -m state --state RELATED,ESTABLISHED -j ACCEPTDans ce cas, vos règles Netfilter sont génériques, et elles n'ont pas besoin d'être modifiées à chaque connexion Internet. Donc vous pouvez écrire vos règles une fois pour toute, et laisser Linux les charger automatiquement au démarrage de votre machine. Pour cela, écrivez vos règles Netfilter dans un script, puis (pour les possesseurs de distributions Mandrake) tapez la commande :
[root@phoenix /]# /etc/rc.d/init.d/iptables save
Enfin, pour que le Netfilter soit opérationnel à chaque démarrage, il faut créer les liens symboliques adéquates dans le /etc/rc.d/ :
[root@phoenix /]# cd /etc/rc.d/rc3.d/ [root@phoenix /]# ln -s ../init.d/iptables s03iptables [root@phoenix /]# cd /etc/rc.d/rc5.d/ [root@phoenix /]# ln -s ../init.d/iptables s03iptablesAu démarrage, votre Linux lancera le script /etc/rc.d/init.d/iptables qui chargera les règles Netfilter précédemment sauvées. Si à un moment vous avez besoin d'arrêter la protection de Netfilter, vous n'avez qu'à lancer la commande suivante :
[root@phoenix /]# /etc/rc.d/init.d/iptables stop
|
Jusqu'à présent, les utilisateurs de Windows® ont pu comparer le fonctionnent des techniques de Firewall de Linux avec ce qu'ils trouvent sur leur OS. Et bien que les fonctionnalités de Netfilter sont au moins équivalentes à ce que l'on trouve dans les outils de firewall sous Windows®, il reste une fonctionnalité qui manque à Linux : c'est le firewall applicatif. On appelle "firewall applicatif" la capacité d'un logiciel à contrôler à la fois les flux de données entrantes et sortantes en fonction de certains critères (adresse IP, port, type de connexion, etc...), mais aussi des applications qui exploitent ces connexions. En gros, un firewall applicatif va permettre de contrôler quelles sont les connexions réseau que fait tel ou tel logiciel. C'est typiquement ce que font des applications fonctionnant sous Windows®, tel que par exemple ZoneAlarm®, TinyFirewall®, Lock 'n' Stop®, etc... A chaque connexion que tente une application, ces firewall applicatifs vérifient que la connexion est autorisée, ou alerte l'utilisateur. Mais à quoi sert exactement ce type d'application ? En fait, elles permettent à l'utilisateur de surveiller si telle ou telle application tente une connexion non autorisée, quasiment dans le dos de l'utilisateur. Par exemple lorsque Word® ou Excel® font une connexion Internet sans raison apparente, que le MediaPlayer® envoie une requête alors qu'il est en pleine lecture de vidéo, ou qu'une dll/ActiveX/autre utilise Internet Explorer® pour accéder à Internet. L'utilisateur de Windows® n'aurait donc pas confiance aux applications qu'il utilise ? Oui, c'est du moins ce qui ressort des discussions des utilisateurs de Windows® et de firewall applicatifs. Et pourquoi ne passent ils pas sous Linux alors ? Parce que ce type de fonctionnalité n'existe pas peut-être ? Que nenni, c'est faisable aussi sous Linux ! La mise en place d'un système de firewall applicatif se fait en fait en 2 temps :
|
Cette partie conclue ce (long !) chapitre sur le firewall de Linux qu'est Netfilter. Comme vous avez pu le voir, le mise en place d'un tel firewall nécessite l'apprentissage de quelques notions. Mais par la suite, l'implémentation est somme toute assez facile. La vraie avancée de Netfilter sur d'autres solutions logicielles non libres est la technique du suivi de connexion, qui permet un réglage très fin des flux de données entrant et sortant. Mais ne vous y fiez pas : croire que le "conntrack" et son principe de "trou noir", appelé aussi technique "stealth" ("furtif" en français), est la protection absolue en terme de sécurité est risquée, très très risqué même. En effet, même si il est très difficile pour un intrus de tester votre adresse IP, vous laissez vous-même des traces sur Internet. Le seul fait de lire en ligne cette documentation permet au serveur web qui la publie de déterminer quelle est votre adresse IP. Car forcément, il faut bien qu'il sache où vous envoyer la page HTML que vous avez demandé. De même, lorsque que vous êtes sur IRC ou que vous faites du "chat" en ligne ("discussion" en français), vous fournissez votre adresse IP. Enfin, lorsque vous envoyez un email, l'adresse IP de votre machine y apparaît la plupart du temps. Pour toutes ces situations, un intrus qui a flairé votre présence connaîtra votre adresse IP, du moins le temps de votre connexion, et il pourra toujours tenter de se forer le passage à travers votre Netfilter. N'allez donc pas narguer des intrus en herbe sur des forums IRC de "l'undeground", sous prétexte que vous avez configuré le firewall de votre Linux ! . De plus, gardez en tête que tout logiciel que vous utilisez, ce navigateur avec lequel vous lisez cette page, votre client IRC, votre application de mails, etc..., est une faille de sécurité potentielle. Donc une trame "officiellement" destinée à votre application, et qui à ce titre passe à travers votre Netfilter, peut s'avérer en fait être une malicieuse attaque de "buffer overflow", destinée à commettre le pire sur votre machine. Et ceci est encore plus vrai lorsqu'il s'agit d'un logiciel serveur que vous avez lancé sur votre machine, et dont vous voulez laisser l'accès à l'extérieur. Pour conclure, les chapitres II et III que nous venons de voir vous permettrons de mieux sécuriser votre machine, et de cesser sa ressemblance à un gruyère. A vous maintenant de vous maintenir au courant des progrès en matière de sécurité, et bien sûr d'attaques, afin d'éviter qu'une souris ne s'y fasse un petit trou ! |
IV-1-1 Interfaces à IptablesComme nous l'avons vu tout au long du précédent chapitre, la plus grosse partie de la configuration de Netfilter est d'utiliser la commande "iptables". Sa syntaxe peut rebuter quelque peu l'utilisateur néophyte, aussi existe t'il des interfaces graphiques qui permettent de créer assez simplement ces règles.N'étant pas spécialement un adepte de ce style d'interface, et de plus ayant des besoins assez spécifiques, je ne me suis pas spécialement intéressé à celles-ci. Cependant, vous en trouverez vous-même de nombreuses sur le site Freshmeat.net, qui a pour vocation de référencer les applications libres. J'en citerai quand même 2 très connues, et qui ont plutôt une bonne réputation :
IV-1-2 Distributions spécialiséesLinux est un système d'exploitation qui peut être utilisé pour un très grand nombre de fonctionnalités différentes. Les distributions qui nous intéresses spécialement dans le cadre de ce document sont celles constituées autour des fonctionnalités de firewall/routeur. Il s'agit en fait de distributions Linux très très simplifiées, et n'ayant qu'un seul but, celui de faire office de firewall et/ou de passerelle. On peut en trouver un grand nombre sur Internet, certaines plus ou moins libres, d'autres plus ou moins petites. Certaines peuvent même tenir sur une disquette 1,44Mo, et fonctionner sur une machine à base de 386 ou de 486 ! Transformer un ancienne machine en un puissant firewall, que voilà de la récupération intéressante et peu coûteuse !En voici une petite liste, non exhaustive bien entendu !
|
Parmi tous les outils de configuration d'Iptables que vous pouvez trouver, j'en propose un moi-même. Je sais ce que vous pouvez penser : "Ce type a fait un long document sur la sécurité Linux, et à la fin, une fois que l'on est bien endormis, hop il propose un vulgaire script qu'il a bricolé sur un coin de table ?" Et bien non, pas du tout ! Le propos n'est pas là. Il s'agit tout simplement de mettre un peu plus en applications tout ce que nous venons de voir jusqu'à présent. Lorsque j'ai commencé à m'intéresser aux problèmes du firewall sous Linux, j'ai dût répondre à des besoins particuliers :
Bien entendu, il est distribué sous la licence GPL, ce qui vous permet de l'utiliser et de le distribuer librement, d'étudier et de modifier son code source. Vous pouvez aussi proposer vos propres patchs pour ce script, et même d'en faire une variante à votre nom (à la condition d'indiquer clairement quelle est la source du script originel). Les points forts de Netfilter_cfg sont :
[root@phoenix ]# /usr/local/sbin/netfilter_cfg + Utilisation des paramètres par défaut : --drop-rules' : on --spoofing-filter' : on --nat' : off --wan-ftp-server' : off --wan-to-server' : off --wan-ping' : off (Utiliser '--help pour avoir de l'aide') + Règles iptables modifiées. Utilisez 'iptables -L -n' ou 'iptables -L -n -v' pour afficher la liste des tables + Fichier de debug : /var/log/netfilter_cfgLancé sans paramètre, "netfilter_cfg" configure la sécurité au maximum. Pour la plupart des utilisations standards, il suffit de le lancer de cette manière au démarrage de votre machine, ou dès que votre connexion à Internet est établie. On peut difficilement faire plus simple, non ? Pour avoir la liste de ses paramètres : [root@phoenix /]# /usr/local/sbin/netfilter_cfg --help netfilter_cfg v0.5.4 Usage: netfilter_cfg [--drop-rules <on|off>] [--nat <on|off>] [--spoofing-filter <on|off>] [--help] [--wan-ftp-server <on|off>] [--wan-to-server <on|off>] [--wan-ping <on|off>] Options : --drop-rules Active/désactive le rejet automatique de certains paquets Défaut : on --nat Active/désactive le fonctionnement en passerelle Internet Défaut : off --spoofing-filter Active/désactive les règles anti-spoofing Défaut : on --wan-ftp-server Active/désactive le serveur FTP Internet Défaut : off --wan-to-server Active/désactive le serveur Tactical Ops Internet Défaut : off --wan-ping Autorise ou nom la machine à répondre aux ping Défaut : off --help Affiche l'aide Exemples : netfilter_cfg --nat on --wan-to-server on --wan-ftp-server off La machine est configurée pour faire du NAT et serveur Tactical Ops. Le serveur FTP est arrêtéPour plus d'information sur ce programme, visitez la page officielle. Pour votre information, j'utilise ce script à chacune de mes connexion Internet. Et j'ai commencé à le diffuser autour de moi, avec jusqu'à présent un grand succès ! Des néophytes en matière de Linux l'utilise d'ailleurs, sans pour l'instant rencontrer de problème. |
Cette section regroupe un certain nombre de liens sur Internet que j'ai utilisé pour mettre au point ce document, ou qui peuvent être des sources d'informations supplémentaires :
|
Comme vous avez pu le constater, la sécurité d'une machine sous Linux n'est pas une mince affaire. Entre les démons à configurer proprement, et les règles de Netfilter à mettre en place, il y a de la matière à travailler. Ce n'est pas pour autant que l'on peu dire que Linux est moins sécurisé qu'un autre OS. Si j'avais fait par exemple un tel document sur la sécurité sous Windows®, il aurait été largement plus long, et nettement moins complet...
Que devez vous retenir d'un tel document ? Cela sera en fonction de vos désirs et besoins. Si vous estimez que la sécurité de votre machine n'a aucune importance, vous venez de perdre quelques heures à me lire et j'en suis navré. Mais ne venez pas vous plaindre si par la suite vous rencontrez des problèmes avec la sécurité de votre machine, et ne mettez pas cela sur le dos de Linux ! Si par contre vous vous sentez concerné par ces problèmes, il est temps pour vous d'appliquer au plus vite les informations vues ici. En urgence, vous pouvez commencer à utiliser "Netfilter_cfg", qui commencera à vous assurer un début de protection. Puis passez à la configuration de vos serveurs. Et enfin, revenez à la configuration de Netfilter, et voyez si vous pouvez ajuster plus finement vos règles à vos besoins.
Malgré sa longueur, ce document n'a pas traité tous les aspects de la sécurité sous Linux (d'ailleurs, est-ce faisable ?). Car même avec une machine "blindée", il vous faudra mettre à jour régulièrement votre système, lancer de temps en temps des tests d'intrusion, surveiller le contenu de vos disques durs, etc... Disons qu'avec ce que vous avez appris là, vous avez moins à craindre lorsque votre machine est connectée à Internet.
Par contre, l'aspect confidentialité de l'Internaute n'a pas du tout été abordé, car ce n'était pas l'intérêt principal de ce guide. Qu'en est t'il de l'utilisation des cookies, des serveurs de publicités, de l'encryptage de pages en HTTPS, etc... Cela fera peut-être (sans doute ?) l'objet d'un autre guide !
Bien, il ne me reste plus qu'à clore ce chapitre et de ranger mon Xemacs au placard (pour quelques minutes, pas plus !). L'écriture de ce document et la conférence qui y est associée ont demandé plus de 15 jours de travail, dont la moitié à raison de plus de 16h par jours... Ce fut un travail réellement intéressant et motivant, et j'espère qu'il vous sera utile. J'ai cherché à le faire le plus simple possible, voir même un peu trop parfois, afin que les utilisateurs les plus débutants ne soient pas perdus. J'espère cependant que les utilisateurs les plus avancés de Linux y aurons quand même trouvé des sources d'informations, et qu'ils n'estiment pas avoir perdu du temps à le lire.
Si vous avez des remarques à faire sur ce guide, des corrections à proposer ou des points à éclaircir, n'hésitez pas à me contacter (). Une traduction de ce guide dans une autre langue n'est pas prévue, mais si vous vous en sentez le courage, n'hésitez pas à me le faire savoir !
Merci tout d'abord à la Guilde, qui m'a permis de présenter une conférence sur ce sujet le 2 juillet 2003. Cet événement fut le moteur de la création de ce document. Elle a été un franc succès, puisqu'elle a réunit environ 75 personnes dans l'amphithéãtre de l'ENSIMAG. Merci tout spécialement à Jérôme pour l'organisation de la conférence, et à Edgar pour son CSS. Et évidement, merci à son Tux pour m'avoir tenu compagnie durant cette présentation !
Merci aux personnes qui m'ont aidé à la préparation de ce document, et tout particulièrement à Keyvan pour les corrections. Merci aussi bien sur aux nombreux lecteurs qui ont apportés leurs avis, corrections, et impressions.
Merci surtout à Rusty Russell, le créateur de Netfilter et les outils qui y sont associés. Même si il est modeste sur sa création, la plus-value que cela apporte à Linux est énorme.
Merci enfin à toute la communauté Libre qui font que Linux existe. Merci à toutes les personnes qui apportent leur pierre à l'édifice du Libre, et qui le rende tout les jours plus facile et plus fiable à utiliser.
Version | Date | Remarque |
---|---|---|
0.5.3 | 23 juillet 2003 | Correction majeur sur l'explication du traceroute Diverses autres petites corrections |
0.5.2 | 20 juillet 2003 | Première version publique |
Ce document peut être librement lu, stocké, reproduit, diffusé, traduit et cité par tous moyens et sur tous supports aux conditions suivantes:
Toute incompatibilité des clauses ci-dessus avec des dispositions ou contraintes légales, contractuelles ou judiciaires implique une limitation correspondante du droit de lecture, utilisation ou redistribution verbatim ou modifiée du document.
This document may be freely read, stored, reproduced, disseminated, translated or quoted by any means and on any medium provided the following conditions are met:
Any incompatibility of the above clauses with legal, contractual or judiciary decisions or constraints implies a corresponding limitation of reading, usage, or redistribution rights for this document, verbatim or modified.
Site de référence : http://olivieraj.free.fr/ | Dernière modification : le mercredi 23 juillet 2003 à 01:58:06 |