Gestion des droits d'accès aux fichiers
Droits Unix
Les droits Unix permettent de donner des droits d'accès différents en lecture, écriture et/ou exécution aux catégories suivantes :
- au propriétaire du fichier (
user), - aux utilisateurs appartenant au même groupe Unix que le propriétaire du fichier (
group), - à tous les autres utilisateurs (
other).
Il suffit d'utiliser la commande chmod pour modifier les droits Unix (pour plus d'informations, voir man chmod).
La plupart du temps, les droits Unix vous suffiront. Si vous avez besoin de contrôler plus finement les accès à vos données, par exemple pour n'ouvrir l'accès à un répertoire qu'à un seul autre utilisateur (quel que soit son groupe Unix), il faudra utiliser une ACL (Access Control List).
Access Control List (ACL)
Il est possible de créer une Access Control List (ACL) sur un répertoire ou un fichier pour en ouvrir l'accès en lecture, écriture et/ou exécution à n'importe quel autre utilisateur ou groupe.
Inversement, une ACL peut aussi servir à imposer des restrictions d'accès sur certains fichiers ou répertoires à l'aide de masques spécifiant des "droits maximaux" attribuables (voir section Dépendances entre ACL et droits Unix (pour utilisateurs avertis)).
Visualisation des ACL
La commande getfacl (pour plus d'information, voir man getfacl)
donne un affichage détaillé des ACL positionnées sur un fichier ou un
répertoire donné :
getfacl <file|directory>
- ACL positionnée par défaut sur un fichier
- ACL positionnée par défaut sur un répertoire
$ getfacl myfile
# file: myfile
# owner: user1
# group: group1
user::rw-
group::r--
other::---
$ getfacl mydirectory
# file: mydirectory
# owner: user1
# group: group1
user::rwx
group::r-x
other::---
Les droits rwx ont les mêmes significations que les droits Unix classiques rwx.
Le but est d'ouvrir les accès à un fichier ou répertoire au-delà du propriétaire et du groupe propriétaire actuels en enrichissant les ACL associées. Nous expliquons comment faire cela dans la section Gestion des ACL.
- Exemple d'ACL enrichie positionnée sur un fichier
- Exemple d'ACL enrichie positionnée sur un répertoire
$ getfacl myfile
# file: myfile
# owner: user1
# group: group1
user::rw-
user:user2:rw-
user:user3:r--
user:user4:r--
group::r--
group:group2:r--
group:group3:r--
mask::rw-
other::r--
$ getfacl mydirectory
# file: mydirectory
# owner: user1
# group: group1
user::rwx
user:user2:r-x
user:user3:r-x
user:user4:r-x
group::r-x
group:group2:rwx
group:group3:r-x
mask::rwx
other::r-x
L'option -l de la commande ls permet d'afficher les droits
Unix classiques mais aussi de voir si des ACL sont positionnées. Dans ce cas, un
signe + apparaît juste après les droits Unix.
$ ls -ld repertoire_avec_acl repertoire_sans_acl
drwxr-x---+ 2 user1 group1 8192 2014-03-29 11:00 repertoire_avec_acl
drwxr-x--- 2 user1 group1 8192 2014-03-29 11:00 repertoire_sans_acl
$ ls -l fichier_avec_acl fichier_sans_acl
-rwx------+ 2 user1 group1 8192 2014-03-29 11:00 fichier_avec_acl
-rwx------ 2 user1 group1 8192 2014-03-29 11:00 fichier_sans_acl
Gestion des ACL
Si l'on désire donner des droits d'accès à un utilisateur et/ou un groupe donné, on peut définir une ACL (Access Control List)
via la commande setfacl sur le fichier ou le répertoire voulu.
Une présentation de cette commande est fournie ci-dessous. Pour plus de détails, vous pouvez taper la commande man setfacl.
La syntaxe générale est la suivante :
setfacl <ACL_options> <file|directory>
où <ACL_options> peut avoir l'une des formes suivantes :
-
pour créer ou remplacer une ACL existante :
--set=<arguments> -
pour modifier une ACL existante :
-m <arguments> -
pour supprimer une ACL existante :
-b
La liste des champs <arguments> possibles est la suivante :
u(comme user) SANS mention de l'utilisateur correspond aux droits donnés au propriétaire du fichier ou du répertoire :u::[r|-][w|-][x|-];remarquePour un répertoire (ou un exécutable), nous vous conseillons de positionner
u::rwxet pour un fichieru::rw-.dangerSans ces droits, le propriétaire ne peut plus accéder au fichier ou répertoire. Il est alors bloqué par les ACL même si les droits Unix sont bien positionnés.
g(comme group) SANS mention de groupe correspond aux droits donnés au groupe propriétaire du fichier :g::[r|-][w|-][x|-];o(comme other) SANS aucune mention correspond aux droits donnés aux utilisateurs qui ne sont pas mentionnés dans les champsuetg:o::[r|-][w|-][x|-];u(comme user) AVEC mention de l'utilisateur correspond aux droits donnés à un utilisateur particulier (iciuserX) :u:userX:[r|-][w|-][x|-];g(comme group) AVEC mention du groupe correspond aux droits attribués à l'ensemble des utilisateurs du groupe Unix spécifié (icigroupX) :g:groupX:[r|-][w|-][x|-];m(comme mask) définit les droits maximaux (ou effectifs) des utilisateurs concernés par les champsu:userX:...et/oug:groupX:....importantIl est conseillé de :
- renseigner vous-même ce champ à chaque modification d'ACL afin d'éviter qu'une valeur par défaut soit définie et ne soit pas cohérente avec vos besoins ;
- donner au masque les droits les plus élevés (
m::rwx) pour ne pas restreindre les droits donnés à un utilisateur et/ou à un groupe.
attentionSi le champ mask est vide (
m::---), les droits d'accès ouverts grâce aux champsuavec mention de l'utilisateur ougavec mention du groupe sont inopérants. Voir la section Dépendances entre ACL et droits Unix (pour utilisateurs avertis) pour plus de détails.
Pour positionner une nouvelle ACL avec la commande setfacl --set=<argument>, les trois premiers champs u sans mention de l'utilisateur, g sans mention du groupe et o sont obligatoires.
Par exemple, la commande suivante donne tous les droits au propriétaire (u::rwx) sur le répertoire mon_repertoire, permet aux membres du groupe propriétaire de consulter le contenu du répertoire en lecture uniquement (g::r-x), et ferme les accès aux autres utilisateur (o::---) :
setfacl --set=u::rwx,g::r-x,o::--- mon_repertoire
Les accès aux sous-répertoires et aux fichiers contenus dans mon_repertoire restent alors contrôlés par les droits Unix. Voir la section Conseils sur l'utilisation des ACL pour plus de détail à ce sujet.
Lorsque vous positionnez des droits ACL sur un répertoire (par exemple $WORK/sub_dir/shared_dir/) ou un fichier (par exemple $WORK/sub_dir/shared_file.h5), vous devez aussi positionner les droits ACL permettant de traverser chacun des répertoires qui composent le chemin d'accès à ce répertoire ou fichier (pour cet exemple $WORK/ et sub_dir/). Sans cela, l'accès sera refusé.
L'utilisation de la commande setfacl avec ces trois seuls champs donne les mêmes permissions que la commande chmod et présente donc peu d'intérêt. Pour élargir les droits d'accès, il faut ajouter les champs u avec mention de l'utilisateur, g avec mention du groupe et/ou le champs m.
Ajout d'un user
Par exemple, si user1 veut donner des droits d'accès en lecture et écriture à l'utilisateur user2 sur son répertoire DIR_user1, il doit utiliser la commande setfacl suivante :
[user1@hostname:~]$ cd $DIR_user1
[user1@hostname:~]$ setfacl --set=u::rwx,u:user2:rwx,g::r-x,o::---,m::rwx .
Il pourra ensuite contrôler les droits ACL positionnés avec la commande
getfacl :
[user1@hostname:~]$ cd $DIR_user1
[user1@hostname:~]$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
user:user2:rwx
group::r-x
mask::rwx
other::---
Lecture de la sortie :
- avec le champ
u::rwx, le propriétaireuser1a les droitsrwxsur son répertoireDIR_user1; - avec le champ
g::r-x, les utilisateurs appartenant au groupe propriétaire (group1) ont les droitsr-x: ils peuvent donc traverser le répertoire et lire son contenu mais pas y écrire ; - avec le champ
o::---, aucun autre utilisateur n'a le moindre droit sur ce répertoire ; - avec le champ
u:user2:rwx,user1ajoute les droitsrwxuniquement pour l'utilisateuruser2: celui-ci peut donc lire et écrire dans le répertoireDIR_user1; - avec le champ
m::rwx: les droits maximaux autorisés pour les utilisateurs extérieurs au groupe propriétaire sontrwx.
Ajout d'un group
Par exemple, si user1 veut donner des droits d'accès particuliers au
groupe group3 sur son répertoire DIR_user1, il doit utiliser la
commande setfacl suivante :
[user1@hostname:~]$ cd $DIR_user1
[user1@hostname:~]$ setfacl --set=u::rwx,g::r-x,g:group3:r-x,o::---,m::rwx .
Il pourra ensuite contrôler les droits ACL positionnés avec la commande
getfacl :
[user1@hostname:~]$ cd $DIR_user1
[user1@hostname:~]$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
group::r-x
group:group3:r-x
mask::rwx
other::---
Lecture de la sortie :
- avec le champ
u::rwx, le propriétaireuser1a les droitsrwxsur son répertoireDIR_user1; - avec le champ
g::r-x, les utilisateurs appartenant au groupe propriétaire (group1) ont les droits'' r-x'' : ils peuvent donc traverser le répertoire et lire son contenu mais pas y écrire ; - avec le champ
o::---, aucun autre utilisateur n'a le moindre droit sur ce répertoire ; - avec le champ
g:group3:r-x,user1ajoute les droitsr-xpour les utilisateurs appartenant au groupegroup3: ils peuvent donc traverser le répertoire et voir son contenu mais pas y écrire ; - avec le champ
m::rwx: les droits maximaux autorisés pour les utilisateurs extérieurs au groupe propriétaire sontrwx.
Mise à jour d'une ACL
Pour modifier les ACL, vous pouvez utiliser la commande setfacl avec
soit :
- l'option
--set=...: les ACL existantes sont alors écrasées. Dans ce cas, il faut toujours au moins spécifier les champsu::rwx,g::...,o::---et le masquem::rwxpour être sûr que les droits ACL positionnés pour le(s) utilisateur(s) et/ou le(s) groupe(s) spécifié(s) seront réellement effectifs. - l'option
-m ...: les ACL existantes sont alors modifiées.
Par exemple, positionnons dans un premier temps des ACL sur le répertoire MY_DIR pour le groupe Unix group3 via l'option --set=
$ cd MY_DIR
$ setfacl --set=u::rwx,g::r-x,g:group3:r-x,o::---,m::rwx .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
group::r-x
group:group3:r-x
mask::rwx
other::---
Puis modifions les ACL en remplaçant le groupe Unix group3 par group4 via l'option --set=
$ cd MY_DIR
$ setfacl --set=u::rwx,g::r-x,g:group4:r-x,o::---,m::rwx .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
group::r-x
group:group4:r-x
mask::rwx
other::---
Enfin, modifions les ACL en ajoutant un second groupe group2 mais via l'option -m qui nous évite de tout spécifier :
$ cd MY_DIR
$ setfacl -m g:group2:r-x .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
group::r-x
group:group2:r-x
group:group4:r-x
mask::rwx
other::---
Suppression d'une ACL
Pour supprimer les ACL, vous pouvez utiliser la commande setfacl avec
l'option -b. Par exemple :
$ cd MY_DIR
$ ls -ld .
drwxr-x---+ 2 user1 group1 8192 2014-03-29 11:00 .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
group::r-x
group:group3:r-x
mask::rwx
other::---
$ setfacl -b .
$ ls -ld .
drwxr-x--- 2 user1 group1 8192 2014-03-29 11:00 .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
group::r-x
other::---
Conseils sur l'utilisation des ACL
Nous vous conseillons de placer une ACL uniquement sur le répertoire racine de l'arborescence à partager pour en filtrer l'accès, puis de positionner ensuite les droits Unix sur les fichiers et sous-répertoires qu'elle contient à l'aide de la commande chmod.
Par exemple, si le compte user1 désire partager une arborescence de fichiers contenue dans ROOT_TREE avec le compte user3 et le groupe Unix group2 :
[user1@hostname:~]$ cd ROOT_TREE
[user1@hostname:~]$ setfacl --set=u::rwx,u:user3:rwx,g::r-x,g:group2:r-x,o::---,m::rwx .
[user1@hostname:~]$ ls -l .
drwxrwx---+ 0 user1 group1 4096 2014-03-30 11:46 .
-rwxr-xrwx 0 user1 group1 1001 2014-03-30 11:46 file1
drwxrwxrwx 0 user1 group1 4096 2014-03-30 11:46 SUB_DIR
[user1@hostname:~]$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
user:user3:rwx
group::r-x
group:group2:r-x
mask::rwx
other::---
Si on analyse ces droits d'accès, on voit que :
Droits ACL sur ROOT_TREE | Droits Unix sur file1 | Droits Unix sur SUB_DIR | |
|---|---|---|---|
user3 | rwx(ligne user:user3: de l'output de getfacl) | rwx(champ other de l'output de ls pour file1) | rwx(champ other de l'output de ls pour SUB_DIR) |
group1 | r-x(ligne group:: de l'output de getfacl) | r-x(champ group de l'output de ls pour file1) | rwx(champ group de l'output de ls pour SUB_DIR) |
group2 | r-x(ligne group:group2: de l'output de getfacl) | rwx(champ other de l'output de ls pour file1) | rwx(champ other de l'output de ls pour SUB_DIR) |
- L'utilisateur
user3a les ACLrwxsur le répertoireROOT_TREEet les droits Unixrwx(champ other) sur le fichierfile1. Il peut ainsi accéder en lecture et écriture au fichierfile1contenu dans leROOT_TREEdeuser1. Notez qu'il peut aussi créer de nouveaux fichiers et des répertoires sousROOT_TREEdeuser1grâce aux ACLrwx. De plus, il peut aussi voir et modifier le contenu des sous-répertoires tel queSUB_DIRpour lesquels les droits Unix (champ other) l'y autorisent. - Le groupe propriétaire (
group1) a les ACLr-xsurROOT_TREEet les droits Unixr-x(champ group) sur le fichierfile1. Les membres du groupegroup1peuvent donc traverserROOT_TREEet lirefile1mais pas y écrire (donc pas le modifier). De plus, ils ne peuvent rien créer directement dansROOT_TREEdeuser1(ACLr-x). Mais ils peuvent voir et modifier le contenu des sous-répertoires tel queSUB_DIRpour lesquels les droits Unix (champ group) les y autorisent. - Par contre le groupe
group2a les ACLr-xsurROOT_TREEet les droits Unixrwx(champ other) sur le fichierfile1. Les membres du groupegroup2peuvent donc traverserROOT_TREEet lire ou écrire (donc modifier ou écraser)file1, ce qui n'est peut-être pas souhaité. Mais, commegroup1, ils ne peuvent rien créer directement dans leROOT_TREEdeuser1(ACLr-x). Mais ils peuvent voir et modifier le contenu des sous-répertoires tel queSUB_DIRpour lesquels les droits Unix (champ other) les y autorisent.
Pour éviter que le groupe group2 puisse écraser file1, on peut être tenté de supprimer le droit Unix d'écriture dans le champ other avec la commande chmod 755 file1. Mais ceci empêcherait alors aussi user3 de modifier le fichier. Dans ce cas, il faut aussi positionner une ACL sur file1 :
$ setfacl --set=u::rwx,u:user3:rwx,g::r-x,g:group2:r-x,o::---,m::rwx file1
$ getfacl file1
# file: file1
# owner: user1
# group: group1
user::rwx
user:user3:rwx
group::r-x
group:group2:r-x
mask::rwx
other::---
Il ne faut pas utiliser le chemin complet de votre $HOME, car vous positionneriez les ACL non pas uniquement sur votre $HOME lui-même, mais aussi sur tous les répertoires et les fichiers qu'il contient. Par conséquent, évitez ce type de commande :
$ setfacl --set=u::rwx,u:user2:rwx,g::r-x,o::---,m::rwx /chemin/complet/vers/home
Le positionnement d'une ACL sur votre répertoire $HOME impliquant des droits en écriture pour une autre personne rend le mécanisme d'authentification par clé SSH inopérant (une connexion SSH demandera alors le mot de passe).
Pour que les clés SSH puissent fonctionner, il faut vérifier que l'on a les droits Unix "maximum" suivants sur le $HOME (pas de droit en écriture sauf pour le propriétaire) :
$ ls -ld ~
drwxr-xr-x+ 9 user1 group1 4096 Apr 13 09:42 /chemin/complet/vers/home
Si besoin, la procédure consiste à d'abord activer les ACL, puis à changer ensuite les droits Unix sur votre HOME avec la commande chmod 750 ~ qui évite de donner l'accès en
écriture à tout le monde :
$ cd $HOME
$ setfacl --set=u::rwx,u:user2:rwx,g::r-x,o::---,m::rwx .
$ chmod 750 ~
Dépendances entre ACL et droits Unix (pour utilisateurs avertis)
Les droits Unix classiques et les droits ACL sont interdépendants. La commande setfacl modifie les ACL mais aussi les droits Unix. Par contre, la commande Unix chmod ne modifie que certains champs des ACL.
Pour bien comprendre cette interdépendance il faut détailler la fonctionnalité du masque d'une ACL (champ mask::...). En effet, les droits effectifs des utilisateurs concernés par les champs user:user:..., group::... et group:group:... peuvent être restreints par les droits présents dans le masque.
Action des ACL sur les droits Unix
Par exemple, si l'on positionne des ACL sur le répertoire courant (dans lequel vous êtes) comme indiqué ci-dessous :
$ setfacl --set=u::rwx,u:user3:rwx,g::rwx,g:group2:rwx,o::---,m::r-x .
$ ls -ld .
drwxr-x---+ 0 user1 group1 4096 2014-03-30 16:28 .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx # indépendant du masque ACL
user:user3:rwx # mais droits effectifs r-x en raison du masque ACL
group::rwx # mais droits effectifs r-x en raison du masque ACL
group:group2:rwx # mais droits effectifs r-x en raison du masque ACL
mask::r-x # masque ACL
other::--- # indépendant du masque ACL
Remarques concernant les droits ACL :
- L'utilisateur
user3, les membres du groupe propriétairegroup1ainsi que ceux du groupegroup2ont comme droits effectifsr-xet non pasrwxcomme espéré en raison du masque ACL demandém::r-x. La commandesetfacleffectue un ET logique bit à bit entre leurs droits ACL respectifs demandésu:user3:rwx,g::rwx,g:group2:rwxet le masque ACL demandém::r-x. - Par contre, le masque ACL ne s'applique pas pour déterminer les droits
user::rwxdu propriétaire et les droitsother::---des utilisateurs qui ne sont pas concernés par les champsuser:user3:rwx,group::rwxetgroup:group2:rwx. Ce sont les droits ACL demandés viasetfaclqui s'appliquent (u::rwxeto::---).
Remarques concernant les droits Unix :
- Le propriétaire
user1du répertoire a les droitsrwxce qui correspond au champ ACLuser::rwx. - Le groupe propriétaire
group1a les droitsr-xce qui correspond au masque ACLmask::r-xlequel définit les droits maximaux des utilisateurs concernés par les champsuser:user3:rwx,group::rwxougroup:group2:rwx. - Les utilisateurs n'appartenant pas aux catégories précédentes n'ont aucun droit
---ce qui correspond au champ ACLother::---.
Action des droits Unix sur les ACL
Inversement, pour mieux comprendre l'action de la commande chmod sur le répertoire courant (dans lequel vous êtes) dont l'accès est supposé être contrôlé par ACL, on part de la situation suivante :
$ setfacl --set=u::r-x,u:user3:rwx,g::---,g:group2:r-x,o::---,m::--- .
$ ls -ld .
dr-x------+ 15 user1 group1 4096 2014-03-30 16:28 .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::r-x # indépendant du masque ACL
user:user3:rwx # mais droits effectifs --- en raison du masque ACL
group::--- # droits effectifs --- car demandés via setfacl (g::---)
group:group2:r-x # mais droits effectifs --- en raison du masque ACL
mask::--- # masque ACL vide
other::--- # indépendant du masque ACL
Remarques :
- Vous noterez que les droits effectifs sont vides (car le masque ACL est vide) : le user
user3et le groupegroup2n'ont donc aucun droit sur le répertoire malgré les champs ACLu:user3:rwxetg:group2:r-xdemandés. - Les droits Unix indiqués par la commande
ls -ld .montrent bien que seul le propriétaire peut accéder au répertoire.
Ensuite, on constate que la commande Unix chmod modifie les ACL suivant les options utilisées :
-
chmod u+rwxmodifie le champuser::...de l'ACL :$ chmod u+w .
$ ls -ld .
drwx------+ 15 user1 group1 4096 2014-03-30 16:28 .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx # indépendant du masque ACL mais modifié par chmod u+...
user:user3:rwx # mais droits effectifs --- en raison du masque ACL
group::--- # droits effectifs --- car demandés initialement via setfacl (g::---)
group:group2:r-x # mais droits effectifs --- en raison du masque ACL
mask::--- # masque ACL vide
other::--- -
chmod g+rwxmodifie le masque ACL (mask::...) mais pas le champ ACLgroup::.... Mais comme le masque influence les droits effectifs des champs ACLgroup::...,group:group2:rwxetuser:user3:rwxdes ACL, l'utilisateuruser3et le groupegroup2retrouvent leurs droits respectifs initialement demandés dans la commandesetfacl(champsu:user3:rwxetg:group2:r-x) :$ chmod g+rwx .
$ ls -ld .
drwxrwx---+ 15 user1 group1 4096 2014-03-30 16:28 .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
user:user3:rwx # et droits effectifs rwx en raison du masque ACL modifié
group::--- # pas modifié par chmod g+... !
group:group2:r-x # et droits effectifs r-x en raison du masque ACL modifié
mask::rwx # masque ACL modifié par chmod g+...
other::---remarqueLes droits concernant le champ
group::...des ACL ne peuvent être modifiés que par la commandesetfacl:$ setfacl -m g::r-x .
$ ls -ld .
drwxrwx---+ 15 user1 group1 4096 2014-03-30 16:29 .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
user:user3:rwx
group::r-x # modifiable uniquement par setfacl !
group:group2:r-x
mask::rwx
other::--- -
La commande
chmod o+rxmodifie le champother::...des ACL:$ chmod o+rx .
$ ls -ld .
drwxrwxr-x+ 15 user1 group1 4096 2014-03-30 16:29 .
$ getfacl .
# file: .
# owner: user1
# group: group1
user::rwx
user:user3:rwx
group::r-x
group:group2:r-x
mask::rwx
other::r-x # modifié par chmod o+...