Llegas a la última lección del módulo con una deuda pendiente. Llevas seis lecciones viendo cadenas como -rw-r----- y drwxr-xr-x en cada ls -l, escribiendo sudo delante de ciertos comandos sin saber del todo por qué, y aceptando que /etc/tramontana/app.conf pertenece a root:tramontana sin poder explicar qué implica eso exactamente. Esta lección salda esa deuda.
El modelo de permisos de Unix tiene más de cincuenta años y sigue siendo, con diferencia, el mecanismo de seguridad más usado del planeta. Es sorprendentemente simple —nueve bits y dos identificadores— y sorprendentemente sutil: el mismo permiso significa cosas distintas en un archivo y en un directorio, y esa asimetría es la fuente de la mayoría de los malentendidos.
No es materia opcional. Un servidor con los permisos mal puestos funciona perfectamente hasta el día en que alguien lee un fichero que no debería, o borra uno que no era suyo, o consigue ejecutar código con privilegios ajenos. Al terminar esta lección sabrás diseñar los permisos de un despliegue completo y justificar cada decisión, que es exactamente lo que se espera de un administrador de sistemas.
Contenido
- El modelo de seguridad de Unix: usuario, grupo, otros
- Leer la cadena de
ls -lcarácter a carácter - Los tres permisos en archivos y en directorios
- Notación octal y notación simbólica
chmoden ambas notacioneschownychgrp- Grupos: por qué el trabajo en equipo no se resuelve con «otros»
- La máscara
umask - Bits especiales: SUID, SGID y sticky
- Caso práctico: los permisos de Tramontana Reservas
- El modelo de seguridad de Unix: usuario, grupo, otros
Todo archivo en Linux tiene exactamente un propietario y exactamente un grupo propietario. A partir de ahí, el sistema divide a todo el mundo en tres categorías, y cada una tiene su propio juego de permisos:
| Categoría | Letra | Quién es |
|---|---|---|
| Usuario (user) | u |
El propietario del archivo |
| Grupo (group) | g |
Los miembros del grupo propietario |
| Otros (others) | o |
Todos los demás usuarios del sistema |
Cuando un proceso intenta acceder a un archivo, el kernel evalúa en este orden estricto:
flowchart TD
A["Un proceso pide acceso a un archivo"] --> R{"¿El usuario<br/>es root?"}
R -->|Sí| RA["ACCESO CONCEDIDO<br/>(root se salta los permisos)"]
R -->|No| B{"¿El UID coincide con<br/>el propietario?"}
B -->|Sí| C["Aplicar los permisos de USUARIO<br/>y no mirar más"]
B -->|No| D{"¿El GID o alguno de<br/>sus grupos coincide?"}
D -->|Sí| E["Aplicar los permisos de GRUPO<br/>y no mirar más"]
D -->|No| F["Aplicar los permisos de OTROS"]
Hay un detalle en ese diagrama que sorprende y que hay que interiorizar: la primera categoría que coincide es la que se aplica, y no se sigue mirando. No es acumulativo.
Consecuencia práctica, y es contraintuitiva:
operador@srv-tramontana:~$ ls -l informe.txt
----rw-r-- 1 operador tramontana 240 ago 18 16:02 informe.txtEse archivo pertenece a operador, el propietario no tiene ningún permiso, y el grupo tiene lectura y escritura. Resultado: operador no puede leer su propio archivo, aunque pertenezca al grupo tramontana. El kernel comprueba primero si es el propietario, ve que sí, aplica --- y termina. No llega a mirar los permisos de grupo.
Es raro encontrarlo en la práctica, pero explica el modelo mejor que cualquier ejemplo bien configurado: los permisos no se suman, se seleccionan.
La excepción es root, que se salta la comprobación entera. Por eso sudo cat funciona sobre cualquier archivo, y por eso los permisos no protegen contra un administrador. Los detalles de sudo son la lección 05-02.
Detrás de los nombres hay números. El sistema trabaja con UID y GID:
operador@srv-tramontana:~$ id
uid=1001(operador) gid=1001(operador) grupos=1001(operador),27(sudo)
operador@srv-tramontana:~$ id -u
1001
operador@srv-tramontana:~$ id -un
operadorLos nombres son una comodidad para las personas; el kernel solo ve números. Esto importa al mover archivos entre máquinas: si copias con tar -p un archivo del UID 1001 a otro servidor donde el 1001 es otra persona, el archivo pasa a pertenecer a esa persona.
- Leer la cadena de
ls -l carácter a carácter
ls -l carácter a carácteroperador@srv-tramontana:~$ ls -l /etc/tramontana/app.conf
-rw-r----- 1 root tramontana 512 ago 18 08:47 /etc/tramontana/app.confLa cadena -rw-r----- tiene 10 caracteres con una estructura fija:
- rw- r-- --- │ │ │ │ │ │ │ └── OTROS: sin permisos │ │ └───────── GRUPO (tramontana): solo lectura │ └──────────────── USUARIO (root): lectura y escritura └────────────────────── TIPO: archivo regular
Carácter 1, el tipo. Los siete que viste en el Módulo 1:
| Carácter | Tipo |
|---|---|
- |
Archivo regular |
d |
Directorio |
l |
Enlace simbólico |
c |
Dispositivo de caracteres |
b |
Dispositivo de bloques |
s |
Socket |
p |
Tubería con nombre (FIFO) |
Caracteres 2 a 10, tres bloques de tres. En cada bloque, siempre en el mismo orden: r, w, x. Un guion significa que ese permiso no está.
Léela así, en voz alta hasta que salga solo:
-rw-r-----→ «archivo regular; el dueño lee y escribe; el grupo solo lee; los demás nada».
Más ejemplos del propio servidor:
operador@srv-tramontana:~$ ls -l /opt/tramontana/app/ejecutable /etc/passwd /tmp
-rwxr-xr-x 1 root root 50319872 ago 18 08:30 /opt/tramontana/app/ejecutable
-rw-r--r-- 1 root root 2891 ago 18 09:00 /etc/passwd
drwxrwxrwt 9 root root 4096 ago 18 16:10 /tmp| Cadena | Lectura |
|---|---|
-rwxr-xr-x |
Archivo; dueño lee, escribe y ejecuta; grupo y otros leen y ejecutan |
-rw-r--r-- |
Archivo; dueño lee y escribe; todos los demás solo leen |
drwxrwxrwt |
Directorio; todos pueden todo... con una t al final que cambia las reglas (apartado 9) |
Y el caso especial:
operador@srv-tramontana:~$ ls -l /usr/bin/python3
lrwxrwxrwx 1 root root 10 ago 2 12:04 /usr/bin/python3 -> python3.12lrwxrwxrwx: los permisos de un enlace simbólico son siempre estos y no significan nada. Como viste en la lección 02-06, los que se aplican son los del destino.
- Los tres permisos en archivos y en directorios
Aquí está el punto donde se pierde más gente. Las mismas tres letras significan cosas distintas según el objeto.
| Permiso | En un archivo | En un directorio |
|---|---|---|
r (4) |
Leer el contenido | Listar los nombres que contiene |
w (2) |
Modificar el contenido | Crear, borrar y renombrar entradas |
x (1) |
Ejecutarlo como programa | Atravesarlo: acceder a lo que hay dentro |
Cada una de las tres filas del lado derecho merece una demostración, porque las tres son contraintuitivas.
x en un directorio: atravesar
x en un directorio se llama a veces search permission. Sin él no puedes acceder a nada de dentro, aunque sepas el nombre exacto y aunque el archivo interior te dé todos los permisos.
operador@srv-tramontana:~$ mkdir -p prueba/interior
operador@srv-tramontana:~$ echo "contenido" > prueba/interior/dato.txt
operador@srv-tramontana:~$ chmod 666 prueba/interior/dato.txt
operador@srv-tramontana:~$ chmod 666 prueba # rw- sin x
operador@srv-tramontana:~$ ls prueba
interior
operador@srv-tramontana:~$ cat prueba/interior/dato.txt
cat: prueba/interior/dato.txt: Permiso denegadoEl archivo tiene rw-rw-rw-: cualquiera puede leerlo. Pero para llegar hasta él, el kernel tiene que atravesar prueba, y ahí no hay x. Acceso denegado.
Y al revés, x sin r:
operador@srv-tramontana:~$ chmod 111 prueba # --x--x--x
operador@srv-tramontana:~$ ls prueba
ls: no se puede abrir el directorio 'prueba': Permiso denegado
operador@srv-tramontana:~$ cat prueba/interior/dato.txt
contenidoNo puedes ver qué hay dentro, pero sí acceder a lo que hay si sabes el nombre exacto. Es un directorio «a ciegas».
Esto no es una curiosidad: es un patrón de seguridad de uso habitual. Un directorio 711 permite que un servicio web sirva /var/www/sitio/pagina.html sin que nadie pueda listar el contenido del directorio y descubrir qué otros archivos hay. Lo mismo se aplica a /home, que en muchos sistemas es 711: los usuarios pueden entrar en su propio home, pero no listar los homes ajenos.
Regla que hay que memorizar: para acceder a /a/b/c/fichero, necesitas x en /, en a, en b y en c, y luego el permiso adecuado sobre fichero. Una sola carencia de x en cualquier punto del camino bloquea todo lo que hay debajo.
r sin x en un directorio
operador@srv-tramontana:~$ chmod 444 prueba # r--r--r--
operador@srv-tramontana:~$ ls prueba
interior
operador@srv-tramontana:~$ ls -l prueba
ls: no se puede acceder a 'prueba/interior': Permiso denegado
total 0
d????????? ? ? ? ? ? interiorPuedes leer los nombres, porque los nombres están en el propio directorio. Pero ls -l necesita consultar los inodos de cada entrada, y para eso hay que atravesar el directorio. De ahí esa salida con interrogantes: ls conoce el nombre y nada más.
r sin x en un directorio es prácticamente inútil. En la práctica, los directorios llevan r y x juntos o ninguno de los dos.
w en un directorio: el permiso que sorprende
Este es el más importante de entender, porque contradice la intuición.
operador@srv-tramontana:~$ chmod 777 prueba
operador@srv-tramontana:~$ sudo touch prueba/de-root.txt
operador@srv-tramontana:~$ sudo chmod 600 prueba/de-root.txt
operador@srv-tramontana:~$ ls -l prueba/de-root.txt
-rw------- 1 root root 0 ago 18 16:25 prueba/de-root.txt
operador@srv-tramontana:~$ cat prueba/de-root.txt
cat: prueba/de-root.txt: Permiso denegado
operador@srv-tramontana:~$ rm prueba/de-root.txt
operador@srv-tramontana:~$ ls prueba/
interiorHas borrado un archivo de root que ni siquiera podías leer.
La explicación es coherente con lo que sabes de la lección 02-06: borrar un archivo no es una operación sobre el archivo, es una operación sobre el directorio que lo contiene. rm elimina una entrada de la lista de nombres del directorio. Y para modificar esa lista solo hace falta w en el directorio.
Los permisos del archivo controlan su contenido. Los permisos del directorio controlan la lista de nombres. Son dos cosas distintas.
Resumen de qué permite w en un directorio:
| Operación | ¿Qué permiso hace falta? |
|---|---|
| Leer un archivo | r en el archivo, x en el camino |
| Modificar el contenido de un archivo | w en el archivo, x en el camino |
| Crear un archivo | w + x en el directorio |
| Borrar un archivo | w + x en el directorio (los del archivo dan igual) |
| Renombrar un archivo | w + x en el directorio |
| Listar el directorio | r en el directorio |
Entrar (cd) |
x en el directorio |
Este comportamiento es la razón de ser del sticky bit, que verás en el apartado 9, y explica por qué /tmp, donde todo el mundo escribe, no es un caos de gente borrándose archivos.
- Notación octal y notación simbólica
Los nueve bits de permisos se expresan de dos formas.
Octal
Cada permiso tiene un valor numérico y se suman por bloque:
| Permiso | Valor |
|---|---|
r |
4 |
w |
2 |
x |
1 |
- |
0 |
Un dígito por bloque, tres dígitos en total: usuario, grupo, otros.
| Octal | Simbólico | Suma |
|---|---|---|
| 0 | --- |
0 |
| 1 | --x |
1 |
| 2 | -w- |
2 |
| 3 | -wx |
2+1 |
| 4 | r-- |
4 |
| 5 | r-x |
4+1 |
| 6 | rw- |
4+2 |
| 7 | rwx |
4+2+1 |
Los que aparecen de verdad en un sistema:
| Octal | Cadena | Uso típico |
|---|---|---|
| 644 | rw-r--r-- |
Archivo normal, legible por todos |
| 600 | rw------- |
Archivo privado. Claves SSH |
| 640 | rw-r----- |
Configuración con secretos, legible por un grupo |
| 755 | rwxr-xr-x |
Ejecutable o directorio público |
| 750 | rwxr-x--- |
Directorio para un grupo concreto |
| 700 | rwx------ |
Directorio privado |
| 711 | rwx--x--x |
Directorio atravesable pero no listable |
| 775 | rwxrwxr-x |
Directorio de trabajo compartido por un grupo |
| 777 | rwxrwxrwx |
Todos pueden todo. Casi nunca correcto |
Traducción en ambos sentidos
De simbólico a octal, bloque a bloque:
De octal a simbólico, descomponiendo cada dígito:
Practica con estos hasta que salgan sin pensar:
| Octal | Simbólico |
|---|---|
| 644 | rw-r--r-- |
| 755 | rwxr-xr-x |
| 600 | rw------- |
| 640 | rw-r----- |
| 664 | rw-rw-r-- |
| 751 | rwxr-x--x |
| 400 | r-------- |
Y al revés:
| Simbólico | Octal |
|---|---|
rwxrwx--- |
770 |
r-xr-x--- |
550 |
rw-rw-rw- |
666 |
--x--x--x |
111 |
rwx------ |
700 |
Truco mental: 7 es todo, 6 es leer y escribir, 5 es leer y ejecutar, 4 es solo leer, 0 es nada. Con esos cinco cubres el 95 % de los casos reales.
stat te da las dos notaciones a la vez, lo que va muy bien mientras aprendes:
operador@srv-tramontana:~$ stat -c '%a %A %n' /etc/tramontana/app.conf /opt/tramontana/app
640 -rw-r----- /etc/tramontana/app.conf
755 drwxr-xr-x /opt/tramontana/appSimbólica
La notación simbólica se usa para modificar permisos sin tocar los demás. Su gramática es:
| Quién | Operador | Permiso | |||
|---|---|---|---|---|---|
u |
usuario | + |
añadir | r |
leer |
g |
grupo | - |
quitar | w |
escribir |
o |
otros | = |
fijar exactamente | x |
ejecutar |
a |
todos (ugo) |
X |
x solo si ya es directorio o tenía algún x |
Esa X mayúscula es una joya poco conocida y la verás en acción en el apartado siguiente.
chmod en ambas notaciones
chmod en ambas notaciones# Octal: fija los nueve bits de golpe
operador@srv-tramontana:~$ chmod 640 datos/casas.txt
operador@srv-tramontana:~$ ls -l datos/casas.txt
-rw-r----- 1 operador operador 446 ago 18 13:02 datos/casas.txt
# Simbólica: modifica solo lo indicado
operador@srv-tramontana:~$ chmod g+w datos/casas.txt
operador@srv-tramontana:~$ ls -l datos/casas.txt
-rw-rw---- 1 operador operador 446 ago 18 13:02 datos/casas.txt
operador@srv-tramontana:~$ chmod o=r datos/casas.txt
operador@srv-tramontana:~$ ls -l datos/casas.txt
-rw-rw-r-- 1 operador operador 446 ago 18 13:02 datos/casas.txt
operador@srv-tramontana:~$ chmod a-w datos/casas.txt
operador@srv-tramontana:~$ ls -l datos/casas.txt
-r--r--r-- 1 operador operador 446 ago 18 13:02 datos/casas.txtSe pueden combinar varias reglas con comas:
operador@srv-tramontana:~$ chmod u=rw,g=r,o= datos/casas.txt
operador@srv-tramontana:~$ ls -l datos/casas.txt
-rw-r----- 1 operador operador 446 ago 18 13:02 datos/casas.txtCuándo usar cada notación:
| Situación | Notación |
|---|---|
| Sabes exactamente qué permisos quieres | Octal: chmod 640 |
| Quieres hacer un cambio puntual sin tocar el resto | Simbólica: chmod g+w |
| Scripts y documentación | Octal: es explícita e inequívoca |
| Recursivo sobre árboles mixtos | Simbólica con X |
-v y --changes muestran lo que hace, útil para verificar:
operador@srv-tramontana:~$ chmod -v 644 datos/casas.txt
el modo de 'datos/casas.txt' cambiado de 0640 (rw-r-----) a 0644 (rw-r--r--)Y --reference copia los permisos de otro archivo:
-R y el problema del recursivo
Parece razonable y acaba de romper todos los directorios del árbol. Al quitarles el x, ya no se pueden atravesar:
operador@srv-tramontana:~$ ls trabajo/2026
ls: no se puede abrir el directorio 'trabajo/2026': Permiso denegadoEl problema es que archivos y directorios necesitan permisos distintos: los archivos normalmente no deben ser ejecutables, y los directorios siempre necesitan x.
La solución correcta es la X mayúscula:
X aplica x solo a los directorios y a los archivos que ya tenían algún bit de ejecución. Los ficheros de datos no se vuelven ejecutables; los directorios conservan su capacidad de ser atravesados. Es exactamente lo que quieres en el 100 % de los casos recursivos.
La alternativa clásica, si prefieres separar explícitamente, usa find (lección 03-03):
operador@srv-tramontana:~$ find /home/operador/trabajo -type d -exec chmod 750 {} +
operador@srv-tramontana:~$ find /home/operador/trabajo -type f -exec chmod 640 {} +Por qué chmod -R 777 nunca es la solución
Aparece en cientos de respuestas de foros como remedio para «permiso denegado». Merece una explicación seria de por qué está mal, porque el argumento «es inseguro» a secas no convence a nadie que tenga prisa.
1. No arregla el problema, lo enmascara. Si algo daba «permiso denegado», había una razón: un usuario equivocado, un grupo mal asignado, una x que falta en un directorio del camino. 777 hace que el síntoma desaparezca sin que sepas cuál era la causa. Volverá a aparecer en otro sitio.
2. Cualquier usuario del sistema puede modificarlo. Y en un servidor hay más usuarios de los que crees: cuentas de servicio como www-data, nobody, postgres. Si un atacante compromete el servicio web —que no tiene privilegios— y tu aplicación es 777, puede reescribirla entera. Le has dado ejecución de código como el usuario que ejecuta la aplicación.
3. Con -R sobre directorios, es peor. Los directorios 777 permiten a cualquiera borrar y sustituir archivos que no son suyos, por lo que viste en el apartado 3. Un atacante puede reemplazar un binario por el suyo.
4. Marca los archivos como ejecutables. Un .conf o un .csv con permiso de ejecución es una señal de alarma para cualquier auditoría, y en algunos servidores web una configuración desafortunada puede hacer que un archivo ejecutable se ejecute en vez de servirse.
5. Es prácticamente irreversible. Después de un chmod -R 777 /var, no hay forma de saber qué permisos tenía cada archivo. En algunos casos hay que reinstalar paquetes para recuperarlos.
El diagnóstico correcto cuando algo da «permiso denegado»:
# 1. ¿Quién soy y a qué grupos pertenezco?
operador@srv-tramontana:~$ id
# 2. ¿Qué permisos tiene el archivo y de quién es?
operador@srv-tramontana:~$ ls -l /ruta/al/archivo
# 3. ¿Y todos los directorios del camino? (esta es la que se olvida)
operador@srv-tramontana:~$ namei -l /ruta/al/archivo
f: /ruta/al/archivo
drwxr-xr-x root root /
drwxr-x--- root root ruta
drwxr-xr-x root root al
-rw-r--r-- root root archivonamei -l muestra los permisos de cada componente de la ruta, y es la herramienta que resuelve el caso más frecuente: el archivo está bien, pero un directorio intermedio no te deja pasar. En este ejemplo, ruta es drwxr-x--- y pertenece a root:root: ahí está el bloqueo.
chown y chgrp
chown y chgrpchown cambia el propietario, chgrp el grupo:
operador@srv-tramontana:~$ sudo chown root /etc/tramontana/app.conf
operador@srv-tramontana:~$ sudo chgrp tramontana /etc/tramontana/app.conf
# Las dos cosas de una vez, con dos puntos
operador@srv-tramontana:~$ sudo chown root:tramontana /etc/tramontana/app.conf
operador@srv-tramontana:~$ ls -l /etc/tramontana/app.conf
-rw-r----- 1 root tramontana 512 ago 18 08:47 /etc/tramontana/app.confFormas de chown:
| Sintaxis | Qué cambia |
|---|---|
chown usuario fichero |
Solo el propietario |
chown usuario:grupo fichero |
Ambos |
chown :grupo fichero |
Solo el grupo (como chgrp) |
chown usuario: fichero |
Propietario, y el grupo pasa a ser el principal de ese usuario |
Opciones:
| Opción | Qué hace |
|---|---|
-R |
Recursivo |
-v / --changes |
Informa de los cambios |
--reference=fich |
Copia el dueño y grupo de otro archivo |
-h |
Actúa sobre el enlace simbólico, no sobre su destino |
--from=usr:grp |
Cambia solo los que ya tenían ese dueño |
Importante: chown requiere root. Un usuario normal no puede regalar un archivo a otro:
operador@srv-tramontana:~$ chown alumno datos/casas.txt
chown: cambiando el propietario de 'datos/casas.txt': Operación no permitidaLa razón es concreta: si pudieras, podrías burlar las cuotas de disco creando archivos enormes y asignándoselos a otro. Y podrías crear un archivo con SUID y regalárselo a root, lo que sería un agujero de seguridad inmediato.
chgrp sí lo puede hacer un usuario normal, pero solo si es miembro del grupo destino:
operador@srv-tramontana:~$ chgrp sudo datos/casas.txt
operador@srv-tramontana:~$ ls -l datos/casas.txt
-rw-r--r-- 1 operador sudo 446 ago 18 13:02 datos/casas.txt
operador@srv-tramontana:~$ chgrp adm datos/casas.txt
chgrp: cambiando el grupo de 'datos/casas.txt': Operación no permitidaoperador es miembro de sudo, así que puede; no es miembro de adm, así que no.
--reference es muy práctico para replicar la propiedad de un archivo modelo:
operador@srv-tramontana:~$ sudo chown --reference=/etc/tramontana/app.conf /etc/tramontana/nuevo.confY -h importa con enlaces:
operador@srv-tramontana:~$ sudo chown root:root ~/app-produccion # cambia el DESTINO
operador@srv-tramontana:~$ sudo chown -h root:root ~/app-produccion # cambia el ENLACEComo el propietario de un symlink es irrelevante para el control de acceso, -h se usa poco; pero conviene saber que sin -h, chown sobre un enlace toca el destino, lo que puede tener consecuencias inesperadas al recorrer un árbol con -R.
- Grupos: por qué el trabajo en equipo no se resuelve con «otros»
Cada usuario tiene un grupo principal (el de sus archivos nuevos) y puede pertenecer a varios grupos secundarios.
operador@srv-tramontana:~$ id
uid=1001(operador) gid=1001(operador) grupos=1001(operador),27(sudo)
operador@srv-tramontana:~$ groups
operador sudo
operador@srv-tramontana:~$ id -Gn operador
operador sudoEn Ubuntu, cada usuario tiene por defecto un grupo propio con su mismo nombre (esquema UPG, User Private Group). El motivo es que permite trabajar con una umask más permisiva de forma segura: como el grupo del usuario solo lo contiene a él, dar permisos de grupo no expone nada.
Consultar los grupos del sistema:
operador@srv-tramontana:~$ getent group sudo
sudo:x:27:operador
operador@srv-tramontana:~$ getent group | tail -n 4
operador:x:1001:
tramontana:x:1002:operador
adm:x:4:syslogEl planteamiento
Marta plantea el escenario real: Luis Ferrer necesita poder leer los logs de la aplicación y escribir en el directorio de despliegues; en el futuro se incorporará otra persona con las mismas necesidades. ¿Cómo se resuelve?
Opción incorrecta: dar permisos a «otros».
Qué has hecho realmente: has dado esos permisos a todos los usuarios del sistema. No solo a Luis, sino a www-data, a nobody, a cualquier cuenta de servicio y a cualquier cuenta que se cree en el futuro. Si un atacante compromete un servicio sin privilegios, tiene acceso a tus logs (que contienen nombres de usuario y patrones de uso) y puede escribir en tu directorio de copias.
Y para gestionarlo: si mañana quieres quitarle el acceso solo a Luis, no puedes. «Otros» no distingue personas.
Opción correcta: un grupo compartido.
# (Esto se hará formalmente en la lección 05-01)
sudo groupadd tramontana
sudo usermod -aG tramontana operador
sudo usermod -aG tramontana luis
sudo chgrp -R tramontana /var/log/tramontana /srv/tramontana/backups
sudo chmod -R g+rX /var/log/tramontana
sudo chmod -R g+rwX /srv/tramontana/backups
sudo chmod o= /var/log/tramontana /srv/tramontana/backupsVentajas concretas:
| Criterio | Permisos a «otros» | Grupo compartido |
|---|---|---|
| Alcance | Todos, incluidas cuentas de servicio | Solo los miembros |
| Dar acceso a alguien nuevo | Ya lo tiene (mal) | usermod -aG, un comando |
| Quitar acceso a una persona | Imposible | gpasswd -d, un comando |
| Auditar quién tiene acceso | Imposible de responder | getent group tramontana |
| Cuentas de servicio comprometidas | Tienen acceso | No lo tienen |
| Escala a más personas | No | Sí |
La regla es absoluta: en un sistema multiusuario, el acceso compartido se resuelve con grupos. El permiso de «otros» se usa para lo que de verdad debe ser público, y en la mayoría de los casos correctos vale 0.
Un detalle que sorprende y hay que conocer: los grupos de un proceso se determinan al iniciar sesión. Si te añaden a un grupo mientras tienes la sesión abierta, tu shell no lo ve:
operador@srv-tramontana:~$ sudo usermod -aG tramontana operador
operador@srv-tramontana:~$ groups
operador sudo # <- tramontana no aparece
operador@srv-tramontana:~$ id -nG operador
operador sudo tramontana # <- pero el sistema ya lo sabeHay que cerrar la sesión y volver a entrar (o usar newgrp tramontana para la sesión actual). Es una fuente clásica de «le he dado permisos y sigue sin funcionar».
Ojo también con usermod -aG: la -a es obligatoria. Sin ella, usermod -G tramontana operador sustituye todos los grupos secundarios por ese, lo que sacaría a operador del grupo sudo y le dejaría sin poder administrar el sistema. Es un error que se comete una vez en la vida.
- La máscara
umask
umaskCuando creas un archivo, no eliges sus permisos: los pone el sistema. La umask es la máscara que decide cuáles se quitan.
Los valores de partida están fijados por el kernel:
| Objeto | Permisos base | Por qué |
|---|---|---|
| Archivo | 666 (rw-rw-rw-) |
Nunca ejecutable por defecto: crear un archivo no debe crear un programa |
| Directorio | 777 (rwxrwxrwx) |
Necesita x para ser atravesable |
La umask se resta de esos valores. Más exactamente, se aplica una operación de bits que elimina los permisos marcados en la máscara.
Cálculo con umask 022:
Comprobación:
operador@srv-tramontana:~$ umask 022
operador@srv-tramontana:~$ touch prueba-022.txt && mkdir dir-022
operador@srv-tramontana:~$ ls -ld prueba-022.txt dir-022
drwxr-xr-x 2 operador operador 4096 ago 18 17:02 dir-022
-rw-r--r-- 1 operador operador 0 ago 18 17:02 prueba-022.txtCálculo con umask 027:
operador@srv-tramontana:~$ umask 027
operador@srv-tramontana:~$ touch prueba-027.txt && mkdir dir-027
operador@srv-tramontana:~$ ls -ld prueba-027.txt dir-027
drwxr-x--- 2 operador operador 4096 ago 18 17:04 dir-027
-rw-r----- 1 operador operador 0 ago 18 17:04 prueba-027.txtComparativa de las máscaras habituales:
| umask | Archivos | Directorios | Efecto | Dónde se usa |
|---|---|---|---|---|
| 022 | 644 | 755 | Todos leen, solo el dueño escribe | Por defecto en la mayoría de distribuciones |
| 002 | 664 | 775 | El grupo también escribe | Ubuntu para usuarios normales (con UPG) |
| 027 | 640 | 750 | «Otros» no ve nada | Servidores con datos sensibles |
| 077 | 600 | 700 | Solo el dueño | Máxima privacidad; cuentas de root |
| 007 | 660 | 770 | Grupo total, otros nada | Directorios de equipo |
Un matiz técnico importante: la umask quita bits, nunca los añade. Por eso decir «se resta» es una simplificación útil pero no exacta. Con umask 022 y permisos base 666, el resultado es 644. Pero si un programa pide crear un archivo con permisos 600 explícitamente, la umask no lo subirá a 644: el resultado será 600. La umask solo puede ser más restrictiva que lo que se pide.
Otro matiz: un dígito impar en la umask sobre archivos no tiene efecto visible, porque los archivos nacen sin x de todos modos. umask 023 y umask 022 producen archivos idénticos, pero directorios distintos (754 frente a 755).
Dónde se define la umask:
# Solo para la sesión actual
operador@srv-tramontana:~$ umask 027
# Permanente para tu usuario
operador@srv-tramontana:~$ echo "umask 027" >> ~/.bashrc
# Para todo el sistema
operador@srv-tramontana:~$ grep -r "UMASK" /etc/login.defs
UMASK 022Los servicios de systemd tienen su propia directiva UMask= en su fichero de unidad, y no heredan la de tu shell. Lo verás en la lección 05-05.
Recomendación para srv-tramontana: umask 027 para las cuentas administrativas. Con datos de huéspedes en el sistema, el valor por defecto de que cualquier usuario pueda leer los archivos nuevos es demasiado permisivo. Con 027, todo lo que crees nace sin acceso para «otros», que es el principio de mínimo privilegio aplicado desde el origen.
- Bits especiales: SUID, SGID y sticky
Además de los nueve bits, hay tres más. Aquí solo vas a aprender a reconocerlos cuando los veas y qué hacen en una frase. Su estudio a fondo, con sus implicaciones de seguridad y su uso correcto, es la lección 05-02.
| Bit | Octal | Se ve en ls -l |
Qué hace |
|---|---|---|---|
| SUID | 4000 | s en la x del usuario |
El programa se ejecuta con los privilegios de su propietario, no de quien lo lanza |
| SGID | 2000 | s en la x del grupo |
En un ejecutable: corre con el grupo del archivo. En un directorio: los archivos nuevos heredan el grupo del directorio |
| Sticky | 1000 | t en la x de otros |
En un directorio: solo el propietario de un archivo puede borrarlo |
SUID: /usr/bin/passwd
operador@srv-tramontana:~$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 mar 23 13:47 /usr/bin/passwdEsa s donde debería ir la x del usuario es el bit SUID.
El problema que resuelve: las contraseñas se guardan cifradas en /etc/shadow, que es -rw-r----- de root:shadow. Un usuario normal no puede ni leerlo. Pero debe poder cambiar su propia contraseña, y eso implica escribir en ese archivo.
Con SUID, cuando operador ejecuta passwd, el proceso corre como root —el propietario del programa— y puede escribir en /etc/shadow. El programa está escrito para permitir únicamente cambiar la contraseña propia.
Esto es también la razón de que los programas SUID sean el objetivo favorito de los atacantes: un fallo en un binario SUID de root es una escalada de privilegios directa. Por eso son pocos, están auditados, y encontrar uno inesperado en un servidor es motivo de alarma.
SGID en directorios: herencia de grupo
operador@srv-tramontana:~$ ls -ld /srv/tramontana/compartido
drwxrws--- 2 root tramontana 4096 ago 18 17:20 /srv/tramontana/compartidoLa s en la posición de la x del grupo. En un directorio, SGID hace que todo lo que se cree dentro herede el grupo del directorio, en lugar del grupo principal de quien lo crea.
Por qué importa para Tramontana: sin SGID, si Luis crea un archivo en el directorio compartido, el grupo será luis y operador no podrá acceder aunque ambos estén en tramontana. Con SGID, el archivo nace con grupo tramontana y el equipo puede trabajar. Es la pieza que hace que un directorio compartido funcione de verdad.
Sticky bit: /tmp
La t al final. /tmp es 777: todo el mundo escribe. Por lo que aprendiste en el apartado 3, eso significaría que cualquiera puede borrar los archivos temporales de cualquiera, incluidos los de procesos del sistema.
El sticky bit lo corrige: en un directorio con este bit, solo el propietario del archivo (o del directorio, o root) puede borrarlo o renombrarlo. Puedes crear tus archivos, pero no tocar los ajenos.
Cómo distinguir mayúscula de minúscula
Una sutileza que aparece en los exámenes de certificación y que conviene reconocer:
| Se ve | Significa |
|---|---|
s minúscula |
El bit especial y el x correspondiente están activos |
S mayúscula |
El bit especial está activo pero falta el x |
t minúscula |
Sticky y x para otros |
T mayúscula |
Sticky sin x para otros |
Una S o una T mayúscula suele indicar un error de configuración: has puesto un bit especial sobre algo que no se puede ejecutar ni atravesar, así que no hará nada útil.
Consultar los tres con stat, donde aparecen como un cuarto dígito:
operador@srv-tramontana:~$ stat -c '%a %A %n' /usr/bin/passwd /tmp
4755 -rwsr-xr-x /usr/bin/passwd
1777 drwxrwxrwt /tmp4755 y 1777: el primer dígito son los bits especiales.
Repito la frontera: cómo y cuándo usar estos bits, sus riesgos, cómo auditar los binarios SUID de un sistema y cómo se relacionan con sudo es materia de la lección 05-02. Aquí solo necesitas reconocerlos en un ls -l y no asustarte.
- Caso práctico: los permisos de Tramontana Reservas
Marta te pide un informe con el diseño de permisos del despliegue y su justificación. Vamos ruta por ruta.
El punto de partida es el principio de mínimo privilegio: cada cuenta tiene exactamente los permisos que necesita para su función, y ni uno más.
Actores del sistema:
| Actor | Qué es | Qué necesita |
|---|---|---|
root |
Administración | Todo, por definición |
operador |
Cuenta administrativa (grupo sudo) |
Administrar vía sudo |
tramontana |
Grupo de la aplicación (se crea en 05-01) | Acceso al despliegue |
svc-tramontana |
Cuenta de servicio que ejecuta la app | Lo mínimo para funcionar |
| Otros | www-data, nobody, cuentas futuras |
Nada |
/opt/tramontana/app — el código
operador@srv-tramontana:~$ sudo chown -R root:tramontana /opt/tramontana/releases
operador@srv-tramontana:~$ sudo chmod -R u=rwX,g=rX,o= /opt/tramontana/releases
operador@srv-tramontana:~$ sudo chmod 755 /opt/tramontana/releases/3.2.1/ejecutable
operador@srv-tramontana:~$ ls -ld /opt/tramontana/releases/3.2.1
drwxr-x--- 4 root tramontana 4096 ago 18 08:30 /opt/tramontana/releases/3.2.1
operador@srv-tramontana:~$ ls -l /opt/tramontana/releases/3.2.1/ejecutable
-rwxr-xr-x 1 root tramontana 50319872 ago 18 08:30 ejecutableDirectorios 750, archivos 640, ejecutable 755.
Justificación:
- Propietario
root: el servicio no debe poder modificar su propio código. Si un atacante compromete la aplicación explotando un fallo, no puede reescribir el ejecutable para persistir en el sistema. Esta es la decisión más importante de todo el diseño. - Grupo
tramontanaconr-x: el equipo puede leer el código y atravesar los directorios para diagnosticar. - Otros sin nada: ninguna cuenta de servicio ajena tiene por qué ver el código de la aplicación.
u=rwX,g=rXen el recursivo: los directorios recibenxy los archivos de datos no, gracias a laXmayúscula.
/etc/tramontana/app.conf — la configuración con credenciales
operador@srv-tramontana:~$ sudo chown root:tramontana /etc/tramontana/app.conf
operador@srv-tramontana:~$ sudo chmod 640 /etc/tramontana/app.conf
operador@srv-tramontana:~$ sudo chmod 750 /etc/tramontana
operador@srv-tramontana:~$ ls -ld /etc/tramontana /etc/tramontana/app.conf
drwxr-x--- 2 root tramontana 4096 ago 18 08:30 /etc/tramontana
-rw-r----- 1 root tramontana 512 ago 18 08:47 /etc/tramontana/app.conf640, y el directorio 750.
Justificación:
- Contiene la contraseña de la base de datos. Con el
644habitual de/etc, cualquier usuario del sistema podría leerla. Eso incluyewww-datay cualquier cuenta comprometida. Es la diferencia entre un incidente contenido y una filtración de la base de datos completa. - El servicio solo necesita leer, nunca escribir. Sin
wpara el grupo. - El directorio también
750: de nada sirve proteger el archivo si el directorio permite listar y atravesar. Recuerda el apartado 3: hacen falta las dos cosas. - Ninguna copia
.bakpuede quedar con permisos más laxos. Este es un fallo real y frecuente: se copia la configuración aapp.conf.baky la copia nace con la umask del momento, quizá644. Se protege el original y se deja el secreto expuesto en la copia. Verifica siempre los permisos de tus copias de seguridad.
operador@srv-tramontana:~$ sudo cp -p /etc/tramontana/app.conf /etc/tramontana/app.conf.bak-$(date +%F)
operador@srv-tramontana:~$ ls -l /etc/tramontana/
-rw-r----- 1 root tramontana 512 ago 18 08:47 app.conf
-rw-r----- 1 root tramontana 512 ago 18 08:47 app.conf.bak-2026-08-18cp -p preserva los permisos, así que la copia nace igual de protegida. Sin -p habría nacido con la umask, que es justo lo que hay que evitar aquí.
/var/log/tramontana/ — los registros
operador@srv-tramontana:~$ sudo chown -R svc-tramontana:adm /var/log/tramontana
operador@srv-tramontana:~$ sudo chmod 750 /var/log/tramontana
operador@srv-tramontana:~$ sudo chmod 640 /var/log/tramontana/*.log
operador@srv-tramontana:~$ sudo ls -ld /var/log/tramontana
drwxr-x--- 2 svc-tramontana adm 4096 ago 18 09:00 /var/log/tramontana
operador@srv-tramontana:~$ sudo ls -l /var/log/tramontana
-rw-r----- 1 svc-tramontana adm 18432 ago 18 09:14 acceso.log
-rw-r----- 1 svc-tramontana adm 6348 ago 18 09:02 errores.logDirectorio 750, archivos 640.
Justificación:
- El propietario es la cuenta de servicio, porque es quien tiene que escribir en los logs. Es la única ruta del despliegue donde el servicio necesita permiso de escritura.
- El grupo
admes la convención de Debian y Ubuntu para «quien puede leer los registros del sistema». Encaja con el resto de/var/log. - Otros sin nada, y esto es importante:
acceso.logcontiene nombres de usuario, direcciones IP y patrones de actividad. Es información que ayuda a un atacante a preparar el siguiente paso, y que además puede constituir dato personal. - El directorio necesita
wpara el servicio porquelogrotatey la propia aplicación crearán ficheros nuevos ahí.
/srv/tramontana/backups — las copias
operador@srv-tramontana:~$ sudo chown -R root:tramontana /srv/tramontana/backups
operador@srv-tramontana:~$ sudo chmod 2770 /srv/tramontana/backups
operador@srv-tramontana:~$ sudo chmod 640 /srv/tramontana/backups/*.tar.gz
operador@srv-tramontana:~$ ls -ld /srv/tramontana/backups
drwxrws--- 3 root tramontana 4096 ago 18 11:20 /srv/tramontana/backups2770: 770 más el bit SGID.
Justificación:
- El grupo necesita escribir, porque los operadores generan y rotan copias.
- El SGID (
2) hace que todo lo creado dentro herede el grupotramontana. Sin él, una copia creada por Luis tendría grupoluisy el resto del equipo no podría gestionarla. Es el caso de uso del apartado 9, aplicado. - Otros, nada. Las copias contienen todo: el código, la configuración con credenciales y, según qué se respalde, datos de huéspedes. Un directorio de copias legible es una forma de dar acceso a todo lo demás saltándose los permisos que acabas de diseñar.
Cuadro resumen para el informe
| Ruta | Dueño:Grupo | Octal | Justificación en una línea |
|---|---|---|---|
/opt/tramontana/releases/*/ |
root:tramontana |
750 |
El servicio no puede modificar su propio código |
/opt/tramontana/releases/*/ejecutable |
root:tramontana |
755 |
Ejecutable por el servicio, no escribible |
/opt/tramontana/app (enlace) |
root:tramontana |
777 (irrelevante) |
Los permisos de un symlink no cuentan |
/etc/tramontana/ |
root:tramontana |
750 |
Proteger el directorio, no solo el fichero |
/etc/tramontana/app.conf |
root:tramontana |
640 |
Contiene credenciales |
/var/log/tramontana/ |
svc-tramontana:adm |
750 |
El servicio escribe; adm lee |
/var/log/tramontana/*.log |
svc-tramontana:adm |
640 |
Contienen datos de actividad de usuarios |
/srv/tramontana/backups |
root:tramontana |
2770 |
El grupo escribe; SGID para la herencia |
/home/operador/scripts |
operador:operador |
750 |
Scripts personales del operador |
Verificación final del diseño:
operador@srv-tramontana:~$ sudo stat -c '%a %U:%G %n' \
/opt/tramontana/releases/3.2.1 \
/etc/tramontana/app.conf \
/var/log/tramontana \
/srv/tramontana/backups
750 root:tramontana /opt/tramontana/releases/3.2.1
640 root:tramontana /etc/tramontana/app.conf
750 svc-tramontana:adm /var/log/tramontana
2770 root:tramontana /srv/tramontana/backupsAdvertencia necesaria
Este diseño es un ejercicio didáctico sobre datos ficticios. En un entorno real, reservas.csv y los logs de acceso contienen datos personales de huéspedes: nombres, fechas de estancia y patrones de comportamiento. Eso los somete al RGPD y a la normativa española de protección de datos.
En un despliegue real:
- El diseño de permisos debe revisarlo el responsable de seguridad de la información o el delegado de protección de datos antes de pasar a producción, no el administrador por su cuenta.
- Puede ser obligatorio cifrar los datos en reposo, no solo restringir el acceso mediante permisos.
- Los registros de acceso a datos personales pueden tener que auditarse y conservarse durante un plazo determinado.
- Los permisos de Unix son el primer nivel de control, no el único: en entornos exigentes se combinan con ACL (lección 05-02) y con control de acceso obligatorio mediante AppArmor o SELinux (lección 06-06).
Los permisos que has diseñado son necesarios y correctos. No son suficientes por sí solos cuando hay datos personales de por medio, y presentarlos como tales sería un error profesional.
Errores Comunes y Consejos
chmod -R 777 para «arreglar» un permiso denegado. Enmascara la causa, expone todo a cualquier cuenta del sistema y es casi irreversible. Diagnostica con id, ls -l y namei -l.
chmod -R 644 sobre un árbol. Deja los directorios sin x y los rompe todos. Usa chmod -R u=rwX,g=rX,o=.
Olvidar el x en los directorios del camino. El archivo está bien y sigue sin funcionar. namei -l /ruta/completa lo resuelve en un segundo.
Creer que los permisos se suman. Se aplica solo la primera categoría que coincide. Un propietario sin permisos no accede aunque el grupo los tenga.
Proteger un fichero y dejar la copia .bak abierta. Usa cp -p y verifica con ls -l después.
Dar acceso a un compañero con o+r. Se lo estás dando a todo el sistema. Grupo, siempre.
usermod -G sin -a. Sustituye todos los grupos secundarios. Puede sacarte del grupo sudo y dejarte sin administración.
No entender por qué el nuevo grupo «no funciona». Los grupos se aplican al iniciar sesión. Cierra la sesión y vuelve a entrar.
Consejo: adopta umask 027 en los servidores. Todo lo que crees nace ya cerrado para «otros». Es mínimo privilegio desde el origen.
Consejo: namei -l es la herramienta más infravalorada de esta lección. Memorízala.
Consejo: stat -c '%a %A %U:%G %n' es el formato de verificación. Te da octal, simbólico y propiedad en una línea, perfecta para informes.
Consejo: antes de cualquier chmod -R o chown -R, guarda el estado actual. Con getfacl -R directorio > permisos.bak puedes volver atrás. Es la versión de «copia antes de editar» aplicada a los permisos.
Ejercicios
Ejercicio 1: traducción y lectura
Sin ejecutar nada:
- Traduce a octal:
rwxr-x---,rw-rw-r--,r--------,rwsr-xr-x. - Traduce a simbólico:
750,644,2775,1777. - Explica qué puede hacer exactamente el usuario
luis(miembro detramontana, no deadm) con cada uno de estos, y por qué:
drwxr-x--- 3 root tramontana 4096 ago 18 09:00 /srv/datos -rw-r----- 1 root tramontana 512 ago 18 09:00 /srv/datos/config.txt -rw-r----- 1 root adm 2048 ago 18 09:00 /srv/datos/registro.log
- ¿Podría
luisborrarregistro.log? Justifica la respuesta.
Ejercicio 2: diagnóstico de un permiso denegado
La aplicación no arranca. En el log del servicio aparece:
El servicio corre como svc-tramontana. Comprueba lo siguiente y da un diagnóstico razonado:
$ id svc-tramontana
uid=997(svc-tramontana) gid=997(svc-tramontana) grupos=997(svc-tramontana)
$ namei -l /etc/tramontana/app.conf
f: /etc/tramontana/app.conf
drwxr-xr-x root root /
drwxr-x--- root tramontana etc/tramontana
-rw-r----- root tramontana app.confIdentifica la causa exacta, propón la corrección con el comando concreto y explica por qué no debe resolverse con chmod 644.
Ejercicio 3: informe de permisos para Marta
Marta ha recibido una consulta del cliente y necesita un informe. Prepara para srv-tramontana:
- Una tabla con los permisos actuales de las cinco rutas de Tramontana, en octal y con propietario.
- La identificación de cualquier ruta cuyos permisos consideres incorrectos, con la corrección propuesta.
- Un párrafo, redactado para alguien no técnico, explicando qué protege este diseño y qué no protege.
Soluciones
Solución 1
1. A octal:
| Simbólico | Cálculo | Octal |
|---|---|---|
rwxr-x--- |
(4+2+1)(4+0+1)(0) | 750 |
rw-rw-r-- |
(4+2)(4+2)(4) | 664 |
r-------- |
(4)(0)(0) | 400 |
rwsr-xr-x |
SUID + (4+2+1)(4+0+1)(4+0+1) | 4755 |
En el último, la s en la posición de la x del usuario indica SUID, que aporta el 4 como cuarto dígito. Los nueve bits normales son 755.
2. A simbólico:
| Octal | Simbólico |
|---|---|
750 |
rwxr-x--- |
644 |
rw-r--r-- |
2775 |
rwxrwsr-x (SGID) |
1777 |
rwxrwxrwt (sticky) |
En 2775, el 2 es SGID y se manifiesta como s en la x del grupo. En 1777, el 1 es el sticky bit y aparece como t en la posición de la x de otros. Ambas son minúsculas porque el x correspondiente también está presente.
3. Qué puede hacer luis:
-
/srv/datos(750,root:tramontana):luisno esroot, así que no se le aplican los permisos de usuario. Sí es miembro detramontana, así que se le aplica el grupo:r-x. Puede listar el directorio (ls) y atravesarlo (cd, acceder a lo de dentro). No puede crear, borrar ni renombrar nada dentro, porque le faltaw. -
config.txt(640,root:tramontana): se le aplica el grupo,r--. Puede leerlo concat. No puede modificarlo. Y puede llegar hasta él porque tienexen el directorio, condición necesaria que se comprueba primero. -
registro.log(640,root:adm):luisno esrootni miembro deadm, así que se le aplican los permisos de otros:---. No puede leerlo. El hecho de que pueda listar el directorio y por tanto ver que el archivo existe no le da ningún acceso a su contenido.
4. ¿Puede luis borrar registro.log?
No, pero la razón no es la que parece a primera vista.
Borrar un archivo no depende de los permisos del archivo: depende de tener w y x en el directorio que lo contiene. Si /srv/datos fuera 770, luis sí podría borrar registro.log aunque no pueda leerlo, porque estaría modificando la lista de nombres del directorio, no el archivo.
En este caso concreto no puede porque /srv/datos es 750: el grupo tiene r-x, sin w. Es la falta de w en el directorio lo que lo impide, no los permisos del log.
Esta distinción es la que hace necesario el sticky bit en directorios como /tmp, donde todos tienen w.
Solución 2
Causa exacta. namei -l muestra la cadena completa y el bloqueo está en la primera línea relevante:
El directorio /etc/tramontana es 750, propiedad de root:tramontana. La cuenta de servicio:
svc-tramontana no pertenece al grupo tramontana. Solo está en su propio grupo. Al evaluar el acceso a /etc/tramontana:
- ¿Es el propietario
root? No. - ¿Pertenece al grupo
tramontana? No. - Se le aplican los permisos de otros:
---.
Sin x en /etc/tramontana, no puede atravesarlo, así que ni siquiera llega a evaluar los permisos de app.conf. Y aunque llegara, el fichero también le daría --- como otros.
El detalle importante: el fichero de configuración está perfectamente configurado. El problema es la pertenencia a grupo de la cuenta de servicio. Sin namei -l es fácil quedarse mirando el 640 del fichero y no ver el bloqueo real, que está un nivel más arriba.
Corrección:
operador@srv-tramontana:~$ sudo usermod -aG tramontana svc-tramontana
operador@srv-tramontana:~$ id svc-tramontana
uid=997(svc-tramontana) gid=997(svc-tramontana) grupos=997(svc-tramontana),1002(tramontana)
# El servicio no recoge el grupo nuevo hasta reiniciarse
operador@srv-tramontana:~$ sudo systemctl restart tramontana
operador@srv-tramontana:~$ sudo -u svc-tramontana cat /etc/tramontana/app.conf | head -n 1
# Configuración de Tramontana ReservasLa -a de usermod -aG es imprescindible: sin ella, sustituiría los grupos secundarios en lugar de añadir.
Y el systemctl restart es necesario porque, como viste en el apartado 7, los grupos de un proceso se fijan al arrancar. Añadir la cuenta al grupo no afecta a un proceso que ya está corriendo.
Por qué no chmod 644:
chmod 644 /etc/tramontana/app.conf haría que el servicio arrancara, sí. Y sería un fallo de seguridad grave.
El fichero contiene la contraseña de la base de datos. Con 644, cualquier usuario del sistema puede leerla: www-data, nobody, cualquier cuenta de servicio de otra aplicación, cualquier usuario que se cree en el futuro y cualquier proceso comprometido que consiga ejecutarse con una cuenta sin privilegios.
El escenario concreto: un atacante encuentra una vulnerabilidad menor en otro servicio del mismo servidor y consigue ejecutar comandos como www-data. Con 640 y el grupo bien puesto, no puede hacer nada con las credenciales de Tramontana. Con 644, lee la contraseña de la base de datos, se conecta directamente y se lleva todos los datos de huéspedes. Un incidente contenido se convierte en una filtración.
Además, 644 no arregla la causa. La cuenta de servicio sigue sin estar en el grupo al que pertenecen todos los demás recursos de la aplicación. El mismo error volverá a aparecer con los logs, con el directorio de copias y con cada recurso nuevo, y se irá parcheando cada vez abriendo permisos, hasta acabar con un despliegue completamente expuesto.
El principio general: cuando algo da «permiso denegado», la pregunta correcta no es «cómo abro esto», sino «quién debería tener acceso y cómo se lo doy solo a ellos». La respuesta casi siempre es la pertenencia a un grupo, no un chmod más permisivo.
Solución 3
1. Estado actual:
operador@srv-tramontana:~$ sudo stat -c '%a %A %U:%G %n' \
/opt/tramontana/app \
/etc/tramontana/app.conf \
/var/log/tramontana \
/srv/tramontana/backups \
/home/operador/scripts
777 lrwxrwxrwx root:root /opt/tramontana/app
640 -rw-r----- root:tramontana /etc/tramontana/app.conf
750 drwxr-x--- svc-tramontana:adm /var/log/tramontana
770 drwxrwx--- root:tramontana /srv/tramontana/backups
775 drwxrwxr-x operador:operador /home/operador/scripts| Ruta | Octal | Dueño:Grupo | Valoración |
|---|---|---|---|
/opt/tramontana/app |
777 | root:root |
Correcto: es un enlace, sus permisos no se aplican |
/etc/tramontana/app.conf |
640 | root:tramontana |
Correcto |
/var/log/tramontana |
750 | svc-tramontana:adm |
Correcto |
/srv/tramontana/backups |
770 | root:tramontana |
Mejorable: falta SGID |
/home/operador/scripts |
775 | operador:operador |
Incorrecto: legible y atravesable por todos |
2. Correcciones propuestas:
# /srv/tramontana/backups: añadir SGID para que las copias hereden el grupo
operador@srv-tramontana:~$ sudo chmod 2770 /srv/tramontana/backups
operador@srv-tramontana:~$ ls -ld /srv/tramontana/backups
drwxrws--- 3 root tramontana 4096 ago 18 11:20 /srv/tramontana/backupsSin SGID, una copia creada por otro miembro del equipo nacería con su grupo personal y el resto no podría gestionarla. Con SGID, todo lo creado dentro hereda tramontana. Es el requisito para que un directorio compartido funcione realmente en equipo.
# /home/operador/scripts: cerrar el acceso a otros
operador@srv-tramontana:~$ chmod 750 /home/operador/scripts
operador@srv-tramontana:~$ chmod -R u=rwX,go= /home/operador/scripts
operador@srv-tramontana:~$ chmod 750 /home/operador/scripts/*.shCon 775, cualquier usuario del sistema podía leer los scripts de administración. Eso no es trivial: los scripts revelan rutas internas, nombres de servicios, procedimientos de copia y a veces —por descuido— credenciales. Es información de reconocimiento gratis para un atacante.
Una comprobación adicional que merece la pena hacer siempre:
# Buscar copias de la configuración con permisos laxos
operador@srv-tramontana:~$ sudo ls -l /etc/tramontana/
-rw-r----- 1 root tramontana 512 ago 18 08:47 app.conf
-rw-r----- 1 root tramontana 512 ago 18 08:47 app.conf.bak-2026-08-18Ambas con 640. Correcto, gracias al cp -p.
3. Informe para Marta:
Diseño de permisos de acceso — Tramontana Reservas
El servidor controla quién puede ver y modificar cada archivo mediante un sistema de permisos que asigna a cada fichero un propietario, un grupo de trabajo y unos derechos concretos para cada uno. Hemos revisado y ajustado los cinco elementos del despliegue.
Qué protege el diseño actual. El código de la aplicación pertenece al administrador y la aplicación puede ejecutarlo pero no modificarlo: si alguien lograra explotar un fallo del programa, no podría alterar el propio programa para instalarse de forma permanente. El fichero de configuración, que contiene la contraseña de la base de datos, solo es legible por el administrador y por las cuentas del equipo de Tramontana; ninguna otra cuenta del servidor puede verlo, ni siquiera las de otros servicios que puedan estar instalados. Los registros de actividad, que incluyen datos de uso de los clientes, están igualmente restringidos. Las copias de seguridad son accesibles solo para el equipo, y hemos añadido un ajuste para que cualquier copia que genere cualquier miembro del equipo quede automáticamente accesible al resto, evitando que una copia acabe siendo inutilizable por un problema de permisos. Finalmente, hemos cerrado el acceso a los scripts de administración, que hasta ahora podía leer cualquier cuenta del servidor y que describen el funcionamiento interno del sistema.
Qué no protege. Este mecanismo controla el acceso desde dentro del servidor y entre cuentas distintas. No protege frente a tres cosas: quien tenga acceso de administrador puede leerlo todo, porque esa es la naturaleza del rol; los datos están almacenados sin cifrar, de modo que quien obtuviera acceso físico al disco o a una copia de seguridad podría leerlos sin necesidad de credenciales; y no impide que alguien con acceso legítimo copie información fuera del servidor.
Recomendación. Dado que el sistema almacena nombres de huéspedes, fechas de estancia e importes —datos personales sujetos al RGPD—, este diseño debería ser revisado y validado por el responsable de protección de datos antes de considerarlo definitivo. Es probable que la normativa exija, además del control de acceso que ya tenemos, el cifrado de los datos almacenados y un registro auditable de los accesos. Propongo tratarlo en la próxima reunión y planificar esas dos medidas como fase siguiente.
Ese informe cumple lo que se espera de un profesional: describe lo que se ha hecho en lenguaje comprensible, es honesto sobre los límites de la solución, y eleva a quien corresponde una decisión que no es técnica sino de cumplimiento normativo.
Conclusión
Cierras el Módulo 2 con la pieza que faltaba: la que convierte un servidor que funciona en un servidor que además es seguro.
- El modelo de Unix asigna a cada archivo un propietario y un grupo, y divide al resto del mundo en tres categorías. Los permisos no se suman: se selecciona la primera categoría que coincide.
- Sabes leer
-rw-r-----carácter a carácter, y reconoces los siete tipos de archivo por su primera letra. - Entiendes que
r,wyxsignifican cosas distintas en archivos y en directorios: quexes atravesar, quersinxes casi inútil, y quewen un directorio permite borrar archivos que no son tuyos, porque borrar es una operación sobre la lista de nombres, no sobre el archivo. - Traduces entre octal y simbólico en ambos sentidos, y conoces los valores que aparecen de verdad: 644, 640, 600, 755, 750, 700, 711.
- Usas
chmoden las dos notaciones, y sabes que el recursivo correcto esu=rwX,g=rX,o=conXmayúscula, nunca-R 644ni-R 777. - Sabes por qué
chmod -R 777no es una solución y cuál es el diagnóstico correcto:id,ls -ly sobre todonamei -l. - Manejas
chownychgrp, sabes quechownexigerooty por qué, y conoces--referencey-h. - Tienes claro que el trabajo en equipo se resuelve con un grupo compartido y no con permisos para «otros», que
usermod -aGnecesita la-a, y que los grupos se aplican al iniciar sesión. - Calculas la
umasky su efecto sobre las bases 666 y 777, y sabes que027es la recomendable en un servidor con datos sensibles. - Reconoces SUID, SGID y sticky en un
ls -l, sabes qué hace cada uno en una frase, y sabes que su estudio a fondo es la lección 05-02. - Y has diseñado y justificado los permisos completos del despliegue de Tramontana Reservas, incluida la parte más profesional de todas: decir con claridad qué protege el diseño y qué no, y elevar a quien corresponde lo que excede tu ámbito de decisión.
Haz balance del módulo entero. Empezaste con un prompt parpadeando y sin saber cómo escribir un comando con soltura. Ahora manejas la línea de órdenes con atajos e historial, resuelves dudas con la documentación del sistema sin depender de un buscador, recorres y caracterizas un servidor desconocido con cinco comandos, creas, copias, mueves, empaquetas y verificas archivos con procedimientos reproducibles, lees y editas contenido con less, nano y el vim justo para no quedarte encerrado, entiendes qué es un inodo y has diseñado un patrón de despliegue con enlaces, y sabes decidir quién accede a qué y por qué. Eso ya no es «saber comandos»: es tener criterio.
En el Módulo 3: Habilidades Avanzadas en la Línea de Comandos todo esto se multiplica. Aprenderás a personalizar tu entorno con variables, alias e historial persistente, a describir conjuntos de archivos con comodines y patrones con expresiones regulares, a buscar cualquier cosa en cualquier sitio con find, locate y grep, a encadenar programas con tuberías y a redirigir su entrada y su salida —esa mecánica que has usado de refilón y que por fin entenderás del todo—, a procesar texto con cut, sort, uniq, sed y awk hasta convertir acceso.log y reservas.csv en los informes que Marta pide, a controlar los procesos del sistema y a programar tareas con cron para que se ejecuten solas de madrugada. Es el módulo donde dejas de ejecutar comandos uno a uno y empiezas a componerlos, que es exactamente lo que anunciaba la filosofía Unix del primer módulo. Actualiza el snapshot de tu VM y nos vemos allí.
Curso de Linux: De Principiante a Administrador de Sistemas
Módulo 1: Introducción a Linux
- ¿Qué es Linux?
- Historia de Linux
- Distribuciones de Linux
- Instalando Linux
- Primer Contacto con el Sistema
- Estructura del Sistema de Archivos de Linux
Módulo 2: Comandos Básicos de Linux
- Introducción a la Línea de Comandos
- Obtener Ayuda y Documentación del Sistema
- Navegando el Sistema de Archivos
- Operaciones con Archivos y Directorios
- Visualización y Edición de Archivos
- Enlaces Duros y Simbólicos
- Permisos y Propiedad de Archivos
Módulo 3: Habilidades Avanzadas en la Línea de Comandos
- El Entorno del Shell: Variables, Alias e Historial
- Uso de Comodines y Expresiones Regulares
- Búsqueda de Archivos y Contenido: find, locate y grep
- Tuberías y Redirección
- Procesamiento de Texto: cut, sort, uniq, sed y awk
- Gestión de Procesos
- Programación de Tareas con Cron
- Comandos de Redes
Módulo 4: Scripting en Shell
- Introducción al Scripting en Shell
- Variables y Tipos de Datos
- Entrada, Salida y Argumentos de un Script
- Estructuras de Control
- Funciones y Librerías
- Depuración y Manejo de Errores
- Scripts de Producción: Buenas Prácticas
Módulo 5: Administración del Sistema
- Gestión de Usuarios y Grupos
- sudo y Permisos Especiales
- Gestión de Paquetes
- Gestión de Discos
- systemd y la Gestión de Servicios
- Registros del Sistema: journald y syslog
- Monitoreo del Sistema y Optimización del Rendimiento
- Respaldo y Restauración
Módulo 6: Redes y Seguridad
- Configuración de Redes
- SSH y Acceso Remoto
- Firewall y Seguridad Perimetral
- Sistemas de Detección de Intrusos
- Gestión de Secretos y Certificados TLS
- Asegurando Sistemas Linux
Módulo 7: Temas Avanzados
- El Proceso de Arranque y la Recuperación del Sistema
- Diagnóstico Avanzado: strace, perf y eBPF
- Optimización del Kernel de Linux
- Virtualización con Linux
- Contenedores de Linux y Docker
- Automatización con Ansible
- Alta Disponibilidad y Balanceo de Carga
