5. NFS et la sécurité

Contenu de cette section

Je ne suis en aucun cas un expert en sécurité informatique. Mais j'ai traîné dans le secteur et j'ai un petit conseil pour ceux qui se préoccupent de la sécurité. Mais attention. Ce n'est pas absolument pas une liste complète des problèmes liés à NFS et si vous pensez être en sécurité une fois que vous avez lu et mis en pratique tout ceci alors j'ai un pilier de pont (presque neuf) à vous vendre.

Cette section n'a probablement pas d'intérêt si vous êtes sur un réseau fermé où vous avez confiance en tous les utilisateurs, et que personne en qui vous n'avez pas confiance ne peut obtenir un accès sur les machines du réseau. I.e., il ne devrait y avoir aucun moyen de se connecter à votre réseau depuis l'extérieur et il ne devrait être relié à aucun autre réseau où vous n'avez pas confiance en tous les utilisateurs et en sa sécurité. Vous pensez que je suis parano ? Je ne suis pas du tout parano. C'est un conseil de sécurité de base. Et rappelez-vous que c'est juste le commencement. Un site sûr nécessite un administrateur consciencieux et bien informé qui sait où trouver l'information sur les problèmes de sécurité existants ou potentiels.

Un problème de base de NFS est que le client, si on ne lui demande pas le contraire, fera confiance au serveur NFS et vice-versa. Ça peut être mauvais. Cela signifie que si le compte root du serveur est cassé (broken into) il peut être très facile de casser le compte root du client. Et vice versa. Il y a quelques moyens de gérer ce problème sur lesquels nous reviendrons.

Les documents consultatifs (advisories) du CERT sur NFS sont une bonne source d'information, la plupart des problèmes (et des solutions) évoquées ci-dessous sont traités dans ces documents. Voyez ftp.cert.orf/01-README pour une liste à jour. En voici quelques-uns liés à NFS (il n'y a pas à ma connaissance de version française) :


CA-91:21.SunOS.NFS.Jumbo.and.fsirand                            12/06/91
     Vulnerabilities concerning Sun Microsystems, Inc. (Sun) Network
     File System (NFS) and the fsirand program.  These vulnerabilities
     affect SunOS versions 4.1.1, 4.1, and 4.0.3 on all architectures.
     Patches are available for SunOS 4.1.1.  An initial patch for SunOS
     4.1 NFS is also available. Sun will be providing complete patches
     for SunOS 4.1 and SunOS 4.0.3 at a later date.

CA-94:15.NFS.Vulnerabilities                                    12/19/94
     This advisory describes security measures to guard against several
     vulnerabilities in the Network File System (NFS). The advisory was
     prompted by an increase in root compromises by intruders using tools
     to exploit the vulnerabilities.

CA-96.08.pcnfsd                                                 04/18/96
     This advisory describes a vulnerability in the pcnfsd program (also
     known as rpc.pcnfsd). A patch is included.

5.1 Sécurité du client

Du côté client il y a quelques options de mount qui permettent de ne pas faire trop confiance au serveur. L'option nosuid interdit le démarrage de programmes suid du système de fichiers NFS. C'est une option à utiliser systématiquement, car elle empêche le root du serveur de créer un fichier suid sur le système de fichiers NFS, puis de se loger dans le client en utilisateur et de lancer le programme suid pour devenir root sur le client. Il est aussi possible d'interdire l'exécution des fichiers du système de fichiers NFS avec l'option noexec. Mais ceci est beaucoup moins utile que nosuid car le système de fichiers contiendra très probablement au moins quelques scripts ou programmes à exécuter. Ces options se rentrent dans la colonne d'options, avec wsize et rsize, séparées par des virgules.

5.2 Sécurité du serveur : nfsd

Du côté serveur on peut ne pas faire confiance au root du client, avec l'option root_squash (rembarrage du root :-) dans le fichier exports :


/mn/eris/local apollon(rw, root_squash)

Dans ce cas, si un utilisateur du client avec l'UID 0 essaye d'accéder (en lecture, écriture ou effacement) au système de fichiers, le serveur remplace l'UID par celui de l'utilisateur 'nobody' du serveur. Ceci signifie que l'utilisateur root du client ne peut accéder/modifier les fichiers du serveur que seul le root du serveur peut accéder/modifier. C'est bien, et vous aurez probablement à utiliser cette option sur tous les systèmes de fichiers que vous exportez. J'en entends un qui me dit : "Mais l'utilisateur root du client peut toujours utiliser 'su' pour devenir n'importe qui et accéder à ses fichiers !" Et là je réponds : "Oui, c'est comme ça, c'est Unix." Ceci a une conséquence importante : tous les fichiers et binaires importants devraient appartenir à root, et pas bin ou un compte autre que root, car le seul compte auquel le root du client ne peut pas accéder est le compte root du serveur. Plusieurs autres options permettant de ne pas faire confiance à qui ne vous plait pas sont énumérées dans la page de manuel nfsd. Il y a aussi des options pour rembarrer (to squash) des intervalles d'UID ou GID.

Il est important aussi de s'assurer que nfsd vérifie que toutes les requêtes viennent d'un port privilégié. S'il accepte les requêtes de n'importe quel port du client, un utilisateur simple peut exécuter un programme qu'il est facile de se procurer sur l'Internet. Il parle le protocole NFS et pourra prétendre être n'importe qui et être cru. Ça fait peur hein ? Le nfsd Linux effectue cette vérification par défaut, sur d'autres systèmes d'exploitation il faut la valider. Ça devrait être décrit dans la page man de ce système.

Autre chose. N'exportez jamais un système de fichiers vers 'localhost' ou 127.0.0.1. Croyez-moi.

5.3 Sécurité du serveur : le portmapper

Le portmapper de base, en combinaison avec nfsd présente un problème de conception qui rend possible de récupérer les fichiers d'un serveur NFS sans avoir aucun privilège. Heureusement le portmapper de Linux est relativement sûr vis à vis de cette attaque, et peut être sécurisé en configurant les listes d'accès au moyen de deux fichiers.

Tout d'abord, éditons /etc/hosts.deny. Il devrait contenir la ligne:


portmap: ALL

qui refusera l'accès à quiconque. C'est peut être un peu excessif, nous ré-ouvrons donc un peu l'accès en éditant le fichier /etc/hosts.allow. Mais il faut d'abord savoir ce qu'on va y mettre. À la base, il devrait contenir les noms de toutes les machines qui doivent avoir accès à votre portmapper. Sur le système Linux moyen il y a très peu de machines qui ont une bonne raison de demander cet accès. Le portmapper administre nfsd, mountd, ypbind/ypserv, pcnfsd et les services "en r" comme ruptime et rusers. Parmis ceux-ci, seuls nfsd, mountd, ypbind/ypserv et peut-être pcnfsd ont de l'importance. Toutes les machines qui ont besoin d'accéder à ces services sur votre machine devraient y être autorisées. Disons que votre machine est 129.240.223.254 et que tout ce qui vit sur le sous réseau 129.240.223.0 doit pourvoir y accéder (si ceci n'est pas clair pour vous, voyez le HOWTO réseau). On écrit :


portmap: 129.240.223.0/255.255.255.0

dans hosts.allow. C'est l'adresse de réseau que vous donnez aussi à la commande route et le masque de réseau que vous donnez à ifconfig. Pour le périférique eth0 sur cette machine ifconfig devrait donner :


...
eth0      Link encap:10Mbps Ethernet  HWaddr 00:60:8C:96:D5:56
          inet addr:129.240.223.254  Bcast:129.240.223.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:360315 errors:0 dropped:0 overruns:0
          TX packets:179274 errors:0 dropped:0 overruns:0
          Interrupt:10 Base address:0x320 
...

et netstat -rn devrait donner :


Kernel routing table
Destination     Gateway         Genmask         Flags Metric Ref Use    Iface
...
129.240.223.0   0.0.0.0         255.255.255.0   U     0      0   174412 eth0
...

(Adresse réseau dans la première colonne).

Les fichiers hosts.deny et hosts.allow sont décrits dans les pages de manuel de mêmes noms.

IMPORTANT : ne rien mettre d'autre que des adresses IP (numériques) dans les lignes portmap de ces fichiers. Les host name lookup (recherche d'adresse IP (numérique) à partir de l'adresse symbolique) peuvent indirectement déclencher une activité portmap qui déclenchera un host name lookup qui déclenchera...

Ceci fait, votre serveur devrait être un peu plus solide. Le dernier problème (mais oui !) est que quelqu'un casse le compte root (ou boute MS-DOS) sur une machine de confiance et utilise ce privilège pour envoyer des requêtes depuis un port sûr en se faisant passer pour n'importe quel utilisateur.

5.4 NFS et les coupent-feu (firewalls)

C'est une très bonne idée de firewaller les ports NFS et portmap dans votre routeur ou firewall. nfsd utilise le port 2049, que ce soit avec tcp ou udp. Le portmapper est au port 749 (tcp et udp) et mountd aux port 745 et 747 (tcp et udp). Vérifiez les ports avec la commande rpcinfo -p.

Si au contraire vous voulez que NFS traverse un firewall, il existe des options sur les nfsd et mountd récents pour leur spécifier le port à utiliser. Vous pouvez donc choisir un port qui ne soit pas bloqué par le firewall.

5.5 Résumé

Si vous configurez correctement votre installation portmapper/NFS avec hosts.allow/deny, root_squash, nosuid et les ports privilégiés, vous évitez beaucoup des bogues connues de NFS et pouvez presque vous sentir en sécurité au moins pour ça. Mais de toutes façons : quand un intrus obtient l'accès à votre réseau, il/elle peut faire apparaître des commandes bizarres dans votre .forward ou dans votre fichier mailbox quand /home ou /var/spool/mail sont montés par NFS. Pour la même raison, vous ne devriez jamais accéder à votre clé privée PGP par NFS. Ou au moins vous devez savoir quel est le risque. Et maintenant vous savez un peu.

NFS et le portmapper constituent un système complexe et il n'est donc pas totalement exclu que de nouvelles bogues soient découvertes, soit dans la conception soit dans l'implémentation que nous utilisons. Il pourrait même y avoir des défauts de sécurité connus, que quelqu'un utilise. Mais c'est la vie. Pour vous tenir au courant, vous devriez au moins lire les forums comp.os.linux.announce et comp.security.announce comme minimum absolu (en français, consultez fr.comp.os.linux.annonces ).


Chapitre suivant, Chapitre Précédent

Table des matières de ce chapitre, Table des matières générale

Début du document, Début de ce chapitre