Première sécurisation NFS   Version imprimable de cet article Enregistrer au format PDF


par Sphix

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 depuis le 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.

Sécurité du serveur : nfsd

Du côté serveur on peut ne pas faire confiance au root du client, avec l’option root_squash 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 l’utilisateur root du serveur peut accéder/modifier. Vous aurez probablement à utiliser cette option sur tous les systèmes de fichiers que vous exportez. J’en entends un déjà 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 quelconque 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 les pages du manuel de ce système.

N’exportez jamais un système de fichiers vers `localhost’ ou 127.0.0.1.

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 utilisé par la plupart des distributions 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.

Toutes les distributions de Linux ne sont pas égales. Certaines apparemment à jour n’incluent pas un portmapper sur, même aujourd’hui, alors que le problème est connu depuis plusieurs années. Au moins une distribution contient même la page de manuel pour un portmapper sûr alors que le portmapper effectivement installé n’est pas sûr. Pour déterminer simplement si votre portmapper est le bon ou pas, lancez strings(1) et voyez s’il lit les fichiers appropriés /etc/hosts.deny et /etc/hosts.allow. Si votre portmapper est /usr/sbin/portmap exécutez la commande strings /usr/sbin/portmap | grep hosts. Sur ma machine cela donne :

/etc/hosts.allow
/etc/hosts.deny
@(#) hosts_ctl.c 1.4 94/12/28 17:42:27
@(#) hosts_access.c 1.20 96/02/11 17:01:27

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

portmap: ALL

qui refusera l’accès à quiconque. Maintenant qu’il est fermé, lancez rpcinfo -p pour vérifier qu’il lit et se conforme au contenu du fichier. rpcinfo ne devrait rien renvoyer, ou peut être un message d’erreur. Il ne devrait pas y avoir besoin de relancer le portmapper.

Fermer le portmapper à tous le monde est peut être un peu excessif, nous ré-ouvrons donc quelque 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 pouvoir 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ériphé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 alphanumérique ex. ftp.lip6.fr donne 132.227.77.2) 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.

NFS et les coupent-feu (firewalls)

C’est une très bonne idée de bloquer 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.

Documentations publiées dans cette rubrique Documentations publiées dans cette rubrique