¿Permission denied incluso después de chmod? Las causas
Si cambiaste chmod y el sistema sigue mostrando Permission denied, el modo del archivo puede no ser el problema. Revisa el camino, la propiedad, montajes, SELinux, AppArmor, ACL, sticky bit y atributos del sistema de archivos.
Revisaste los permisos. Incluso probaste chmod 777 por frustración. Y la terminal sigue diciendo:
-bash: ./deploy.sh: Permission denied
Cuando un modo aparentemente correcto sigue siendo rechazado, ampliar los permisos suele atacar el problema equivocado. Los bits del archivo son solo una capa de la comprobación. El bloqueo puede estar en los directorios superiores, la propiedad, el sistema de archivos o una política de seguridad adicional.
Si antes necesitas descifrar 755 o 644, empieza por qué significa chmod 755. Aquí asumimos que el modo parece correcto y buscamos qué más puede impedir el acceso.
Primero inspecciona; no abras permisos
La primera pregunta es: ¿bloquea el archivo o bloquea algo a su alrededor? No uses chmod 777 como sonda. Cambia el estado y no representa necesariamente la cuenta que de verdad falla. Empieza por recorrer toda la ruta:
namei -l /home/alice/app/deploy.sh
namei -l muestra el modo, propietario y grupo de cada componente desde / hasta el destino. Combínalo con id y ls -l, ejecutados como el usuario o la cuenta de servicio que falla. A menudo eso identifica la barrera sin cambiar nada. namei pertenece a util-linux; en macOS, revisa cada directorio con ls -ld.
Evita el reflejo de usar chmod 777 “solo para probar”. chmod u+rwx solo modifica los bits del propietario, por lo que no sirve si tú no eres el propietario. Probar con sudo responde si root entra, no si entra el usuario o servicio que necesita hacerlo.
Causa 1: el problema es la ruta, no el archivo
Para abrir /home/alice/app/deploy.sh, necesitas permiso de ejecución/recorrido en todos los directorios del camino: /, /home, /home/alice y /home/alice/app. Si falta x en uno, se deniega todo lo que queda debajo antes de consultar el modo del archivo.
ls -ld / /home /home/alice /home/alice/app
Si other es realmente la clase que debe atravesar ese directorio, podrías restaurarlo así:
chmod o+x /home/alice
o+x permite atravesar, pero no listar el contenido. En un entorno compartido suele ser más restringido dar g+x al grupo adecuado.
También importa qué operación falla. Para leer o ejecutar un archivo existente necesitas sus propios permisos y x en cada directorio padre. Para crear, borrar o renombrar una entrada manda el directorio padre: necesitas w+x allí. Que el archivo destino sea escribible no decide si puedes borrarlo.
| Para… | Necesitas… |
|---|---|
| Abrir, leer o ejecutar un archivo existente | permiso del archivo y x en todos los padres |
| Crear, borrar o renombrar una entrada | w+x en el directorio padre |
| Listar y trabajar con las entradas de un directorio | r+x en ese directorio |
Un Permission denied de rm, mv o una creación nueva suele apuntar al directorio, no al archivo. El sticky bit añade otra condición al borrar.
Causa 2: propiedad, no modo
Los permisos se aplican por clase: propietario, grupo u otros. La clase que te corresponde depende de tu identidad, tus grupos y el propietario/grupo del archivo.
ls -l deploy.sh # -rwxr-x--- 1 root staff ...
id # uid=1000(alice) gid=1000(alice) groups=1000(alice)
Aquí el archivo pertenece a root:staff, tiene modo 750 y Alice no pertenece a staff. Cae en la clase de otros, que con 750 no recibe nada. chmod cambia lo que puede hacer cada clase; no cambia propietario, grupo ni pertenencia a grupos.
id -nG alice # primero, confirma los grupos reales de alice
sudo chown alice deploy.sh # hacer a alice propietaria, o…
sudo chgrp developers deploy.sh # solo si alice ya pertenece a developers, o…
sudo usermod -aG staff alice # añadir a alice a staff y volver a iniciar sesión
Mover el archivo a un grupo al que la usuaria no pertenece no concede nada. Este caso se arregla alineando propiedad y grupos, no abriendo el archivo al mundo con 777.
Causa 3: el sistema de archivos dice que no
Una opción de montaje puede imponerse al modo. Dos son especialmente comunes:
noexec: impide ejecutar directamente un archivo de ese sistema de archivos aunque tengax. Aparece en directorios temporales reforzados, medios extraíbles y contenedores../scriptpuede dar Permission denied;bash ./script, que hace que un intérprete lea el archivo, es otra operación.ro: el montaje es de solo lectura. No puedes escribir aunque el archivo tengaw.
findmnt -T /tmp/deploy.sh
# → TARGET SOURCE FSTYPE OPTIONS
# /tmp tmpfs tmpfs rw,nosuid,nodev,noexec
Si el problema es noexec, mueve el archivo a un sistema que permita ejecución directa o cambia el montaje solo si controlas esa política. En macOS, mount sin argumentos lista los montajes y sus opciones.
Causa 4: SELinux o AppArmor
En RHEL, Fedora y sistemas afines, SELinux añade un control basado en contextos de seguridad. Un servidor web puede no leer un archivo legible para todo el mundo si su contexto es incorrecto. Sospecha de ello si falla solo el servicio, no tu shell, y el modo parece perfecto.
getenforce
ls -Z deploy.sh
sudo ausearch -m avc -ts recent
Si aparecen denegaciones AVC, el modo es una distracción. En una ruta que deba usar la etiqueta predeterminada de la política, puedes restaurarla con:
sudo restorecon -v /var/www/html/deploy.sh
En Ubuntu y SUSE puede estar activo AppArmor. Revisa sudo aa-status y busca apparmor="DENIED" en el registro del kernel. En ambos casos estás depurando una política, no chmod.
Causa 5: una ACL completa la historia
chmod cambia las tres clases clásicas, pero un archivo puede llevar una ACL POSIX con reglas adicionales por usuario o grupo. Un + al final de ls -l es la pista habitual:
ls -l report.csv # -rw-r-----+
getfacl report.csv
Con una ACL, la vista de propietario/grupo/otros deja de ser completa. Las entradas extra pueden conceder acceso adicional, y la máscara (mask) de la ACL puede limitar los permisos efectivos de usuarios con nombre, grupos con nombre y grupo propietario. Por ejemplo, group::rwx junto con mask::r-- da de hecho solo r--. Además, en ls -l la tríada de grupo representa la máscara, no siempre la entrada real del grupo propietario. Lee getfacl y sus permisos efectivos antes de cambiar nada; después ajusta solo la entrada necesaria:
setfacl -m u:alice:rx report.csv
No conviertas setfacl -b en la solución por defecto: elimina reglas extendidas que pueden ser deliberadas.
Causa 6: bits especiales y atributos
A veces el modo sí se está respetando; lo que falla es la interpretación.
- Sticky bit:
1777, como en/tmp. En un directorio compartido, solo el propietario de la entrada, el propietario del directorio o un usuario con privilegios pueden borrarla o renombrarla. - Scripts setuid en Linux: el kernel ignora setuid/setgid en scripts interpretados.
4755 install.shno se ejecutará como su propietario igual que un binario setuid. - Atributo immutable: en sistemas de archivos Linux que lo soportan, bloquea escritura y muchos cambios de metadatos; chmod no lo muestra.
lsattr deploy.sh
sudo chattr -i deploy.sh
macOS no usa chattr; sus mecanismos cercanos son uchg/schg mediante chflags, además de System Integrity Protection en rutas del sistema.
Cuando ni siquiera es Permission denied
bad interpreter: No such file or directorysuele indicar un shebang roto o CRLF de Windows en la línea#!.- Un disco o sus inodos llenos dan normalmente
No space left on device; revisadfydf -i. - En NFS con
root_squash, el root remoto se mapea a una identidad sin privilegios y puede recibir Permission denied incluso consudo. Es una política de exportación, no un modo de archivo.
Si funciona a mano pero falla desde cron, es otro problema de entorno. Consulta por qué no se ejecutó mi tarea cron.
Lista de diagnóstico
- Inspecciona como la cuenta que falla. Usa
namei -l /ruta/completa,idyls -l; no empieces conchmod 777. - Recorre la ruta. Un
xausente en cualquier ancestro bloquea el acceso. Crear, borrar y renombrar requierenw+xen el padre. - Comprueba propiedad y grupos. Si no eres el propietario ni miembro del grupo, corrige
chown,chgrpo la pertenencia al grupo. - Comprueba el montaje.
findmnt -T <ruta>: noexec bloquea ejecución directa y ro bloquea escritura. - Comprueba módulos de seguridad. SELinux con
getenforce/ls -Z; AppArmor conaa-statusy registros. - Comprueba ACL. Un
+enls -llleva agetfacl; mira en especial la mask. - Comprueba restricciones especiales. Sticky bit, scripts setuid y atributos immutable.
Al seguir este orden aparece la barrera real, y normalmente no es algo que chmod pueda solucionar por sí solo. Para verificar qué concede realmente un modo octal o simbólico, usa el calculador de chmod. Y una vez despejada la barrera, chmod 644 vs 755 trata qué modo dejar puesto, incluido cómo aplicarlo a un árbol sin volver ejecutable cada archivo.