Una vez que hemos compilado el kernel con soporte para ACLs y
que hemos compilado las herramientas necesarias para poder
trabajar con ellas (además de parchear aquellas utilidades de
gestión de ficheros y sistemas de ficheros para que reconozcan
las ACLs y las respeten y sepan interpretarlas), podemos ya
dedicarnos a la gestión de las propias ACLs en si.
Para ello disponemos de dos utilidades principalmente:
-
getfacl: que nos permite consultar las ACLs de un fichero
dado.
-
setfacl: que nos permite modificar las ACLs de un fichero
dado.
Ambas utilidades se hayan perfectamente documentadas en sus
respectivas páginas del manual (setfacl(1) y
getfacl(1)), y podemos encontrar una pequeña introducción en
la página del manual de acl(5), vamos a
ver aquí algunos ejemplos sencillos que ilustrarán el uso básico
de estas utilidades.
Creación de una ACL básica.
Existen casos en los cuales el tradicional juego de pemisos UGO
(User, Group, Others) no es suficiente. Casos en los que
desearíamos que más de un usuario o más de un grupo pudiese
tener acceso a un fichero, pero con permisos diferenciados. Con
el modelo UGO esto no es posible, puesto que sólo tenemos sitio
para los permisos de un único Usuario o un único Grupo. Todo lo
demás cae en el Other (el resto). Con las ACLs esto es sencillo.
Vamos a presuponer que tenemos un directorio que contiene una
serie de ficheros y dos subdirectorios (a su vez con ficheros)
como se indica en
la figura disponible aquí (ubicada en un sitio
externo por limitaciones de scoop).
Tenemos asimismo los siguiente tipos de usuarios diferenciados:
-
Los usuarios del grupo de sistemas de información, que deben
tener acceso completo a todos los directorios y ficheros,
para su mantenimiento. Llamaremos a este grupo
sistemas.
-
Los usuarios del grupo de desarrollo (llamaremos a este
grupo desarrollo), que deben tener acceso de
lectura y escritura (y ejecución en su caso) en el primer
subdirectorio y todos sus ficheros y subdirectorios. En este
directorio es donde se desarrollan las nuevas versiones del
software que usa el tercer grupo.
Asi mismo debe tener acceso de lectura/escritura al segundo
de los subdirectorios para implantar las nuevas versiones
estables del software.
-
Los usuarios de explotación. Este grupo debe tener acceso en
modo lectura (y eventualmente ejecucion) sobre los ficheros
de la aplicacion. Llamaremos a este grupo
explotacion.
-
El resto de usuarios del sistema no deben tener ningún tipo
de acceso a ninguno de los ficheros o subdirectorios.
Con las condiciones anteriores es imposible usar el modelo de
permisos tradicional UGO, puesto que tenemos tres grupos de
usuarios diferentes, sin contar el resto de usuarios del
sistema. Eso significa que con un sólo grupo de usuarios con
permisos asignados por directorio o fichero no es posible
acomodar los permisos para los tres grupos.
Utilizando ACLs es fácil resolver el problema, puesto que
podemos asignar un juego de permisos diferente para cada grupo
de usuarios. Para ello debemos crear las ACLs necesarias para
cada grupo de usuarios y directorio o fichero.
-
Tenemos que dar permisos completos al grupo de sistemas
sobre todos los ficheros y directorios implicados. Para ello
usamos setfacl de la siguiente forma:
setfacl -b -k -R dir_raiz
setfacl -R -m g:sistemas:rw
Vayamos por partes con la sintaxis de setfacl:
-
En el primer caso usamos la opcion -b para borrar
la ACL que ya pudiera tener el directorio raíz. Usamos
también la opción -k para borrar la ACL por
defecto que pudiera tener el directorio raíz (más sobre
esto después), y por último usamos la opción -R
para aplicar los cambios de forma recursiva a todo lo
que cuelga del directorio raíz. Con esto conseguimos
tener todo limpio y listo para empezar.
Teóricamente la primere vez no hace falta limpiar la ACL
puesto que aún no hemos asignado ninguna ACE, pero de
paso aprovechamos para mostrar como se hace :)
-
En el segundo caso indicamos de nuevo que queremos
aplicar de forma recursiva los cambios (opción
-R) pero esta vez le decimos que queremos
modificar (-m) la ACL del objeto en
cuestión. En este caso es necesario además indicar el
valor de la ACE que deseamos añadir o
modificar. setfacl distingue entre asignar una
ACL (opción -s) en la cual se eliminan las ACEs
existentes y se añade la ACE especificada en la orden, y
modificar una ACL (opción -m) en la cual
podemos modificar o añadir una ACE.
En este caso queremos añadir una nueva ACE. Para ello
debemos escribimos la ACE que nos interesa:
g:sistemas:rw
Todas las ACEs tienen tres componentes separadas por ':'
(en el caso de las operaciones de borrado de ACEs el
tercer componente es opcional). El primero de los
componentes indica si se trata de un ACE de usuario
(valor u) o de grupo (valor
g). Incluso es posible asignar ACEs al grupo de
usuarios resto (other), pero esto no suele ser
habitual, así que omitiremos la sintaxis (se pueden
encontrar más detalles en la página del manual de
setfacl(1)).
El segundo de los componentes es el nombre de usuario o
grupo al que se le aplica la ACE. Se puede dar el nombre
simbólico o el valor numérico del uid o gid
correspondiente. El tercer componente es el valor del
permiso asociado a esta ACE, y puede ser una combinación
cualquiera de las letras r, w,
x y -, o un valor numérico octal
(como en chmod).
Por tanto, en nuestro caso tenemos que es una ACE de
grupo (g), que se aplica al grupo de
sistemas y que le estamo dando los permisos de
lectura y escritura (rw).
-
A continuacion tenemos que dar permisos al grupo de
desarrollo tanto en el directorio subdir_1 y todo
su contenido, como en el directorio subdir_2 y todo
su contenido. Sin embargo no tenemos que dar acceso a los
ficheros que cuelgan directamente de dir_raiz.
Para ello usamos setfacl con la sintaxis explicada
en el punto anterior:
setfacl -R -m g:desarrollo:rw dir_raiz/subdir_1
setfacl -R -m g:desarrollo:rw dir_raiz/subdir_2
-
Por último tenemos que dar permisos al grupo de explotación
en el directorio subdir_2 y todo su contenido:
setfacl -R -m g:explotacion:rx dir_raiz/subdir_2
Lo normal en este punto es comprobar cuales son los permisos
reales que tienen cada uno de los ficheros y directorios
existentes, para ver si efectivamente se ajustan a los
requisitos planteados.
Para ello podemos usar getfacl para ver cuales son las
ACL de cada uno de los directorios o ficheros implicados. La
sintaxis es sencilla:
getfacl fichero ...
Si lo usamos para ver el resultado de las órdenes anteriores
tenemos:
# getfacl dir_raiz
# file: dir_raiz
# owner: root
# group: root
user::rwx
group::r-x
group:sistemas:rw-
mask::rwx
other::r-x
El listado de permisos que obtenemos al ejecutar
getfacl se compone de entradas de tipo user y
group, además de las entradas para mask y
other. En el caso de las entradas user y
group, tendremos siempre una entrada para el
propietario del fichero y el grupo del fichero (son las líneas
que no indican un usuario o grupo concreto) y tantas líneas
adicionales como ACEs de ese tipo hayamos asginado al fichero o
directorio. La entrada other es la entrada del permiso
tradicional other del modelo UGO.
La entrada mask es especial. Esa entrada, que se puede
manipular con setfacl permite especificar el máximo de
permisos que se pueden asignar en dicho fichero con las ACEs de
usuario y grupo.
Veamos ahora las ACL del resto de ficheros y directorios:
# getfacl dir_raiz/fich*
# file: dir_raiz/fich_1
# owner: root
# group: root
user::rw-
group::r--
group:sistemas:rw-
mask::rw-
other::r--
# file: dir_raiz/fich_2
# owner: root
# group: root
user::rw-
group::r--
group:sistemas:rw-
mask::rw-
other::r--
# getfacl dir_raiz/dir_1
# file: dir_raiz/dir_1
# owner: root
# group: root
user::rwx
group::r-x
group:sistemas:rw-
group:desarrollo:rw-
mask::rwx
other::r-x
# getfacl dir_raiz/dir_1/fich*
# file: dir_raiz/dir_1/fich_3
# owner: root
# group: root
user::rw-
group::r--
group:sistemas:rw-
group:desarrollo:rw-
mask::rw-
other::r--
# file: dir_raiz/dir_1/fich_4
# owner: root
# group: root
user::rw-
group::r--
group:sistemas:rw-
group:desarrollo:rw-
mask::rw-
other::r--
# getfacl dir_raiz/dir_2
# file: dir_raiz/dir_2
# owner: root
# group: root
user::rwx
group::r-x
group:sistemas:rw-
group:desarrollo:rw-
group:explotacion:r-x
mask::rwx
other::r-x
# getfacl dir_raiz/dir_2/fich*
# file: dir_raiz/dir_2/fich_5
# owner: root
# group: root
user::rw-
group::r--
group:sistemas:rw-
group:desarrollo:rw-
group:explotacion:r-x
mask::rw-
other::r--
# file: dir_raiz/dir_2/fich_6
# owner: root
# group: root
user::rw-
group::r--
group:sistemas:rw-
group:desarrollo:rw-
group:explotacion:r-x
mask::rw-
other::r--
ACLs por defecto.
Todo lo anterior está muy bien, pero tiene un problema: los
ficheros y directorios nuevos que se creen no van a tener todas
esas ACLs con los valores adecuados, y por tanto tendremos que
estar cada dos por tres ajustando los valores de las ACLs con
las órdenes anteriores. Evidentemente eso no es operativo en
absoluto. En nuestra ayuda llegan las ACLs por defecto (en
realidad habría que hablar de ACEs por defecto, pero la
documentación habla de ACLs por defecto, así que mantendremos la
misma terminología para no crear más confusión).
Las ACLs por defecto nos permiten indicar cuál es el juego de
ACEs que queremos que se apliquen automáticamente a los nuevos
ficheros y directorios que se creen dentro de un directorio
dado. Se dice en estos casos que los permisos se heredan desde
el directorio padre.
La sintaxis es idéntica a la de una ACE normal, con la
diferencia de que debemos usar además la opción -d:
setfacl -d -m g:sistemas:rw dir_raiz
setfacl -d -m g:desarrollo:rw dir_raiz/dir_1
setfacl -d -m g:desarrollo:rw dir_raiz/dir_2
setfacl -d -m g:explotacion:rw dir_raiz/dir_2
Si usamos getfacl para ver la ACL del directorio raíz por
ejemplo, tenemos lo siguiente:
# getfacl dir_raiz
# file: dir_raiz
# owner: root
# group: root
user::rwx
group::r-x
group:sistemas:rw-
mask::rwx
other::r-x
default:user::rwx
default:group:sistemas:rwx
default:group::r-x
default:mask::rwx
default:other::r-x
Es decir, se añaden una serie de ACEs especiales, de tipo
default que contienen la información a utilizar para
los nuevos ficheros y directorios que se creen dentro de éste.
Y aquí concluye la tercera parte de la saga. Para la cuarta y
última parte tengo previsto hablar de como compilar SAMBA para
que use las ACLs nativas del sistema, de forma que podamos
ofertar recursos compartidos 100% compatibles con los sistemas
de Microsoft en cuanto a características de seguridad.
Hablaré asimismo del demonio winbind, que nos permite integrar
las cuentas de un dominio NT/2000 en nuestro sistema, sin tener
que dar de alta dichas cuentas en local (las crea de forma
automágica al vuelo). Con estas dos características podremos
crear un sistema que remplace un servidor de ficheros NT/2000 de
forma 100% transparente, con un rendimiento igual o superior al
de este (especialmente en el caso de usar raid por software para
el sistema de disco). Y con una estabilidad y precio a años luz
de la solución Microsoft.
Para un futuro más lejano puede que escriba un miniartículo
sobre los atributos extendidos, su manejo y posibilidades. Los
atributos extendidos son el bloque fundamental para poder
implementar las ACLs, pero permiten en general asociar cualquier
tipo de atributos definidos por el usuario a los ficheros (en
realidad a los i-nodos). De esta forma es posible por ejemplo
codificar el tipo MIME de los ficheros en dichos atributos y
hacer así innecesario el uso de extensiones de ficheros y
heurísticas para determinar el tipo de contenido y sistema de
codificación del mismo para un fichero dado.
Hasta entonces, permanezcan atentos a sus liberto-pantallas. Y
no olviden supervitaminarse y supermineralizarse :)
Saludos. Iñaki.