Protections

Savoir ce qui est installé

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é.

Construire une barrière

Etat des lieux

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é:

  • SAMBA, pour communiquer avec le réseau Microsoft.
  • APACHE, pour tester ses pages web sur un serveur classique de l'Internet
  • WU-FTPD, serveur FTP pour pouvoir charger ses pages HTML avec les outils de FrontPage.
  • BIND, pour avoir son propre DNS,
  • POSTFIX, pour avoir son propre serveur SMTP,
  • VNC SERVER pour ouvrir des sessions X depuis les postes Microsoft du réseau privé.
  • Et j'en passe…

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).

Démonstration

Un scan de ports avec « nmap » De quoi vraiment donner envie de s'y intéresser de plus près!

  • 21, c'est WU-FTPD
  • 23, Telnet, ah! nous verrons ça…
  • 25 C'est Postfix, faudra voir si ce ne serait pas un « open relay » :-)
  • 53 Tiens, il y a un DNS, intéressant.
  • 80, sans doute apache.
  • 139, Ce monsieur a installé SAMBA. Bon, ça suffit comme ça pour l'instant. Exploitons un peu le sujet…

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.

Construction de barrières

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é :

  • En entrée, on accepte tout par défaut (comme c'était dans l'exemple précédent),
  • en sortie, on laisse tout passer aussi,
  • au travers de la passerelle (le routage entre le Net et le réseau privé), on n'accepte rien, mais on va faire du masquage d'adresse pour tout ce qui vient du réseau privé et va vers le Net,

Ensuite, pour tout ce qui vient du Net, nous bloquerons en UDP comme en TCP les ports :

  • 21 tcp, qui est le port de commande FTP,
  • 23 tcp, qui est le port Telnet,
  • 25 tcp, qui est le port SMTP,
  • 110 tcp, qui est le port POP3,
  • 111 tcp/udp qui est le port des « Remote Procedure Call »,
  • 135 à 139 tcp/udp, des ports utilisés par NetBIOS,
  • 143 tcp, le port IMAP,
  • 6000 à 6009 tcp, les ports utilisés pour le serveur graphique.
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 ».

Conclusion

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.

Les miradors du Net

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.

Les « loggers »

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.

IPTRAF

C'est peut-être le plus « convivial » mais pas forcément le plus paramétrable. Il fonctionne bien en mode texte mais présente quelques bugs d'affichage dans une console sous X, suivant la taille de la fenêtre.
Les « anciens » de MS DOS retrouveront avec nostalgie les menus arborescents en mode caractère…
Ici, il est possible de choisir les protocoles à tracer.
Malheureusement, s'il est possible de définir des filtres personnalisés pour UDP, l'option n'existe pas pour les autres protocoles.
Il est également possible de choisir l'interface que l'on souhaite tracer
Voici un exemple de trace. Si les connexions TCP sont affichées de manière très lisible, il n'en va malheureusement pas de même pour les autres protocoles

IPPL

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.

Snort

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.

Conclusions

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:

  • Il tracera des événements qui n'en valent peut-être pas la peine. Si vous lui demandez de tracer tout trafic sur une interface, il le fera. Les logs de la journée risqueront peut-être de peser plusieurs Mo et seront inexploitables, autrement que par des filtres qu'il vous faudra écrire.
  • Il ne tracera peut-être pas des événements qu'il aurait été important de ne pas rater.


Vous apprendrez certainement beaucoup de choses en passant du temps à essayer de maîtriser ce genre d'outils

Les Coupe feux actifs

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, le pompier du Net

Portsentry est capable de détecter un « scan » de ports TCP et UDP. La détection peut déclencher plusieurs types de parades:

  • Un simple « log » via syslogd. Dans ce cas, Portsentry agit comme un simple « loggeur », un peu léger toutefois, puisqu'il ne sait pas traiter les activités ICMP.
  • Une inscription du scanner dans « hosts.deny », pour qu'il soit pris en compte par le « TCP Wrapper »
  • L'ajout d'une règle dans la chaîne « input » d'IPtables pour bloquer l'intrus.
  • La modification de la route par défaut dans un « black hole » de manière à ce qu'une éventuelle réponse à l'intrus soit dirigée vers nulle part.
  • Le déclenchement d'une commande externe pouvant être, par exemple, la désactivation pure et simple de l'interface réseau.

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.

Juste un exemple

  • Dans le rôle de l'intrus: 213.56.228.199. Une machine Linux équipée du scanner « nmap ».
  • Dans le rôle du défenseur, une autre machine Linux, équipée de portsentry. La configuration est à peu de choses près celle qui est donnée par défaut dans le paquetage rpm pour Mandrake. En cas de détection de scan, portsentry va réagir de la manière suivante:
    • Inscription de l'intrus dans /etc/hosts.deny »
    • Ecriture d' une règle de blocage dans IPChains (fonctionne aussi avec IPTables).

Avant l'attaque

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.

L'attaque a lieu...

Le scan est démarré avec nmap sur l'hôte « pirate ». Portsentry s'en rend compte et effectue les opérations suivantes:

  • Les lignes qui suivent sont ajoutées au journal /var/log/messages
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
  • La règle suivante est ajoutée dans la chaîne INPUT d'IPchains:

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

  • Le fichier /etc/hosts.deny est modifié de la manière suivante :

#
# 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

Bilan

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:

  • D'un scan UDP.
    C'est généralement moins dangereux, mais pas à négliger tout de même. Portsentry peut également être démarré pour surveiller les ports UDP, mais le fonctionnement est plus délicat et peut provoquer des réactions parasites.
  • D'une attaque ICMP
    Portsentry ne sait rien faire contre ça. Il ne vous reste de ce côté qu'à écrire des règles correctes.
  • D'une attaque sans qu'il y ait de scan préalable

Portsentry n'est donc hélas pas un outil miraculeux, il n'en existe d'ailleurs pas.

Fail2ban

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 :

  • écriture d'une règle IPtables pour bloquer la source, pendant une durée paramétrable ;
  • envoi d'un message d'alerte à l'administrateur

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 :-P