Linux est un système multiutilisateur. Cela signifie que plusieurs personnes peuvent utiliser l'ordinateur simultanément (et pas uniquement les unes à la suite des autres), et que le système se charge de faire respecter la loi entre elles. Les ressources de la machine sont ainsi partagées équitablement, tant au niveau de la puissance de calcul qu'au niveau de la mémoire, du disque, des imprimantes...
Évidemment, une question se pose : comment plusieurs utilisateurs peuvent-ils se partager le clavier et l'écran ? La réponse est simple : ils ne le peuvent pas. Par conséquent, il n'y a que trois solutions possibles : soit on connecte à l'ordinateur d'autres claviers et d'autres écrans (on appelle un couple clavier/écran un « terminal »), soit on accède au système par l'intermédiaire d'un autre ordinateur via le réseau, soit les utilisateurs lancent tour à tour leurs programmes. La dernière solution nécessite que les programmes ne soient pas interactifs : ils doivent être capable de fonctionner sans intervention de celui qui les a lancés.
La première hypothèse n'est pas sérieuse pour un particulier, il est d'ailleurs assez difficile de connecter un terminal supplémentaire sur un PC (c'est réalisable, soit en connectant un terminal dédié à l'un des ports série, soit en ajoutant une carte graphique PCI et en connectant un deuxième clavier et une deuxième souris, par exemple sur le port USB, et en utilisant une version modifiée de XFree86. Ce n'est donc pas une opération à la portée du commun des mortels.). La deuxième solution, en revanche, est nettement plus envisageable. Il est parfaitement possible qu'un particulier dispose de deux PC connectés en réseau, et que deux membres de la même famille cherchent à utiliser des ressources de la même machine (par exemple, une imprimante ou tout autre périphérique, un programme installé sur un seul ordinateur, des fichiers personnels, etc.). Quant à la troisième solution, elle est du domaine du quotidien, même pour un ordinateur sans réseau et avec un seul utilisateur. En effet, certains programmes sont lancés par le système pour effectuer des tâches de maintenance, et fonctionnent au nom de l'administrateur de la machine.
Il va de soi que pour être multiutilisateur, le système doit satisfaire certains critères :
il doit être multitâche, c'est-à-dire qu'il doit être capable de faire fonctionner plusieurs programmes simultanément sur la même machine, en partageant les ressources de celle-ci ;
il doit être fiable, car un arrêt du système peut déranger un nombre arbitraire de personnes, y compris celles qui ne sont pas à proximité de l'ordinateur ;
il doit être sûr, car il ne faut pas que les erreurs ou les malveillances d'un utilisateur ne puissent déranger les autres.
Le multitâche est assuré au niveau du noyau. Chaque programme en cours d'exécution (on les appelle « processus ») fonctionne dans sa propre zone de mémoire, qui est complètement contrôlée par le noyau. Les ressources du processeur sont partagées entre les processus, et il est impossible à l'un d'entre eux de monopoliser la mémoire, le disque ou quoi que ce soit. Les processus doivent toujours passer par le noyau pour effectuer une opération, ce qui permet un contrôle absolu.
La fiabilité est également assurée au niveau du noyau. Les zones de mémoire utilisées par chaque processus (encore appelées « espaces d'adressage ») sont bien distinctes et bien identifiées par le noyau. Cela implique qu'il est impossible à un processus de perturber le fonctionnement d'un autre processus. Ainsi, si un processus fait une faute, il est purement et simplement terminé par le noyau. Cela est sans appel : le noyau est le seul maître à bord.
Enfin, la sécurité est assurée par le noyau et par le système de fichiers. Au niveau du noyau, chaque utilisateur est identifié de manière unique par un numéro dans le système. Ce numéro est utilisé pour vérifier les droits de l'utilisateur, ou, autrement dit, ce qu'il peut faire. Les droits des utilisateurs comprennent la possibilité de lire ou écrire un fichier, d'accéder ou non à une ressource ou d'exécuter un programme. Il est également possible de créer un ou plusieurs « groupes » d'utilisateurs, et de donner des droits particuliers à ces groupes. Tous les utilisateurs qui font partie de ce groupe recevront les droits du groupe. Ainsi, des classes d'utilisateurs peuvent être facilement définies, et ces classes peuvent se voir attribuer un peu plus de privilèges que les utilisateurs normaux selon les nécessités. Il existe toutefois un utilisateur spécial, qui a tous les droits : l'administrateur du système (« root » en anglais). Aucune restriction ne s'applique à cet utilisateur, car il doit être capable de gérer le système, l'installer, l'arrêter, le mettre à jour si nécessaire, et de définir les utilisateurs et leurs droits.
Au niveau du système de fichiers, la sécurité est assurée par le stockage d'informations additionnelles pour chaque fichier ou répertoire. Ces informations permettent de connaître :
le numéro de l'utilisateur qui possède le fichier ou le répertoire. En général, le propriétaire est simplement celui qui l'a créé. Cependant, l'administrateur peut changer le propriétaire d'un fichier à tout moment ;
le numéro du groupe auquel appartient le fichier ou le répertoire. Tout fichier ou répertoire appartient à un groupe unique, qui est utilisé pour calculer les droits des utilisateurs faisant partie de ce groupe. Par défaut, un fichier nouvellement créé par un utilisateur appartient au groupe des utilisateurs « users », ce qui convient dans la majorité des cas (attention, ce comportement varie selon les systèmes). L'utilisateur peut toutefois donner ses fichiers à n'importe quel groupe dont il fait partie ;
les droits d'accès au fichier ou au répertoire pour le propriétaire, pour les utilisateurs faisant partie du groupe auquel appartient le fichier ou le répertoire, et pour tous les utilisateurs en général. Ces droits comprennent le droit de lecture (représenté par la lettre 'r', pour « Read only »), le droit d'écriture (représenté par la lettre 'w', pour « Writeable »), le droit d'exécution (représenté par la lettre 'x', pour « eXecutable ») et quelques attributs supplémentaires (qui seront détaillés plus loin).
Il n'est sans doute pas inutile de préciser un peu le fonctionnement des droits dans le système de fichiers. Le droit de lecture correspond à la possibilité d'ouvrir et de consulter un fichier, ou de lister le contenu d'un répertoire. Le droit d'écriture correspond à la possibilité de modifier un fichier, ou de créer ou supprimer un fichier d'un répertoire. Enfin, le droit d'exécution correspond à la possibilité d'exécuter un fichier contenant un programme, ou d'entrer dans un répertoire. On notera par exemple qu'il est possible d'obtenir la liste des fichiers d'un répertoire sans pouvoir s'y déplacer, ou encore de modifier un fichier sans pouvoir le lire. On prendra garde également que le fait d'avoir le droit d'écriture sur un fichier ne donne pas le droit de le supprimer (cependant, on peut le vider !). Pour cela, il faut avoir le droit d'écriture sur le répertoire contenant ce fichier. Comme on le voit, les droits d'accès aux fichiers et aux répertoires sont très souples.
Ces droits sont attribués séparément pour le propriétaire, le groupe et les autres utilisateurs (c'est-à-dire les utilisateurs qui ne font pas partie du groupe auquel appartient le fichier). Il est donc possible de donner par exemple tous les droits au propriétaire d'un fichier, et seulement le droit de lecture aux autres utilisateurs. Cette configuration est celle qui est choisie par défaut lors de la création d'un fichier, elle assure que seul le propriétaire peut modifier ou exécuter ce fichier, tout en laissant la possibilité aux autres de le lire. Ce choix privilégie la sécurité des données de chacun en laissant le maximum de liberté aux autres. Si plusieurs personnes doivent travailler sur les mêmes fichiers, il suffit de les regrouper dans un groupe, de donner les fichiers sur lesquels ils doivent travailler à ce groupe, et de donner les droits d'écriture aux membres de ce groupe sur ces fichiers.
La sécurité du système est transitive, cela signifie que tout programme lancé par un utilisateur s'exécute en son nom et reçoit donc les droits de cet utilisateur. Le processus correspondant se voit donc attribuer les mêmes restrictions que l'utilisateur qui l'a lancé. Il dispose également des droits du groupe auquel le fichier du programme appartient. Il existe toutefois quelques exceptions à cette règle, pour les programmes dont le comportement est bien connu et qu'il est impossible de détourner de leur fonction initiale. C'est notamment le cas de quelques commandes systèmes (comme passwd, qui permet de changer de mot de passe), qui peuvent être lancées par les utilisateurs et qui s'exécutent toutefois au nom du système (dans le compte root). Il est donc impossible à un utilisateur de violer les règles de sécurité du système. Pour parvenir à ce comportement, il faut utiliser des attributs spéciaux sur les fichiers de ces programmes. Les attributs spéciaux sont décrits ci-dessous.
Le premier attribut spécial est le bit « setuid » (qui est l'abréviation de l'anglais « SET User IDentifier »). Il ne peut être placé qu'au niveau des droits du propriétaire sur le fichier. Il permet d'indiquer que le fichier est exécutable, et que lorsque le programme qu'il contient est lancé par un utilisateur, le processus correspondant s'exécute avec les droits du propriétaire du fichier et non pas avec ceux de l'utilisateur qui l'a lancé. Cependant, le système conserve tout de même le numéro de l'utilisateur réel qui a lancé le processus, ce qui fait que le programme peut savoir par qui il a été lancé et au nom de qui il s'exécute. Un processus dispose donc toujours de deux numéros d'utilisateur :
le numéro de l'utilisateur réel (« real user id » en anglais), qui est le numéro de l'utilisateur qui a lancé le programme ;
le numéro de l'utilisateur effectif (« effective user id » en anglais), qui est le numéro de l'utilisateur avec les droits duquel le processus fonctionne.
Le bit setuid permet donc simplement d'affecter le numéro du propriétaire du fichier au numéro d'utilisateur effectif du processus lorsqu'il est lancé. Le fait de conserver le numéro de l'utilisateur réel permet au programme de réaliser des vérifications de sécurité additionnelles. Par exemple, la commande passwd, qui permet de changer le mot de passe d'un utilisateur, a besoin des droits de l'utilisateur root pour enregistrer le nouveau mot de passe. Il dispose donc du bit setuid pour que tous les utilisateurs puissent l'utiliser. Cependant, même s'il s'exécute au nom de l'utilisateur root, il ne doit pas permettre à n'importe qui de changer le mot de passe des autres utilisateurs : seul l'utilisateur root a le droit de faire cette opération. Il utilise donc le numéro de l'utilisateur réel qui a lancé la commande pour savoir si c'est bien l'utilisateur root qui l'a lancé.
Le bit setuid est l'attribut le plus couramment utilisé, essentiellement pour certaines commandes systèmes. Il est représenté par la lettre 's' (comme « Setuid »), et il remplace le droit d'exécution ('x') des fichiers pour le propriétaire des fichiers (rappelons que le bit setuid implique que le fichier est exécutable). Il n'a aucune signification pour les répertoires.
Le deuxième attribut spécial est le bit « setgid » (qui est l'abréviation de l'anglais « SET Group IDentifier »). Ce bit fonctionne un peu de la même manière que le bit setuid, à ceci près qu'il fixe le numéro de groupe effectif du processus lancé à celui de son fichier exécutable. Cet attribut est également représenté par la lettre 's', et remplace le droit d'exécution ('x') pour les utilisateurs du groupe auquel appartient le fichier exécutable. De plus, et contrairement au bit setuid, ce bit a une signification pour les répertoires. Un répertoire disposant du bit setgid permet de faire en sorte que tous les fichiers qui sont créés dans ce répertoire se voient automatiquement attribués le même groupe que le répertoire. Ce bit est relativement peu utilisé.
Enfin, le troisième et dernier attribut spécial est le bit « sticky ». Cet attribut remplace l'attribut exécutable pour les autres utilisateurs que le propriétaire du fichier ou du répertoire et les membres du groupe auquel il appartient. Contrairement aux bits setuid et setgid, il est représenté par la lettre 't' (pour « sTickky »). Sa signification est assez spéciale : elle permet de faire en sorte que les programmes restent chargés en mémoire après leur terminaison, ce qui permet de les relancer plus rapidement. Afin de ne pas consommer la mémoire de manière permanente, le code du programme est placé automatiquement dans le swap s'il n'est toujours pas relancé après un certain temps, mais même dans ce cas, tous les calculs de chargement sont déjà effectués. Le lancement des programmes marqués de ce bit sera donc toujours accéléré. Sachez cependant ne pas abuser du bit sticky car la mémoire (même virtuelle) est encore une ressource rare. Pour les répertoires, sa signification est totalement différente : elle permet de restreindre les droits des utilisateurs sur les répertoires ayant ce bit positionné. Ce bit fait en sorte que même si un utilisateur dispose des droits d'écriture sur le répertoire, il ne peut pas supprimer tous les fichiers de ce répertoire. Les seuls fichiers qu'il est autorisé à supprimer sont ses propres fichiers. Bien entendu, il est toujours possible d'ajouter des fichiers dans le répertoire en question.
En pratique, les utilisateurs n'ont pas à se soucier des attributs des fichiers, et en fait même l'administrateur laisse souvent les attributs par défaut, car ils correspondent à la majorité des besoins de sécurité. L'administrateur a cependant le contrôle total sur les droits d'accès aux fichiers, sur le propriétaire et le groupe de chaque fichier. Il est également le seul utilisateur capable de créer un autre utilisateur ou un groupe, ainsi que de les détruire.
Les questions qui se posent évidemment sont les suivantes. Est-ce qu'un particulier a besoin de tout cela ? Ces fonctionnalités ne sont-elles pas réservées aux serveurs ? Est-ce qu'on ne risque pas de perdre beaucoup de temps pour définir les droits pour chaque utilisateur et pour chaque ressource du système ? La gestion de la sécurité ne consomme-t-elle pas trop de ressources ? Ces questions sont légitimes, mais en fait, il est très intéressant même pour un particulier de disposer de ces fonctionnalités. En effet, la sécurité permet tout simplement de protéger le système contre ses propres erreurs. Qui n'a pas effacé un jour un fichier important ou déplacé le répertoire Windows en bougeant légèrement la souris lors d'un double clic effectué trop lentement ? Avec Linux, on peut faire n'importe quoi, on est certain que le système restera intact. D'ailleurs la règle essentielle, même pour un ordinateur utilisé par une seule personne, est de toujours créer un compte utilisateur normal et de ne jamais travailler sous le compte root. Cette sécurité est telle que Linux est le système d'exploitation idéal pour apprendre l'informatique à quelqu'un : savoir que le système protège tout ce qui est important permet aux débutants de prendre des initiatives sans crainte. Quant aux éventuels revers de médaille, ils sont absents : la gestion de la sécurité ne consomme quasiment aucune ressource, et sa configuration est élémentaire. Toutes les distributions s'installent de telle sorte que le système se protège des utilisateurs, et que ceux-ci soient indépendants les uns des autres.
En résumé :
le multitâche est un confort indéniable. Il est appréciable de pouvoir utiliser son ordinateur même lorsqu'il est en train de faire une tâche longue en arrière-plan ;
la fiabilité est évidemment indispensable. Il est rassurant de se dire que même si un processus très gourmand en ressources fonctionne en arrière-plan, il ne perturbera pas les autres processus ;
la sécurité permet de se protéger de ses propres erreurs, pour un coût minimal. Il suffit de conserver les paramètres par défaut du système et de ne plus s'en soucier !
Précédent | Sommaire | Suivant |
Concepts de base | Niveau supérieur | Fonctionnalités des systèmes de fichiers |