Información blog

Linux, tutoriales, noticias, sistemas, redes y seguridad informática, entre otras cosas.

viernes, 12 de junio de 2015

Control Access List en Linux

Hace un tiempo hablé sobre los permisos en Linux, lo cual uno puede encontrar muy útil,pues se trata de un concepto que se usa casi a diario. Con esos concepto asimilados, uno puede llegar a encontrarse con el problema de que el acceso al fichero le resulte restrictivo, ya que no es el propietario del archivo, no quiere pertenecer a dicho grupo únicamente para acceder a dicho fichero, ni se quiere dar acceso a todo el mundo a ese fichero; por ello hoy quiero hablaros sobre una funcionalidad que resuelve dicho problema, los Access Control List o ACL.


Una ACL no es ni más ni menos que una lista que gestiona los distintos permisos que posee cada usuario para acceder a un fichero en concreto. En caso de no establecer ninguna, el fichero tendría los permisos básicos y cualquier usuario ajeno sería incapaz de acceder a dicho fichero y/o directorio. Aunque se trata de una funcionalidad muy útil, no está implantada por defecto en el sistema operativo, con lo que para poder disfrutar de sus ventajas es necesario realizar algunos pequeños ajustes. El primer e imprescindible paso sería ver  si el propio núcleo del sistema operativo (comúnmente llamado Kernel) es capaz de soportar dicha funcionalidad; aunque hoy en día cualquier sistema operativo tiene un núcleo lo suficientemente nuevo cómo para soportar esta funcionalidad, en caso de poseer un sistema o un núcleo muy antiguo podríamos llegar a tener problemas. Para comprobar si tenemos el núcleo adecuado, sería necesario ejecutar los siguientes comandos:

Para empezar es necesario conocer bajo qué Kernel está corriendo el sistema. Para ello usaremos un comando muy útil llamado uname; éste tiene la capacidad de mostrar distinta información del sistema, entre otras cosas la versión del kernel, junto con la arquitectura del sistema. Para ello se usa el comando -r, con lo que el comando sería uname -r, el cual nos debería mostrar un resultado parecido al siguiente:


En este caso tendríamos la versión 3.16 en una arquitectura amd64, pero estos valores que se muestran aquí pueden ser completamente distintos en vuestro equipo. Conociendo la versión sobre la que se está cargando el sistema operativo, ahora habría que ver si ésta tiene los módulos necesarios habilitados; Por suerte la forma de obtener esta información es sencilla: A sabiendas de la versión que tenemos, habría que dirigirse a la carpeta /boot y consultar si el fichero config-${versión_kernel} contiene dichos módulos cargados. El comando ideal para consultar dicho fichero sin posibilidad a cometer ningún error sería:

  1. cat /boot/config-$(uname -r) |grep "_ACL"

Este comando ya incluiría el comando uname, evitando así cualquier posible error. Dicho comando debería mostraros una serie de líneas en referente a ACL; En mi caso por ejemplo tendría el siguiente resultado:


La cantidad de líneas varía dependiendo de la antigüedad del sistema operativo, al igual que el contenido de dichas líneas; Aún así, lo importante de éstas líneas es que cada una de éstas representa un módulo asociado a un sistema de ficheros, entre los cuales el más importante es el sistema de ficheros ext4; en algunas versiones más antiguas, lo normal sería que aparte del sistema ext4 se mostrasen las versiones anteriores ext3 y ext2. Al lado de cada módulo podemos ver que hay asignado un valor que puede ser s o n. En caso que el módulo ext4 (o inferiores) posea el valor establecido en s (sería lo más común) significaría que el sistema está capacitado para trabajar con ACL; en caso contrario la única posibilidad que habría para que ACL funcionase sería recompilar el núcleo; lo cual es muy trabajoso.

Supongamos que nuestro kernel cumple los requisitos para trabajar con ACL; eso no significa que nuestro sistema esté preparado para trabaja con éste, ya que nuestro disco duro no ha cargado dicha funcionalidad. La solución a dicho problema radica en editar el fichero /etc/fstab; fichero que alberga toda la configuración de los discos duros. En dicho fichero habría que buscar el disco duro que es "montado" en la ubicación /. Para ello habría que observar las distintas líneas que no empiecen por el carácter # . Dichas líneas siguen la siguiente estructura:

Disco  punto_de_montaje  tipo_de_sistema_de_ficheros

Lo que conlleva a que habría que buscar un disco que a su lado tuviese el símbolo /. En mi caso por ejemplo el disco a editar sería siguiente:

  1. UUID=ab6e3da5-35ff-4c82-89e3-0c70064442c1 /               ext4    errors=remount-ro 0       1

Y habría que editar dicha línea para que el disco en cuestión use ACLtal que así:

  1. UUID=ab6e3da5-35ff-4c82-89e3-0c70064442c1 /               ext4    errors=remount-ro,acl 0       1

Con esto ya tendríamos todos los preparativos realizados. Ahora sólamente habría que aplicar los cambios en el disco, para lo cual habrían dos opciones:
  1. Reiniciar el equipo.
  2. Montar de nuevo el disco duro para evitar dicho reinicio, para lo cual habría que teclear el comando mount. El comando mount no reconoce el UUID, sino que unidades de disco duro físicas, con lo que para montar exitosamente el disco duro de nuevo tenemos que saber a qué disco duro corresponde dicho UUID. Dicha obtención de unidad también está contemplada en el comando; solamente hay que sustituir el contenido que hay entre las comillas por vuestro UUID en particular: 
  1. mount -o remount,acl $(blkid |grep "ab6e3da5-35ff-4c82-89e3-0c70064442c1" |awk '{print $1}' |cut -d ":" -f 1)

Siguiendo este proceso, por fin tendríamos todo listo para trabajar con ACL. Ahora para poder realizar dicha tarea se usan dos herramientas: setfacl y getfcal. Ambas herramientas sirven para manipular la ACL de un fichero en concreto y su funcionamiento guarda cierto parecido con la modificación de permisos de un fichero mediante caracteres.

Comencemos con el establecimiento de una ACL. Para lograr dicho objetivo se usa la herramienta setfacl, la cual posee la siguiente estructura:

setfacl  -m u:${usuario}:${permisos} ${archivo}

La estructura de los permisos que se van a establecer, guardan mucho parecido con la modificación de permisos mediante caracteres, tal y cómo he comentado antes, aunque no es del todo igual. Para entender este cambio vamos a crear un fichero de pruebas llamado por ejemplo prueba.txt; dicho fichero puede ir en cualquier lado, pero en mi caso lo voy a almacenar en el directorio /tmp. Al no querer complicarnos la vida, vamos a simplemente crearlo sin ningún contenido dentro mediante el comando:

  1. touch /tmp/prueba.txt

Tras tener el fichero de pruebas creado, habría que ver que permisos posee éste mediante el uso del comando ls -l /tmp; es muy importante usar el parámetro -l, pues en caso contrario dicho comando no mostraría los permisos. En mi caso he obtenido el siguiente resultado:


Cómo podréis apreciar, aquí aparecen todos los permisos referentes al fichero. Cómo sabréis, el primer carácter hace referencia a si es un directorio o no; En caso de ser un directorio aparecería una d en vez de un guión, pero en este caso al ser un fichero muestra únicamente un guión. Tras dicho guión, los tres siguientes caracteres hacen información a los permisos que posee el propietario del archivo, los tres que van después harían referencia a los permisos que posee el grupo, y los tres últimos a los permisos que poseen el resto de usuarios. Si nos fijamos bien en la información que muestra es captura, llegaríamos a la conclusión de que: El usuario root tiene permisos de lectura y escritura y tanto los miembros del grupo cómo el resto de usuarios únicamente permisos de lectura. Eso significa que si cualquier otro usuario, en mi caso por ejemplo invitado, tratase de borrar dicho archivo, obtendríamos el siguiente resultado:


Eso es debido a que el usuario no posee permisos de escritura, y eso incluye la propia eliminación del fichero. Para hacer que únicamente el usuario invitado tuviese permisos de lectura y escritura (aparte del propio dueño del fichero) habría que escribir:

  1. setfacl  -m u:invitado:rw- /tmp/prueba.txt

Allí donde se ponen los permisos, dependiendo de lo que se desee asignar, habría que hacer combinaciones con los caracteres r,w y x; Aunque este concepto ya fue explicado con los permisos globales en Linux, os dejo aquí una pequeña tabla que os puede servir de ayuda; no he puesto los permisos que carezcan de lectura ya que el hecho de quitar permisos de lectura sólo lograría entorpecer en vez de ayudar :


Ahora si repitiésemos el comando ls -l / tmp observaríamos una pequeña variación en lo que vemos:


Si os fijáis bien, veréis que se ha añadido el símbolo más al final de los permisos del fichero; dicho símbolo representa la existencia de una ACL para dicho fichero y que aunque los permisos globales son los que aparecen allí, existen usuarios que tienen permisos especiales.

La forma de conocer la ACL que posee dicho fichero con todos sus detalles es tan sencilla cómo usar el comando getfacl, el cual carece de parámetro alguno cómo podéis ver a continuación:

  1. getfacl /tmp/prueba.txt

Este comando funciona con cualquier fichero, se le haya asignado una ACL o no, con lo que no tenéis que tener miedo en usarlo en un fichero que carezca de éste, pues funcionará igualmente aún cuando la información que muestre sea la misma que muestra el comando ls -l. En el caso del fichero prueba.txt, el resultado del comando ha sido el siguiente:


Dicho comando muestra todos los permisos, incluyendo los permisos referentes al usuario invitado; permisos que únicamente él posee sobre este archivo (aparte del propietario). Eso significa que si ahora el usuario invitado tratase de eliminar el fichero prueba.txt, éste tendría éxito.

Espero que os resulte útil.

Saludos.

No hay comentarios :

Publicar un comentario