Credit : Logo officiel
Les permissions Linux expliquees : chmod, chown, ACL
Les permissions Linux expliquees : chmod, chown, ACL
Il y a quelques annees, j'ai recupere en intervention urgente un site WordPress qui venait de se faire injecter du code malveillant. Quelques heures d'analyse et de logs Nginx plus tard, le coupable etait clair : le dossier /var/www/wordpress/wp-content/uploads etait en chmod 777 parce que le precedent administrateur en avait marre de se battre avec des erreurs d'upload. Resultat : un fichier PHP deguise en image, deposable par n'importe qui, executable comme du code, et un attaquant qui s'est servi pour deployer un webshell.
Le chmod 777 partout, c'est la cle qu'on laisse sous le paillasson. Ca marche, oui, mais ca laisse aussi entrer tout le monde. Apres cet incident, j'ai pris le temps de comprendre vraiment les permissions Linux, et c'est devenu un reflexe a chaque deploiement. Dans cet article je te donne tout ce que je sais : notation rwx, octale, symbolique, bits speciaux, ACL avancees, et les configurations type pour un serveur web sur Debian 12.
Le modele standard : user, group, other
Chaque fichier ou repertoire Linux est associe a :
- Un proprietaire (user,
u). - Un groupe (group,
g). - Tout le reste (other,
o).
Et pour chacun de ces niveaux, trois droits :
| Droit | Lettre | Octal | Sur un fichier | Sur un repertoire |
|---|---|---|---|---|
| Lecture | r | 4 | Lire le contenu | Lister les fichiers |
| Ecriture | w | 2 | Modifier le fichier | Creer/supprimer des fichiers |
| Execution | x | 1 | Executer le binaire | Traverser le repertoire |
La subtilite a connaitre : x sur un repertoire = pouvoir y entrer (cd), pas l'executer. Sans x sur un repertoire, meme si tu as r (lister les noms), tu ne peux pas acceder aux fichiers a l'interieur. C'est ce qui permet de masquer le contenu d'un dossier sans le rendre completement invisible.
Lire les permissions
ls -la /var/www/
drwxr-xr-x 3 www-data www-data 4096 mai 7 10:00 html
-rw-r--r-- 1 www-data www-data 612 mai 7 10:00 index.html
lrwxrwxrwx 1 root root 16 mai 7 10:00 current -> /var/www/v2
Decoupage du premier fichier drwxr-xr-x :
d: type (drepertoire,-fichier ordinaire,llien symbolique,cperipherique caractere,bbloc).rwx: droits du proprietaire (www-data).r-x: droits du groupe (www-data).r-x: droits des autres.
Soit 755 en notation octale.
chmod en notation octale
Chaque groupe de trois droits donne un chiffre entre 0 et 7 (somme des bits) :
rwx = 4+2+1 = 7
rw- = 4+2 = 6
r-x = 4+0+1 = 5
r-- = 4 = 4
--- = 0
Quelques classiques que j'utilise tous les jours :
chmod 755 /var/www/html # rwxr-xr-x : repertoire web public
chmod 644 /var/www/html/index.html # rw-r--r-- : fichier web public
chmod 700 ~/.ssh # rwx------ : seul moi
chmod 600 ~/.ssh/id_ed25519 # rw------- : cles SSH (sinon SSH refuse)
chmod 640 /etc/nginx/sites-available/monsite.fr # rw-r----- : conf serveur
chmod 750 /opt/scripts/deploy.sh # rwxr-x--- : script equipe
La notation octale est rapide et sans ambiguite. C'est ce que j'utilise dans 90% des cas.
chmod en notation symbolique
Utile quand tu veux juste ajouter ou retirer un droit sans toucher aux autres :
chmod u+x script.sh # ajouter execution au proprietaire
chmod g-w fichier.txt # retirer ecriture au groupe
chmod o-rwx config.ini # tout retirer aux autres
chmod a+r document.pdf # ajouter lecture a tous (a = all)
chmod u+rwx,g=rx,o=r dir/ # combine
chmod -R u+rw /var/log/app # recursif
L'option -R est puissante mais dangereuse. Sur un gros arbre, prefere find qui te permet de distinguer fichiers et repertoires :
find /var/www/html -type f -exec chmod 644 {} \;
find /var/www/html -type d -exec chmod 755 {} \;
Sinon chmod -R 755 mettrait x sur tous les fichiers, ce qui n'est pas necessaire et ouvre une surface d'attaque inutile.
chown : changer proprietaire et groupe
chown www-data /var/www/html/index.html
chown www-data:www-data /var/www/html/index.html
chown -R www-data:www-data /var/www/html
chgrp developers /opt/projet
chown :developers /opt/projet # equivalent a chgrp
Quelques regles que j'applique systematiquement :
- Code applicatif (PHP, JS, Python) : owner
www-data, groupwww-data, ou un user dedie pour l'app etwww-dataen groupe. - Fichiers de log : owner
root, groupadm, droits640. - Cles SSH : owner = utilisateur, droits
600pour les privees,644pour les publiques. - Cron files dans
/etc/cron.d/: ownerroot, grouproot, droits644.
Les bits speciaux (setuid, setgid, sticky)
La partie que peu de gens maitrisent. Trois bits supplementaires modifient le comportement de l'execution ou de la creation :
setuid (4xxx) : executer avec les droits du proprietaire
Un binaire avec le bit setuid s'execute avec les droits de son proprietaire, pas de l'utilisateur qui le lance. L'exemple canonique : /usr/bin/passwd doit ecrire dans /etc/shadow (lisible/modifiable uniquement par root) meme quand un utilisateur normal change son mot de passe.
ls -la /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 fev 3 12:00 /usr/bin/passwd
# ^
# s = setuid actif
A poser uniquement sur des binaires audites. Ne jamais mettre setuid sur un script shell, c'est un trou de securite enorme : entre l'invocation du shell et l'execution du script, l'attaquant peut substituer le contenu.
chmod u+s /usr/local/bin/mon-binaire
chmod 4755 /usr/local/bin/mon-binaire
setgid (2xxx) : heritage de groupe pour les nouveaux fichiers
Utile sur un repertoire de projet d'equipe. Avec setgid, les nouveaux fichiers crees dedans heritent du groupe du repertoire (au lieu du groupe primaire de l'utilisateur qui cree).
mkdir /opt/projet-equipe
chgrp developers /opt/projet-equipe
chmod 2775 /opt/projet-equipe
ls -ld /opt/projet-equipe
# drwxrwsr-x 2 root developers 4096 mai 7 10:00 /opt/projet-equipe
# ^
# s = setgid sur repertoire
Maintenant, peu importe quel membre du groupe developers cree un fichier, il appartiendra a developers et tout le monde pourra le modifier. Tres pratique pour bosser a plusieurs sur un repo.
Sticky bit (1xxx) : protection des fichiers dans un dossier partage
Sur un repertoire avec sticky bit, seul le proprietaire d'un fichier peut le supprimer (ou root). Meme si tout le monde a w sur le repertoire.
ls -ld /tmp
# drwxrwxrwt 18 root root 4096 mai 7 10:00 /tmp
# ^
# t = sticky bit
C'est pourquoi /tmp peut etre en 1777 sans que ca soit catastrophique : tu peux ecrire, mais tu ne peux pas supprimer les fichiers des autres utilisateurs.
chmod 1777 /var/spool/uploads-publics
Les ACL : permissions fines au-dela du modele unix
Le modele owner/group/other est limite : un seul proprietaire, un seul groupe, et apres c'est tout. Quand tu dois donner acces a Jean en lecture, au groupe designers en ecriture, au groupe stagiaires en lecture seule, et a Pierre en rien du tout, le modele standard ne suffit plus. Les ACL (Access Control Lists) repondent a ce besoin.
Installation et activation
apt install acl -y
Sur Debian 12, ext4 supporte les ACL nativement, pas besoin de remonter le filesystem. Sur des distros plus anciennes, verifie l'option acl dans /etc/fstab.
Definir des ACL
setfacl -m u:jean:rx /opt/projet
setfacl -m g:designers:rwx /opt/projet/assets
setfacl -m g:stagiaires:r-x /opt/projet/docs
setfacl -m u:pierre:--- /opt/projet/secret
setfacl -d -m g:developers:rwx /opt/projet
setfacl -d -m u::rwx,g::rwx,o::rx /opt/projet
-m modifie les ACL, -d definit les ACL par defaut (heritage pour les fichiers crees apres). -x retire une entree, -b purge tout.
Lire les ACL
getfacl /opt/projet
# file: opt/projet
# owner: root
# group: developers
user::rwx
user:jean:r-x
group::rwx
group:designers:rwx
group:stagiaires:r-x
mask::rwx
other::r-x
default:user::rwx
default:group::rwx
default:group:developers:rwx
default:other::r-x
Le mask limite les permissions effectives des entrees nommees (utilisateurs et groupes specifiques). Si le mask est r-x, meme un utilisateur ACL avec rwx n'aura en effet que r-x. C'est le filet de securite global.
Detecter les fichiers avec ACL
Le + apres les permissions standard indique la presence d'ACL :
ls -la /opt/projet
# drwxrwxr-x+ 3 root developers 4096 mai 7 10:00 .
Configuration type pour un serveur web
C'est la config que je deploie chez tous mes clients pour un WordPress, PrestaShop ou Symfony :
USER=www-data
GROUP=www-data
ROOT=/var/www/wordpress
chown -R $USER:$GROUP $ROOT
find $ROOT -type d -exec chmod 755 {} \;
find $ROOT -type f -exec chmod 644 {} \;
chmod 600 $ROOT/wp-config.php
chmod 600 $ROOT/.env
chmod -R 775 $ROOT/wp-content/uploads
chmod -R 775 $ROOT/wp-content/cache
chmod g+s $ROOT/wp-content/uploads
- Repertoires en
755, fichiers en644: tout le monde peut lire/traverser, seulwww-datapeut modifier. wp-config.phpen600: contient les credentials, lisible uniquement par le proprietaire.- Uploads en
775avec setgid :www-datapeut ecrire (uploads media), groupe peut ecrire (cron user pour purges), others peuvent lire (Nginx). - Setgid sur uploads : les nouveaux fichiers heritent du groupe
www-data, evite les surprises quand un script tourne sous un autre user.
Cas particuliers
Un dossier ou WP-CLI doit ecrire en tant qu'utilisateur SSH deploy mais Nginx (www-data) doit pouvoir lire :
setfacl -R -m u:deploy:rwx /var/www/wordpress
setfacl -d -R -m u:deploy:rwx /var/www/wordpress
Le deploy peut ecrire, www-data reste proprietaire et peut lire.
Erreurs courantes et leur fix
Permission deniedsur des fichiers en 644 : le repertoire parent n'a pas le bitxpour ton utilisateur. Verifie la chaine complete avecnamei -l /chemin/complet/vers/fichier.- WordPress refuse les uploads malgre 777 :
open_basedirPHP, AppArmor, ou SELinux bloquent. Regarde/var/log/apparmor/etaudit.logcote SELinux. - SSH refuse de se connecter avec une cle privee :
chmod 600 ~/.ssh/id_ed25519etchmod 700 ~/.ssh. SSH refuse les cles avec des permissions trop laxistes. chmod -Rsur un site casse les liens symboliques : utilisefindau lieu dechmod -Rpour eviter de modifier la cible des symlinks.setfaclne semble rien faire : le filesystem n'a pas l'optionacl. Verifiemount | grep votre-disqueet remonte avecmount -o remount,acl /.- Mask ACL qui annule les permissions :
setfacl -m m::rwx /cheminrecalcule le mask au max des entrees. Sinon lesrwxaccordes a un user nomme sont reduits au mask. - Setuid sur un script shell ignore : le kernel Linux desactive systematiquement setuid sur les scripts. Reflechis a un wrapper en C ou utilise
sudoproprement.
Pour aller plus loin
Les permissions sont une brique parmi d'autres en securite Linux :
- Resoudre les problemes de permissions Linux
- Hardening Linux : securiser son serveur
- Securiser SSH avec sshd_config
- Comprendre et configurer iptables
- Logs Linux : ou chercher et comment les lire
Conclusion : la securite commence par les permissions
Le chmod 777 doit disparaitre de ton vocabulaire. Une fois que tu as compris la difference entre 644 et 755, l'effet de setgid sur un repertoire de projet, et le pouvoir des ACL pour les configurations multi-utilisateurs, tu fais des deploiements securises sans y reflechir. La regle d'or : le minimum de droits necessaire au bon fonctionnement, jamais plus. Mon client de l'intro paie encore aujourd'hui les consequences de ce 777 en uploads (perte de donnees, blacklist email, refonte complete). Apprends de ses erreurs, prends 30 minutes pour bien faire les choses, et tu evites des semaines de galere.