Permisos en Linux más allá de chmod: setuid, setgid, sticky bit y ACLs
Cuando rwx no basta: cómo funcionan los bits especiales, las ACLs POSIX y los atributos extendidos, con ejemplos reales y errores frecuentes.
rwx no siempre es suficiente
El modelo clásico de permisos de Unix son tres bits (read, write, execute) para tres clases (owner, group, other). Es simple y funciona el 90% del tiempo. El calculador chmod traduce entre notación octal y simbólica al vuelo. Pero hay casos donde necesitas más: ejecutar un binario con los privilegios del dueño, compartir un directorio entre varios usuarios sin colisiones, o dar acceso a un usuario concreto sin cambiar de grupo.
Los tres bits especiales
setuid (4000)
Cuando un binario tiene setuid, se ejecuta con los privilegios del dueño del archivo, no de quien lo lanza. El ejemplo canónico es /usr/bin/passwd: cualquier usuario puede cambiar su contraseña porque el binario corre como root para escribir en /etc/shadow.
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ...
chmod u+s archivo # activa setuid
Peligroso: un binario setuid con un bug de buffer overflow es una escalada instantánea a root. Nunca apliques setuid a shell scripts (el kernel lo ignora en la mayoría de sistemas modernos por seguridad).
setgid (2000)
En binarios: se ejecuta con el grupo del archivo. En directorios hace algo distinto y muy útil: cualquier archivo creado dentro hereda el grupo del directorio, no el grupo primario del usuario. Es la forma clásica de compartir carpetas entre varios usuarios de un mismo equipo.
chmod g+s /srv/compartida
# ahora todos los archivos nuevos serán del grupo "equipo"
sticky bit (1000)
En /tmp verás drwxrwxrwt. Ese t final es el sticky bit. Significa: en este directorio, solo el dueño del archivo (o root) puede borrarlo o renombrarlo, aunque el directorio tenga permiso de escritura para todos. Sin él, cualquier usuario podría borrar archivos de otros en /tmp.
Notación octal completa
El chmod octal admite cuatro dígitos, no tres. El primero son los bits especiales:
4755: setuid + rwxr-xr-x.2775: setgid + rwxrwxr-x (el clásico de carpetas compartidas).1777: sticky + rwxrwxrwx (el clásico de/tmp).
ACLs POSIX: cuando el modelo owner/group/other se queda corto
Imagina un archivo del que el dueño es Alice, el grupo es dev, y necesitas dar lectura solo a Bob (que no está en dev). Con permisos clásicos, o metes a Bob en el grupo (y le das acceso a todo lo demás del grupo) o abres a other (y se lo das al mundo). Ninguna opción es correcta.
Las ACLs POSIX permiten permisos por usuario y por grupo, adicionales al modelo clásico:
setfacl -m u:bob:r-- archivo.log
getfacl archivo.log
El ls -l muestra un + al final de los permisos para indicar que hay ACLs. Las ACLs por defecto en directorios (setfacl -d) se heredan a los hijos.
Atributos extendidos e inmutabilidad
Además de permisos hay atributos a nivel de filesystem (ext4, xfs, btrfs):
chattr +i archivo: inmutable. Ni root puede modificarlo sin quitar el flag. Útil para/etc/resolv.confen servidores.chattr +a archivo: append-only. Ideal para logs auditados.lsattrlos lista.
Capabilities: setuid granular
En lugar de dar todo el poder de root, las capabilities dividen los privilegios. Por ejemplo, para que un binario pueda abrir puertos <1024 sin ser root:
setcap 'cap_net_bind_service=+ep' /usr/local/bin/miservicio
Es la forma moderna y segura de sustituir muchos setuid.
Errores frecuentes
- chmod 777 "para que funcione": casi siempre es un fallo de propietario, no de permisos. Corrige con
chownen su lugar. - Copiar archivos con
cpsin-p: pierdes permisos y ownership. Usacp -aen scripts de despliegue. - setuid en scripts: no funciona y da falsa sensación de seguridad.
- No usar umask: el umask por defecto (022) da 755 a directorios y 644 a archivos. Para directorios compartidos, considera 002 (grupo con escritura).
Domina estos permisos y podrás resolver el 99% de los "no tengo acceso" sin caer en el clásico chmod 777.
Casos prácticos resueltos paso a paso
Directorio compartido entre varios usuarios del equipo
El escenario clásico: /srv/proyecto debe ser escribible por todo el grupo dev y los archivos nuevos deben heredar el grupo.
groupadd dev
usermod -aG dev ana && usermod -aG dev luis
mkdir -p /srv/proyecto
chgrp -R dev /srv/proyecto
chmod 2775 /srv/proyecto # setgid: hereda grupo
setfacl -d -m g:dev:rwx /srv/proyecto # ACL por defecto para nuevos ficheros
El 2 del 2775 es el bit setgid; sin él, cada usuario crearía archivos con su grupo primario y el resto no podría escribir. Comprueba el número con la calculadora chmod antes de aplicarlo.
Web server que solo debe leer, nunca escribir
chown -R deploy:www-data /var/www/app
find /var/www/app -type d -exec chmod 750 {} ;
find /var/www/app -type f -exec chmod 640 {} ;
chmod 770 /var/www/app/storage # única ruta escribible
Separar propietario (deploy) de grupo (www-data) es lo que impide que una vulnerabilidad en PHP sobrescriba tu código.
Claves SSH con permisos correctos
SSH rechaza claves demasiado abiertas. Los valores válidos son siempre:
~/.ssh→700~/.ssh/id_ed25519(privada) →600~/.ssh/id_ed25519.pubyauthorized_keys→644
Si generas el par con nuestro generador de claves SSH, aplica esos permisos justo después de copiarlas al servidor.
Auditar permisos peligrosos en todo el sistema
find / -xdev -perm -0002 -type f 2>/dev/null # escribibles por cualquiera
find / -xdev -perm -4000 -type f 2>/dev/null # binarios setuid
find /home -xdev -perm -0111 -name "*.conf" # configs ejecutables (sospechoso)
Guarda la salida como línea base y compárala tras cada despliegue: un fichero setuid nuevo suele ser la primera señal de una intrusión.
Tabla rápida de referencia
600— secretos: claves privadas,.env, tokens640— configuración legible por el grupo de servicio644— contenido público estático700— directorios privados de usuario750— directorio de aplicación con grupo de servicio755— directorios y binarios públicos2775— directorio compartido con setgid1777— solo para directorios tipo/tmp(sticky bit)
Cómo depurar un "Permission denied" en 60 segundos
1. namei -l /ruta/completa/al/fichero — muestra permisos de cada componente de la ruta; casi siempre el problema es un directorio intermedio sin x. 2. id usuario — comprueba que el usuario está realmente en el grupo (si acabas de añadirlo, necesita nueva sesión). 3. getfacl fichero — puede haber una ACL que sobrescriba lo que ves con ls -l. 4. ausearch -m avc -ts recent o dmesg | grep -i denied — si es SELinux o AppArmor, los permisos POSIX son correctos y el bloqueo viene de la política. 5. lsattr fichero — un +i (inmutable) bloquea incluso a root.
Preguntas frecuentes
?¿Qué significa exactamente chmod 755?
Lectura, escritura y ejecución para el propietario (7) y lectura más ejecución para grupo y resto (5 y 5). Es el valor habitual para directorios y binarios públicos, porque en un directorio el bit de ejecución permite entrar en él.
?¿Es seguro usar chmod 777?
No. 777 permite a cualquier usuario o proceso del sistema modificar y ejecutar el fichero. Casi siempre el problema real es el propietario o el grupo: corrígelo con chown o chgrp en lugar de abrir los permisos.
?¿Cuál es la diferencia entre permisos POSIX y ACL?
Los permisos POSIX solo definen propietario, un grupo y el resto. Las ACL (setfacl/getfacl) permiten dar permisos distintos a varios usuarios o grupos sobre el mismo fichero y definir herencia por defecto en directorios.
?¿Para qué sirve el bit setgid en un directorio?
Hace que los ficheros y subdirectorios creados dentro hereden el grupo del directorio en lugar del grupo primario del usuario. Es imprescindible en carpetas compartidas por un equipo.
?¿Por qué SSH rechaza mi clave privada?
Porque tiene permisos demasiado abiertos. La clave privada debe ser 600 y el directorio ~/.ssh 700, propiedad del usuario que la usa.
?¿Cómo veo los permisos en formato numérico?
Con el comando stat y el formato %a (por ejemplo, stat -c %a fichero). También puedes traducir entre notación simbólica y octal con la calculadora chmod de la web.
Herramientas relacionadas
Convierte entre notación simbólica (rwxr-xr-x) y octal (755) con explicación.
Genera pares de claves Ed25519, ECDSA o RSA directamente en el navegador con Web Crypto.
Genera unidades .service listas para instalar en /etc/systemd/system.