Aller au contenu

Administration Unix - CM séance 13

12. Droits étendus : les ACLs

On a vu au 1er semestre la gestion des droits avec chmod.

Problème : on veut donner à des utilisateurs des droits sur certains fichiers. Une solution est de créer un groupe, de le rendre propriétaire des fichiers, et de rajouter ce groupe aux utilisateurs. L'inconvénient, lorsqu'il y a beaucoup d'utilisateurs, est une multiplication des groupes.

Une autre solution, plus souple, est d'utiliser les "droits étendus" : les ACL (Access Control List).

Les ACL ont été inventées dans le système Multics en 1965, et existent sous différentes formes : dans les systèmes Unix, sous MacOS, Windows, Active Directory, NFSv4, et même SQL !

En ce qui concerne les fichiers Unix, les ACL sont normalisés POSIX, et sont disponibles dans la plupart des systèmes de fichiers récents.

12.1. Gestion des droits étendus

L'idée consiste à rajouter les mêmes triplets (rwx) de droits, mais pour d'autres utilisateurs ou d'autres groupes que les propriétaires du fichier.

La lecture étendue habituelle d'un répertoire (ls -l) indiquera seulement qu'il existe des ACLs avec un "+" à la fin : (exemple plus loin)

$ ls -l toto
-rw-rwx---+ 1 thiel thiel 8 sept. 25 14:37 toto*

Les ACLs seront représentées sous l'une des formes suivantes :

u:username:rwx      ou  user:username:rwx
g:groupname:rwx     ou  group:groupname:rwx
o:rwx               ou  other:rwx
m:rwx               ou  mask:rwx

Deux commandes permettent de manipuler les ACLs :

  • getfacl pour lister les ACLs ;
  • setfacl pour les positionner (ou les effacer).

Leurs options principales sont les suivantes :

  • getfacl :

    -n              affiche les uid et gid au lieu des noms
    -t              affiche les informations tabulées
    -R              réalise un affichage récursif sur un répertoire.
    
  • setfacl :

    -x acl file     supprime l'acl de file
    -b file         supprime toutes les acls de file
    -m acl file     modifie (ou ajoute acl) à file
    –h              affiche une aide
    

Exemple :

$ umask 027
$ echo "bonjour" > toto

$ ls -l toto
-rw-r----- 1 thiel thiel 8 sept. 25 14:37 toto

$ getfacl toto
# file: toto
# owner: thiel
# group: thiel
user::rw-
group::r--
other::---

# On rajoute un utilisateur dupond
$ sudo adduser dupond
...

# On rajoute des droits pour l'utilisateur dupond
$ setfacl -m u:dupond:rwx toto

# Remarque : si l'utilisateur n'existe pas on aurait eu
$ setfacl -m u:bidon:rwx toto
setfacl : Option -m : Argument invalide près du caractère 3

$ ls -l toto
-rw-rwx---+ 1 thiel thiel 8 sept. 25 14:37 toto*
# le + signifie qu'il y a des ACL
# le * signifie que c'est un exécutable (car on a rajouté x avec setfacl)

$ getfacl toto
# file: toto
# owner: thiel
# group: thiel
user::rw-
user:dupond:rwx                     # ça a marché
group::r--
mask::rwx
other::---

On peut aussi préciser un "masque de droits effectifs", qui définit quels sont les droits maximaux pour tous les groupes et utilisateurs (sauf pour le propriétaire) :

$ setfacl -m m::w toto              # le masque est après ::, ici w
$ getfacl toto
# file: toto
# owner: thiel
# group: thiel
user::rw-
user:dupond:rwx     #effective:-w-
group::r--          #effective:---
mask::-w-
other::---

Maintenant dupond ne peut plus lire le fichier, mais il peut le modifier :

thiel:~$ cat toto
bonjour

thiel:~$ sudo su dupond                     # on change d'utilisateur
[sudo] Mot de passe de thiel :

dupond:/home/thiel$ cat toto
cat: toto: Permission non accordée          # dupond n'a pas le droit r

dupond:/home/thiel$ echo "hop" >> toto      # on modifie toto, droit w

dupond:/home/thiel$ cat toto
cat: toto: Permission non accordée

dupond:/home/thiel$ exit                # retour à l'utilisateur précédent
déconnexion

thiel:~$ cat toto
bonjour
hop                                     # la modification a marché

Défaire le masque = donner les droits maximaux

$ setfacl -m m::rwx toto

Archives tar : par défaut la commande tar ne conserve pas les ACL, il faut rajouter l'option --acls

$ tar cvf essai.tar toto
toto
$ tar tvf essai.tar
-rw--w---- thiel/thiel      12 2021-01-29 15:35 toto

$ tar cvf essai.tar --acls toto     # on recrée le tarball avec --acls
toto
$ tar tvf essai.tar --acls          # il y a le '+' qui signale les ACLs
-rw--w----+ thiel/thiel      12 2021-01-29 15:35 toto

La commande mv préserve les ACLs. Pour copier un fichier avec ses ACLs, utiliser cp -p

12.2. Droits étendus par défaut

On peut donner des ACL par défaut à un répertoire ; tout ce qui sera créé dedans recevra des droits par défaut.

Options de setfacl :

  • -d   donne des droits par défaut
  • -k   supprime les droits par défaut

Exemple :

$ umask
0027
$ mkdir rep1                            # Création d'un répertoire
$ touch rep1/fic1                       # et d'un fichier avec le umask
$ ls -laR rep1
rep1:
total 8
drwxr-x---  2 thiel thiel 4096 janv. 24 11:37 .
drwxr-xr-x 16 thiel thiel 4096 janv. 24 11:37 ..
-rw-r-----  1 thiel thiel    0 janv. 24 11:37 fic1

$ setfacl -d -m u:dupond:rwx rep1       # ajout d'ACLs par défaut

$ getfacl -R rep1
# file: rep1
# owner: thiel
# group: thiel
user::rwx                               # ça n'a pas ajouté d'ACL ici (pour
group::r-x                              # les rajouter, setfacl sans -d)
other::---
default:user::rwx                       # mais ça a ajouté les ACL par
default:user:dupond:rwx                 # défaut
default:group::r-x
default:mask::rwx
default:other::---

# file: rep1/fic1                       # ça n'a pas modifié fic1
# owner: thiel                          # qui existait déjà
# group: thiel
user::rw-
group::r--
other::---

$ touch rep1/fic2                       # Création d'un répertoire et d'un
$ mkdir rep1/rep2                       # fichier avec les ACLs par défaut

$ getfacl rep1/{fic2,rep2}
# file: rep1/fic2
# owner: thiel
# group: thiel
user::rw-
user:dupond:rwx     #effective:rw-      # ça a créé les ACLs pour fic1
group::r-x          #effective:r--
mask::rw-                               # avec un masque pour enlever x
other::---

# file: rep1/rep2
# owner: thiel
# group: thiel
user::rwx
user:dupond:rwx                         # ça a créé les ACLs pour rep1
group::r-x
mask::rwx
other::---
default:user::rwx                       # et recopié les ACLs par défaut
default:user:dupond:rwx
default:group::r-x
default:mask::rwx
default:other::---

$ setfacl -k rep1                       # pour supprimer les ACLs par défaut
$ setfacl -kR rep1                      # idem récursivement sur les rep

Pour aller plus loin : lire le document sur les ACLs POSIX.

13. Élévation de privilèges

C'est un mécanisme qui permet à un utilisateur d'accéder à des privilèges supérieurs à ceux qu'il possède habituellement.

13.1. Commande sudo (superuser do)

Elle permet d'exécuter une commande en changeant temporairement le user et le groupe.

Un utilisateur peut utiliser sudo s'il est dans le groupe :

  • sur Debian et Ubuntu : sudo
  • Fedora et CentOS : wheel

Configuration : voir

  • man sudo.conf ; fichier /etc/sudo.conf
  • man sudoers ; fichiers /etc/sudoers, /etc/sudoers.d/*.conf

Le système lui demande ensuite son propre mot de passe. Ensuite, pendant 5 minutes, on peut utiliser sudo sans mot de passe.

$ sudo commande...              # exécute commande par root
$ sudo -u user commande...      # exécute commande par le user

Exemples :

thiel@xubu1:~$ groups
thiel adm cdrom sudo ...        # est dans le groupe sudo

thiel@xubu1:~$ sudo id
[sudo] Mot de passe de thiel : 
uid=0(root) gid=0(root) groupes=0(root)

thiel@xubu1:~$ sudo addgroup boulga
Ajout du groupe « boulga » (GID 1007)...
Fait.

thiel@xubu1:~$ sudo -u dupond id
uid=1006(dupond) gid=1006(dupond) groupes=1006(dupond)

Test avec un utilisateur qui n'est pas dans le group sudo :

thiel@xubu1:~$ sudo su dupond           # on devient dupont
dupond@xubu1:/home/thiel$ groups
dupond                                  # n'est pas dans le groupe sudo
dupond@xubu1:/home/thiel$ sudo id
[sudo] Mot de passe de dupond : 
dupond n'apparaît pas dans le fichier sudoers. Cet incident sera signalé.

13.2. Commande su (substitute user)

Usage :

su [options] [-] [user [argument...]]

Elle permet de changer le user et le groupe. En principe, elle commence par demander le mot de passe du nouvel utilisateur. Elle démarre ensuite le shell par défaut de l'utilisateur.

Devenir root : su

thiel@debian:~$ su
Mot de passe :                              # mot de passe de root

root@debian:/home/thiel$ id                 # on n'a pas changé de répertoire
uid=0(root) gid=0(root) groupes=0(root)     # on est bien devenu root

root@debian:/home/thiel$ exit               # retour à l'utilisateur
thiel@debian:~$

Pour que ce soit possible il faut que root ait un mot de passe. Ce n'est pas le cas par défaut sur Ubuntu ; une solution est d'utiliser sudo :

thiel@xubu1:~$ sudo su
[sudo] Mot de passe de thiel : 
root@xubu1:/home/thiel# id
uid=0(root) gid=0(root) groupes=0(root)
root@xubu1:/home/thiel# exit
exit
thiel@xubu1:~$ 

Changer d'utilisateur : su user

thiel@xubu1:~$ su dupond
Mot de passe :                              # mot de passe de dupond
dupond@xubu1:/home/thiel$ id                # on n'a pas changé de répertoire
uid=1006(dupond) gid=1006(dupond) groupes=1006(dupond)
dupond@xubu1:/home/thiel$ exit
thiel@xubu1:~$ 

Changer d'utilisateur et démarrer un login shell dans son homedir : su - [user]

thiel@xubu1:~$ su - dupond
Mot de passe :                              # mot de passe de dupond
dupond@xubu1:~$ id                          # on est dans son home
uid=1006(dupond) gid=1006(dupond) groupes=1006(dupond)
dupond@xubu1:~$ exit
déconnexion
thiel@xubu1:~$ 

Changer d'utilisateur et de groupe (réservé à root) : su -g groupe [user]

thiel@xubu1:~$ sudo su
[sudo] Mot de passe de thiel :

root@xubu1:/home/thiel# su -g boulga dupond
dupond@xubu1:/home/thiel$ id
uid=1006(dupond) gid=1007(boulga) groupes=1007(boulga)

dupond@xubu1:/home/thiel$ exit
root@xubu1:/home/thiel# exit
thiel@xubu1:~$ 

Changer d'utilisateur pour exécuter une commande : su -c "commande" [user]

thiel@xubu1:~$ su -c "id ; pwd" dupond
Mot de passe :                              # mot de passe de dupond
uid=1006(dupond) gid=1006(dupond) groupes=1006(dupond)
/home/thiel
thiel@xubu1:~$ 

Pour aller plus loin :

  • commande sg pour changer de groupe
  • utilisateurs réel, effectif, sauvegardé : man 7 credentials, /real
  • commandes runuser, setpriv (man)
  • capabilities (man)

13.3. Droits spéciaux : setuid, setgid, sticky bit

Flags setuid et setgid

Ils signifient : "set user ID", "set group ID"

Les droits d'accès setuid et setgid sont placés sur un fichier ou un répertoire avec chmod :

  • sur un fichier régulier exécutable :

    n'importe quel utilisateur qui a les droits d'exécution l'exécutera avec les privilèges :

    • du propriétaire du fichier s'il y a le flag setuid,
    • du groupe du fichier s'il y a le flag setgid.
  • sur un fichier régulier non exécutable :

    aucun effet

  • sur un répertoires :

    • flag setuid : aucun effet (sauf FreeBSD).
    • flag setgid : les fichiers et répertoires créés dans ce répertoire héritent du gid du répertoire.

Affichage étendu : ls -l affiche

..s ... ...   fichier exécutable     + setuid
..S ... ...   fichier non exécutable + setuid
... ..s ...   fichier exécutable     + setgid
... ..S ...   fichier non exécutable + setgid

Exemples :

$ ls -l /bin/su /usr/bin/sudo /usr/bin/passwd /bin/ping /bin/bash /usr/bin/at
-rwxr-xr-x 1 root   root   1037528 juil. 12  2019 /bin/bash*
-rwsr-xr-x 1 root   root     44168 mai    7  2014 /bin/ping*
-rwsr-xr-x 1 root   root     40128 mars  26  2019 /bin/su*
-rwsr-sr-x 1 daemon daemon   51464 janv. 14  2016 /usr/bin/at*
-rwsr-xr-x 1 root   root     54256 mars  26  2019 /usr/bin/passwd*
-rwsr-xr-x 1 root   root    136808 janv. 31  2020 /usr/bin/sudo*

Donner les droits à un fichier :

$ chmod u+s         # donne le setuid
$ chmod g+s         # donne le setgid
$ chmod ug+s        # donne le setuid et le setgid

En octal, u+s est codé 4000, et g+s est codé 2000, aucun 0000.

Par exemple :

$ touch ga
$ chmod 0755 ga                                 # pas de setuid/setgid
$ ls -l ga
-rwxr-xr-x 1 thiel thiel 0 janv. 25 11:22 ga

$ chmod 4755 ga                                 # setuid
$ ls -l ga
-rwsr-xr-x 1 thiel thiel 0 janv. 25 11:22 ga

$ chmod 2755 ga                                 # setgid
$ ls -l ga
-rwxr-sr-x 1 thiel thiel 0 janv. 25 11:22 ga

$ chmod 6644 ga                                 # setuid+setgid mais non-
$ ls -l ga                                      # exécutable
-rwSr-Sr-- 1 thiel thiel 0 janv. 25 11:22 ga

Au niveau de la sécurité, l'emploi inconsidéré de ces droits est un réel danger. C'est pourquoi la plupart des unix modernes (dont Linux) ignorent setuid et setgid lorsque l'exécutable est un script (voir tests en TP).

Le sticky bit

Il s'agit d'un droit que l'on peut donner à un répertoire avec chmod. En général il est ignoré pour les fichiers.

Lorsqu'un répertoire rep possède le sticky bit, les fichiers et répertoires qui sont dans rep ne peuvent être renommés ou effacés que par leur propriétaire, ou par le propriétaire de rep, ou par root.

C'est typiquement ce qui se passe pour /tmp.

Affichage étendu : ls -l affiche

... ... ..t   répertoire traversable par les users (x) + sticky bit
... ... ..T   répertoire non traversable par les users + sticky bit

Exemple :

$ ls -l / | grep tmp
drwxrwxrwt  14 root root      4096 janv. 25 14:03 tmp

Donner le sticky bit à un répertoire :

$ chmod +t rep          # donne le sticky bit

En octal, +t est codé 1000.

$ umask
0027
$ mkdir rep1
$ ls -l | grep rep1
drwxr-x---  2 thiel thiel  4096 janv. 25 14:56 rep1
$ chmod 1755 rep1
$ ls -l | grep rep1
drwxr-xr-t  2 thiel thiel  4096 janv. 25 14:56 rep1