 
 
 
 
 
 
 
  
 Siguiente: Recuperación de datos
 Subir: El sistema de ficheros
 Anterior: Atributos de un archivo
     Índice General 
Las listas de control de acceso (ACLs, Access Control Lists) proveen
de un nivel adicional de seguridad a los ficheros extendiendo el clásico
esquema de permisos en Unix: mientras que con estos últimos sólo podemos 
especificar permisos para los tres grupos de usuarios habituales (propietario, 
grupo y resto), las ACLs van a permitir asignar permisos a usuarios o grupos
concretos; por ejemplo, se
pueden otorgar ciertos permisos a dos usuarios sobre unos ficheros sin necesidad
de incluirlos en el mismo grupo. Este mecanismo está
disponible en la mayoría de Unices (Solaris, AIX, HP-UX...), mientras
que en otros que no lo proporcionan por defecto, como Linux, puede instalarse 
como un software adicional. A pesar de las agresivas campañas de 
marketing de alguna empresa, que justamente presumía de ofrecer este 
modelo de protección en sus sistemas operativos frente al `arcaico' 
esquema utilizado en Unix, las listas de control de acceso existen en Unix 
desde hace más de diez años ([Com88]).
Los ejemplos que vamos a utilizar aquí (órdenes, resultados...) se
han realizado sobre Solaris; la idea es la misma en el resto de Unices, aunque 
pueden cambiar las estructuras de las listas. Para obtener una excelente 
visión de las ACLs es recomendable consultar [Fri95], y por supuesto
la documentación de los diferentes clones de Unix para detalles concretos de 
cada manejo e implementación.
La primera pregunta que nos debemos hacer sobre las listas de control de
acceso es obvia: >cómo las vemos? Si habitualmente queremos saber si a un 
usuario se le permite cierto tipo de acceso sobre un fichero no tenemos más 
que hacer un listado largo:
anita:~# ls -l /usr/local/sbin/sshd 
-rwx------   1 root     bin      2616160 Apr 28  1997 /usr/local/sbin/sshd
anita:~#
Viendo el resultado, directamente sabemos que el fichero sshd puede ser
ejecutado, modificado y leído por el administrador, pero por nadie más;
sin embargo, no conocemos el estado de la lista de control de acceso asociada al
archivo. Para ver esta lista, en Solaris se ha de utilizar la orden getfacl:
anita:/# getfacl /usr/local/sbin/sshd 
# file: /usr/local/sbin/sshd
# owner: root
# group: bin
user::rwx
group::---              #effective:---
mask:---
other:---
anita:/#
Acabamos de visualizar una lista de control de acceso de Solaris; en primer 
lugar se nos indica el nombre del fichero, su propietario y su grupo, todos
precedidos por `#'. Lo que vemos a continuación es la propia lista de
control: los campos user, group y other son básicamente
la interpretación que getfacl hace de los permisos del fichero (si nos
fijamos, coincide con el resultado del ls -l). El campo mask es
muy similar al umask clásico: define los permisos máximos que un
usuario (a excepción del propietario) o grupo puede tener sobre el fichero. 
Finalmente, el campo effective nos dice, para cada usuario (excepto el
propietario) o grupo el efecto que la máscara tiene sobre los permisos: es
justamente el campo que tenemos que analizar si queremos ver quién puede
acceder al archivo y de qué forma.
Sin embargo, hasta ahora no hemos observado nada nuevo; podemos fijarnos que
la estructura de la lista de control de acceso otorga los mismos permisos que
las ternas clásicas. Esto es algo normal en todos los Unix: si no indicamos
lo contrario, al crear un fichero se le asocia una ACL que coincide con los
permisos que ese archivo tiene en el sistema (cada archivo tendrá una lista
asociada, igual que tiene unos permisos); de esta forma, el resultado anterior
no es más que la visión que getfacl tiene de los bits rwx 
del fichero ([Gal96c]).
Lo interesante de cara a la protección de ficheros es extender los permisos
clásicos del archivo, modificando su lista asociada. Esto lo podemos conseguir
con la orden setfacl:
anita:~# setfacl -m user:toni:r-x /usr/local/sbin/sshd 
anita:~# getfacl /usr/local/sbin/sshd 
# file: /usr/local/sbin/sshd
# owner: root
# group: bin
user::rwx
user:toni:r-x           #effective:---
group::---              #effective:---
mask:---
other:---
anita:~#
Como vemos, acabamos de modificar la lista de control de acceso del archivo
para asignarle a toni permiso de ejecución y lectura sobre el mismo. La
orden setfacl se utiliza principalmente de tres formas: o bien añadimos
entradas a la ACL, mediante la opción -m seguida de las entradas que 
deseemos añadir separadas por comas (lo que hemos hecho en este caso, aunque
no se han utilizado comas porque sólo hemos añadido una entrada), o bien 
utilizamos el parámetro -s para reemplazar la ACL completa (hemos de 
indicar todas las entradas, separadas también por comas), o bien borramos
entradas de la lista con la opción -d (de sintaxis similar a -m).
Cada entrada de la ACL tiene el siguiente formato:
tipo:UIDGID:permisos
El tipo indica a quién aplicar los permisos (por ejemplo, user para
el propietario del archivo, o mask para la máscara), el UID indica el
usuario al que queremos asociar la entrada (como hemos visto, se puede utilizar
también el login, y el GID hace lo mismo con el grupo (de la misma 
forma, se puede especificar su nombre simbólico). Finalmente, el campo de
permisos hace referencia a los permisos a asignar, y puede ser especificado 
mediante símbolos rwx- o de forma octal.
Acabamos de indicar que el usuario toni tenga permiso de lectura y
ejecución en el archivo; no obstante, si ahora este usuario intenta acceder 
al fichero en estos modos obtendrá un error:
anita:/usr/local/sbin$ id
uid=100(toni) gid=10(staff)
anita:/usr/local/sbin$ ./sshd
bash: ./sshd: Permission denied
anita:/usr/local/sbin$
>Qué ha sucedido? Nada anormal, simplemente está actuando la máscara sobre
sus permisos (antes hemos dicho que debemos fijarnos en el campo effective, y aquí podemos comprobar que no se ha modificado). Para 
solucionar esto hemos de modificar el campo mask:
anita:~# setfacl -m mask:r-x /usr/local/sbin/sshd
anita:~#
Si ahora toni intenta acceder al fichero para leerlo o ejecutarlo, ya
se le va a permitir:
anita:/usr/local/sbin$ id
uid=100(toni) gid=10(staff)
anita:/usr/local/sbin$ ./sshd
/etc/sshd_config: No such file or directory
...
Aunque obtenga un error, este error ya no depende de
la protección de los ficheros sino de la configuración del programa: el
administrador obtendría el mismo error. No obstante, sí que hay 
diferencias entre una ejecución de toni y otra del root, pero 
también son impuestas por el resto del sistema operativo Unix: toni no
podría utilizar recursos a los que no le está permitido el acceso, como
puertos bien conocidos, otros ficheros, o procesos que no le pertenezcan. Hay
que recordar que aunque un usuario ejecute un archivo perteneciente al root, si el fichero no está setuidado los privilegios del usuario no
cambian. Sucede lo mismo que pasaría si el usuario tuviera permiso de
ejecución normal sobre el fichero, pero éste realizara tareas privilegiadas:
podría ejecutarlo, pero obtendría error al intentar violar la
protección del sistema operativo.
En Solaris, para indicar que una lista de control de acceso otorga permisos
no reflejados en los bits rwx se situa un símbolo `+' a la
derecha de los permisos en un listado largo:
anita:~# ls -l /usr/local/sbin/sshd
-rwx------+  1 root     bin      2616160 Apr 28  1997 /usr/local/sbin/sshd
anita:~#
Otra característica que tiene Solaris es la capacidad de leer las 
entradas de una lista de control de acceso desde un fichero en lugar de
indicarlas en la línea de órdenes, mediante la opción -f de
setfacl; el formato de este fichero es 
justamente el resultado de getfacl, lo que nos permite copiar ACLs entre
archivos de una forma muy cómoda:
anita:~# getfacl /usr/local/sbin/sshd >/tmp/fichero
anita:~# setfacl -f /tmp/fichero /usr/local/sbin/demonio
anita:~# getfacl /usr/local/sbin/demonio
# file: /usr/local/sbin/demonio
# owner: root
# group: other
user::rwx
user:toni:r-x           #effective:r-x
group::---              #effective:---
mask:r-x
other:---
anita:~#
Esto es equivalente a utilizar una tubería entre las dos órdenes, lo
que produciría el mismo resultado:
anita:~# getfacl /usr/local/sbin/sshd | setfacl -f - /usr/local/sbin/demonio
Antes de finalizar este apartado dedicado a las listas de control de acceso,
quizás sea conveniente comentar el principal problema de estos mecanismos. 
Está claro que las ACLs son de gran ayuda para el administrador de sistemas
Unix, tanto para incrementar la seguridad como para facilitar ciertas tareas;
sin embargo, es fácil darse cuenta de que se pueden convertir en algo 
también de gran ayuda, pero para un atacante que desee situar puertas
traseras en las máquinas. Imaginemos simplemente que un usuario 
autorizado de nuestro sistema aprovecha el último bug de sendmail
(realmente nunca hay un `último') para conseguir privilegios de administrador 
en una máquina; cuando se ha convertido en root modifica la lista de
control de acceso asociada a /etc/shadow y crea una nueva entrada que
le da un permiso total a su login sobre este archivo. Una vez hecho esto,
borra todo el rastro y 
corre a avisarnos del nuevo problema de sendmail, problema que 
rápidamente solucionamos, le damos las gracias y nos olvidamos del asunto.
>Nos olvidamos del asunto? Tenemos un usuario que, aunque los bits rwx
no lo indiquen, puede modificar a su gusto un archivo crucial para nuestra 
seguridad. Contra esto, poco podemos hacer; simplemente comprobar frecuentemente
los listados de todos los ficheros importantes (ahora entendemos por qué 
aparece el símbolo `+' junto a las ternas de permisos), y si 
encontramos que un 
fichero tiene una lista de control que otorga permisos no reflejados en los
bits rwx, analizar dicha lista mediante getfacl y verificar que
todo es correcto. Es muy recomendable programar un par de shellscripts
simples, que automaticen estos procesos y nos informen en caso de que algo 
sospechoso se detecte.
 
 
 
 
 
 
 
  
 Siguiente: Recuperación de datos
 Subir: El sistema de ficheros
 Anterior: Atributos de un archivo
     Índice General 
2003-08-08