Introduction
Les Linux file permissions contrôlent qui peut lire, écrire ou exécuter des fichiers et des répertoires. Quand vous tombez sur un message "Permission denied", le moyen le plus rapide d'en sortir est un workflow clair et reproductible. Ce guide montre comment :
- Identifier le chemin et l'opération qui échouent
- Lire correctement l'ownership et les modes
- Utiliser chmod et chown de manière sûre et avec le moindre privilège
- Comprendre umask pour que les valeurs par défaut à la création soient correctes
- Valider l'accès des services (Linux service permissions) dans des conditions proches de la production
Vue d'ensemble du workflow
Utilisez cette séquence pour réduire le bruit et éviter les retours arrière :
- Reproduire et capturer l'échec
- Notez la commande et le chemin : quel fichier ou répertoire, et quelle opération (lecture, écriture, exécution, liste, création, suppression).
- Si le message est générique, tracez localement les appels fichiers :
strace -e trace=file -f -o /tmp/trace.log votre_commande- Recherchez
EACCESouEPERMet le chemin fautif.
- Inspecter le chemin et ses parents
- Affichez la cible et chaque répertoire parent :
namei -l /chemin/vers/objet- Inspectez les détails :
ls -ld /chemin /chemin/vers /chemin/vers/objetstat -c "%A %a %U:%G %n" /chemin/vers/objet- Vérifiez les options de montage pouvant bloquer l'exécution :
findmnt -no TARGET,OPTIONS --target /chemin/vers/objetnoexecbloque l'exécution ;nodevetnosuidaffectent les bits device et suid.- Vérifiez l'attribut immuable (rare mais pénible) :
lsattr /chemin/vers/objet- S'il est présent,
chattr -i fichieravant toute écriture.
- Confirmer l'identité agissante
- En shell interactif :
whoami;id;id -Gn- Pour un service :
systemctl show -p User, Group, SupplementaryGroups votre.serviceps -o user, group, egroup, egid= -C votre-binaire(ou par PID)
- Choisir le correctif minimal
- Mismatch d'ownership : privilégiez
chownsur le plus petit sous-arbre, pas sur tout le filesystem. - Accès groupe manquant : utilisez un groupe partagé et
setgidsur le répertoire. - Mode trop strict : n'ajoutez que le nécessaire (souvent
g+rwXpour des collaborateurs). - Mode trop large : supprimez l'accès monde (
o-rwx) et reposez-vous sur user/groupe.
- Poser de bons défauts
- Si les nouveaux fichiers arrivent avec de mauvaises permissions, ajustez
umaskou forcez l'héritage de groupe avecsetgidsur les répertoires partagés.
- Valider en tant qu'utilisateur cible
sudo -u appuser -g appgroup -- test -r /chemin && echo readablesudo -u appuser -g appgroup -- test -w /chemin && echo writablesudo -u appuser -g appgroup -- test -x /chemin/vers/bin && echo executable
Diagnostiquer « Permission denied »
La plupart des refus proviennent de l'une de ces causes : manque d'exécution (x) sur un répertoire à traverser, manque de lecture/écriture sur la cible, ou option de montage/attribut empêchant l'opération.
Checklist :
- Droit de traversée sur chaque répertoire parent :
namei -l /srv/app/data/file.txt- Assurez
xsur chaque répertoire pour l'utilisateur/groupe effectif. - Lecture/Écriture sur la feuille :
stat -c "%A %a %U:%G %n" /srv/app/data/file.txt- Échecs d'exécution :
- Si c'est un script : assurez le bit
xet un shebang valide, et que l'interpréteur est exécutable. - Si le filesystem est monté
noexec, un binaire ne s'exécutera pas même avecx. - Attributs et montages :
lsattrpeut révéler des fichiers immuables (i) qui refusent l'écriture.findmntmontre des options commenoexecqui bloquent l'exécution.
Propriété, groupes et modes
Les permissions sont évaluées ainsi :
- Bits du propriétaire (u=rwx)
- Bits du groupe (g=rwx) si le processus est dans le groupe du fichier
- Bits autres (o=rwx)
Points clés :
- Répertoires :
xpermet la traversée,rliste les noms,wcrée/supprime des entrées. - Fichiers :
rlit,wécrit,xexécute. - Le groupe effectif compte : assurez que le processus appartient au groupe attendu (
id -Gn). - Corrigez avec une portée minimale : opérez sur le chemin réellement en défaut.
Inspections utiles :
ls -ld /srv/app /srv/app/datastat -c "%A %a %U:%G %n" /srv/app/datanamei -l /srv/app/data/report.csv
Bien utiliser chmod
Évitez les changements en vrac. Préférez des modes symboliques qui expriment l'intention :
- Accorder propriétaire
rwet groupersur fichiers et répertoires, retirer le monde : chmod -R u+rwX,g+rX,o-rwx /srv/app/data- Rendre un script exécutable par owner et group :
chmod ug+x /srv/app/bin/run.sh- Répertoire de collaboration : lecture, écriture et traversée pour le groupe :
chmod 2770 /srv/shared- Le
2activesetgidpour que les nouveaux fichiers héritent du groupe.
Références numériques courantes :
- Fichiers : 0644 (
rw-r--r--) ou 0660 (rw-rw----) - Répertoires : 0755 (
rwxr-xr-x) ou 0770 (rwxrwx---)
À éviter :
chmod -R 777 ...(surexpose les données et masque les problèmes d'ownership)- Retirer
xdes répertoires que vous devez encore traverser
Utiliser chown et les groupes
Ajustez l'ownership selon la responsabilité.
- Définir précisément owner et group :
chown app: appdata /srv/app/datachown -R app: appdata /srv/app/data/logs# ciblez uniquement ce qui est nécessaire- Créer et utiliser un groupe de collaboration :
groupadd appdatausermod -aG appdata aliceusermod -aG appdata app- Les utilisateurs doivent se reconnecter pour prendre le nouveau groupe (
newgrp appdata). - Imposer l'héritage de groupe dans les répertoires partagés :
chmod g+s /srv/app/shared- Les nouveaux fichiers prendront automatiquement le groupe du répertoire.
- Créer les répertoires avec owner, group et mode corrects en une seule étape :
install -d -o app -g appdata -m 2770 /srv/app/shared
Bases de umask
umask définit quels bits de permission sont retirés par défaut lors de la création.
- Les fichiers partent de 0666 ; les répertoires de 0777.
- Mode effectif = base & ~umask
- Exemples :
umask 022→ fichiers 0644, répertoires 0755umask 027→ fichiers 0640, répertoires 0750umask 002→ fichiers 0664, répertoires 0775 (bien pour la collaboration par groupe)
Définir umask :
- Pour les shells interactifs : ajoutez
umask 027dans~/.profileou/etc/profile. - Pour les services systemd : ajoutez
UMask=0027sous[Service]dans l'unité, puissystemctl daemon-reload && systemctl restart votre.service.
Astuce : combinez UMask= avec un répertoire de projet en setgid pour des défauts partagés et prévisibles.
Valider l'accès d'un service
Les services tournent souvent sous des comptes non login ; testez toujours avec cette identité.
- Découvrir l'utilisateur et les groupes du service :
systemctl show -p User, Group, SupplementaryGroups your.service- Vérifier répertoire de travail, données, et binaires :
sudo -u app -g appdata -- test -r /srv/app/config.yml && echo readablesudo -u app -g appdata -- test -w /srv/app/data && echo writablesudo -u app -g appdata -- test -x /srv/app/bin/run && echo executable- Vérifier la traversée des parents du chemin :
sudo -u app -- namei -l /srv/app/data/report.csv- Confirmer que les montages ne bloquent pas l'exécution :
findmnt -no TARGET,OPTIONS --target /srv/app/bin
Si les permissions paraissent correctes mais que les refus persistent, un système de contrôle d'accès obligatoire (comme SELinux ou AppArmor) peut être en cause. Ce guide se concentre sur les permissions de fichiers, mais les symptômes peuvent se ressembler.
Plan pilote local
Commencez petit pour pouvoir inspecter et revenir facilement.
- Créer un utilisateur, un groupe et des répertoires de test
groupadd appdatauseradd -m -G appdata appinstall -d -o app -g appdata -m 2770 /srv/app-test/sharedinstall -d -o app -g appdata -m 0750 /srv/app-test/logs
- Régler les défauts avec umask pour la collaboration
- En tant que
app:umask 002; créez des fichiers et sous-répertoires sous/srv/app-test/shared - Vérifiez que les nouveaux fichiers sont en 0664 et les répertoires en 0775, avec le groupe
appdata
- Valider les chemins d'accès
sudo -u app -g appdata -- touch /srv/app-test/shared/pilot.txtnamei -l /srv/app-test/shared/pilot.txtsudo -u app -g appdata -- test -w /srv/app-test/logs && echo logs writable
- Provoquer l'échec et corriger
- Retirer l'écriture groupe et confirmer le refus :
chmod g-w /srv/app-test/logssudo -u app -g appdata -- test -w /srv/app-test/logs || echo denied as expected- Restaurer l'accès minimum nécessaire :
chmod g+w /srv/app-test/logs
- Documenter commandes et résultats
- Tenez un journal simple des commandes pour reproduire ou revenir en arrière.
Quand le pilote se comporte comme prévu, appliquez les mêmes changements minimaux aux chemins réels.
Conclusion
Utilisez un workflow systématique pour résoudre "Permission denied" :
- Identifier le chemin et l'opération qui échouent
- Inspecter ownership, groupes et modes à chaque niveau
- Appliquer des changements minimaux avec
chmodetchown(least privilege) - Mettre en place des défauts prévisibles avec
umask(etsetgidsi utile) - Valider en tant qu'utilisateur réel du service avant un déploiement plus large
Commencez par un petit pilote local, confirmez les résultats, puis étendez en toute confiance à des chemins proches de la production.