La première règle est bien entendu de savoir exactement quels sont les services installés sur sa machine et de n'y laisser que ce qui est strictement nécessaire. Cette méthode, surtout dans le cas d'un réseau local connecté à l'Internet par une passerelle est toutefois assez pénalisante. On peut souhaiter disposer de quelques services sur l'hôte qui sert de passerelle.
Bien entendu, la solution la plus sûre consiste à installer une passerelle qui ne fera que son travail de passerelle et de firewall et d'installer par ailleurs sur le réseau privé un serveur pour les divers services souhaités. Ceci augmente tout de même le nombre de machines et la facture EDF. Ca ne résoudra pas non plus certains problèmes pour les entreprises qui souhaitent accéder à certaines de leurs ressources depuis l'extérieur, mais le cas de figure dépasse largement le propos de cet exposé.
Une solution de protection consiste à interdire l'accès aux ports inutiles côté Internet. L'étude qui suit date un peu, mais malgré l'obsolescence du système utilisé, elle n'en est pas moins toujours pertinente.
Sur Linux Mandrake 7.x (plus généralement avec un noyau 2.2.x bien compilé), ceci peut se faire avec IPChains. Les noyaux 2.4.x et supérieurs, bien que supportant IPChains, gagneront à exploiter plutôt IPTables, nettement plus évolué.
Pour fixer les esprits, donnons un exemple.
Soit une machine Linux servant de passerelle sur l'Internet. Comme on aime bien jouer avec les diverses applications fournies, on y a installé:
Et comme on ne veut pas s'embêter, la règle par défaut sur INPUT est ACCEPT.
Croyez-vous que ce soit prudent? Pas du tout bien entendu. Sur une machine exposée à l'Internet, moins on installe de serveurs, mieux ça vaut. Examinons ce que verrait un pirate qui ferait un « scan » de cette machine avec l'un des meilleurs outils dans le genre nmap
(inclus dans toutes les bonnes distributions GNU/Linux).
De quoi vraiment donner envie de s'y intéresser de plus près!
Telnet, c'est intéressant:
Welcome to gateway2.maison.mrs Linux Mandrake release 7.1 (helium) Kernel 2.2.16-9mdk on an i586 login:
Voilà, une Mandrake 7.1 avec un kernel 2.2.16-9 et la machine s'appelle gateway2.maison.mrs. Ca c'est intéressant. Allons faire un tour sur le DNS du monsieur…
E:\>nslookup Serveur par défaut : <peu importe> Address: <peu importe> > server 62.161.100.113 Serveur par défaut : ca-ol-marseille-5-113.abo.wanadoo.fr Address: 62.161.100.113
> set q=any > ls maison.mrs [ca-ol-marseille-5-113.abo.wanadoo.fr] maison.mrs. NS server = gateway2.maison.mrs gateway2 A 192.168.0.253 remi A 192.168.0.12 michele A 192.168.0.2 chris A 192.168.0.10 gateway1 NS server = 192.168.0.250 daniel A 192.168.0.11 gateway2 NS server = 192.168.0.253**
Et hop! On sait tout du réseau de ce monsieur (Même, si vous avez bien suivi, que ce monsieur dispose sans doute d'une seconde machine du même genre qui s'appelle gateway1)
Il faut dire que c'est quand même très mal, de laisser libre le transfert de zone sur un DNS. Mais j'ai trouvé cette gravissime lacune sur des sites très « professionnels ».
Reprenons le scénario, mais avec BIND correctement configuré. Ça donne ceci:
E:\>nslookup Serveur par défaut : gateway1.maison.mrs Address: 192.168.0.250 > server 62.161.100.113 Serveur par défaut : ca-ol-marseille-5-113.abo.wanadoo.fr Address: 62.161.100.113
> set q=any
> ls maison.mrs. ls: connect: No error *** Impossible de fournir la liste du domaine maison.mrs.: Unspecified error > pchris.maison.mrs Serveur : ca-ol-marseille-5-113.abo.wanadoo.fr Address: 62.161.100.113 *** ca-ol-marseille-5-113.abo.wanadoo.fr ne parvient pas à trouver pchris.maison.mrs : No response from server
C'est déjà mieux, au moins le DNS ne répond plus aux requêtes venant de l'Internet. Comment il faut faire? Dans /etc/named.conf, il faut utiliser les directives « allow-transfert », « allow-query » et même « listen-on » (cf. la doc. de BIND)
Cet exemple est juste donné pour bien montrer que la sécurité passe d'abord par une configuration correcte des serveurs installés…
Mais continuons l'investigation. Voyons le serveur FTP, un petit coup de telnet sur le port 21:
220 gateway2.maison.mrs FTP server (Version wu-2.6.0(1) Wed Jun 28 23:51:34 EDT2000) ready.
Oui, c'est bien un wu-ftp, version 2.6.0. Faudra voir ce qu'il y a comme « exploits » là dessus. On va s'arrêter là, mais il y a pas mal d'investigations à faire sur un serveur FTP
Allez, encore un telnet sur le port 25
220 gateway2.maison.mrs ESMTP Postfix (Postfix-19991231) (Linux-Mandrake)
C'est bien Postfix. (Là aussi, il y aurait encore beaucoup à faire).
Convaincu? en très peu de temps, le pirate accumule une quantité intéressante d'informations sur votre équipement, autant d'informations qu'il pourra exploiter pour essayer de « casser » votre matériel.
Comme l'objectif de cet exposé n'est pas de faire un cours sur l'intrusion (encore que ce soit le meilleur moyen pour apprendre à mettre en place des parades), on va s'arrêter là.
La situation exposée est d'autant plus absurde, qu'avec IPTables, on peut déjà compliquer passablement le travail de l'indélicat.
Que les utilisateurs de Windows n'abandonnent pas la lecture de ce qui suit. La démonstration se fait avec IPtables, mais le principe reste vrai quel que soit l'OS. Nous verrons plus loin les solutions proposées aux utilisateurs de produits Microsoft.
Disons d'abord ce que l'on veut faire en français. D'abord une simple passerelle avec masquage d'adresses du réseau privé :
Ensuite, pour tout ce qui vient du Net, nous bloquerons en UDP comme en TCP les ports :
iptables -P INPUT ACCEPT iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT iptables -t nat -A POSTROUTING -s 192.168.0.0/255.255.255.0 -o ppp0 -j MASQUERADE iptables -A INPUT -p tcp --dport 21 -i ppp0 -j REJECT iptables -A INPUT -p tcp --dport 23 -i ppp0 -j REJECT iptables -A INPUT -p tcp --dport 25 -i ppp0 -j REJECT iptables -A INPUT -p tcp --dport 110 -i ppp0 -j REJECT iptables -A INPUT -p tcp --dport 111 -i ppp0 -j REJECT iptables -A INPUT -p udp --dport 111 -i ppp0 -j REJECT iptables -A INPUT -p tcp --dport 135:139 -i ppp0 -j REJECT iptables -A INPUT -p udp --dport 135:139 -i ppp0 -j REJECT iptables -A INPUT -p tcp --dport 143 -i ppp0 -j REJECT iptables -A INPUT -p tcp --dport 6000:6009 -i ppp0 -j REJECT
Traduit en français, ça veut dire que l'on jette (REJECT) les paquets qui viennent de n'importe où pour aller n'importe où, s'ils ont le malheur de rentrer par ppp0 sur les ports 21, 23, 25, 110, 111, 139, 143 et de 6000 à 6009. C'est bien ce que nous voulions. Refaisons un scan:
Starting nmap V. 2.30BETA17 by fyodor@insecure.org ( www.insecure.org/nmap/ ) Interesting ports on ca-ol-marseille-5-113.abo.wanadoo.fr (62.161.100.113): (Ports scanned but not shown below are in state: filtered) Port State Service Owner 1/tcp unfiltered tcpmux 2/tcp unfiltered compressnet 3/tcp unfiltered compressnet ... 80/tcp open http nobody ... 113/tcp open auth nobody ... 515/tcp open printer root ... ... 3306/tcp open mysql mysql ... TCP Sequence Prediction: Class=random positive increments Difficulty=4917615 (Good luck!) Remote operating system guess: Linux 2.1.122 - 2.2.14** Nmap run completed -- 1 IP address (1 host up) scanned in 220 seconds
nmap ne s'y trompe pas, il constate qu'il y a des règles de filtrage sur cette machine et essaye de trouver les ports non filtrés. Il va en trouver beaucoup, mais ça ne veut pas dire qu'ils sont ouverts. Ceux qu'il trouve ouverts sont ceux que l'on n'a pas filtrés.
Il est clair que l'on a déjà limité les problèmes. Mais on pourrait encore faire beaucoup mieux . L'objectif ici n'était que de montrer comment l'on peut établir des règles de filtrage de paquets, mais d'expliquer comment un port peut être bloqué par un firewall.
Dans la pratique, il sera probablement plus judicieux de tout interdire, puis de n'ouvrir que ce qui est nécessaire. Voyez à ce propos le chapitre « NetFilter et IPtables ».
Ce type de protection passive offre déjà un bon niveau de sécurité, si l'on a convenablement analysé la configuration de sa machine et placé les bonnes règles. Il y aurait encore à faire sur cette machine, car si l'on a à peu près filtré les ports TCP, qui sont les plus dangereux parce qu'ils permettent un mode connecté, on n'a encore rien fait ni sur UDP, ni sur ICMP. Ces deux protocoles peuvent cependant créer des nuisances parce qu'ils peuvent être utilisés pour bloquer la machine.
Cependant, il est intéressant de placer en plus quelques systèmes qui vont épier le trafic et prévenir, voire réagir, en cas d'activité suspecte avec les « loggers » et les firewalls actifs.
IPtables sait déjà « logger » les événements qui satisfont aux critères des chaînes, mais il est peut-être plus intéressant d'utiliser des outils spécifiques.
La plupart des attaques commencent par un scan des ports ouverts sur la cible. Des outils particuliers permettent de détecter ce scan, d'en identifier la source par son adresse IP et certains permettent même de monter un firewall « sur mesure » pour bloquer l'intrus. Le scanner n'aura même pas le temps de finir son travail et aura l'impression que la cible a disparu.
J'en ai plus ou moins testé trois sous Linux, il en existe beaucoup d'autres, chacun dispose, à mon sens, d'avantages et d'inconvénients. Bien qu'ils n'aient plus beaucoup évolué depuis pas mal de temps, ils sont toujours distribués dans Debian Etch.
Celui-ci fonctionne de manière différente. Son but principal étant d'enregistrer la trace dans des fichiers, bien qu'il soit possible de diriger ses traces sur une console. Lui aussi, se trouve encore dans la Debian Etch, bien que sa dernière version (1.4.14) remonte à septembre 2001.
Sa configuration se fait par le fichier /etc/ippl.conf, je n'ai malheureusement pas trouvé le moyen de limiter son activité à l'interface choisie autrement qu'en donnant son adresse IP, ce qui n'est guère pratique lorsque l'on dispose d'une adresse dynamique.
Il s'agit d'un outil de détection et de prévention d'intrusions. Disposant d'un langage de définition de règles, il travaille un peu comme un antivirus heuristique, en combinant des recherches de signatures et des analyses comportementales. Probablement l'outil le plus utilisé dans le monde, mais pas facile à maitriser.
Un outil de log comme iplog est un bon moyen pour contrôler le trafic. Il ne sait cependant tracer que ce qu'il lui est demandé (ce que vous lui demandez) et uniquement ce qu'il lui est demandé. Ca veut dire deux choses importantes:
Vous apprendrez certainement beaucoup de choses en passant du temps à essayer de maîtriser ce genre d'outils
Un coupe feu actif, en plus de surveiller les connexions entrantes est capable de détecter une activité réputée frauduleuse et y parer de manière dynamique. Il existe sous Linux au moins une application de ce type: « Portsentry »
Portsentry est capable de détecter un « scan » de ports TCP et UDP. La détection peut déclencher plusieurs types de parades:
Bien entendu, ces parades sont configurables.
Portsentry ne semble plus évoluer depuis sa version 1.2 de 2003, mais est toujours disponible sur Debian Etch.
Voyons un peu l'allure de la chaîne INPUT (IPtables):
Chain INPUT (policy ACCEPT) target prot opt source destination REJECT tcp -- anywhere anywhere tcp dpt:telnet reject-with icmp-port-unreachable REJECT tcp -- anywhere anywhere tcp dpt:smtp reject-with icmp-port-unreachable
Les protections sont très simplistes, seuls telnet et smtp sont filtrés.
Portsentry est démarré avec la commande « portsentry -atcp » (Entamer ici une étude détaillée de portsentry nous mènerait trop loin.).
Le démarrage de portsentry ajoute ces lignes au fichier /var/log/messages:
adminalert: Psionic PortSentry is starting. adminalert: Advanced mode will monitor first 1023 ports adminalert: Advanced mode will manually exclude port: 113 adminalert: Advanced mode will manually exclude port: 139 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 21 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 23 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 25 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 53 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 80 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 110 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 111 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 113 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 139 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 143 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 515 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 820 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 901 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 113 adminalert: Advanced Stealth scan detection mode activated. Ignored TCP port: 139 adminalert: PortSentry is now active and listening.
Le scan est démarré avec nmap sur l'hôte « pirate ». Portsentry s'en rend compte et effectue les opérations suivantes:
attackalert: SYN/Normal scan from host: ca-ol-marseille-21-199.abo.wanadoo.fr/213.56.228.199 to TCP port:52 attackalert: Host 213.56.228.199 has been blocked via wrappers with string: « ALL: 213.56.228.199 » attackalert: Host 213.56.228.199 has been blocked via dropped route using command: « /sbin/ipchains -I input -s 213.56.228.199 -j DENY » attackalert: SYN/Normal scan from host: ca-ol-marseille-21-199.abo.wanadoo.fr/213.56.228.199 to TCP port:175 attackalert: Host: ca-ol-marseille-21-199.abo.wanadoo.fr/213.56.228.199 is already blocked Ignoring attackalert: SYN/Normal scan from host: ca-ol-marseille-21-199.abo.wanadoo.fr/213.56.228.199 to TCP port:32 attackalert: Host: ca-ol-marseille-21-199.abo.wanadoo.fr/213.56.228.199 is already blocked Ignoring attackalert: SYN/Normal scan from host: ca-ol-marseille-21-199.abo.wanadoo.fr/213.56.228.199 to TCP port:621 attackalert: Host: ca-ol-marseille-21-199.abo.wanadoo.fr/213.56.228.199 is already blocked Ignoring attackalert: SYN/Normal scan from host: ca-ol-marseille-21-199.abo.wanadoo.fr/213.56.228.199 to TCP port:312 attackalert: Host: ca-ol-marseille-21-199.abo.wanadoo.fr/213.56.228.199 is already blocked Ignoring
Chain INPUT (policy ACCEPT) target prot opt source destination DROP all -- 213.56.228.199 anywhere *** //L'attaquant est bloqué sur tous les ports, sur tous les protocoles, *** quelle que soit la destination//**// REJECT tcp -- anywhere anywhere tcp dpt:telnet reject-with icmp-port-unreachable REJECT tcp -- anywhere anywhere tcp dpt:smtp reject-with icmp-port-unreachable
# # hosts.deny This file describes the names of the hosts which are # *not* allowed to use the local INET services, as decided # by the '/usr/sbin/tcpd' server. # # The portmap line is redundant, but it is left to remind you that # the new secure portmap uses hosts.deny and hosts.allow. In particular # you should know that NFS uses portmap! # ALL: 213.56.228.199
L'attaquant n'aura même pas le temps de finir son scan. il aura l'impression que la cible n'existe plus, tout simplement.
N'est-ce pas joli? Attention toutefois, si la modification de /etc/hosts.deny n'est pas volatile (écriture dans le fichier), il n'en va pas de même pour IPChains. Sans précautions particulières, si la machine est arrêtée, la règle sera perdue. Il existe cependant une parade grâce, par exemple, à la possibilité d'exécuter une commande externe en cas de détection d'attaque. Il suffit de sauvegarder la règle INPUT pour pouvoir la recharger au prochain démarrage. Ceci dit, les attaques venant le plus souvent d'adresses dynamiques, il n'est pas forcément nécessaire de rendre la règle définitive. Par ailleurs, si l'on agit sur IPChains, il n'est pas nécessaire de conserver l'option de modification de /etc/hosts.deny.
Notez tout de même que nous n'avons pas couvert les risques émanant:
Portsentry n'est donc hélas pas un outil miraculeux, il n'en existe d'ailleurs pas.
Fail2ban lit des fichiers de log comme /var/log/pwdfail ou /var/log/apache/error_log et bannit les adresses IP qui ont obtenu un trop grand nombre d'échecs lors de l'authentification. Il met à jour les règles du pare-feu pour rejeter cette adresse IP. Ces règles peuvent êtres définies par l'utilisateur.
Il ne s'agit pas ici de détecter des « scans » mais des tentatives de « loggin ». Lorsque le logiciel détecte un nombre déterminé de loggins ratés dans un temps également déterminé, il peut déclencher un certain nombre d'actions :
Il peut surveiller plusieurs serveurs susceptibles de réclamer un loggin comme Openssh, Apache, Postfix, Proftpd, vsftpd,wuftpd etc.
Voici un exemple de message reçu en cas de détection :
Hi, The IP 62.38.244.99 has just been banned by Fail2Ban after 5 attempts against SSH. Here are more information about 62.38.244.99: % This is the RIPE Whois query server #2. % The objects are in RPSL format. ... ## Suivent les informations recueillies par "hois" Regards,
On ne devrait pas pouvoir se passer de Fail2ban