Cuando ves Permission denied en un servidor Linux, los permisos son uno de los primeros aspectos a revisar: el del archivo en sí, el de los directorios en la ruta y, en algunos sistemas, otras restricciones de acceso. chmod es el comando que controla los bits de permiso de cada archivo y directorio. Entenderlo bien evita dos tipos de errores opuestos: los de seguridad —usar 777 en producción porque "así funciona"— y los de acceso —un directorio que no puede atravesarse después de un despliegue.
Este artículo cubre los nueve bits de permisos Unix, la diferencia entre notación octal y simbólica, el comportamiento específico del bit de ejecución en directorios, y el caso concreto de SSH donde los permisos incorrectos bloquean la autenticación.
Los tres conjuntos de permisos
Unix aplica los permisos de cada archivo y directorio en tres niveles:
- Propietario (user / u): el usuario que creó el archivo o al que se lo asignó
chown. - Grupo (group / g): el grupo asociado al archivo. En servidores web, el proceso
nginxoapachesuele pertenecer a un grupo comowww-data. - Otros (other / o): cualquier otro usuario del sistema que no sea el propietario ni miembro del grupo.
Cuando un proceso intenta acceder a un archivo, el kernel aplica el primer conjunto que corresponda. Si el proceso corre como el propietario, solo se evalúan los permisos del propietario —aunque el grupo tenga más acceso, no importa. Si el proceso pertenece al grupo, se aplican los permisos del grupo. En cualquier otro caso, los de "otros". Los conjuntos son mutuamente excluyentes.
Los tres bits: qué significan en archivos y en directorios
Cada conjunto tiene tres bits. Su significado cambia según el tipo de objeto.
En archivos
| Bit | Valor | Significado |
|---|---|---|
| r (lectura) | 4 | Leer el contenido (cat, less, cp) |
| w (escritura) | 2 | Modificar o truncar el contenido |
| x (ejecución) | 1 | Ejecutarlo como programa (./script.sh) |
En directorios
| Bit | Valor | Significado |
|---|---|---|
| r (lectura) | 4 | Leer las entradas del directorio: los nombres de archivo que contiene |
| w (escritura) | 2 | Crear, eliminar o renombrar archivos dentro |
| x (traversal) | 1 | Acceder al directorio (cd), obtener metadatos de sus archivos y abrir su contenido |
El bit x en directorios es la fuente de confusión más frecuente. Un directorio con permisos 644 (rw-r--r--) tiene r pero no x: el sistema puede leer las entradas del directorio y obtener los nombres de archivo, pero sin el bit x no es posible obtener sus metadatos (permisos, tamaño, fecha), entrar con cd ni abrir los archivos dentro. En ls -l, cada fila muestra ? en los campos de permisos y tamaño porque el kernel no puede ejecutar la llamada stat() sobre los archivos sin permiso de traversal.
# Directorio con 644: nombres visibles, nada más
$ ls /var/data
index.html config.php # nombres leídos de las entradas del directorio
$ ls -l /var/data
ls: cannot access '/var/data/index.html': Permission denied
# (o bien: ?????????? ? ?) # sin bit x, stat() no puede ejecutarse
$ cd /var/data
bash: cd: /var/data: Permission deniedPor eso el modo estándar de directorios es 755 y no 644. Un servidor Nginx que sirve archivos de un directorio con 644 puede leer los nombres, pero recibe 403 Forbidden al intentar abrir los archivos —le falta el bit x para traversal.
Notación octal: de bits a número
Cada conjunto de tres bits se convierte en un dígito del 0 al 7 sumando los valores de los bits activos (r=4, w=2, x=1). La notación final concatena los tres dígitos: propietario, grupo, otros.
chmod 755 /var/www
│││
││└── otros: r-x = 4+0+1 = 5
│└─── grupo: r-x = 4+0+1 = 5
└──── propietario: rwx = 4+2+1 = 7Tabla de los 8 valores posibles:
| Octal | Simbólico | Permisos activos |
|---|---|---|
| 7 | rwx | Leer, escribir, ejecutar/traversar |
| 6 | rw- | Leer y escribir |
| 5 | r-x | Leer y ejecutar/traversar |
| 4 | r-- | Solo leer (o listar nombres en directorios) |
| 3 | -wx | Escribir y ejecutar |
| 2 | -w- | Solo escribir |
| 1 | --x | Solo ejecutar/traversar |
| 0 | --- | Sin acceso |
La calculadora de permisos de Kuvron traduce en tiempo real entre checkboxes visuales y el dígito octal: al marcar o desmarcar cualquier casilla, el valor octal se actualiza automáticamente. También acepta el número directamente en el campo de edición y ajusta los checkboxes en consecuencia.
Notación simbólica: modificar permisos de forma relativa
chmod también acepta un modo simbólico que modifica permisos relativos al estado actual, sin necesidad de conocer ni especificar los nueve bits completos.
La sintaxis es [quién][operador][permisos]:
- Quién:
u(propietario),g(grupo),o(otros),a(todos) - Operador:
+(agregar),-(quitar),=(establecer, quitando el resto) - Permisos:
r,w,x
chmod u+x script.sh # agrega ejecución para el propietario
chmod go-w archivo.conf # quita escritura a grupo y otros
chmod a+r archivo.txt # todos pueden leer
chmod u=rwx,go=rx /var/www # equivalente a 755La diferencia práctica respecto a la notación octal: chmod g+w archivo agrega escritura al grupo sin alterar los otros seis bits, algo que con un número octal requeriría conocer el estado actual para calcular el nuevo valor completo.
Permisos comunes y cuándo usarlos
| Modo | Simbólico | Cuándo usarlo |
|---|---|---|
| 644 | rw-r--r-- | Archivos de texto, HTML, JSON: el propietario edita, todos leen |
| 755 | rwxr-xr-x | Directorios y scripts ejecutables |
| 600 | rw------- | Claves SSH privadas, archivos con credenciales sensibles |
| 700 | rwx------ | Directorios privados (~/.ssh, ~/.gnupg) |
| 400 | r-------- | Archivos que solo deben leerse (OpenSSH también acepta este modo para claves privadas) |
| 640 | rw-r----- | Config accesible al grupo del servidor pero no a "otros" |
| 664 | rw-rw-r-- | Archivos colaborativos entre miembros del mismo grupo |
| 777 | rwxrwxrwx | ⚠ Todo acceso — evitar en producción |
La calculadora de Kuvron incluye cuatro presets seleccionables: 644, 755, 600 y 777. Al seleccionar 777, la herramienta muestra una advertencia explícita. El modo 777 da acceso de escritura y ejecución a cualquier usuario del sistema —en un servidor con múltiples procesos o usuarios, cualquier proceso comprometido puede reemplazar o modificar el archivo.
chmod -R: aplicar permisos recursivamente
El flag -R aplica el comando a todos los archivos y subdirectorios dentro de una ruta:
chmod -R 755 /var/www/htmlEl problema habitual: aplica el mismo modo a archivos y a directorios por igual. 755 en directorios es correcto. 755 en un archivo config.json o index.php agrega innecesariamente el bit de ejecución.
Para aplicar permisos distintos según el tipo de objeto se combina find con chmod:
# Directorios: 755 (rwxr-xr-x)
find /var/www/html -type d -exec chmod 755 {} +
# Archivos: 644 (rw-r--r--)
# ⚠ Revisa antes de ejecutar: este comando quita el bit x de todos los archivos.
# Si el directorio contiene scripts u otros ejecutables que necesitan x,
# excluirlos explícitamente o ajustarlos después.
find /var/www/html -type f -exec chmod 644 {} +En un directorio web con únicamente HTML, CSS, PHP e imágenes, el segundo comando es seguro. En un directorio que mezcla assets con scripts de deploy o binarios ejecutables, ajustar los casos antes de correrlo.
Permisos SSH: un caso práctico de seguridad
OpenSSH impone restricciones sobre los permisos de las claves privadas. Si la clave privada es accesible por otros usuarios del sistema, el cliente SSH la rechaza con este error:
WARNING: UNPROTECTED PRIVATE KEY FILE!
Permissions 0644 for '/home/user/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/home/user/.ssh/id_rsa": bad permissions
user@host: Permission denied (publickey).La razón: el cliente ssh verifica que la clave privada no sea legible por grupo ni por otros. El requisito es que únicamente el propietario tenga acceso —lo que en la práctica significa 600 (rw-------) o 400 (r--------).
Para otros archivos del directorio ~/.ssh, la práctica habitual recomendada es:
| Ruta | Modo recomendado | Notas |
|---|---|---|
| ~/.ssh/ | 700 | Práctica habitual para evitar que otros accedan al directorio; algunas configuraciones admiten 755 |
| ~/.ssh/id_rsa (o id_ed25519) | 600 | Clave privada: solo el propietario lee y escribe. 400 también es válido |
| ~/.ssh/id_rsa.pub | 644 | Clave pública: puede ser leída por todos |
| ~/.ssh/authorized_keys | 600 | Recomendado para evitar modificaciones no autorizadas |
| ~/.ssh/config | 600 | Recomendado; algunos entornos admiten 644 |
Comandos para corregir los permisos de una clave privada. Ejecutar solo los correspondientes a archivos que existan y al nombre real de la clave en uso:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa # sustituir por id_ed25519 u otro si es el caso
chmod 644 ~/.ssh/id_rsa.pub # idem para la clave pública correspondiente
chmod 600 ~/.ssh/authorized_keys # omitir si no existe o no aplicaSi SSH sigue rechazando la conexión después de ajustar la clave, verificar que el directorio ~/.ssh no tenga permisos más abiertos de lo habitual y que el propietario de todos los archivos sea el usuario correcto (ls -la ~/.ssh). Un directorio con permisos incorrectos puede anular la protección de los archivos dentro.
Los archivos de clave SSH en formato PEM incluyen el material criptográfico representado en Base64 —una codificación de transporte que no cifra ni protege la clave por sí sola. Si te interesa entender qué hace Base64 y por qué no equivale a cifrado, el artículo Base64: qué es, cómo funciona y por qué no es cifrado lo cubre en detalle.
Errores frecuentes
Usar 777 para resolver "Permission denied"
El error Permission denied casi nunca se resuelve con 777. Propietario o grupo incorrectos son causas frecuentes, pero también conviene revisar los permisos de los directorios superiores en la ruta de acceso y otras restricciones del sistema. Si el archivo tiene los permisos correctos y el error persiste, el problema puede estar en algún directorio más arriba en la jerarquía.
Directorio en 644 y 403 Forbidden en el servidor web
Un directorio con 644 lista nombres pero no puede traversarse. Nginx y Apache necesitan el bit x para acceder a los archivos dentro. Modo correcto para directorios: 755.
Directorio privado en 600 en lugar de 700
600 en un directorio da lectura y escritura pero no traversal: nadie puede entrar. El modo correcto para un directorio privado es 700.
chmod -R 755 en un directorio con scripts y assets juntos
Aplica el bit de ejecución a todos los archivos sin distinción. Usar find -type d y find -type f para diferenciar, con cuidado de no quitar el bit x a scripts o ejecutables que lo necesitan.
Confundir chmod 400 y chmod 0400
En la línea de comandos son equivalentes. El 0 inicial es la notación octal explícita. La diferencia aparece al especificar bits especiales —setuid, setgid, sticky— mediante un cuarto dígito: chmod 4755 archivo.
Preguntas frecuentes
¿Qué significa la d al principio en ls -la (como en drwxr-xr-x)?
La d indica que es un directorio. Otros tipos de archivo: - (archivo regular), l (enlace simbólico), p (named pipe), s (socket), c (device de caracteres), b (device de bloques). Los nueve caracteres siguientes son los permisos: tres para el propietario, tres para el grupo, tres para otros.
¿Existen más bits además de r, w y x? ¿Qué son setuid, setgid y sticky?
Sí. Existen tres bits especiales que forman un cuarto dígito octal (el que precede a los tres habituales): setuid (4), setgid (2) y sticky bit (1). Setuid en un ejecutable hace que corra con los permisos del propietario —así funciona /usr/bin/passwd, que necesita escribir /etc/shadow aunque lo ejecute un usuario sin privilegios. Setgid en un directorio hace que los archivos creados dentro hereden el grupo del directorio. Sticky bit en un directorio —clásicamente en /tmp— permite que solo el propietario de cada archivo pueda eliminarlo, aunque otros tengan escritura sobre el directorio. Se especifican como chmod 4755 archivo. La calculadora de permisos de Kuvron trabaja con el modo estándar de tres dígitos y no cubre estos bits especiales.
¿Por qué SSH sigue rechazando mi clave aunque tenga 600?
Verificar que el directorio ~/.ssh no tenga permisos más abiertos de lo habitual —700 es la práctica recomendada habitual. Verificar también que el propietario de todos los archivos en ~/.ssh sea el usuario correcto con ls -la ~/.ssh. Un authorized_keys con propietario incorrecto es una causa frecuente de "Permission denied (publickey)" que no se resuelve cambiando solo los permisos de la clave.
¿Qué es umask y cómo se relaciona con chmod?
umask define qué permisos se restan a los archivos nuevos al crearlos. El valor por defecto habitual es 0022. Para archivos, el sistema parte de 0666 y aplica la máscara: 0666 & ~0022 = 0644 —por eso los archivos nuevos aparecen con 644. Para directorios parte de 0777: 0777 & ~0022 = 0755. chmod cambia los permisos de un archivo ya existente; umask determina los permisos con los que se crean archivos nuevos.
¿chmod cambia el propietario de un archivo?
No. chmod solo modifica los bits de permisos. Para cambiar el propietario se usa chown usuario archivo. Para cambiar propietario y grupo a la vez: chown usuario:grupo archivo. En servidores web es habitual ejecutar chown -R www-data:www-data /var/www/html para que el proceso del servidor tenga acceso, y luego ajustar permisos con find diferenciando directorios y archivos —evitando un chmod -R 755 indiscriminado que agrega el bit de ejecución a todos los archivos.
¿Puedo cambiar permisos de un archivo que no me pertenece?
Solo con root o sudo. chmod falla con "Operation not permitted" si intentás cambiar los permisos de un archivo cuyo propietario no sos y no tenés privilegios de superusuario.
¿Qué diferencia hay entre chmod 755 y chmod u=rwx,go=rx?
En resultado, ninguna —ambas producen rwxr-xr-x. La diferencia práctica está en modificaciones relativas: chmod g+w archivo agrega escritura al grupo sin alterar los otros seis bits, algo que con un número octal requeriría conocer el estado actual del archivo para calcular el nuevo valor completo.
Fuentes
- The Open Group, The Single UNIX Specification — chmod (POSIX)
- Linux man7, chmod(1) — Linux manual page
- OpenBSD Manual Pages, ssh(1) — sección FILES
- Linux man7, inode(7) — bits de tipo y permisos