Manual de SELinux para Gentoo
Contenido:
-
Introducción a Gentoo/Hardened SELinux
Esta parte cubre SELinux y cómo está posicionado en el proyecto
Gentoo/Hardened.
-
Mejorando la seguridad en Linux
La seguridad consiste en algo más que habilitar un cierto marco de
trabajo o instalar un núcleo Linux diferente. Es una forma de trabajar
y administrar su sistema Gentoo Linux. Aquí cubrimos algunas buenas
prácticas (genéricas), y entonces trabajamos en el llamado Control de
Acceso Obligatorio (MAC) y cómo SELinux cubre este hueco.
-
Conceptos detrás de SELinux
Para poder trabajar correctamente con SELinux, es vital que comprenda
algunos conceptos como dominios, transiciones de dominios y contextos
de ficheros. Sin una comprensión básica de estos aspectos, será dificil
comprender cómo funcionan las directrices de SELinux y cómo actuar en
caso de que las cosas no vayan bien.
-
Recursos de SELinux
Para familiarizarse mejor con SELinux, existen muchos recursos en
Internet. En este capítulo ofreceremos una vista rápida de los
variados recursos así como lugares donde se puede obtener más ayuda
en la lucha contra SELinux.
-
Usando SELinux Gentoo/Hardened
Dejando atrás las cuestiones teóricas, abordamos ahora la instalación
de Gentoo/Hardened con un núcleo SELinux así como las herramientas
SELinux tools.
-
Instalación de Gentoo SELinux / Conversión
Para poner en marcha SELinux en Gentoo/Hardened, necesitará en primer
lugar instalar Gentoo con el perfil Hardened apropiado (o convertir
su perfil actual al perfil Hardened), a continuación puede actualizar
su sistema para convertirlo en uno gestionado por SELinux. En este
capítulo le guiaremos a través de este proceso.
-
Configurar SELinux para adaptarlo a sus necesidades
Con SELinux ahora "instalado" y habilitado (aunque funcionando en modo
permisivo), podemos configurarlo para que se adapte a nuestra necesidades
particulares. Después de todo, SELinux es un sistema de Control de
Acceso Obligatorio en el cual, como administrador de seguridad, pude
definir lo que está permitido y lo que no.
-
Órdenes en SELinux
Demos un paso atrás y conozcamos algunas otras órdenes. Cubrimos la
mayoría de ellas en la sección previa y ahora profundizaremos un poco
más en su sintaxis, características y faltas más potenciales.
-
Permisivo, no confinado, deshabilitado o lo que no...
Su sistema puede encontrarse en muchos estados SELinux. En este capítulo,
el ayudaremos a cambiar entre varios estados y directrices.
-
Modificar la directriz de SELinux en Gentoo Hardened
Gentoo Hardened ofrece un directriz por defecto, sin embargo, puede que
ésta no le permita hacer lo que desea (o permita demasiado). En este
capítulo le contaremos como puede ajustar la directriz de Gentoo e
incluso crear la suya.
-
Solucionando problemas con SELinux
Todo lo que haga un humano puede y de hecho, fallará. En este capítulo
intentaremos mostrar todos los problemas potenciales con los que se
puede encontrar y cómo resolverlos.
-
Historial de cambios
A medida que la documentación evoluciona con la tecnología, este manual
sufrirá sus cambios correspondientes. Para permitir a los usuarios que
ya utilizand SELinux, verificar si hay cambios de los que necesitan tener
conocimiento, este capítulo muestra la lista de cambios en orden
cronológico.
A. Introducción a Gentoo/Hardened SELinux
1. Mejorando la seguridad en Linux
1.a. Introducción
Una bienvenida amigable
Bienvenido al manual de SELinux para Gentoo. Con este recurso
queremos presentarle rápidamente la implementación de SELinux y
las directrices implicadas. Parte de esta presentación consiste
en ayudarle a comprender porqué se creó SELinux y qué conceptos se
esconden detrás de los parches de SELinux. Cubriremos los conceptos
más importantes de SELinux, las directrices de referencia que utiliza
Gentoo Hardened y desarrollaremos el trabajo con algunas herramientas
de SELinux.
El propósito de este libro no es explicar en detalle el funcionamiento
del propio SELinux. Existen muchas referencias disponibles en Internet
y en muchos libros que le ayudarán con SELinux. En lugar de esto, nos
centraremos en la integración de SELinux en Gentoo Hardened. Desde
luego, le ofreceremos una rápida introducción a SELinux para que
pueda comprender cómo trabaja, lo que es, y le ayudaremos a identificar
las acciones que necesita realizar para asegurar su sistema usando
las herramientas de SELinux.
1.b. Asegurando Linux
Seguridad en general
La seguridad se ve a menudo como un concepto vago. ¿Qué es la seguridad
en general? ¿Cómo se mide? ¿Qué beneficio se obtiene y cómo asegurarse
de no poner demasiado esfuerzo en asegurar su sistema?
Bien, los fanáticos de la seguridad le contarán que no existe otra
cosa salvo el exceso de seguridad. Si se implementa de forma correcta,
la seguridad no restrige la funcionalidad o el rendimiento. No le da
demasiado trabajo para realizar sus tareas. Pero implementar la
seguridad de forma apropiada es una tarea diferente y que conlleva
mucho tiempo. Esta es la razón por la que en muchas ocasiones se
escucha que la seguridad es tan buena como su administrador.
Entonces, ¿Cómo puedo velar por la seguridad?. Una buena práctica
consiste en definir sus metas en lo que a seguridad se refiere. Haga
una lista de que lo que quiere conseguir y porqué lo quiere hacer.
Haciendo un seguimiento de las amenazas que quiere minimizar, podrá
construir un modelo de seguridad que es el adecuado para su entorno.
Estas amenazas pueden ser muy pretenciosas, como por ejemplo
"Asegurarse de que nadie pueda violar nuestras medidas de seguridad".
En el caso de un sistema Linux funcionando con SELinux, esto podría
significar que desea que nadie o nada, salvo los procesos de confianza,
puedan escribir en ficheros críticos del sistema, como por ejemplo,
la(s) imagen(es) del núcleo, configuración del gestor de arranque,
las contraseñas y el propio binario de SELinux con las directrices.
Control de acceso
Un control de acceso decente de un sistema (o grupo de sistemas),
asegura que únicamente se permite acceso a las personas o procesos
autorizados a los recursos con los que quieren trabajar.
Antes de que pueda implementar un control de acceso al sistema,
necesitará obtener la autorización adecuada. Si sus esquemas de
autenticación fallan, su sistema de control de acceso al sistema
podría no diferenciar a los usuarios legítimos de los maliciosos.
La autenticación de los usuarios en los sistemas Linux se realiza
a través de PAM (Módulos de Autenticación Enchufables), un
potente mecanismo para integrar esquemas múltiples de autenticación
de bajo nivel en una interfaz de alto nivel.
Sin embargo, la autorización para el uso de los recursos, se realiza
a veces a través de un esquema simple de permisos. La mayoría de los
recursos no están ocultos por defecto, aunque existen parches y
actualizaciones (tales como las ofrecidas por las fuentes del núcleo
Gentoo Hardened con parches grSecurity que incluyen soporte para este
tipo de medidas). Puede ocultar la existencia de archivos en todo
el sistema de ficheros asegurándose de que el directorio en el que
residen no es legible ni "ejecutable" por cuentas no autorizadas.
Este esquema de permisos por defecto tiene algunos inconvenientes
importantes. No le permite definir autorizaciones flexibles (únicamente
permite autorizaciones a tres niveles: propietario, grupo propietario
y cualquier otra cuenta) y además está limitada a los permisos
lectura/escritura/ejecución (aunque algunos atributos adicionales
están disponibles hoy en día).
Otro problema es que el esquema de permisos es discrecional, lo
que significa que los usuarios y procesos pueden cambiar las directrices
de seguridad.
Este esquema de permisos es suficiente Para la mayoría de usuarios y ha
demostrado ofrecer un método adecuado para gestionar las autorizaciones
de acceso. Si embargo, los inconvenientes que presenta han resultado
ser un agujero importante en lo que Linux ofrece.
1.c. Control de acceso obligatorio
Entre en SELinux
Si el control de acceso discrecional, abreviado DAC, mencionado
arriba no es suficiente (y si es riguroso con la seguridad, no lo
encontrará suficiente), entonces necesitará un sistema Control de Acceso
Obligatorio o MAC.
Cuando se usa un sistema MAC, se necesita permitir explícitamente las
actividades que un proceso quiere realizar en un recurso. Esto ofrece
mayor granularidad con los permisos y los recursos. A menudo
ofrecen no sólo soporte para ficheros, sino también para zócalos
(sockets), puertos, segmentos de memoria, colas, procesos, servicios
del núcleo, llamadas al sistema, dispositivos, sistemas de ficheros y
mucho más. La granularidad de las actividades soportadas es también
muy grande. Para los ficheros, esto incluye: añadir, crear, ejecutar,
escribir, enlazar, llamadas ioctl, obtener atributos (getattr), dar
valor a atributos (setattr), lectura, renombrado, bloqueo,... mientras
que para los zócalos (sockets) estos pueden ser: añadir, asociar (bind),
conectar, crear, escribir, enviar a, aceptar,... También, cuando se
utiliza un sistema MAC, ningún usuario ni proceso puede manipular las
directrices de seguridad por sí mismo: lo que el administrador ha
concedido no puede ser revocado.
Aquí es donde SELinux entra en juego. SELinux es una característica del
núcleo Linux que implementa, entre otras cosas, un sistema MAC para
controlar y gobernar el acceso a varios recursos. Usa un esquema de
permisos de denegación por defecto, de forma que se necesita conceder
explícitamente el acceso que ha solicitado un proceso.
SELinux permite igualmente un modelo de permisos más fino encima
del sistema tradicional DAC (el cual se usa también mientras SELinux
está en funcionamiento; en otras palabras: si el sistema tradicional
no permite ciertas actividades, éstas no serán permitidas incluso si
las directrices de SELinux permiten la acción).
¿Qué es SELinux?
Para dar soporte a este modelo fino de permisos, es lógico pensar que
se deben realizar cambios al núcleo Linux. Sí, gracias a la interfaz
del núcleo Linux LSM (Módulos de Seguridad de Linux), el
soporte para SELinux se añadió de forma muy sencilla desde el comienzo
de las series 2.6 del núcleo. SELinux se ha integrado en el árbol
principal del núcleo. Sin embargo, el soporte de SELinux y su utilización
son dos cosas muy diferentes.
Para identificar adecuadamente los recursos, SELinux necesita asignar
etiquetas a estos recursos. Cuando los recursos están en memoria, se
realiza principalmente en el núcleo Linux, sin embargo, para recursos
persistentes como ficheros, estas etiquetas deben localizarse en algún
lugar. En SELinux, se ha elegido usar atributos extendidos del fichero
(que son almacenados en el propio sistema de ficheros). La ventaja de
este enfoque es que la etiqueta permanece junto al fichero incluso si
éste cambia de nombre. Por el contrario, una desventaja de este enfoque
es que el sistema de ficheros debe soportar estos
atributos extendidos, los cuales no todos los sistemas de
ficheros poseen (o tienen activados).
SELinux también utiliza roles para gestionar el acceso a los recursos.
A un usuario que no tiene el rol de acceso a la administración del
sistema no se le debe permitir ejecutar cualquier actividad de
administración del sistema incluso si es capaz de escalar sus privilegios
(por ejemplo usando una aplicación con la capacidad set-uid). Para el
soporte de roles, SELinux requiere cambios en los servicios de
autenticación (PAM) y necesita almacenar en algún lugar las definiciones
de los roles y las autorizaciones.
Aparte del soporte en el núcleo y las etiquetas asignadas a los recursos
en el sistema de autorización, SELinux requiere también herramientas
específicas para consultar y manipular las etiquetas, gestión de
privilegios (por ejemplo la herramienta sudo), servicios del
sistema (como SysVInit) etc. Esto se traduce en un conjunto de parches que
se aplican a estas herramientas (y más) los cuales no son siempre parte
del código fuente principal de la aplicación.
Gentoo Hardened y SELinux
Gentoo Hardened ofrece SELinux integrado en la distribución. Cuando se
selecciona soporte para SELinux, Gentoo Hardened aplicará los parches
necesarios a las aplicaciones y le ayudará a (re)etiquetar sus ficheros y
otros recursos para que puedan ser gestionados por SELinux. Gentoo Hardened
también integra soporte SELinux en Portage, permitiendo que los nuevos
ficheros que se instalen sean etiquetados automáticamente y que se utilice
un entorno inofensivo (sandbox) para la construcción segura de los
paquetes.
Aparte del soporte tecnológico puro, esperamos que encuentre los documentos
de soporte, guías, experiencia y soporte en línea necesarios para usar
SELinux en Gentoo. No dude en entrar y decir ¡hola! en el canal de chat
#gentoo-hardened de la red IRC en Freenode o en nuestra lista de
correo.
Si piensa que SELinux es apropiado para sus pretensiones y quiere
probarlo usando Gentoo Hardened, por favor, continúe leyendo. En el
próximo capítulo le informaremos de como se ha "diseñado" la seguridad
en SELinux y cómo está estructurada conceptualmente. En capítulos
posteriores le ayudaremos con el lenguaje de autorización y las
directrices "base" con las que la mayoría de las distribuciones
comienzan y finalmente le ayudaremos a instalar, ejecutar y gestionar
un sistema SELinux con Gentoo Hardened.
2. Conceptos detrás de SELinux
2.a. Introducción
Conceptos detrás de SELinux
Debido a que SELinux es un sistema MAC, probablemente se habrá dado cuenta
de que la gestión de los permisos y privilegios basados en SELinux va
a ser un poco más complicada que la gestión de privilegios en un control
de acceso discrecional que es el que se utiliza generalmente en un sistema
Linux. Algo importante a tener en cuenta es que SELinux trabaja
encima del sistema DAC que es el que utiliza todo el mundo en Linux.
Siendo un administrador de sistemas, necesitará familiarizarse con algunos
conceptos y estructuras que SELinux ha colocado para gestionar el acceso
a estos sistemas.
El propósito de este capítulo es La descripción de estos conceptos. Daremos
ejemplos de estos conceptos en un sistema Gentoo Hardened con SELinux
habilitado. Sin embargo, no se preocupe si el uso de algunas órdenes
en particular no se detalla suficientemente. Se muestran únicamente como
ejemplos (lo que se aprenda de esto es más importante) y será discutido
más abajo en este documento.
Directrices de SELinux
Dentro de Gentoo (y también dentro de otras distribuciones), SELinux es
soportado por varios niveles de directriz. Estos son, en orden ascendente
en complejidad (significando que pueden ofrecer mayor seguridad pero
que son más difíciles de gestionar):
-
targeted es una directriz en la que los servicios que utilizan
la red (demonios) están confinados (los procesos solo pueden ejecutar
aquellas acciones que estén definidas en la directriz). Sin embargo,
otras aplicaciones corren en el llamado unconfined (no
confinado), lo que indica que hay muy pocas restricciones para estos
procesos.
-
strict es una directriz en la que todos los procesos están
confinados. No existen dominios no confinados. En otras distribuciones,
esta es considerada la directriz targeted pero sin la
definición de dominio no confinado.
-
multi-category security es una directriz en la que los
dominios (confinados) pueden ser categorizados (clasificados),
permitiendo que múltiples procesos corran en diferentes instancias
de un dominio confinado.
-
multi-level security es una directriz en la que existen
reglas relativas a la sensibilidad de dominios y recursos. Esto
permite una directriz de flujo de información "adecuada" (asegurándose
de que la información sensible no se filtra a través de dominios
con menores privilegios). Conceptualmente, esto se puede comprender
mejor si se consideran los niveles de sensibilidad Público, Interno,
Confidencial, Estrictamente confidencial, etc.
Cuando se utiliza Gentoo Hardened, todas estas directrices están
disponibles. Sin embargo el desarrollo se centra principalmente en
strict y mcs (multi-category security). Se asume que la
directriz targeted funciona si funciona la directriz strict
aunque sabemos que la directriz mls (multi-level security) no
está preparada para el uso en producción.
Nota:
Para aclarar posibles confusiones, especialmente cuando se intenta buscar
soporte fuera de Gentoo: nuestra implementación "strict" no es la
implementación que era "strict" hasta el año 2008. El antiguo significado
de "strict" involucraba una implementación diferente de la directriz.
|
2.b. Contextos de seguridad
Usuarios, Roles y Dominios
Uno de los primeros conceptos con los que debe familiarizarse es el
de contexto de seguridad. Se trata de un estado que se asigna
a un recurso de modo que identifica únicamente qué concesiones (permisos)
se dan al recurso. Este contexto es extremadamente importante para
SELinux ya que es la definición en la cual basa sus permisos (concesiones
o revocaciones). Cuando un recurso no tiene un contexto asignado, SELinux
intentará darle un contexto de seguridad por defecto, el cual, considerando
la filosofía del menor privilegio posible, tiene pocos permisos para
realizar cualquier acción.
En el marco de SELinux, este contexto de seguridad se muestra usando de
tres a cinco definiciones, dependiendo del tipo de directriz que se
esté utilizando:
- user
-
El usuario SELinux (no el mismo que el usuario técnico de
Linux/Unix) asignado al recurso.
- role
-
El rol SELinux en el que el recurso trabaja actualmente.
- type
-
El tipo asignado al recurso, la clave para las reglas de reforzamiento
de SELinux.
- sensitivity
-
Este es un nivel dado a un recurso informado al sistema sobre la
sensibilidad de este recurso. La sensibilidad es algo relacionado
con Publico, Interno, Restringido, Confidencial, Estrictamente
confidencial, ... Los niveles de sensibilidad están soportados únicamente
por las directrices MLS.
- category
-
Se trata de una instanciación específica de un recurso. Permite la
segregación de recursos incluso si son del mismo tipo. Se hablará
más acerca de las categorías más adelante. Las categorías están
soportadas únicamente por las directrices MLS y MCS.
Se dará más información sobre estas definiciones en particular a lo largo
de este capítulo.
Como ejemplo, echemos un vistazo al contexto de seguridad de un usuario
que ha ingresado en el sistema:
Listado de Código 2.1: Obtener el contexto de seguridad de un usuario que ha ingresado en el sistema |
~$ id -Z
staff_u:staff_r:staff_t
|
En este caso, el usuario está identificado como el usuario SELinux
staff_u, que actualmente tiene el rol staff_r y está
asignado al tipo staff_t. Las acciones que se permiten a este
usuario están basadas en este contexto de seguridad. También, observará
que únicamente se muestran tres identificadores. Esto es debido a que
se ha tomado el ejemplo de un sistema con directriz strict (o
targeted). El siguiente ejemplo da el mismo resultado pero para
una sistema con directriz MCS.
Listado de Código 2.2: Obteniendo el contexto de seguridad de un usuario que ha ingresado en un sistema con directriz MCS |
~$ id -Z
staff_u:staff_r:staff_t:s0-s0:c0.c1023
|
Aquí, el usuario está corriendo con el nivel de sensibilidad s0 (el cual,
en un sistema con directriz MCS, el el único disponible) y con una categoría
c0 hasta c1023 (inclusive). Sin embargo, observe que en un sistema con
directriz MCS, las categorías son opcionales, por lo que deberá ver una salida
del tipo: staff_u:staff_r:staff_t:s0.
Directrices de control de acceso
Como ya se ha mencionado, estos contextos de seguridad se usan como
base de las reglas de permisos. Lo que hace SELinux es comprobar el
contexto de seguridad de la fuente (por ejemplo un proceso) y del
destino (por ejemplo un fichero que el proceso necesita leer). Entonces
se comprueba si la operación solicitada (lectura) está permitida entre
estos dos contextos. Recuerde que SELinux trabaja encima del sistema
de permisos estándar usados en Linux. Si un proceso no puede, en
principio, leer un fichero, ni siquiera se consulta a SELinux.
Hasta ahora, el contexto de seguridad define el estado de un recurso,
sin embargo, no hemos hablado de los recursos en sí. En el marco de
SELinux, los tipos de recursos están definidos como
clases de objetos. Ejemplos muy comunes son file
o dir. SELinux también gestiona clases como
filesystem, tcp_socket, process, sem
(semáforos) y mucho más.
En cada clase de objeto, se declara un conjunto de permisos, los
cuales son aplicables a un recurso de esta clase de objeto. Por ejemplo,
la clase de objeto process soporta cuanto menos los siguientes
permisos:
Listado de Código 2.3: Permisos soportados para un recurso 'process' |
~# ls /selinux/class/process/perms
dyntransition getcap rlimitinh setpgid siginh
execheap getpgid setcap setrlimit sigkill
execmem getsched setcurrent setsched signal
execstack getsession setexec setsockcreate signull
fork noatsecure setfscreate share sigstop
getattr ptrace setkeycreate sigchld transition
|
La regla más común de SELinux para el control de acceso (allow)
se describe de la siguiente forma:
Listado de Código 2.4: La sentencia SELinux allow |
allow ACTOR TARGET:CLASS PRIVILEGE;
+-+-+ +-+--+ +-+-+ +---+---+
| | | `- Permiso a conceder (como "write")
| | `- Clase a la que se da el permiso (como "file")
| `- Recurso (etiqueta) en la que el permiso es válido (como "portage_conf_t")
`- Actor (dominio) que obtiene el privilegio (como "sysadm_t")
|
Echemos un vistazo a un pequeño ejemplo que explica las reglas de permisos
y cómo las utiliza SELinux. El usuario ejemplo está en el contexto
staff_u:staff_r:staff_t y desea escribir en su propio directorio.
Lo lógico sería que se le permitiera esta acción. No se preocupe por las
órdenes mostradas aquí, las discutiremos en detalle más abajo en este
mismo documento.
Listado de Código 2.5: Comprobar si un usuario puede escribir en su propio directorio home |
~$ ls -dZ ${HOME}
staff_u:object_r:user_home_dir_t /home/swift
~$ sesearch -s staff_t -t user_home_dir_t -c dir -p write -A
Found 1 semantic av rules:
allow staff_t user_home_dir_t : dir { ioctl read write create ... };
|
Como era de esperar, el contexto de seguridad del usuario (para ser más
específico, el dominio en el que reside) tiene acceso de escritura al
dominio de los directorios destino. La noción de dominio aparece
frecuentemente en la documentación de SELinux y se refiere al tipo
asignado a un proceso. Por cierto, como los ficheros no tienen ningún
rol, SELinux les asigna el rol por defecto object_r.
Ahora echemos un vistazo al siguiente ejemplo. Nuestro usuario, que
pertenece al grupo portage, quiere escribir en el directorio
/var/tmp/portage:
Listado de Código 2.6: Comprobar si un usuario puede escribir en el directorio /var/tmp/portage |
~$ id -a
uid=1001(swift) gid=100(users) groups=100(users),...,250(portage),...
~$ ls -ldZ /var/tmp/portage
drwxrwxr-x. 3 portage portage system_u:object_r:portage_tmp_t 4096 Dec 6 21:08 /var/tmp/portage
|
Desde le punto de vista de los permisos estándar de Linux, el usuario
tiene permiso para escribir. Pero, ¿Le permitirá SELinux hacerlo?
Listado de Código 2.7: Intentar escribir en /var/tmp/portage |
~$ sesearch -s staff_t -t portage_tmp_t -c dir -p write -A
~$
~$ touch /var/tmp/portage/foo
touch: no se puede efectuar `touch' sobre «/var/tmp/portage/foo»: Permiso denegado
|
Como SELinux no pudo encontrar una regla que permitiera al dominio
staff_t escribir en cualquier directorio etiquetado con el tipo
portage_tmp_t type, se denegó el acceso.
2.c. Forzado de tipos / Tipos de dominio
Tipos y dominios
Para explicar como funcionan las reglas de permisos y como se fuerzan
mediante los contextos de seguridad, comencemos con la última definición
en el contexto (el tipo) y trabajemos hacia los roles y usuarios.
-
Un tipo SELinux es una etiqueta en particular que se asigna
a un recurso. Por ejemplo, la orden passwd está etiquetada
con el tipo passwd_exec_t.
-
Un dominio SELinux es el estado de seguridad de un proceso e
identifica los derechos y permisos que posee. Normalmente, nos
referiremos a él por su declaración de tipo. Por ejemplo, el dominio
para una orden passwd es passwd_t.
Las reglas que identifican las acciones permitidas para un dominio ya se
han descrito anteriormente, las citamos de nuevo:
Listado de Código 3.1: Reglas estándar de las directrices SELinux |
allow <src_domain> <dst_type> : <class> { permiso [ permiso [ ... ] ] } ;
|
Un ejemplo del dominio passwd_t podrían ser los permisos
concedidos entre el dominio passwd_t y el tipo shadow_t
(usado por el fichero /etc/shadow).
Listado de Código 3.2: Concesiones entre passwd_t y shadow_t |
allow passwd_t shadow_t : file { ioctl read write create ... } ;
|
Esta sintaxis de permisos es muy potente, pero también complicada. Para
tener un sistema seguro en el que se permite un comportamiento normal,
necesitará ajustar finamente estas reglas para todas y cada una de las
aplicaciones (y de igual forma para los dominios) que desea albergar en
su sistema. Dar permisos de forma extensiva a un dominio en un tipo
en particular, puede resultar en la pérdida de eficiencia e incluso
de efectividad.
Para soportar reglas de concesión de forma más sencilla, SELinux permite
el agrupamiento de tipos usando los atributos de tipos. Por ejemplo, el
atributo exec_type agrupa todos los tipos que se asignan a los
ficheros ejecutables (como bin_t, ssh_exec_t, ...), mientras
que el atributo file_type agrupa todos los tipos que se asignan
a ficheros regulares. Aunque esto pueda simplificar la gestión de las
reglas, puede resultar en que se asignen sin quererlo más permisos de
los que se desean asignar.
Transiciones de dominio
Hasta aquí hemos hablado de tipos, definiciones de dominios y sus permisos.
Hemos comentado previamente que los permisos están basados en el dominio
en el que reside un proceso. Pero, ¿cómo llega un proceso a ser parte de
un dominio? Podrá pensar que esto ocurre de una forma prefijada (ejecutar
la orden passwd conllevaría que el proceso se asociara al
dominio passwd_t), de hecho, esto se realiza mediante la combinación
de tres privilegios muy específicos que deben ser concedidos:
-
Se debe permitir al dominio actual la transición a otro dominio.
-
El dominio destino debe tener un punto de entrada, que es
un ejecutable, al cual se le permite arrancar en el dominio.
-
El dominio fuente debe tener permisos de ejecución (en el
dominio) sobre ese ejecutable.
Importante:
El hecho de que no se permita la transición, no significa que no se pueda
ejecutar el binario. El binario puede ser ejecutado, pero no lo hará
dentro del dominio destino. En lugar de eso, heredará el dominio del
ejecutor y por lo tanto los permisos y derechos de ese dominio.
|
Usando estas reglas, el administrador de la seguridad de un sistema puede
controlar de forma más específica quién y bajo qué condiciones se pueden
realizar acciones particulares.
2.d. Roles y derechos
El rol de un rol
Los dominios y las reglas de dominio expuestas anteriormente son bastante
potentes. Sin embargo, SELinux ofrece mucho más. Después de todo, debe
ser posible denegar el acceso a dominios particulares a usuarios no
autorizados. Un requisito es, desde luego, no permitir transiciones desde
el dominio del usuario a un dominio restringido, pero, ¿cómo se permite
a un conjunto de usuarios mientras que se deniega a otro?
Presentaremos los roles. Usando roles, puede indicarle a SELinux qué
dominios se permiten para un rol y cuales no. Un ejemplo podría ser el
dominio ifconfig_t. Este dominio tiene los derechos para cambiar
las definiciones de las interfaces de red, lo cual es algo que no debe
permitir a sus usuarios. Y, de hecho, si pudiera verificarlo, SELinux
no permite asignar el rol de usuario user_r al dominio
ifconfig_t.
Listado de Código 4.1: Comparación de user_r y sysadm_r para el dominio ifconfig_t |
~$ seinfo -ruser_r -x
user_r
Dominated Roles:
user_r
Types:
...
~$ seinfo -rsysadm_r -x
sysadm_r
Dominated Roles:
sysadm_r
Types:
...
ifconfig_t
...
|
Importante:
De nuevo, el hecho de no poder asociar un dominio, no significa que el rol
user_r no pueda ejecutar el binario ifconfig. Puede,
pero ejecutará este binario en su propio dominio (user_t). Este
dominio no tiene derechos para manipular la interfaces de red (sin
embargo puede leer información del interfaz aunque con información
limitada).
|
Los roles se usan a menudo en sistemas de control de acceso para agrupar
permisos en un solo conjunto funcional (el rol), el cual se puede asignar
a individuos (cuentas). Por ejemplo, estos sistemas de control de acceso
crean roles para contables, operadores, administradores,... y conceden los
privilegios apropiados a estos roles. Entonces, a estos usuarios se les
asigna uno (o a veces varios) roles y los usuarios heredan los permisos
asignados a estos roles.
En SELinux, se usa esta idea (se usan roles para diferenciar privilegios
de forma funcional), sin embargo se implementa de forma distinta: a los
roles se le asignan dominios destino en los que se permite que un rol
"pueda entrar". Los permisos permanecen asignados a los dominios.
Transiciones de rol
Los usuarios (y los procesos) pueden cambiar de rol. En SELinux se permite,
pero únicamente cuando se concede la posibilidad de cambiar. Por defecto,
las directrices de SELinux usadas en Gentoo Hardened ofrecen cinco roles
en un sistema SELinux:
- object_r
-
El rol object_r es el único rol disponible por defecto en
SELinux. Normalmente solo se asigna a recursos en los que no se
puede obtener ningún valor o rendimiento del sistema de roles (como
en ficheros y directorios).
- system_r
-
El rol system_r se usa para servicios del sistema con muchos
privilegios. Se permite al rol system_r cambiar a cualquier
otro rol definido por "defecto". Ningún rol excepto sysadm_r
puede cambiar al rol system_r.
- sysadm_r
-
El rol sysadm_r se usa para actividades de administración del
sistema. Se permite al rol sysadm_r cambiar a cualquier otro
rol definido por "defecto". Únicamente se permite a los roles
system_r y staff_r cambiar al rol sysadm_r.
- staff_r
-
El rol staff_r se asigna a los operadores del sistema que
deberían tener derechos para realizar tareas de administración.
Al rol staff_r se le permite cambiar únicamente al rol
sysadm_r. Solo sysadm_r y system_r pueden
cambiar al rol staff_r.
- user_r
-
El rol user_r se asigna a usuarios estándar y sin muchos
privilegios. No se permite la transición a ningún otro rol; únicamente
se permite a los roles sysadm_r y system_r cambiar al
rol user_r.
Nota:
Los roles por "defecto" son: user_r, staff_r,
sysadm_r y system_r. Si se crean roles adicionales, éstos
no serán parte del los roles por "defecto".
|
Usando estas definiciones, un usuario dentro del rol user_r nunca
podrá ejecutar ifconfig en el dominio ifconfig_t. El uso
de la palabra nunca es importante: no podrá, incluso si el usuario
puede usar la cuenta root mediante sudo o cualquier otra orden
que permita ejecutar ifconfig en el dominio ifconfig_t,
porque, a pesar de que ha ejecutado sudo, el usuario está
utilizando el rol user_r.
Usuarios de SELinux
Un usuario de SELinux no es lo mismo que un usuario Linux. Mientras que
se puede cambiar de una cuenta de usuario estándar de Linux a otra usando
órdenes como su o sudo, un usuario SELinux no se puede
cambiar. Incluso cuando ejecute con éxito sudo, su usuario SELinux
seguirá siendo el mismo.
Cuando observe un sistema gestionado con SELinux, podrá ver que ese
sistema no tiene muchos usuarios SELinux. Por ejemplo, la configuración
por defecto de Gentoo Hardened define los usuarios root,
user_u, staff_u, sysadm_u y system_u y en
muchos sistemas nunca se crea ningún usuario SELinux más. En este caso,
¿la ventaja mencionada arriba sobre usuarios SELinux (una vez que el
usuario ingresa en el sistema, éste no puede cambiar a otro usuario
SELinux) es la única?
Bien, no. Los usuarios SELinux también se usan para categorizar las
cuentas que tienen el permiso de usar un rol en particular.
Listado de Código 4.2: Usuarios SELinux y sus roles asociados |
~# semanage user -l
SELinux User SELinux Roles
root staff_r sysadm_r
staff_u staff_r sysadm_r
sysadm_u sysadm_r
system_u system_r
user_u user_r
|
Los usuarios Linux estándar están vinculados a estos usuarios SELinux:
Listado de Código 4.3: Usuarios Linux y sus vínculos con usuarios SELinux |
~# semanage login -l
Login Name SELinux User
__default__ user_u
root root
swift staff_u
|
En este ejemplo, únicamente el nombre de los usuarios Linux swift
(a través de staff_u) y root (a través del usuario SELinux
root) podrán eventualmente trabajar en el rol sysadm_r. El
resto de cuentas serán vinculadas por defecto al usuario user_u
(y al rol user_r).
Esto se aplica únicamente a los usuarios interactivos. Los procesos
que se lanzan mediante un guión de inicio o de cualquier otra forma no
se asocian con el usuarios SELinux user_u: dependiendo del contexto
de seguridad de los procesos que los lancen, podrán cambiar a cualquier
otro. Desde luego, si el contexto de seguridad del proceso que los está
lanzando es user_u:user_r:user_t entonces no podrán transformarse
en otro más que user_u:user_r:* con * un dominio soportado
por el rol user_r.
Los usuarios SELinux se utilizan también para implementar el Control
de Acceso Basado en Usuario o UBAC. Esta funcionalidad de
SELinux permite a los dominios conocer a los usuarios: un proceso
corriendo en el contexto de un usuario SELinux en particular puede, por
ejemplo, únicamente trabajar con ficheros del mismo usuario SELinux. Esto
ofrece un método de acceso más fino ya que ese proceso podrá correr en un
dominio que tenga acceso al dominio del fichero, pero no podrá escribir
en el fichero ya que el usuario SELinux es distinto.
Actualmente SELinux en Gentoo Hardened soporta ambas directrices y
también el soporte sin UBAC, aunque se recomienda encarecidamente el uso
de UBAC. Esto se controla usando el ajuste USE ubac.
2.e. Seguridad multinivel / Seguridad multicategoría
Introducción
Además de la característica para forzar los tipos, SELinux también ofrece
soporte MLS (seguridad multinivel) y MCS (seguridad multicategoría). Esto
permite a los administradores definir una directriz de confidencialidad
jerárquica. Por ejemplo, puede asegurarse de que un proceso o usuario en
un determinado dominio de seguridad y nivel, pueda escribir en ficheros
del mismo nivel (o superior), o leer ficheros del mismo nivel (o inferior),
pero no puede escribir en ficheros de un nivel inferior. Esto permite a
los administradores implementar un nivel de seguridad jerárquica
pública/interna/confidencial/estrictamente confidencial para los ficheros.
Aunque la implementación de MLS podría realizarse usando las reglas de
forzado de tipos que hemos explicado previamente, hacerlo así podría
desembocar en una colección inmanejable de tipos y permisos. La
implementación MLS facilita esto.
Seguridad Multinivel
Es la más flexible, pero la más complicada de gestionar. El método que
ofrece SELinux es MLS, o Seguridad Multinivel (Multi-Level Security).
Cuando se utiliza este tipo de directriz, los administradores de seguridad
pueden asignar etiquetas de sensibilidad a los recursos y definir qué
dominios (y qué niveles de seguridad) pueden leer o escribir en qué nivel.
Un nivel se da siempre como un rango, mostrando el menor y mayor nivel en el
que un dominio en particular está corriendo.
Además del nivel de sensibilidad, la directriz MLS soporta categorías por
cada nivel. Estas categorías permiten que el administrador de seguridad
pueda hacer distintos "contenedores" probablemente independientes para
los recursos que sean sensibles. Para dar un ejemplo, el administrador
puede soportar los niveles desde Público hasta Estrictamente confidencial
y categorías como "Finanzas", "Análisis de Riesgo", "Adquisiciones",
"Sistemas TIC", ...
Con estas categorías, uno puede permitir que un rol tenga acceso a todos
los niveles de sensibilidad para una categoría en particular (digamos
"Sistemas TIC") pero que tenga acceso únicamente a los documentos
Públicos e Internos del resto de categorías.
Seguridad Multicategoría
La directriz MCS o Seguridad Multicategoría (Multi-Category Security)
es un subconjunto de la directriz MLS. Soporta las distintas categorías, pero
sin usar los múltiples niveles de seguridad para los recursos.
El uso de la directriz MCS se ha hecho popular debido aq que es bastante
más fácil de gestionar mientras que conserva algo de la flexibilidad
presente en la directriz MLS. La directriz MLS se utiliza más para
propósitos de negocio (y así, tiene alguna influencia en la propia
organización de ese negocio). La directriz MCS es más utilizada en
arquitecturas multipropiedad. En una arquitectura multipropiedad,
los sistemas son procesos en ejecución para varios clientes a la vez. La
categorización permite la separación de estos privilegios a través de estos
procesos sin introducir dominios múltiples (los cuáles requerirían el
desarrollo de nuevas directrices para cada nuevo cliente al que se quisiera
servir).
2.f. Directriz de referencia
Acerca de refpolicy
Como se ha descrito previamente, SELinux utiliza forzado de tipos para
describir el estado de su sistema. Esto se realiza dando a cada recurso
del sistema (sea un proceso, un puerto de red, un fichero o directorio)
un tipo específico y describiendo las reglas de cómo cada tipo puede
trabajar con otros tipos.
La gestión de esta directriz no es fácil. Al contrario que otros
sistemas MAC, los cuales confían en un modo de aprendizaje y no utilizan
definiciones de dominio (éstos en su lugar registran qué órdenes tiene
permitidas ejecutar un proceso), una definición correcta SELinux
requiere muchas (miles y miles) líneas de permisos.
Para asegurarse de que no se realizan esfuerzos duplicados, y para
ayudar a las distribuciones como Gentoo, Fedora, RedHat, Debian, ... en
sus esfuerzo de integración de SELinux, se ha lanzado un proyecto
denominado The Reference Policy (La directriz de referencia).
Este proyecto, gestionado por Tresys, se usa
en la mayoría de las distribuciones que soportan SELinux, incluyendo
Gentoo Hardened, Fedora, RedHat Enterprise Linux, Debian, Ubuntu y más.
Esta implementación no solo ofrece las directrices modulares que los
usuarios están buscando, sino que mejora la experiencia con SELinux
añadiendo herramientas de desarrollo adicionales que hacen más fácil
trabajar con las directrices de SELinux en su sistema. Las actualizaciones
en la directriz de referencia se realizan eventualmente en todas las
distribuciones soportadas. Lo mismo sucede con Gentoo Hardened, que
trata de utilizar una directriz los más cercana a la de referencia, y
envía sus propios parches a la directriz de referencia, lo cual
beneficia a toda la comunidad.
El API de la directriz de referencia
Una de las mayores ventajas de la directriz de referencia es su API.
Para ayudar a los autores de las directrices, la directriz de referencia
utiliza un lenguaje de macros que genera las reglas necesarias de
permisión así como otras reglas. Este lenguaje de macros, hace muy fácil
añadir derechos a dominios en particular. El API documentado se
encuentra
en línea, sin embargo, si tiene ajustado USE="doc", se almacenará
en su sistema en el momento en que instale y configure SELinux.
Enfoque modular
Otra característica de la directriz de referencia es el uso de
modulos. Si quisiera construir todas las reglas en una única
directriz (un fichero binario legible por el núcleo Linux, permitieńdole
interpretar y forzar las reglas SELinux rules), el fichero enseguida
crecería demasiado y se mostraría ineficiente.
En lugar de esto, la directriz de referencia define las reglas en los
llamados módulos, los cuales a su vez definen un dominio (por ejemplo
portage_t) o más (si están fuertemente relacionados) y los
derechos y privilegios que ese dominio necesitaría para funcionar de
forma correcta. Cualquier derecho que necesita el dominio respecto a
otro dominio debe definirse en las interfaces de ese dominio (mire
más arriba), forzando que los módulos sean específicos y manejables.
Listado de Código 6.1: Vista rápida de ejemplo de módulos SELinux instalados |
# semodule -l
alsa 1.11.0
apache 2.3.0
audioentropy 1.6.0
dbus 1.15.0
dmidecode 1.4.0
|
Al utilizar un enfoque modular, únicamente se necesita cargar la directriz
base (la capa del núcleo, así como otras definiciones fundamentales) y los
módulos relacionados con ese sistema. Podrá entonces ignorar de forma
segura los demás módulos. Esto mejora el rendimiento (directrices más
cortas, lo cual conlleva que las reconstrucciones sean un poco menos
penosas) y la manejabilidad (definiendo de forma adecuada los límites
de las reglas de la directriz).
Configuraciones y condicionales
Pero, ¡un momento!, aún hay más. La directriz de referencia también soporta
el uso de booleanos. Éstos son ajustes que un administrador de la
seguridad puede habilitar o deshabilitar para cambiar la directriz activa.
Los booleanos definidos de forma correcta permiten a los administradores
de seguridad ajustar finamente la directriz para sus sistemas.
Listado de Código 6.2: Vista rápida de los booleanos disponibles |
# getsebool -a
allow_execheap --> off
allow_execmem --> off
allow_execmod --> off
allow_execstack --> off
allow_gssd_read_tmp --> on
allow_httpd_anon_write --> off
|
Los booleanos son una parte importante para construir una directriz de
referencia genérica que sea utilizable por la mayoría de los usuarios
de SELinux. Aunque tiene requisitos específicos (como el hecho de
permitir ptrace o deshabilitar execmem) aún pueden utilizar la misma
directriz de referencia y definir únicamente aquellos booleanos que
se necesiten.
Ficheros de directriz y versiones
La infraestructura de directriz SELinux utilizada (por ejemplo, las
capacidades y funcionalidades que ésta ofrece) no se incluyen en su
primera versión. Actualmente, las entregas de SELinux utilizan un
versión del binario 24 o 26 (dependiendo de la versión del núcleo
utilizada).
Listado de Código 6.3: Obtener la versión del binario de la directriz |
# sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 24
Policy from config file: strict
|
Cada vez que se añaden funcionalidades o capacidades que requieren
cambios a la estructura interna de la directriz compilada, se incrementa
este número de versión. A continuación se muestra una vista rápida
del histórico de versiones de la directriz, básicamente es una traducción
del fichero security/selinux/include/security.h
perteneciente al núcleo Linux.
- Versión 12
- "Antigua API" para SELinux, la cual es ahora obsoleta
- Versión 15
- "Nueva API" para SELinux, integrada en el núcleo Linux 2.6.0 (hasta
la versión 2.6.5)
- Versión 16
- Añadidas extensiones condicionales a la directriz (2.6.5)
- Versión 17
- Añadido soporte para IPV6 (2.6.6 - 2.6.7)
- Versión 18
- Añadido soporte para zócalos (sockets) de enlace de red con ajuste fino
(2.6.8 - 2.6.11)
- Versión 19
- Mejorada la seguridad multinivel (2.6.12 - 2.6.13)
- Versión 20
- Optimizaciones en el acceso al tamaño de la tabla de vectores (2.6.14 -
2.6.18)
- Versión 21
- Transiciones en rango de clases de objetos (2.6.19 - 2.6.24)
- Versión 22
- Capacidades de la directriz (características) (2.6.25)
- Versión 23
- Modo permisivo para cada dominio (2.6.26 - 2.6.27)
- Versión 24
- Jerarquía explícita (limites de tipos) (2.6.28 - 2.6.38)
- Versión 25
- Soporte de transiciones basadas en nombres de fichero (2.6.39)
- Versión 26
- Soporte de transición de roles para clases no-proceso (3.0)
- Versión 27
- Soporte para la herencia flexible de los usuarios y roles de los
objetos creados (3.5)
- Versión 28
- Soporte para la herencia flexible del tipo de los objetos creados
(3.5)
2.g. Siguientes pasos
Qué es lo siguiente
Puede que sea difícil comprenderlos ahora, pero estos conceptos son
importantes ya que si algo va mal en su sistema cuando habilite SELinux,
pero todo funciona bien cuando se deshabilita, entonces necesitará
estudiar más a fondo los contextos de seguridad, las reglas, los tipos
y transiciones de dominio para averiguar el motivo del fallo.
En el siguiente capítulo, le ofrecemos información sobre recursos
(recursos en línea, libros, preguntas frecuentes, etc.). A continuación,
nos sumergeremos en la instalación y configuración de SELinux en su
sistema Gentoo Hardened system. Entonces, configuraremos y ajustaremos
la directriz SELinux a nuestro antojo.
3. Recursos de SELinux
3.a. Conceptos previos
Introducción a SELinux
3.b. Directriz de SELinux
Referencias relacionadas con la directriz
3.c. Libros
Libros en papel
-
SELinux mediante ejemplos: Usando la seguridad mejorada de SELinux,
por Frank Mayer, Karl MacMillan y David Caplan. Prentice Hall, 2006;
ISBN 0131963694
-
SELinux: Linux con la seguridad mejorada de código abierto de NSA,
por Bill McCarty. O'Reilly Media, 2004; ISBN 0596007167
3.d. Recursos específicos de Gentoo
Gentoo Hardened
Los siguientes recursos son específicos de la implementación de SELinux
en Gentoo Hardened.
B. Usando SELinux Gentoo/Hardened
1. Instalación de Gentoo SELinux / Conversión
1.a. Instalar Gentoo (Hardened)
Introducción
Instalar el sistema Gentoo con SELinux no requiere acciones extrañas.
Lo que se necesita es instalar Gentoo Linux con el perfil correcto, la
configuración del núcleo correcta y etiquetar algunos sistemas de ficheros.
Recomendamos seriamente usar SELinux junto con otras mejoras que hagan más
robusto nuestro sistema (como PaX / grSecurity).
Este capítulo describe los pasos para instalar Gentoo con SELinux.
Asumimos que tiene un sistema Gentoo Linux ya funcionando que quiere
convertir a Gentoo con SELinux. Si no es éste el caso, puede igualmente
continuar leyendo: podrá instalar Gentoo con SELinux de forma directa si
toma las decisiones correctas, basadas en la información contenida en
este capítulo, durante el proceso de instalación.
Realizar una instalación estándar
Instale Gentoo Linux siguiendo las instrucciones del
manual de Gentoo. Recomendamos usar
los ficheros tarball hardened de stage3 y el núcleo
hardened-sources en lugar de los ficheros estándar, sin embargo,
las instalaciones con stages estándar se permiten también en SELinux.
Haga una instalación completa hasta el punto en el que debe reiniciar
su sistema para obtener una instalación base (primitiva) de Gentoo.
Nota:
Si utiliza XFS, asegúrese de que el tamaño de los nodos-i del sistema
de ficheros XFS es de 512 bytes. Debido a que el valor por defecto es
256, necesitará ejecutar la orden mkfs.xfs con los argumentos
-i size=512, de esta forma: mkfs.xfs -i size=512 /dev/sda3
|
Cambiar a Python 2
Hasta la fecha, no todas las utilidades de gestión de SELinux son
compatibles con Python 3 por lo que le recomendamos cambiar a
Python 2 hasta que los paquetes sean actualizados y corregidos.
Listado de Código 1.1: Cambiar a python 2 |
~# emerge '<=dev-lang/python-3.0'
~# eselect python list
Available Python interpreters:
[1] python2.7
[2] python3.1 *
~# eselect python set 1
~# source /etc/profile
|
Elegir un tipo de directriz SELinux
Gentoo ofrece soporte a cuatro tipos de directriz en SELinux:
strict, targeted, mcs y mls.
La diferencia entre strict y targeted es debida
al dominio no confinado. Cuando se carga la directriz,
los procesos en su sistema que no están confinados específicamente
en un módulo de directriz en particular formarán parte de los
dominios no confinados cuyo propósito es permitir por defecto
la mayoría de las actividades (en lugar de prohibirlas por
defecto). Como resultado, los procesos que corren dentro de
dominios no confinados no tienen restricciones aparte de
aquéllas ya forzadas por la seguridad estándar de Linux.
A pesar de que el hecho de trabajar sin dominios no confinados
está considerado más seguro, también será un más complicado para
el administrador tener la certeza de que el sistema funciona
correctamente ya que no hay módulos de directriz para cada una
de las aplicaciones "ahí fuera".
Aparte de targeted y strict, puede optar por
mcs para permitir la categorización de los dominios de
los procesos. Esto es útil en sistemas gestionados por
múltiples propietarios como servidores Web, equipos de
virtualización, etc. en los que muchos procesos están
corriendo, la mayoría de ellos en el mismo dominio de seguridad,
pero en diferentes categorías. Observe, sin embargo, que para
para poder utilizar el soporte de categorías adicionales, bien
las propias aplicaciones (como el servidor Web o las herramientas
de supervisión) necesitan configurar las categorías SELinux
(por lo que deben ofrecer soporte a SELinux), bien se
necesitará un guión para arrancar las instancias individuales
en categorías diferentes. De lo contrario, mcs es
simplemente lo mismo que targeted o strict.
Para terminar, puede también elegir mls para
diferenciar los dominios de seguridad a un nivel sensible.
Sin embargo, MLS aún está considerado experimental en Gentoo
y por lo tanto no lo recomendamos.
En el caso de mcs o mls, necesitará utilizar el
ajuste USE unconfined para habilitar o deshabilitar los
dominios no confinados en estos tipos de directriz. El tipo
strict (sin dominios no confinados) no ofrece este ajuste
USE, y el tipo targeted (dominios no confinados) requiere
que el ajuste USE esté habilitado.
Cuando haya elegido los tipos de directriz, guárdelos también en
su fichero /etc/make.conf. De esta forma, Portage
instalará únicamente los módulos SELinux para ese tipo de directriz.
Por defecto, los perfile SELinux habilitan strict y
targeted (siendo strict el tipo activo por
defecto).
Listado de Código 1.2: Ajustar el tipo de directriz en make.conf |
~# nano /etc/make.conf
POLICY_TYPES="strict"
|
Ajustar los contextos del sistema de ficheros
Si su directorio /tmp está en un sistema de ficheros
tmpfs montado, entonces necesitará indicarle al núcleo que el
contexto raíz de esta localización es tmp_t en lugar de
tmpfs_t. Muchos objetos en la directriz de SELinux (incluyendo
algunas directrices al nivel de servidor) asumen que /tmp
es tmp_t.
Para configurar el montaje de /tmp, edite su fichero
/etc/fstab:
Listado de Código 1.3: Actualizar /etc/fstab para /tmp |
tmpfs /tmp tmpfs defaults,noexec,nosuid,rootcontext=system_u:object_r:tmp_t 0 0
tmpfs /tmp tmpfs defaults,noexec,nosuid,rootcontext=system_u:object_r:tmp_t:s0 0 0
|
A continuación, ajuste la siguiente línea en su /etc/fstab para
configurar el contexto para la localización /run.
Listado de Código 1.4: Actualizar /etc/fstab para /run |
tmpfs /run tmpfs mode=0755,nosuid,nodev,rootcontext=system_u:object_r:var_run_t 0 0
tmpfs /run tmpfs mode=0755,nosuid,nodev,rootcontext=system_u:object_r:var_run_t:s0 0 0
|
Cambie el perfil de Gentoo
Ahora que tiene una instalación de Gentoo Linux funcionando, cambie el
perfil de Gentoo al perfil SELinux adecuado (por ejemplo,
hardened/linux/amd64/no-multilib/selinux). Observe que los
perfiles antiguos (como selinux/v2refpolicy/amd64/hardened)
todavía están soportados.
Listado de Código 1.5: Cambiar el perfil de Gentoo |
~# eselect profile list
Available profile symlink targets:
[1] default/linux/amd64/10.0
[2] default/linux/amd64/10.0/selinux
[3] default/linux/amd64/10.0/desktop
[4] default/linux/amd64/10.0/desktop/gnome
[5] default/linux/amd64/10.0/desktop/kde
[6] default/linux/amd64/10.0/developer
[7] default/linux/amd64/10.0/no-multilib
[8] default/linux/amd64/10.0/server
[9] hardened/linux/amd64
[10] hardened/linux/amd64/selinux
[11] hardened/linux/amd64/no-multilib *
[12] hardened/linux/amd64/no-multilib/selinux
~# eselect profile set 12
|
Nota:
A partir del momento en que cambie su perfil, Portage le advertirá después
de cada instalación que "No pudo ajustar las etiquetas de seguridad de
SELinux". Esto es lo esperado, ya que las herramientas y capacidades que
requiere Portage para ajustar las etiquetas de seguridad todavía no están
disponibles. Esta advertencia desaparecerá en el momento en que se complete
la instalación de SELinux.
|
No actualice su sistema aún. Necesitaremos instalar un par de paquetes
en las siguientes dos secciones en un orden en particular para el
que Portage no está preparado.
Actualice make.conf
A continuación, eche un vistazo a los siguientes ajustes USE y decida si
quiere habilitarlos o deshabilitarlos.
| Ajuste USE |
Valor por defecto |
Descripción |
| peer_perms |
Habilitado |
La capacidad peer_perms gestiona los controles de la directriz de
SELinux para los principales (peers) de red. Si está habilitada, los
mecanismos de control de acceso que utiliza SELinux para el etiquetado
basado en red, se consolidan. Se recomienda este ajuste ya que la
directriz también se actualiza para reflejar este hecho. Si no se
habilita, los mecanismos antiguos (NetLabel y Labeled IPsec) se usan
en cada lado.
|
| open_perms |
Habilitado |
La capacidad open_perms habilita el permiso "open" para las clases
de fichero y relacionadas con los ficheros. El soporte para la llamada
"open" se añadió poco después que otros por lo que el soporte al
principio fue opcional. Sin embargo, las directrices han madurado lo
suficiente para tener los permisos abiertos habilitados.
|
| ubac |
Habilitado |
Cuando está deshabilitado, la directriz SELinux se construye sin el
control de acceso basado en usuario.
|
| unconfined |
Deshabilitado |
Cuando está habilitado, la construcción de la directriz (excepto para
la directriz "strict") incluirán el módulo no confinado
(permitiendo así que existand dominios no confinados en el sistema).
|
Elija sus opciones y actualice la variable USE en
/etc/make.conf o en una localización apropiada
/etc/portage/package.use para el paquete
sec-policy/selinux-base.
Cambios manuales en el sistema
Aviso:
La mayoría, o todos los cambios que se comentan a continuación se
resolverán automáticamente en los paquetes en cuanto sea posible. Estos
cambios, sin embargo, tienen un impacto más allá de las instalaciones
de Gentoo Hardened. Por lo tanto, serán incorporados a un ritmo más
bajo que las actualizaciones específicas de SELinux. Actualmente, es
suficiente con realizar la corrección manual de estas situaciones
(además se trata de una operación que se realiza una única vez).
|
Los siguientes cambios pueden ser necesarios en su sistema
dependiendo de las configuraciones o herramientas implicadas.
-
Compruebe si tiene los ficheros *.old en /bin.
Si es así, puede eliminarlos o hacer una copia de los mismos de forma
que tengan su propio contexto de seguridad. Los ficheros
.old son enlaces duros que pueden interferir con el
etiquetado de ficheros. Por ejemplo, puede hacer
cp /bin/hostname /bin/hostname.old.
Instalar un núcleo SELinux
Aunque los núcleos Linux por defecto ofrecen soporte SELinux, recomendamos
el uso del paquete sys-kernel/hardened-sources.
Listado de Código 1.6: Instalar hardened-sources |
~# emerge hardened-sources
|
A continuación, reconfigure su núcleo con los ajustes apropiados de
seguridad. Esto incluye (pero no está limitado a):
-
Soporte de los atributos extendidos en los distintos sistemas de
ficheros
- Soporte de la auditoría de llamadas al sistema
- Soporte de SELinux
Debajo encontrará una lista rápida de los ajustes recomendados.
Listado de Código 1.7: Ajustes recomendados para la configuración del núcleo Linux |
[*] Prompt for development and/or incomplete code/drivers
[*] Auditing support
[*] Enable system-call auditing support
<*> Second extended fs support
[*] Ext2 extended attributes
[ ] Ext2 POSIX Access Control Lists
[*] Ext2 Security Labels
[ ] Ext2 execute in place support
<*> Ext3 journalling file system support
[ ] Default to 'data=ordered' in ext3
[*] Ext3 extended attributes
[ ] Ext3 POSIX Access Control Lists
[*] Ext3 Security Labels
<*> The Extended 4 (ext4) filesystem
[*] Ext4 extended attributes
[ ] Ext4 POSIX Access Control Lists
[*] Ext4 Security Labels
<*> JFS filesystem support
[ ] JFS POSIX Access Control Lists
[*] JFS Security Labels
[ ] JFS debugging
[ ] JFS statistics
<*> XFS filesystem support
[ ] XFS Quota support
[ ] XFS POSIX ACL support
[ ] XFS Realtime subvolume support (EXPERIMENTAL)
[ ] XFS Debugging Support
<*> Btrfs filesystem (EXPERIMENTAL)
[ ] Btrfs POSIX Access Control Lists
[*] Enable different security models
[*] Socket and Networking Security Hooks
[*] NSA SELinux Support
[ ] NSA SELinux boot parameter
[ ] NSA SELinux runtime disable
[*] NSA SELinux Development Support
[ ] NSA SELinux AVC Statistics
(1) NSA SELinux checkreqprot default value
[ ] NSA SELinux maximum supported policy format version
Default security module (SELinux) --->
|
Recomendamos igualmente el uso de PaX. Puede encontrar más información
sobre PaX en el contexto Gentoo Hardened en
Guía de inicio rápido
para usar PaX con Gentoo Hardened.
Construya e instale el nuevo núcleo Linux y sus módulos.
Actualice fstab
A continuación, edite /etc/fstab y añada la siguiente línea:
Listado de Código 1.8: Habilitar las opciones del sistema de ficheros específicas de selinux |
none /selinux selinuxfs defaults 0 0
|
También deberá crear el punto de montaje
Listado de Código 1.9: Crear el punto de montaje /selinux |
# mkdir /selinux
|
Reinicie
Una vez realizados los cambios mencionados arriba, reinicie su sistema.
Asegúrese de que ahora está corriendo un núcleo Linux con SELinux
habilitado (el sistema de ficheros /selinux deberá estar
montado). No se preocupe, todavía no está activado SELinux.
1.b. Configure SELinux
Introducción
Ahora necesitaremos configurar SELinux, para ello, deberemos instalar las
utilidades apropiadas, etiquetar nuestro sistema de ficheros y configurar
la directriz.
Instalar directrices y utilidades
En primer lugar, instale los paquetes sys-apps/checkpolicy y
sys-apps/policycoreutils. Aunque éstos serán instalados
obligatoriamente debido a las dependencias con los paquetes de
directriz SELinux, necesitaremos instalarlos en primer lugar, por ello
se utiliza la opción -1.
Listado de Código 2.1: Instalar la directriz y utlidades principales de SELinux |
~# emerge -1 checkpolicy policycoreutils
|
Ahora deberá instalar el paquete de directriz de SELinux
(sec-policy/selinux-base-policy). Este paquete contiene la
directriz base de SELinux. Ya que Portage intentará etiquetar y recargar
las directrices (debido a la instalación de
sys-apps/policycoreutils), necesitaremos desactivar
temporalmente el soporte de SELinux (ya que Portage no podrá etiquetar
nada si todavía no lo comprende).
Listado de Código 2.2: Instalar los paquetes de directriz de SELinux |
~# FEATURES="-selinux" emerge selinux-base-policy
|
A continuación, reconstruya aquellos paquetes afectados por el cambio
de perfil que hicimos previamente usando una actualización estándar de
"world" que tendrá en cuenta los cambios en los ajustes USE (ya que
el nuevo perfil cambiará muchos ajustes USE por defecto, incluyendo el
ajuste USE selinux). No olvide utilizar después
etc-update o dispatch-conf ya que se necesitarán
realizar algunos cambios a los ficheros de configuración.
Listado de Código 2.3: Actualice su sistema Gentoo Linux |
~# emerge -uDN world
|
Ahora, instale las herramientas adicionales de SELinux que necesitará en
el futuro para depurar o ayudarle con su instalación de SELinux. Estos
paquetes son opcionales, pero recomendamos su instalación.
Listado de Código 2.4: Instalar paquetes adicionales de SELinux |
~# emerge setools sepolgen checkpolicy
|
Para terminar, instale los módulos de directrices para aquellas utilidades
en las que crea que va a necesitarlas. En un futuro no muy lejano, esta
acción se realizará de forma automática (los paquetes tendrán una
dependencia opcional producida por el ajustes USE selinux), pero hasta
ese momento, necesitará hacer este trabajo manualmente.
Listado de Código 2.5: Instalar los módulos de SELinux |
~# emerge --search selinux-
[...]
~# emerge selinux-screen selinux-gnupg selinux-sudo selinux-ntp selinux-networkmanager ...
|
Configure la directriz de SELinux
Dentro de /etc/selinux/config puede definir cómo se va a
configurar SELinux en el momento en que se inicie el sistema.
Listado de Código 2.6: Editar el fichero /etc/selinux/config |
# This file controls the state of SELinux on the system on boot.
# SELINUX can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE can take one of these four values:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
# mls - Full SELinux protection with Multi-Level Security
# mcs - Full SELinux protection with Multi-Category Security
# (mls, but only one sensitivity level)
SELINUXTYPE=strict
|
En este fichero de configuración se pueden definir dos variables:
-
SELINUX indica cómo se debe comportar SELinux:
-
enforcing (forzado) habilitará el cumplimiento de las
directrices. Esto es precisamente lo que queremos, sin embargo,
probablemente quiera comenzar con el modo permisivo
(permissive).
-
permissive (permisivo) habilitará las directrices pero no
obligará a su cumplimiento. Se le notificará cualquier violación
de las directrices pero no se denegará. Es recomendable comenzar
trabajando con este modo de forma que no tenga impacto en su
sistema hasta que no esté más familiarizado con SELinux. Deberá
validar las advertencias recibidas para ver si puede cambiar al
modo forzado (enforcing) o no.
-
disabled (deshabilitado) desactivará completamente las
directrices. Debido a que en esta situación no se muestran las
violaciones de las directrices, no es la situación recomendada.
-
SELINUXTYPE define el tipo de directriz SELinux que se debe
cargar. La mayor parte del desarrollo se realiza usando el tipo
strict (ya que ofrece confinamiento completo), aunque
también se ofrece soporte para los otros.
Reinicie y etiquete el sistema de ficheros
Importante:
Repita estos pasos cada vez que haya reiniciado desde un núcleo que no
tenga SELinux habilitado a un núcleo que sí lo tenga, ya que ejecutar
un núcleo con SELinux deshabilitado no actualizará los atributos de los
ficheros que se creen o manipulen en las actividades diarias en su
sistema.
|
En primer lugar, reinicie su sistema de modo que se carguen las
directrices instaladas. Ahora, necesitaremos reetiquetar sus
dispositivos y sus ficheros relacionados con openrc. Esto aplicará los
contextos de seguridad adecuados (etiquetas) en los ficheros necesarios.
Listado de Código 2.7: Reetiquetar la estrucura /dev |
~# mkdir /mnt/gentoo
~# mount -o bind / /mnt/gentoo
~# setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/dev
~# setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/lib64
~# umount /mnt/gentoo
|
A continuación, si tiene un fichero de intercambio en lugar de una partición,
etiquételo de la forma adecuada:
Listado de Código 2.8: Etiquetar el fichero de intercambio |
~# semanage fcontext -a -t swapfile_t "/swapfile"
~# restorecon /swapfile
|
Ahora reetiquete completamente su sistema de ficheros. La orden de abajo
aplicará el contexto de seguridad adecuado a los ficheros de su sistema
de ficheros basándose en la información de contexto de seguridad que
ofrecen los módulos de directrices de SELinux instalados.
Listado de Código 2.9: Reetiquetar completamente el sistema de ficheros |
~# rlpkg -a -r
|
Si alguna vez tiene que instalar una directriz de SELinux para un paquete
después de haberlo instalado, necesitará ejecutar rlpkg para ese
paquete de forma que tenga la certeza de que los contextos de seguridad
para los ficheros del paquete se ajustan adecuadamente. Por ejemplo,
si ha instalado sec-policy/selinux-screen después de
darse cuenta de que tiene instalado screen en su sistema:
Listado de Código 2.10: Etiquetar de nuevo los ficheros de un único paquete |
~# rlpkg -t screen
|
Habilitar el servicio selinux_gentoo
Gentoo ofrece un guión llamado selinux_gentoo
que restaura los contextos de los ficheros y dispositivos
creados dinámicamente así como los pseudo sistemas de
ficheros (/dev (opcionalmente) y /sys)
ya que estos sistemas de ficheros nos pueden persistir en
los cambios de contexto que suceden entre reinicios.
El guión de inicio también ofrece soporte para iniciar en
modo permisivo en primer lugar (por ejemplo si tiene un
initramfs creado que no funciona en modo forzado) y cambiar
a modo forzado a continuación.
Habilite este guión utilizando
rc-update add selinux_gentoo boot y actualice la
configuración de su gestor de arranque con las siguientes
opciones de inicio:
-
nosetenforce si inicia con enforcing=0
y no quiere que el guión de inicio vuelva a cambiar
a modo forzado (si fue configurado en
/etc/selinux/config). Si su fichero
/etc/selinux/config está configurado para
iniciar en modo permisivo, este guión de inicio no
alterará este comportamiento.
-
norestorecon si no quiere restaurar los contextos
de /dev.
Listado de Código 2.11: Configuración GRUB ejemplo |
title Gentoo Hardened/SELinux
root (hd0,0)
kernel /boot/kernel root=/dev/vg/root ... enforcing=0 ...
title Gentoo Hardened/SELinux
root (hd0,0)
kernel /boot/kernel root=/dev/vg/root ... enforcing=0 nosetenforce ...
|
Reinicie y ajuste los booleanos de SELinux
Reinicie su sistema. Así, se utilizarán los nuevos contextos de fichero
que se aplicaron. Ingrese en el sistema, y, si ha instalado Gentoo usando
los fuentes hardened (como hemos recomendado), habilite el booleano SSP de
SELinux, permitiendo a cada dominio acceso de lectura al dispositivo
/dev/urandom:
Listado de Código 2.12: Habilitar el booleano global_ssp |
~# setsebool -P global_ssp on
|
Defina las cuentas de administrador
Si SELINUXTYPE está definido a strict, entonces
necesitamos mapear la(s) cuenta(s) que utiliza para gestionar su sistema
(aquéllas que necesitan acceso a Portage) al usuario de SELinux
staff_u. Si no, no podrá gestionar correctamente el sistema
con ninguna de las cuentas (aparte de root, pero entonces
necesitará entrar en el sistema como root directamente y no
a través de sudo o su). Por defecto, los usuarios se mapean
al usuario SELinux user_u, el cual no tiene los privilegios
adecuados (tampoco los roles apropiados de acceso) para gestionar un
sistema. Las cuentas que son mapeadas a staff_u pueden hacerlo,
pero podrían necesitar cambiar del rol staff_r al rol
sysadm_r antes de que se les concedan los privilegios apropiados.
Asumiendo que su nombre de cuenta es juan:
Listado de Código 2.13: Mapear la cuenta Linux juan al usuario SELinux staff_u |
~# semanage login -a -s staff_u juan
~# restorecon -R -F /home/juan
|
Si más tarde ingresa en el sistema como juan y quiere gestionar
su sistema, probablemente necesitará cambiar su rol. Puede usar
newrole para hacer esto:
Listado de Código 2.14: Cambiar de rol |
~$ id -Z
staff_u:staff_r:staff_t
~$ newrole -r sysadm_r
Password:
~$ id -Z
staff_u:sysadm_r:sysadm_t
|
Si, por el contrario, utiliza una directriz targeted, entonces
el usuario con el que trabaja será de tipo unconfined_t y ya
dispondrá de los privilegios necesarios para realizar tareas
administrativas del sistema.
Cuando haya terminado, disfrute de su trabajo. Acaba de dar sus primeros
pasos por el mundo SELinux.
Soporte del servicio de administración
Por defecto, las directrices de SELinux en Gentoo Hardened permiten
al dominio sysadm_t el acceso a todos los servicios. Sin embargo,
algunos de estos servicios tienen directrices que les permiten
se asignados a usuarios individuales diferentes de root. Esto
requiere que se conceda al usuario el rol system_r (lo
que implica que el usuario puede, en ciertos casos, obtener este
cambio de rol hacia el rol de sistema).
Por tanto, se recomienda conceder el rol system_r al usuario
SELinux administrador que va a utilizar en mayor medida. Estos son,
en la mayoría de los casos, los usuarios root y staff_u.
Listado de Código 2.15: Conceder el rol system_r al usuario staff y root |
# semanage user -a -R "staff_r sysadm_r system_r" root
# semanage user -a -R "staff_r sysadm_r system_r" staff_u
|
2. Configurar SELinux para adaptarlo a sus necesidades
2.a. Administrando usuarios
Introducción
A lo largo de la instalación, hemos hablado de como mapear un usuario
Linux a uno SELinux. En el ejemplo, hemos utilizado un usuario
hipotético llamado "juan" y lo hemos mapeado al usuario SELinux
"staff_u". Si está corriendo un sistema multiusuario, la gestión de los
mapeos de derechos es importante. Un usuario que se mapea al usuario
"user_u" no obtendrá ningún derecho adicional. Incluso si le concediera
derechos adicionales a través de órdenes como sudo, la
directriz de SELinux no le permitiría a este usuario hacer nada que esté
relacionado con la administración.
Por esta razón, es importante tratar los mapeos de usuarios en SELinux y
los usuarios Linux de su sistema.
Mapeos de usuario
Ejecute semanage login -l para mostrar los mapeos actuales entre
las cuentas de usuario Linux y los usuarios SELinux.
Listado de Código 1.1: Ejecutar semanage login -l |
# semanage login -l
Login Name SELinux User
__default__ user_u
root root
juan staff_u
system_u system_u
|
El usuario SELinux "user_u" se utiliza para las cuentas normales. De esta
forma, el mapeo especial __default__ se define en SELinux para
notar que esa cuenta no está definida de otra forma. Esto nos asegura
que una cuenta nueva nos obtiene privilegios elevados por defecto.
La siguiente tabla ofrece una vista rápida de los usuarios estándar
SELinux disponibles después de la instalación.
| Usuario SELinux |
Descripción |
| user_u |
Usuario normal por defecto de SELinux, el cual se debe utilizar
para las cuentas de usuario final que no van a ser empleadas para
administrar ningún servicio del sistema.
|
| staff_u |
Usuario SELinux para administradores. Este usuario tiene derechos para
conmutar roles y así ganar privilegios elevados.
|
| root |
Usuario SELinux para la cuenta root. Se diferencia ligeramente de la
cuenta staff_u aparte de tener un identificador diferente. Esto
nos asegura que los ficheros protegidos por el control de acceso
basado en usuario para root no puede ser gestionado por los usuarios
staff_u (y otros).
|
| sysadm_u |
Usuario SELinux para la administración del sistema. Por defecto,
esta cuenta no se utiliza inmediatamente ya que este usuario obtiene
de forma inmediata el rol administrativo (por lo que staff_u y root
todavía necesitarán conmutar roles).
|
| system_u |
Usuario SELinux para administrar servicios. Nunca se debe utilizar
para usuarios finales ya que ofrece acceso directo al rol del sistema
(y sus privilegios).
|
| unconfined_u |
Usado cuando la directriz es targeted, este usuario SELinux
tiene muchos privilegios (esencialmente no está limitado en sus
acciones, aunque todavía se gestiona través de SELinux con una
directriz "muy abierta").
|
Para mapear una cuenta a un usuario especifico de SELinux, utilice la
orden semanage login -a:
Listado de Código 1.2: Mapera la cuenta 'sofia' al usuario staff_u |
# semanage login -a -s staff_u sofia
|
Sin embargo, cuando se actualiza este mapeo, los ficheros en el directorio
de inicio (home) del usuario serán propiedad de un usuario SELinux
incorrecto. Por ello, es importante etiquetar de nuevo los ficheros de
ese usuario:
Listado de Código 1.3: Etiquetar de nuevo los ficheros de sofia |
# restorecon -R -F /home/sofia
|
Cuentas adicionales de SELinux
Es perfectamente posible crear usuarios SELinux adicionales, y mapear
las cuentas Linux a esos nuevos usuarios. Esto se puede necesitar
cuando desee una auditoría más profunda (al nivel del usuario final) o
cuando esté mejorando la directriz con roles adicionales. También, si
quiere utilizar la característica de Control de Acceso Basada en
Usuario (UBAC), el hecho de usar diferentes usuarios SELinux es
importante para reforzar el control de los distintos usuarios (si
todos ellos utilizan el mismo usuario SELinux, el UBAC tendrá poco
efecto).
La gestión de los usuarios SELinux se realiza usando semanage user:
Listado de Código 1.4: Crear un usuario SELinux |
# semanage user -a -R "staff_r sysadm_r" sofia
|
Verifiquemos como los usuarios SELinux están configurados actualmente:
Listado de Código 1.5: Comprobar las identidades de los usuarios SELinux |
# semanage user -l
SELinux User SELinux Roles
root staff_r sysadm_r
sofia staff_r sysadm_r
staff_u staff_r sysadm_r
sysadm_u sysadm_r
system_u system_r
unconfined_u unconfined_r
user_u user_r
# semanage login -l
Login Name SELinux User
__default__ user_u
root root
sofia staff_u
swift staff_u
system_u system_u
|
Ahora que hemos creado un nuevo usuario llamado "sofia", podemos
actualizar el mapeo de la cuenta Linux "sofia" hacia el nuevo usuario
SELinux "sofia":
Listado de Código 1.6: Actualizar el mapeo del usuario Linux |
# semanage login -m -s sofia sofia
# semanage login -l
Login Name SELinux User
__default__ user_u
root root
sofia sofia
swift staff_u
system_u system_u
|
No olvide etiquetar de nuevo los ficheros de este usuario.
Como puede ver, la gestión de los usuarios SELinux implica definer el
rol al cual tiene acceso cada usuario. Hemos dado una introducción de
alto nivel a los roles por defecto en
Conceptos detrás de SELinux, sin
embargo ya que los roles son importantes cuando usamos un sistema
de Control de Acceso Obligatorio, refresquémos la memoria de nuevo:
| Rol SELinux |
Descripción |
| user_r |
Rol por defecto para el usuario final. Este rol ofrece acceso a las
aplicaciones y actividades comunes, sin embargo, no permite la
administración del sistema ni de ningún servicio más allá de lo
esperado para un usuario normal.
|
| staff_r |
Rol de administración por defecto para las actividades diarias. Este
rol posee privilegios adicionales más allá de los ofrecidos a
user_r, sin embargo, no es un rol de administración del sistema
completo. Está pensado para las actividades que no sean de
administración realizadas por operadores y administradores.
|
| sysadm_r |
Rol de administración del sistema. Este role tiene privilegios muy
elevados (ya que contiene aquellos privilegios necesarios para
actualizar la directriz) y debería asignarse únicamente a
administradores en los que se confíe plenamente. En casi ninguna
situación es asignado a usuarios de forma inmediata (deben en
primer lugar conmutar entre roles) excepto para el acceso directo
de root (por ejemplo a través de la consola).
|
| system_r |
Rol de servicio del sistema, el cual se utiliza para los servicios
que están corriendo (procesos). Se asigna únicamente a los usuarios
cuando estos obtienen derechos específicos y limitados de
administración (por ejemplo, derechos de administración sobre
un único dominio de un demonio).
|
| unconfined_r |
El rol no confinado se utiliza cuando la directriz targeted
está soportada. Este rol se asigna a usuarios no confinados (por
ejemplo el usuario SELinux unconfined_u) los cuales tienen muchos
privilegios (éstos trabajan prácticamente sin limitaciones).
|
Se debe observar que estos roles son los que existen por defecto, sin
embargo, el administrador de seguridad puede crear roles adicionales
y añadir privilegios particulares. Hablaremos sobre esto más adelante
en este manual ya que implica que se debe actualizar la directriz
SELinux de Gentoo Hardened.
2.b. Leyendo el registro de auditoría
Introducción
Cuando trabaje con un sistema que tiene habilitado SELinux, se dará
cuenta de que las cosas se comportan de forma diferente pero sin
indicar ningún mensaje de error con sentido. Normalmente, cuando
SELinux "deniega" un acceso en particular, lo almacena en el registro
de auditoría del sistema, aunque para la aplicación en si misma, es
perfectamente posible que muera de forma silenciosa. En caso contrario,
lo más seguro es que obtenga un mensaje de error permiso denegado.
Inicialmente, SELinux se ejecuta en modo permisivo, lo cual
significa que SELinux registrará lo que denegaría aunque nos
deje continuar. Este modo es perfecto para poner al sistema en forma
sin tener demasiados problemas mientras se hace esto. Una vez que
crea que sus ajustes de seguridad son correctos, se puede cambiar el
modo de permisivo a forzado. Hablaremos de esto más
adelante.
En primer lugar, echemos un vistazo al registro de auditoría y
veamos lo que se dice allí...
Ubicación(es) del registro de auditoría
El código del núcleo SELinux escribe las denegaciones de acceso (y
en alguna ocasión incluso las actividades que se permiten pero que
están siendo auditadas) en el registro de auditoría. Si está corriendo
una instalación Gentoo Hardened con el registrador del sistema
syslog-ng, entonces, el registrador ya está configurado para
colocar las líneas de auditoría en /var/log/avc.log.
Sin embargo, otros registradores de sistema podrían colocar estas
entradas en una ubicación diferente (por ejemplo
/var/log/audit.log).
Abajo encontrará las líneas para la configuración apropiada del
registrador del sistema syslog-ng de modo que escriba los eventos
en el fichero /var/log/avc.log.
Listado de Código 2.1: Extracto de syslog-ng.conf para las entradas AVC de SELinux |
source kernsrc { file("/proc/kmsg"); };
destination avc { file("/var/log/avc.log"); };
filter f_avc { message(".*avc: .*"); };
log {
source(kernsrc);
filter(f_avc);
destination(avc);
};
|
¿Qué es AVC?
Como ya hemos mencionado, SELinux escribe sus entradas en el registro de
auditoría. Estas entradas se llaman mensajes avc o
entradas de registro avc. El acrónimo AVC significa
Access Vector Cache (Caché de Acceso Vectorial), tal y como indica
su nombre, se trata de un sistema caché.
Utilizar un sistema cache de acceso vectorial mejora el rendimiento
cuando se trata con (y se fuerzan) actividades y privilegios. Ya que
SELinux ofrece un enfoque muy detallado sobre privilegios y permisos,
sería tremendamente penoso (en lo que se refiere a rendimiento) si
cada llamada supusiera buscar el dominio, el recurso destino, el
privilegio y si está permitido o no, esto una y otra vez. En lugar
de esto, SELinux utiliza la Caché de Acceso Vectorial para almacenar
las solicitudes y respuestas pasadas. Es es sistema AVC el responsable
de comprobar los accesos y (si es necesario) registrarlos.
Leyendo un mensaje de denegación en la AVC
Abajo encontrará un mensaje típico de denegación en la AVC.
Listado de Código 2.2: Ejemplo de mensaje de denegación en la AVC |
Oct 15 13:04:54 hpl kernel: [963185.177043] type=1400 audit(1318676694.660:2472):
avc: denied { module_request } for pid=14561 comm="firefox" kmod="net-pf-10"
scontext=staff_u:staff_r:mozilla_t tcontext=system_u:system_r:kernel_t tclass=system
|
Analicemos cada una de las partes de este mensaje una a una.
Listado de Código 2.3: Denegación AVC: Fecha, hora e información de la ubicación |
Oct 15 13:04:54 hpl kernel: [963185.177043] type=1400 audit(1318676694.660:2472):
avc: denied { module_request } for pid=14561 comm="firefox" kmod="net-pf-10"
scontext=staff_u:staff_r:mozilla_t tcontext=system_u:system_r:kernel_t tclass=system
|
La primera parte del mensaje le informa del momento en el que se escribió
el mensaje (Oct 15 13:04:54), en qué equipo (hpl) y cuántos segundos
transcurrieron desde que se inició el sistema (963185.177043).
Listado de Código 2.4: Denegación AVC: información fuente |
Oct 15 13:04:54 hpl kernel: [963185.177043] type=1400 audit(1318676694.660:2472):
avc: denied { module_request } for pid=14561 comm="firefox" kmod="net-pf-10"
scontext=staff_u:staff_r:mozilla_t tcontext=system_u:system_r:kernel_t tclass=system
|
La información que aparece después es el origen de la denegación, es decir,
qué proceso está intentando hacer qué cosa. En este caso, el proceso es
firefox, con identificador de proceso (PID) 14561, el cual está corriendo
en el dominio fuente staff_u:staff_r:mozilla_t.
Listado de Código 2.5: Denegación AVC: recurso destino |
Oct 15 13:04:54 hpl kernel: [963185.177043] type=1400 audit(1318676694.660:2472):
avc: denied { module_request } for pid=14561 comm="firefox" kmod="net-pf-10"
scontext=staff_u:staff_r:mozilla_t tcontext=system_u:system_r:kernel_t tclass=system
|
El destino de la actividad es un módulo del núcleo (net-pf-10, el cual
es el nombre interno que se le da a IPv6), etiquetado
system_u:system_r:kernel_t
Listado de Código 2.6: Denegación AVC: acción denegada |
Oct 15 13:04:54 hpl kernel: [963185.177043] type=1400 audit(1318676694.660:2472):
avc: denied { module_request } for pid=14561 comm="firefox" kmod="net-pf-10"
scontext=staff_u:staff_r:mozilla_t tcontext=system_u:system_r:kernel_t tclass=system
|
Por último, aparece la acción que ha sido denegada (module_request) y
su clase (system). Estas clases le ayudan a identificar qué es lo
que se ha denegado, ya que leer un fichero no el lo mismo que leer un
directorio.
Por ejemplo, en el siguiente caso, un proceso gorg con identificador
(PID) 13935 está intentando leer un fichero llamado
localtime con inodo 130867 el cual se encuentra en el
dispositivo /dev/md3:
Listado de Código 2.7: Ejemplo de denegación AVC |
Oct 15 14:40:30 hpl kernel: [968909.807802] type=1400 audit(1318682430.323:2614):
avc: denied { read } for pid=13935 comm="gorg" name="localtime" dev=md3 ino=130867
scontext=staff_u:sysadm_r:gorg_t tcontext=system_u:object_r:locale_t tclass=file
|
En este caso debería ser obvio que el fichero es /etc/localtime,
sin embargo, cuando este no es el caso, las dos órdenes siguiente pueden
ser útiles:
Listado de Código 2.8: Encontrar el recurso destino basándose en el inodo y dispositivo |
# mount | grep /dev/md3
/dev/md3 on / type ext4 (rw,seclabel,noatime,barrier=1,nodelalloc,data=journal)
# find / -xdev -inum 130867
/etc/localtime
|
Gestionar las denegaciones AVC
La mayor parte del trabajo para configurar SELinux es la lectura de las
denegaciones y encontrar lo que debe ser corregido (o ignorado),
corregirlo y repetir el proceso. Con un poco de suerte, el resto de
este manual le ayudará a averiguar lo que está causando la denegación.
Las denegaciones pueden ser cosméticas (una actividad que se deniega
pero que no tiene impacto en el comportamiento funcional de la aplicación).
Si este es el caso, se puede marcar la denegación como dontaudit,
(no auditar) indicando que, por defecto, la denegación ya no será
registrada. Si cree que se está denegando algo pero no lo ve en el
registro, intente deshabilitar las reglas dontaudit:
Listado de Código 2.9: Deshabilitar dontaudit |
# semodule --build --disable_dontaudit
|
En la mayoría de los casos, se debe actuar sobre las denegaciones. Las
acciones que entonces necesitará realizar son:
-
Etiquetar de nuevo el recurso destino (las etiquetas erróneas pueden
causar que acciones legítimas sean denegadas)
-
Etiquetar de nuevo el origen (el fichero binario del proceso) ya que
una etiqueta errónea puede causar que la aplicación se ejecute en
el dominio incorrecto.
-
Cargar el módulo SELinux necesario, ya que los módulos contienen
reglas para permitir (y etiquetar) recursos. Sin el módulo
correcto cargado, observará algunas denegaciones ya que no hay
ningún módulo que realice las concesiones necesarios (sentencias
para permitir las acciones).
-
Conceder el rol adecuado al usuario que ejecuta la aplicación. Hemos
cubierto los usuarios y sus roles inicialmente, sin embargo,
profundizaremos en esto más adelante en este manual.
-
Añadir sus propias sentencias de directriz SELinux, principalmente
porque no existen módulos de directriz SELinux para la aplicación
que está intentando ejecutar.
2.c. Utilizar etiquetas (de fichero)
Introducción
Dentro de SELinux, los privilegios de acceso se basan en la etiqueta que
se da a la parte original (llamada domain) y a su recurso
destino. Por ejemplo, un proceso que corre en el dominio passwd_t quiere
leer (tener privilegio) el fichero /etc/shadow que está
marcado shadow_t (el recurso destino). No es sorprendente que la
mayoría de la administración de SELinux consiste en (re)etiquetar los
recursos de forma adecuada (y asegurarse que su etiqueta permanece
correcta).
Obtener etiqueta(s) de fichero
Existen varias formas de etiquetar de nuevo las órdenes y muchas de ellas
son iguales. Pero, antes de explicar esto más en detalle, echaremos un
vistazo a algunas etiquetas de fichero (y a cómo puede consultarlas).
En SELinux, las etiquetas se asignan al nivel del fichero a través de la
capacidad del sistema de mantener atributos extendidos.
Para SELinux, los atributos se llaman security.selinux y se
pueden obtener usando getfattr:
Listado de Código 3.1: Obtener el atributo extendido de un fichero en SELinux |
$ getfattr -n security.selinux /etc/hosts
# file: etc/hosts
security.selinux="system_u:object_r:net_conf_t"
|
Desde luego, obtener el atributo del fichero de esta forma, requiere
mucho tiempo y no es flexible. Para este propósito, la aplicaciones
más importante (incluyendo coreutils) se hacen compatibles con
SELinux. Estas aplicaciones en la mayoría de las ocasiones utilizan
la opción -Z para mostrar la información de contexto de SELinux.
En el caso de ficheros, esto implica el contenido de los atributos
extendidos.
Listado de Código 3.2: Obtener el contexto de un fichero |
$ ls -Z /etc/hosts
system_u:object_r:net_conf_t /etc/hosts
|
Existen otras órdenes como matchpathcon que muestran el
contexto tal como debería ser. Sin embargo, su propósito es
consultar la directriz SELinux en su sistema para averiguar la
directriz que debería usarse, no la que se utiliza:
Listado de Código 3.3: Diferencia entre resultados de contexto y resultados de matchpathcon |
$ ls -Z /etc/make.conf
staff_u:object_r:etc_t /etc/make.conf
$ matchpathcon /etc/make.conf
/etc/make.conf system_u:object_r:portage_conf_t
|
Ajustando la(s) etiqueta(s) de fichero
Y ahora, ¿Cómo podemos manipular las etiquetas de fichero?. Bien, en
primer lugar: no se le permitirá cambiar las etiquetas de un fichero
(incluso si es el propietario del mismo) a menos que la directriz
SELinux se lo permita. Estas reglas de concesión se realizan sobre
dos tipos de privilegios: Las etiquetas que puede cambiar
(relabelfrom) y a qué etiquetas puede cambiar (relabelto).
Puede consultar estar regals usando sesearch:
Listado de Código 3.4: Consultar los tipos relabelto y relabelfrom |
$ sesearch -s user_t -c file -p relabelfrom -A
allow user_t mozilla_home_t : file { relabelfrom relabelto } ;
|
Si tiene permiso, entonces puede utilizar chcon para cambiar
(ch) el contexto de un fichero:
Listado de Código 3.5: Cambiar el contexto de un fichero |
$ ls -Z strace.log
staff_u:object_r:user_home_t strace.log
$ chcon -t mutt_home_t strace.log
$ ls -Z strace.log
staff_u:object_r:mutt_home_t strace.log
|
Si no posee los privilegios adecuados, obtendrá un mensaje de error
descriptivo:
Listado de Código 3.6: Intentar cambiar el contexto de un fichero |
$ chcon -t shadow_t strace.log
chcon: failed to change context of `strace.log' to `staff_u:object_r:shadow_t': Permission denied
|
Ahora, si cree que todo lo que necesita es la orden chcon, no está
en lo cierto. La orden chcon no hace nada más que lo que dice:
cambiar el contexto. Cuando el sistema etiqueta de nuevo los ficheros,
los cambios se van. El reetiquetado de los ficheros se realiza a menudo
para asegurarse de que las etiquetas son las correctas (es decir, las
etiquetas concuerdan con lo que la directriz SELinux dice que debería ser).
La directriz SELinux contiene, para cada módulo de directriz, la lista
de ficheros, directorios, zócalos (sockets), ... y sus contextos de
fichero apropiados (etiqueta).
Echaremos un vistazo a los módulos de directriz de SELinux más adelante.
Abajo puede encontrar un extracto de esta definición para el módulo
mozilla:
Listado de Código 3.7: Extracto de los contextos de fichero del módulo mozilla |
/usr/bin/firefox-bin -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/bin/mozilla-[0-9].* -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/bin/mozilla-bin-[0-9].* -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/lib(64)?/galeon/galeon -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/lib(64)?/netscape/.+/communicator/communicator-smotif\.real -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/lib(64)?/netscape/base-4/wrapper -- gen_context(system_u:object_r:mozilla_exec_t,s0)
/usr/lib/[^/]*firefox[^/]*/plugin-container -- gen_context(system_u:object_r:mozilla_plugin_exec_t,s0)
/usr/lib64/[^/]*firefox[^/]*/plugin-container -- gen_context(system_u:object_r:mozilla_plugin_exec_t,s0)
|
Para poner la etiqueta adecuada a un fichero, puede utilizar las órdenes
setfiles o restorecon. Debido a que ambas son la misma
orden (pero con una forma ligeramente diferente de utilización), ahora
hablaremos solo de restorecon. Se puede encontrar más información
acerca de la orden setfiles en su página del manual.
Cuando utilice restorecon, la aplicación consultará la directriz
SELinux para averiguar qué etiqueta debería ser la correcta para el
fichero. Si ésta es diferente, cambiará la etiqueta para que sea la
adecuada. Esto significa que no necesita ofrecer la etiqueta a un
fichero para que funcione la orden correspondiente. También,
restorecon soporta recursión, por lo que no necesita etiquetar
de nuevo los ficheros uno a uno.
Listado de Código 3.8: Usar restorecon |
$ ls -Z /etc/make.conf
staff_u:object_r:etc_t /etc/make.conf
$ restorecon /etc/make.conf
$ ls -Z /etc/make.conf
system_u:object_r:portage_conf_t /etc/make.conf
|
Por último, Gentoo también ofrece una aplicación muy útil: rlpkg.
Este guión etiqueta de nuevo los ficheros de un paquete Gentoo package
(rlpkg <nombredepaquete>) o, dando los argumentos adecuados,
todos los ficheros del sistema.
Listado de Código 3.9: Usar rlpkg |
# rlpkg firefox
# rlpkg -a -r
|
Saltándose las etiquetas de fichero de la directriz de SELinux
Puede que no esté siempre de acuerdo con la etiqueta que la directriz
de SELinux fuerza a los ficheros: puede que tenga sus ficheros ubicados
en otro lugar (una localización diferente de su árbol Portage es un buen
ejemplo) o quizá necesite etiquetarlos de forma diferente para que
funcionen otras aplicaciones. Para no tener que chcon estos
ficheros una y otra vez, puede mejorar la directriz SELinux en su
sistema con reglas adicionales de contextos de fichero. Estas reglas
también se utilizan cuando llama a restorecon y se salta las
reglas ofrecidas por la directriz SELinux.
Para añadir reglas de contexto de fichero adicionales, necesitará
usar la orden semanage. Esta orden se utiliza para manipular
y actualizar la directriz local de SELinux en su sistema. En este caso
en particular, utilizaremos la orden semanage fcontext:
Listado de Código 3.10: Usar semanage para añadir una regla de contexto de fichero |
# semanage fcontext -a -t portage_conf_t /mnt/gentoo/etc/make.conf
# semanage fcontext -a -t portage_ebuild_t "/mnt/gentoo/usr/portage(/.*)?"
|
Como puede observar en el ejemplo, puede utilizar caracteres comodín:
cuando una regla tiene caracteres comodín, tiene menor prioridad que
una regla que no los tiene. La prioridad de las reglas con caracteres
comodín se basa en lo "bajo" que está la cadena con la primera
ocurrencia del carácter comodín. Para más información, por favor,
consulte nuestras
Preguntas
Frecuentes: ¿Cómo averiguo qué regla de contexto de fichero se está
utilizando para un fichero en particular?.
Si quiere eliminar una definición de contexto de fichero, puede utilizar
semanage fcontext -d:
Listado de Código 3.11: Eliminar una definición de contexto de fichero |
# semanage fcontext -d -t portage_ebuild_t /mnt/gentoo/etc/make.conf
|
Por último, para ver todas las definiciones de contexto de fichero
(tanto las definidas por el usuario como las ofrecidas por la directriz
SELinux), puede utilizar semanage fcontext -l. Para ver únicamente
el conjunto local, añada -C:
Listado de Código 3.12: Ver las mejoras en el contexto de ficheros definidas por el usuario |
# semanage fcontext -C -l
SELinux fcontext type Context
/opt/xxe/bin/.*\.jar all files system_u:object_r:lib_t
/srv/virt/gentoo(/.*)? all files system_u:object_r:qemu_image_t
|
Tipos personalizables
No es muy difícil comprender cómo funcionan las etiquetas sobre los
ficheros, sin embargo, puede encontrarse alguna sorpresa si no conoce
los tipos personalizables.
Un tipo personalizable es un tipo específico que por defecto
no es modificado por las herramientas de administración de SELinux.
Si quiere etiquetar de nuevo un fichero que actualmente posee un tipo
personalizable, necesitará forzarlo usando algunas órdenes (por ejemplo
restorecon -F).
No existe muchos tipos personalizables por defecto. La lista de tipos
que SELinux considera personalizables se indican en el fichero
customizable_types en la ubicación
/etc/selinux/*/contexts:
Listado de Código 3.13: Listar los tipos personalizables |
# cat /etc/selinux/strict/contexts/customizable_types
mount_loopback_t
public_content_rw_t
public_content_t
swapfile_t
textrel_shlib_t
|
Estos tipos existen porque se utilizan para los ficheros cuya ubicación
no es fija (y por lo tanto, la directriz de SELinux no puede asegurar
si la etiqueta de los ficheros es correcta o no). El tipo
public_content_t, que se utiliza para ficheros que se van a
leer por varios servicios (por ejemplo, FTP, servidor web, ...) debería
darle una idea de este tipo de ficheros.
Si mira en la página del manual de restorecon, se mencionan tanto
los tipos personalizables como la sección de usuario. Esta última es para
las reglas que se identifican en la directriz de SELinux para ficheros
de un usuario final, como las siguientes definiciones en el módulo de
directriz mozilla:
Listado de Código 3.14: Definición de sección de usuario dentro del módulo mozilla |
HOME_DIR/\.mozilla(/.*)? gen_context(system_u:object_r:mozilla_home_t,s0)
HOME_DIR/\.netscape(/.*)? gen_context(system_u:object_r:mozilla_home_t,s0)
HOME_DIR/\.phoenix(/.*)? gen_context(system_u:object_r:mozilla_home_t,s0)
|
Aunque en el ejemplo de arriba, forzar restorecon en los ficheros
es probablemente correcto, se pueden dar ejemplos en los que ésto no
se desea. Por ejemplo, la directriz firefox por defecto únicamente
permite a la aplicación escribir en los directorios etiquetados con
mozilla_home_t. Si se quiere descargar algo, esto es imposible
(a menos que lo haga en ~/.mozilla). La solución para
esto es etiquetar un directorio (digamos ~/Descargas) con
mozilla_home_t.
2.d. Directriz SELinux y Booleanos
Introducción
Hemos tratado con usuarios y etiquetas, pero todavía tenemos que tratar
con un tercer aspecto que no hemos tocado: La propia directriz SELinux.
La directriz SELinux tal y como se ofrece en Gentoo Hardened es una
directriz cuidadosamente ajustada y basada en la directriz de referencia
(una directriz SELinux independiente de toda distribución) con cambios
menores. Con suerte, no necesitará escribir de nuevo la directriz para
adaptarla a sus necesidades, sin embargo, de vez en cuando son necesarios
algunos cambios.
Cambiar el comportamiento de la directriz SELinux: Booleanos
Una forma común y agradable de ajustar la directriz SELinux es mediante
el uso de un booleano. Un booleano SELinux, también llamado
condicional, modifica el comportamiento de la directriz SELinux
basándose en los ajustes que realiza el usuario. Para clarificar esto un
poco, echemos un vistazo a algunos de los booleanos disponibles:
Listado de Código 4.1: Obtener los booleanos SELinux |
# getsebool -a | grep ^user
user_direct_mouse --> off
user_dmesg --> off
user_ping --> on
user_rw_noexattrfile --> off
user_tcp_server --> off
user_ttyfile_stat --> off
|
Aunque parece que no hay mucho que decir a primera vista, estos booleanos
alteran el modo en que la directriz SELinux fuerza la actividad de los
usuarios (de ahí que los booleanos comiencen con user_).
Por ejemplo, user_ping esta definido a on, por lo que
se permite al usuario utilizar la orden ping. Si se define a
off, la directriz SELinux no permitiría al usuario utilizar
ping.
Se puede cambiar el valor de un booleanos entre on y off utilizando
setsebool o togglesebool. Con setsebool necesitará
indicar el valor (on u off), mientras que togglesebool conmuta
el valor.
Listado de Código 4.2: Deshabilitar el uso de ping por parte de los usuarios |
# setsebool user_ping off
|
Por defecto, setsebool no almacena los valores booleanos, por lo
que después de un reinicio los antiguos valores se cargarán. Para hacer
estos cambios persistentes, necesitará añadir la opción -P:
Listado de Código 4.3: Permitir a los usuarios ejecutar dmesg de forma persistente |
# setsebool -P user_dmesg on
|
Los booleanos permiten a los administradores ajustar la directriz, y a
los administradores de seguridad escribir directrices que sean los
suficientemente flexibles para que su uso se extienda. En términos de
la flexibilidad de Gentoo, estos booleanos no deberían usarse demasiado
(sería deseable asociar estos booleanos con ajustes USE, de modo que un
servidor instalado con USE="ldap" obtenga la directriz SELinux para
utilizar, mientras que USE="-ldap" la deshabilita). Aún así, el uso
de booleanos es una forma popular para hacer más flexible una directriz
SELinux.
Gestionar los módulos de directriz SELinux
En esta última parte, cubriremos los módulos de reglas de la directriz
SELinux. Mencionamos anteriormente que la directriz SELinux que usa
Gentoo Hardened se basa en la directriz de referencia, la cual ofrece
un enfoque modular a las directrices de SELinux. Existe una directriz
base que es obligatoria en todos los sistemas y se trata de que sea
lo más pequeña posible. El resto son módulos de la directriz SELinux,
que normalmente ofrecen las declaraciones, reglas y los contextos de
ficheros para una sola aplicación (o tipo de aplicación).
Con semodule -l puede ver la lista de módulos de directriz
SELinux que están cargados:
Listado de Código 4.4: Listar los módulos cargados por SELinux |
# semodule -l
alsa 1.11.0
apache 2.3.0
entropyd 1.6.0
dbus 1.15.0
dnsmasq 1.9.0
|
En Gentoo Hardened, cada módulo se ofrece mediante el paquete
sec-policy/selinux-<nombredemódulo>. Por ejemplo,
el primer módulo que vemos en el ejemplo de arriba lo ofrece
el paquete selinux-alsa:
Listado de Código 4.5: Paquete de módulo de directriz SELinux en Gentoo |
$ emerge --search selinux-alsa
Searching...
[ Results for search key : selinux-alsa ]
[ Applications found : 1]
* sec-policy/selinux-alsa
Latest version available: 2.20110726
Latest version installed: 2.20110726
Size of files: 574 kB
Homepage: http://www.gentoo.org/proj/en/hardened/selinux/
Description: SELinux policy for alsa
License: GPL-2
|
Cuando se necesita un módulo que no está instalado en su sistema, se
considera un fallo (los paquetes que lo necesitan deben depender del
paquete de la directriz SELinux si se ha definido el ajuste USE
selinux). Por esto, una vez que instale el paquete, el módulo se
cargará automáticamente:
Listado de Código 4.6: Instalar un paquete de directriz SELinux |
# emerge selinux-screen
|
Si necesita eliminar un módulo de su sistema, desinstalar el paquete no
será suficiente: el propio módulo directriz SELinux se copia antes al
almacén de directrices (como parte del proceso de instalación) y
Portage no lo eliminará de este almacén. Por lo tanto, deberá eliminarlo
manualmente:
Listado de Código 4.7: Desinstalar un módulo de directriz SELinux |
# emerge -C selinux-screen
# semodule -r screen
|
2.e. Siguientes pasos
¿Qué hacer ahora?
Hasta ahora, su sistema ha estado corriendo en modo permisivo.
Necesitará habilitar el modo forzado antes de estar protegido
adecuadamente mediante SELinux. Discutiremos cómo cambiar al modo forzado
en Permisivo, no confinado, deshabilitado o
lo que no..., pero antes de eso, necesitará tener en cuenta algunas
cosas...
Usuarios de Initramfs
Si su sistema utiliza un initramfs para arrancar, no podrá iniciar
el sistema directamente en modo forzado (debido a la incidencia #397597). Para
evitar esta cuestión, puede crear el siguiente guión de inicio que
cambiará de modo permisivo a modo forzado de una forma razonablemente
rápida dentro del proceso de inicio (y antes de arrancar los servicios
de red):
Listado de Código 5.1: Contenido de /etc/init.d/selinux_enforce |
#!/sbin/runscript
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo/xml/htdocs/proj/es/hardened/selinux/hb-using-configuring.xml,v 1.6 2013/01/02 18:28:08 nimiux Exp $
description="Switch into SELinux enforcing mode"
depend() {
need sysfs
}
start() {
if get_bootparam "norestorecon" ; then
ewarn "Skipping restoring file contexts in /dev as requested"
else
ebegin "Restoring file contexts in /dev"
restorecon -R /dev
eend 0
fi
if get_bootparam "nosetenforce" ; then
ewarn "Skipping switching to enforcing mode as requested by kernel cmdline"
else
. /etc/selinux/config
CURRENTMODE=$(cat /sys/fs/selinux/enforce)
if [ "${SELINUX}" = "enforcing" ] && [ "${CURRENTMODE}" = "0" ];
then
ebegin "Switching to enforcing mode"
echo 1 > /sys/fs/selinux/enforce
eend $?
else
ewarn "Not switching to enforcing mode, or enforcing mode already enabled"
fi
fi
}
|
Añada el guión de inicio al nivel de ejecución boot, y edite la
configuración de su gestor de arranque para arrancar siempre con la
definición enforcing=0. El guión de inicio actualizará los
contextos de fichero en /dev y a continuación, si su
sistema está configurado para arrancar en modo forzado, cambiará a
ese modo.
Si necesita permanecer en modo permisivo de forma temporal, puede añadir
nosetenforce como parámetro de inicio (después de enforcing=0)
lo cual evitará el paso setenforce).
Usuarios de entornos gráficos
Si arranca en un entorno gráfico (es decir, si utiliza GDM, KDM u otro
gestor gráfico de acceso al sistema), necesitará actualizar el(los)
fichero(s) de configuración PAM de los gestores mediante las siguientes
indicaciones:
Listado de Código 5.2: Ejemplo de actualización del fichero de configuración LXDM PAM |
session required pam_loginuid.so
session optional pam_gnome_keyring.so auto_start
session optional pam_selinux.so
|
Esto asegurará que el contexto de seguridad en el que ha accedido al
sistema está definido correctamente. Actualizaremos los paquetes que
definen esos ficheros PAM de forma adecuada, pero esto nos llevará algún
tiempo.
3. Órdenes en SELinux
3.a. Información sobre las órdenes en SELinux
Introducción
A estas alturas, debería tener un sistema con SELinux habilitado (pero
corriendo en modo permisivo (permissive) de modo que no obliga a cumplir
las reglas de la directriz). Por lo que antes de introducirle en el mundo
de SELinux y describir la forma de añadir más reglas sin perder la
funcionalidad cuando cambie al modo forzado (enforcing), echaremos un
vistazo rápido a algunas de las órdenes relacionadas con SELinux.
Comenzaremos con las órdenes de estado con las cuales puede obtener
información global sobre el estado de SELinux (si está corriendo
en modo forzado o no, conocer las versiones, etc).
Obteniendo el estado de SELinux
La primera orden de la que hablaremos es sestatus.
Listado de Código 1.1: Ejecutar sestatus |
# sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: permissive
Mode from config file: permissive
Policy version: 24
Policy from config file: strict
|
La salida de esta orden indica que SELinux está habilitado y está
trabajando actualmente en modo permisivo (permissive). También
nos indica que el sistema está configurado para correr en modo
estricto (strict) por lo que no existe el dominio unconfined_t.
La orden sestatus también ofrece una salida extendida si la
ejecuta con la opción -v option. Cuando se indica esta opción,
la orden devuelve los contextos de ficheros y procesos importantes:
Listado de Código 1.2: Correr sestatus -v |
# sestatus -v
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 24
Policy from config file: strict
Process contexts:
Current context: staff_u:sysadm_r:sysadm_t
Init context: system_u:system_r:init_t
/sbin/agetty system_u:system_r:getty_t
/usr/sbin/sshd system_u:system_r:sshd_t
File contexts:
Controlling term: staff_u:object_r:user_devpts_t
/sbin/init system_u:object_r:init_exec_t
/sbin/agetty system_u:object_r:getty_exec_t
/bin/login system_u:object_r:login_exec_t
/sbin/rc system_u:object_r:rc_exec_t
/usr/sbin/sshd system_u:object_r:sshd_exec_t
/sbin/unix_chkpwd system_u:object_r:chkpwd_exec_t
/etc/passwd system_u:object_r:etc_t
/etc/shadow system_u:object_r:shadow_t
/bin/sh system_u:object_r:bin_t -> system_u:object_r:sh
ll_exec_t
/bin/bash system_u:object_r:shell_exec_t
/usr/bin/newrole system_u:object_r:newrole_exec_t
/lib/libc.so.6 system_u:object_r:lib_t -> system_u:object_r:li
b_t
/lib/ld-linux.so.2 system_u:object_r:lib_t -> system_u:object_r:ld
_so_t
|
Otra orden de estado general de SELinux es getenforce, el cual
le permite ver rápidamente si su SELinux está corriendo en modo
forzado (las directrices de SELinux se fuerzan), permisivo
(las directrices de SELinux policies se comprueban y registran pero no
se fuerzan) o deshabilitado (la directriz de SELinux no se carga y por
lo tanto no se comprueba).
Listado de Código 1.3: Usar la orden getenforce |
# getenforce
Enforcing
|
Obteniendo información de los objetos de SELinux
En la siguiente tabla se muestra la orden seinfo. Esta orden
le permite consultar la directriz en ejecución definida para todos los
objetos (tipos, roles, atributos, usuarios, booleanos,...).
Algunos usos comunes son los siguientes:
-
Comprobar si un dominio en particular se ha definido en su sistema
(para el caso en que se esté preguntando si necesita cargar algún
módulo adicional de directriz de SELinux o no).
-
Comprobar en qué dominios en particular puede estar un rol (para el
caso en que se esté preguntando si las directrices SELinux permiten
a sus usuarios normales cambiar a otro dominio).
-
Comprobar qué atributos están asignados a un dominio específico (o
viceversa, qué dominios tienen activado un atributo en particular) ya
que algunas reglas de directriz trabajan sobre atributos en lugar de
dominios.
Como ejemplo, consultaremos si se conoce el dominio crontab_t, si el rol
user_r puede usar el dominio contab_t y finalmente qué dominios tienen
el atributo cron_spool_type activado.
Listado de Código 1.4: Usar seinfo |
# seinfo -tcrontab_t
crontab_t
# seinfo -ruser_r -x
user_r
Dominated Roles:
user_r
Types:
[...]
crontab_t
[...]
# seinfo -acron_spool_type -x
cron_spool_type
user_cron_spool_t
system_cron_spool_t
|
Consultando las reglas de directriz de SELinux
Una orden que se usa menudo es sesearch. Esta orden le permite
consultar las reglas usadas en la directriz actual y es de gran ayuda
cuando queremos averiguar si algo está permitido (o porqué no
está permitido).
La orden sesearch se usa frecuentemente con un dominio origen
(-s), dominio destino (-t) o ambos, la clase sobre la que
quiere hacer la consulta permite reglas para: fichero, directorio, zócalo
(socket), proceso,... y el privilegio que quiere consultar: lectura,
escritura, transición, ejecución...
Por ejemplo, para averiguar qué dominios pueden escribir en los ficheros
que tienen el dominio shadow_t:
Listado de Código 1.5: Consultar las reglas de concesión con sesearch |
# sesearch -t shadow_t -c file -p write -A
Found 8 semantic av rules:
[...]
allow portage_t shadow_t : file { ioctl read write ... };
allow useradd_t shadow_t : file { ioctl read write ... };
...
|
Observará que en algunas ocasiones los resultados están basados en los
atributos en lugar de los dominios:
Listado de Código 1.6: Regla de permisión basada en atributo |
allow portage_t file_type : file { ioctl read write ... };
|
En este caso, al dominio origen (portage_t) se le permite escribir en
los ficheros cuyo dominio tengan el atributo file_type activado. Si ya le
va cogiendo el tacto a todo esto, se preguntará si la regla de arriba
no es un fallo flagrante en la seguridad ya que todos los dominios de los
ficheros tienen el atributo file_type activado. Sí y no, si echamos un
vistazo a los dominios que tienen privilegios para escribir en los
dominios file_type domains, se dará cuenta de que el único es portage:
Listado de Código 1.7: Consultar los dominios que tienen privilegios de escritura en fichero en dominios file_type |
# sesearch -t file_type -c file -p write -A -d
Found 1 semantic av rules:
allow portage_t file_type : file { ioctl read write ... };
|
Observe que tenemos una orden sin la opción -d y otra que usa
esta opción. Cuando se indica -d, la búsqueda será realizada de
forma exacta sin resolver los atributos. Cuando no se indica -d,
entonces se resolverá el atributo. En el último ejemplo, el hecho de no
indicar -d podría resultar en cientos de reglas de permisión: para
cada dominio que tenga file_type activado, la búsqueda intenta encontrar
reglas que permiten acceso de escritura al fichero en ese dominio en
particular.
Otra interesante funcionalidad de la orden sesearch es mostrarle
las reglas que se aplican dependiendo del estado de un booleano. Si quiere
consultar un booleano en particular, utilice -b. Si quiere ver la
lógica que usa la directriz, utilice, -C (y, sí, ambas opciones
se pueden combinar).
A modo de ejemplo, comprobaremos qué permitimos (o denegamos) cuando
el booleano global_ssp está habilitado.
Listado de Código 1.8: Comprobar la directriz respecto al booleano global_ssp |
# sesearch -b global_ssp -A -C -d
Found 2 semantic av rules:
ET allow domain device_t : dir { getattr search open } ; [ global_ssp ]
ET allow domain urandom_device_t : chr_file { ioctl read getattr lock open } ; [ global_ssp ]
|
El prefijo que se muestra al comienzo de las líneas consiste en dos letras,
las cuales están relacionadas con dos definiciones importantes:
-
¿Está la regla habilitada (Enabled) o deshabilitada
( Disabled)?
-
¿Necesita el booleano definirse a cierto (True) o falso
(or False para habilitar la regla?
Obteniendo información del contexto de seguridad
Mientras esté realizando labores de administración y especialmente cuando
esté comprobando si se está produciendo una denegación SELinux, es
importante averiguar qué contexto de seguridad se está empleando para un
recurso en particular. Afortunadamente, si se instala adecuadamente,
Gentoo Hardened ha modificado algunas herramientas para obtener esta
información usando sus herramientas estándar.
Para consultar el contexto de seguridad de un fichero, utilice ls -Z:
Listado de Código 1.9: Obtener el contexto de seguridad de un fichero |
~$ ls -Z /etc/make.conf
system_u:object_r:portage_conf_t /etc/make.conf
|
Para obtener el contexto de seguridad de un proceso, utilice ps -Z:
Listado de Código 1.10: Obtener el contexto de seguridad de un proceso |
# ps -Z $(pidof init)
LABEL PID TTY STAT TIME COMMAND
system_u:system_r:init_t 1 ? Ss 0:00 init [3]
|
Para obtener el contexto de seguridad del usuario actual, utilice
id -Z:
Listado de Código 1.11: Obtener el contexto de seguridad de un usuario |
~$ id -Z
staff_u:staff_r:staff_t
|
3.b. Gestionar SELinux
Introducción
La gestión de los objetos de SELinux (booleanos, usuarios, puertos,
contextos ...) se realiza en la mayoría de las ocasiones usando
semanage. Debido a que esta aplicación ofrece la interfaz para
varias configuraciones de SELinux, le dedicaremos una sección completa,
aunque cubriremos también las órdenes que ofrecen una funcionalidad
parecida (y que en algunas ocasiones son más fáciles de recordar).
Booleanos
Hemos hablado de los booleanos de SELinux anteriormente en este libro
así como de las órdenes getsebool and setsebool. Con
semanage puede también gestionar los booleanos y, como valor
añadido, al listar los booleanos también se mostrará su descripción
(aunque queda aún trabajo por realizar en este área).
Listado de Código 2.1: Listar los booleanos de SELinux disponibles |
# semanage boolean -l
SELinux boolean Description
allow_ptrace -> off allow_ptrace
rsync_export_all_ro -> off rsync_export_all_ro
|
Nota:
Como habrá notado, la mayor parte de las descripciones consisten
únicamente en el nombre del booleano, sin embargo encontrará booleano
con una mejor descripción cuando se haya familiarizado y/o instale más
módulos de directriz de SELinux.
|
Puede definir el valor de un booleano con setsebool y
semanage:
Listado de Código 2.2: Definir el valor de un booleano de SELinux |
# semanage boolean -m --on -F user_dmesg
|
Usuarios y cuentas de SELinux
Los usuarios y cuentas de SELinux son diferentes de las de Unix. Las
cuentas de SELinux le permiten asociar una cuenta Unix a un usuario
SELinux:
Listado de Código 2.3: Listar las cuentas de SELinux |
# semanage login -l
Login Name SELinux User
__default__ user_u
root root
swift staff_u
system_u system_u
|
El comportamiento por defecto es que los usuarios ingresan en el sistema
como el usuario user_u de SELinux. Este usuario de SELinux es un
usuario no administrador: no tiene privilegios específicos y se debe
usar para para cada cuenta que nunca requiera elevar sus privilegios
(por lo que no tendrá privilegios su o sudo para nada).
La cuenta que use para administrar su sistema debe ser mapeada al
usuario SELinux staff_u (o su propio usuario con los roles
apropiados). Esto se puede conseguir de la siguiente forma (ejemplo
con la cuenta Unix ana):
Listado de Código 2.4: Permitir que 'ana' ingrese en el sistema como 'staff_u' |
# semanage login -a -s staff_u ana
|
Importante:
Asegúrese de que sea cual sea la cuenta que utilice para administrar
su sistema, está mapeada al usuario staff_u o tiene la capacidad
de cambiar al rol sysadm_r. Portage únicamente trabaja desde el
rol sysadm_r.
|
Como se ha mencionado, los usuarios SELinux están configurados para que
puedan unirse a uno o más roles. Para listar los roles disponibles, puede
usar semanage user -l:
Listado de Código 2.5: Listar las asociaciones de cuentas a roles |
# semanage user -l
SELinux User SELinux Roles
root staff_r sysadm_r
staff_u staff_r sysadm_r
[...]
|
Gestionando puertos
Incluso los puertos (como el puerto 22 para SSH) están 'protegidos' por
SELinux. Para echar un vistazo rápido de qué dominios están asignados
a qué puertos (o rangos de puertos) utilice semanage port -l.
Listado de Código 2.6: Listar los puestos gestionados por SELinux |
# semanage port -l | grep '22$'
ssh_port_t tcp 22
|
3.c. Usar SELinux
Introducción
Hasta ahora hemos visto cómo obtener información relacionada con SELinux
así como la gestión de los ajustes de SELinux. Sin embargo los usuarios
de un sistema reforzado con SELinux necesitarán también saber algunas
cosas acerca de cómo trabajar con SELinux, incluyendo (pero no
limitándose a) roles y transiciones entre roles.
Cambiando de roles
Como una forma más del reforzamiento de un sistema de control de acceso,
SELinux permite que algunos roles en particular estén en un conjunto de
dominios. Si está utilizando un rol que no está permitido en un dominio
en particular, no podrá usar ese dominio y se le denegará el acceso a las
acciones asignadas a ese dominio.
Si sus usuarios estándar son todos usuarios user_u de SELinux
(soportándose únicamente el rol user_r), entonces estos usuarios nunca
necesitarán cambiar a otro rol (aunque tampoco se les permitiría). Sin
embargo, se tiene que dejar bien claro como cambian entre roles los
usuarios que son staff_u (u otros usuarios que tienen múltiples roles).
Hemos visto cómo asociar estos usuarios al usuario correcto SELinux
(mire Usuarios y cuentas de SELinux).
La orden que permite cambiar entre roles es newrole. Su uso es
bastante lógico.
Listado de Código 3.1: Usar newrole |
~$ newrole -r sysadm_r
Password:
|
Cuando se realiza una transición de rol, SELinux pedirá que el usuario
vuelva a autenticarse usando su contraseña.
4. Permisivo, no confinado, deshabilitado o lo que no...
4.a. Estados de SELinux
Introducción
Cuando SELinux está disponible, normalmente se encontrará en uno de los
tres estados de su sistema: deshabilitado, permisivo o forzado.
Deshabilitado
Cuando la orden getenforce devuelve "Disabled", entonces SELinux
no está corriendo en su sistema. Incluso aunque está construido en
su núcleo, definitivamente está deshabilitado. Su sistema correrá con
los controles de acceso discrecionales normales (las reglas de permiso
usuales para los entornos Linux estándar), sin embargo, los controles
de acceso obligatorio no estarán activos.
Cuando SELinux está deshabilitado, esto significa que los ficheros,
directorios, etc que se modifican o crean no obtendrán el contexto SELinux
correcto que se les debe asignar. Cuando, más adelante, arranque su sistema
con SELinux habilitado (permisivo o forzado), algunos problemas podrán
surgir ya que el subsistema SELinux no conoce qué etiquetas tienen los
ficheros (se usará una etiqueta por defecto que no es accesible por la
mayoría de los dominios).
La mejor forma de continuar en este caso es iniciar en modo permisivo y
etiquetar de nuevo todo el sistema de ficheros:
Listado de Código 1.1: Etiquetar de nuevo todo el sistema de ficheros |
# rlpkg -a -r
|
Permisivo
Cuando se activa SELinux en modo permisivo (getenforce devuelve
"Permissive"), entonces SELinux está habilitado y tiene cargada una
directriz. Cada acceso que realiza un proceso se comprueba en las
reglas de la directriz y, en caso de que un acceso no esté permitido,
éste se registrará (a menos que la denegación esté marcada como dontaudit)
pero no se prohibirá.
El modo permisivo es perfecto para familiarizarse con SELinux y preparar
el sistema para el modo "forzado" que se empleará en el futuro. Mientras
se trabaja en modo permisivo, las aplicaciones que no están integradas
con SELinux funcionará como si SELinux no estuviera instalado.
Esta situación es perfecta para validar si un problema es causado por
SELinux o no: si estando en modo permisivo el problema aún persiste,
entonces el problema no lo está causando SELinux.
Sin embargo, hay una salvedad: si la aplicación está
integrada con SELinux (es decir, sabe que está corriendo en un
entorno con SELinux activado y es capaz de hacer llamadas específicas
de SELinux) puede que reaccione de forma diferente. Aunque esto es
a menudo (pero no siempre) debido a unas malas prácticas en la
programación, algunas aplicaciones comprueban si SELinux está activado
y basan su flujo funcional en este resultado, independientemente si el
estado es permisivo o forzado.
Para averiguar si una aplicación está integrada o no con SELinux,
simplemente compruebe si está enlazada con libselinux (haciendo
ldd o scanelf, esto es parte del paquete
app-misc/pax-utils):
Listado de Código 1.2: Comprobar si /bin/ls está integrada con SELinux |
# scanelf -n /bin/ls
TYPE NEEDED FILE
ET_DYN libselinux.so.1,librt.so.1,libc.so.6 /bin/ls
|
Forzado
Si la orden getenforce devuelve "Enforcing", entonces SELinux
esta cargado y actuará en base a la directriz. Cuando un proceso
intenta realizar alguna actividad que no está permitida por la
directriz, esta actividad será registrada (a menos que se defina
un dontaudit) y no se permitirá la continuidad de la actividad.
Este es el único modo en el que puede decir que SELinux está
verdaderamente activo, ya que es el único momento en que la directriz
está actuando.
Cambiando entre estados
Dependiendo de su configuración del núcleo Linux, puede conmutar entre
estados utilizando los siguientes métodos. La configuración del núcleo
puede, sin embargo, hacer que alguna de estas opciones estén
deshabilitadas (por ejemplo, un sistema hardened que no permita
deshabilitar SELinux de ningún modo).
Usar la orden setenforce:
Listado de Código 1.3: Conmutar entre forzado y permisivo |
# setenforce 0
# setenforce 1
|
Usar la opción de inicio enforcing del núcleo:
Listado de Código 1.4: Conmutar entre forzado y permisivo a través de opciones de inicio |
kernel /kernel-2.6.39-hardened-r8 root=/dev/md3 rootflags=data=journal enforcing=0
|
Usar la variable SELINUX /etc/selinux/config:
Listado de Código 1.5: Ajuste SELinux /etc/selinux/config |
# cat /etc/selinux/config
# This file controls the state of SELinux on the system on boot.
# SELINUX can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE can take one of these four values:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
# mls - Full SELinux protection with Multi-Level Security
# mcs - Full SELinux protection with Multi-Category Security
# (mls, but only one sensitivity level)
SELINUXTYPE=strict
|
Cuando quiera cambiar del modo permisivo al forzado, se recomienda hacerlo
en el orden descrito arriba:
-
En primer lugar inicie el sistema en modo permisivo, entre en él
y verifique que su contexto es correcto (id -Z), luego
conmute a forzado (setenforce 1). Puede comprobar ahora si
su sistema está funcionado correctamente.
-
A continuación, inicie el sistema con el parámetro del núcleo
enforcing=1 (a menos que inicie con un initramfs, lea más
arriba en este mismo manual). De esta forma, sus sistema se iniciará
en modo forzado, si las cosas van mal, simplemente reinicie, elimine
la opción y volverá al modo permisivo.
-
Finalmente, edite /etc/selinux/config para que los
cambios sean persistentes.
Modo Dominio permisivo
Puede también optar por marcar un solo dominio permisivo mientras
ejecuta el resto del sistema en modo forzado. Por ejemplo, para marcar
mplayer_t como un dominio permisivo (lo que implica que SELinux no
forzará nada):
Listado de Código 1.6: Marcar mplayer_t como permisivo |
# semanage permissive -a mplayer_t
|
Con la opción -d, puede eliminar la marca permisiva de nuevo.
4.b. Tipos de directriz SELinux
Introducción
Aparte del estado de SELinux, también se ofrecen distintos tipos de
directriz. Estos tipos se diferencian entre ellos en que tienen
características específicas de SELinux habilitadas o deshabilitadas.
Dentro de Gentoo, se soportan tres (una cuarta también está disponible,
como veremos):
targeted, strict, mcs (y mls).
El tipo utilizado en un sistema se declara en
/etc/selinux/config:
Listado de Código 2.1: La información SELINUXTYPE en /etc/selinux/config |
# cat /etc/selinux/config
# This file controls the state of SELinux on the system on boot.
# SELINUX can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE can take one of these four values:
# targeted - Only targeted network daemons are protected.
# strict - Full SELinux protection.
# mls - Full SELinux protection with Multi-Level Security
# mcs - Full SELinux protection with Multi-Category Security
# (mls, but only one sensitivity level)
SELINUXTYPE=strict
|
strict (sin dominios no confinados)
El tipo de directriz strict es aquél que se describió en
capítulos anteriores y casualmente se trata del tipo más fácil de
comprender. Con el tipo de directriz strict, todas y cada una de las
aplicaciones que se ejecutan lo hacen en un dominio que tiene privilegios
limitados. Aunque hay dominios altamente privilegiados, nunca son
ilimitados en sus privilegios.
targeted (utilizando dominios no confinados)
El tipo de directriz targeted es similar al strict con un
añadido importante: el soporte para dominios no confinados. Las
aplicaciones (o usuarios) que corren en un dominio no confinado
prácticamente no tienen límite en sus privilegios. Los dominios no
confinados se utilizan normalmente para los usuarios y las aplicaciones
de usuario, sin embargo, el inicio del sistema y otros dominios se
marcan también como "no confinados".
La idea detrás de la directriz targeted es que los servicios orientados
a red que están corriendo en dominios (confinados) regulares mientras
que el resto utiliza el control de acceso discrecional estándar que
ofrece Linux. Estos otros dominios corren como "no confinados".
mcs (utiliza categorías múltiples)
La introducción de mls y mcs ofrece la capacidad
multi-tenancy: varias instancias de la misma aplicación pueden
ejecutarse, pero cada instancia se debe confinar respecto a las otras
(en lugar de tener todos los procesos en el mismo dominio y por lo tanto
los mismo privilegios).
Un ejemplo sencillo es la virtualización: una máquina virtual que corre
en el dominio qemu_t necesita privilegios de escritura en el
fichero imagen que contiene el sistema operativo de la máquina virtual.
Sin embargo, si correo dos máquinas, no deseará que una de ellas escriba
en el fichero imagen de la otra y viceversa. Con dominios regulares,
necesitará ofrecer este comportamiento. Con mcs, puede darle
a cada instancia en ejecución una categoría específica (un número) y
únicamente conceder privilegios de escritura al fichero de la máquina
virtual con la categoría (el número) correcta.
mls (utilizando múltiples niveles de seguridad)
El tipo de directriz mls está disponible, pero aún no está soportado
por Gentoo Hardened. Con este tipo de directriz, es posible ofrecer
niveles de sensibilidad a ficheros y recursos así como a dominios. Los
niveles de sensibilidad se pueden expresar mejor en los términos
public, private, confidential o strictly
confidential (público, privado, confidencial o estrictamente
confidencial). Con MLS, puede marcar un fichero con un (o un conjunto)
nivel de sensibilidad y asegurarse de que únicamente los dominios con
el nivel de sensibilidad correcto puede acceder a él.
Conmutando entre tipos
No se recomienda conmutar entre tipos con frecuencia. En el mejor de
los casos, elegimos un tipo de directriz en el momento de instalar y
nos ajustamos a él. No es imposible (ni tampoco muy difícil) cambiar
entre tipos.
Asegúrese de que su variable POLICY_TYPES en
make.conf ya contiene el tipo de directriz destino y
que se han reconstruido los paquetes de la directriz de SELinux.
Si este no es su caso, edite la variable POLICY_TYPES
para incluir la directriz destino y reconstruya todos los paquetes
de directriz SELinux utilizando emerge $(qlist -IC sec-policy).
Ahora cambie sus sistema la modo permisivo (permissive) utilizando
setenforce 0 o, si su sistema no permite el cambio de modo,
edite /etc/selinux/config para que el sistema arranque
en modo permisivo. Si no puede utilizar setenforce 0 entonces
necesitará reiniciar ahora de modo que el sistema funcione en modo
permisivo.
A continuación, edite /etc/selinux/config y cambie
la variable SELINUXTYPE de la directriz actual a la nueva.
Esto le indicará a SELinux que cargue la directriz correcta cuando
se inicie el sistema.
Ahora vaya a los módulos construidos para la directriz en
/usr/share/selinux ya que necesitamos cargar la nueva
directriz (ya que actualmente el sistema está corriendo con la
antigua). El ejemplo de abajo muestra como hacer esto si viene
de un tipo de directriz estricto strict y quiere ir al
tipo mcs:
Listado de Código 2.2: Cargar la directriz mcs |
# cd /usr/share/selinux/mcs
# semodule -b base.pp -i $(ls *.pp | grep -v base.pp | grep -v unconfined.pp)
|
Ahora su sistema está corriendo con la directriz mcs cargada, pero
observará que se producen múltiples denegaciones de acceso a la hora
de realizar cualquier acción en el sistema de ficheros, ya que los
ficheros de su sistema no están etiquetados correctamente: El tipo de
directriz mcs requiere a las etiquetas tener una etiqueta de
sensibilidad sobre ellas, lo cual no es el caso si utiliza la directriz
estricta. Por lo tanto, reetiquetemos completamente el sistema de
ficheros, incluyendo aquéllas localizaciones que podrían estar ocultas
debido a que otros sistemas de ficheros se han montado sobre ellas.
Listado de Código 2.3: Reetiquetar completamente el sistema de ficheros |
# rlpkg -a -r
# mount -o bind / /mnt/gentoo
# setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/dev
# setfiles -r /mnt/gentoo /etc/selinux/strict/contexts/files/file_contexts /mnt/gentoo/lib64
# umount /mnt/gentoo
|
Para terminar, edite /etc/fstab y actualice los parámetros
rootcontext= para incluir también una etiqueta de sensibilidad
(en caso de que cambiara a mcs o mls) o ninguna (en caso de que cambiara
a targeted o strict).
Listado de Código 2.4: Cambiar /etc/fstab |
tmpfs /tmp tmpfs defaults,noexec,nosuid,rootcontext=system_u:object_r:tmp_t:s0 0 0
|
Una vez realizadas todas estas acciones, reinicie su sistema para
asegurarse de que funciona correctamente (también la secuencia de
arranque).
5. Modificar la directriz de SELinux en Gentoo Hardened
5.a. Lenguaje de la directriz SELinux
Introduction
Por defecto, Gentoo ofrece una directriz genérica aunque altamente
controlada que es considerada como una buena directriz de comienzo
para todos los usuarios. Sin embargo, el propósito detrás de los
sistemas de Control de Acceso Obligatorio es que el administrador
de seguridad tome el control. Por lo tanto, un manual sobre SELinux
sin información acerca de como escribir directrices no estaría
completo.
En este capítulo, hablaremos un poco sobre el lenguaje que hay
detrás de las directrices SELinux y daremos algunos consejos sobre
cómo crear sus propias directrices, roles, etc.
Construyendo un módulo SELinux
En primer lugar, antes de que descubramos el arte sobre la escritura
de directrices SELinux, crearemos un pequeño módulo SELinux con una
regla que podamos probar, construiremos el módulo y veremos si las
cosas funcionan. A pesar de que estos pasos son muy fáciles de
realizar, son muy importantes. Modificar la directriz SELInux tal y
como la ofrece Gentoo se lleva a cabo de mejor forma a través de las
directrices de módulo adicionales. Solo cuando la directriz principal
(la directriz base) no es de su agrado, deberá plantearse el uso
de una directriz completamente distinta.
Comencemos con un esqueleto para un módulo de directriz que llamaremos
testmod. Utilice nombres simples para los módulos ya que la
infraestructura de construcción es muy sensible a nombres especiales.
Utilice únicamente letras de la a a la z y números, y nunca comience
el nombre de un módulo con un número.
Listado de Código 1.1: Esqueleto de módulo de directriz |
policy_module(testmod, 1.0.0)
|
Sí, eso es todo. Pero, como puede observar, está prácticamente vacío.
Añadamos una regla que permita a un usuario normal (en el dominio
user_t) leer ficheros ebuild (de tipo portage_ebuild_t).
Listado de Código 1.2: Módulo de directriz testmod |
policy_module(testmod, 1.0.0)
require {
type user_t;
type portage_ebuild_t;
class file { read open getattr };
class dir { read search open getattr };
}
allow user_t portage_ebuild_t:file { read open getattr };
allow user_t portage_ebuild_t:dir { read search open getattr };
|
Como puede ver, algo tan simple como permitir a un usuario leer
ficheros requiere unos cuantos privilegios. Los privilegios de
directorio son necesarios para permitir a un usuario navegar
por la estructura de árbol de Portage, mientras que los privilegios
de fichero son necesarios para que el usuario puede acceder y abrir
los ebuilds. Guarde este fichero con el nombre testmod.te.
Para construir la directriz y convertirla en un módulo binario que
se pueda cargar en el almacén de directriz SELinux, podemos utilizar
el fichero Makefile disponible en
/usr/share/selinux/strict/include (sustituya strict por
el tipo de directriz SELinux que esté utilizando).
Listado de Código 2.6: Construir un módulo de directriz binario |
$ make -f /usr/share/selinux/strict/include/Makefile testmod.pp
|
El nombre de fichero (testmod.pp) es el nombre para
el fichero binario SELinux destino. El Makefile
buscará automáticamente el fichero testmod.te que tiene
en su directorio de trabajo.
Deberá obtener como resultado un fichero llamado
testmod.pp. Este fichero de módulo se puede ahora
cargar en el almacén de directriz SELinux de la siguiente forma:
Listado de Código 1.4: Cargar un módulo binario |
# semodule -i /path/to/testmod.pp
|
¡Enhorabuena! Acaba de construir su primer módulo de directriz SELinux.
Si quiere deshabilitarlo, elimínelo usando semodule -r testmod.
Este método de construcción de una directriz (utilizando el
Makefile y semodule) es algo que necesitará hacer
cada vez que actualice la directriz SELinux en su sistema. El contenido
de la directriz, sin embargo, cambia como veremos en el resto de este
documento.
Obtener las interfaces de directriz SELinux
Para hacer más rápido el desarrollo de directrices, la directriz
SELinux basada en la directriz de referencia utiliza interfaces
para acceder a los privilegios dentro de un módulo. Si ha
construido selinux-base-policy con USE="doc"
entonces esta información está disponible en
/usr/share/doc/selinux-base-policy-<versión>/html.
Se recomienda tener esta información a mano ya que la mayoría
de los desarrollos o actualizaciones se realizarán utilizando las
interfaces que ofrece la directriz.
Si está interesado, puede también encontrar estas definiciones de
interfaz en línea.
Recuerde que este recurso en línea es únicamente la directriz
de referencia y puede variar un poco de la disponible en Gentoo.
Usar interfaces de directriz
El uso de interfaces de directriz le permite actualizar la directriz
con funciones más legibles. Por ejemplo, para permitir al dominio
user_t domain llamar y utilizar aplicaciones Portage, el módulo
podría tener el siguiente aspecto:
Listado de Código 1.5: Directriz ejemplo para permitir a user_t utilizar portage |
policy_module(testmod, 1.0.0)
require {
type user_t;
role user_r;
}
portage_run(user_t, user_r)
|
Desde luego, esto hace que el dominio user_t tenga más privilegios que
las reglas definidas anteriormente para leer fichero ebuild: permite
al usuario llamar a portage, actualizar el sistema, etc. Desde luego,
el usuario todavía necesita los permisos comunes de Linux apropiados
(por lo que necesita pertenecer al grupo portage o poder convertirse
en root). Por supuesto, no recomendamos conceder esto a un usuario
regular ;-)
5.b. Módulos completos de directriz SELinux
Comprobando un módulo aislado
Teniendo en cuenta lo de arriba, podemos avanzar un poco más e
investigar un módulo de directriz completo, con las reglas de
forzado de tipos (fichero .te), los ficheros de
contextos (.fc) e interfaces (.if).
Debería saber que escribir un módulo requiere familiarizarse con la
aplicación. Es cuestión de simplemente esperar lo mejor: como
administrador de seguridad, será el responsable de definir qué accesos
se permiten y cuáles no. Si olvida alguno, la aplicación se podría
romper en las manos de los usuarios. Pero, si añade demasiados, podría
estar concediendo privilegios de los cuales se podría abusar en
adelante. También sería más complicado hacer un seguimiento y eliminar
privilegios más adelante ya que se dudaría de si ese privilegio es
necesario o no.
En esta sección, no discutiremos como crear uno. Tenemos un excelente
recurso: Desarrollo
SELinux en Gentoo Hardened que le guía en ese proceso. Sin embargo,
echaremos un vistazo a ese módulo completo para explicar otros
aspectos del desarrollo de directrices.
Fichero de forzado de tipos
El fichero .te que escribimos anteriormente es un
fichero de forzado de tipos. Se utiliza para definir reglas de
acceso al módulo que se está construyendo, pero también, y
más importante, define nuevos tipos (e incluso roles).
El ejemplo de abajo es un extracto de un módulo para la aplicación skype.
Listado de Código 2.1: Extracto de skype.te |
policy_module(skype, 1.0.0)
type skype_t;
type skype_exec_t;
application_domain(skype_t, skype_exec_t)
type skype_home_t;
userdom_user_home_content(skype_home_t)
manage_dirs_pattern(skype_t, skype_home_t, skype_home_t)
manage_files_pattern(skype_t, skype_home_t, skype_home_t)
|
En el ejemplo de arriba, se declaran tres nuevo tipos: skype_t
(que se usará para la aplicación), skype_exec_t (que es la
etiqueta que se asigna al binario de la aplicación) y
skype_home_t (que se utilizará para la ubicación del fichero de
usuario ~/.Skype). También, se asignan al dominio
skype_t algunos privilegios con respecto a la etiqueta
skype_home_t (gestionar directorios y ficheros).
Fichero de contexto de ficheros
En el fichero .fc (cuya extensión significa
file context file o fichero de contexto de ficheros), se definen
los recursos del modulo (ficheros, directorios, zócalos, etc.). Una
vez se carga el módulo, estas reglas se añaden de forma que el
reetiquetado del sistema de ficheros asignará los contextos correctos
a cada uno de los ficheros.
El ejemplo de abajo es un extracto del fichero de contexto de ficheros
del módulo skype.
Listado de Código 2.2: Extracto de skype.fc |
HOME_DIR/\.Skype(/.*)? gen_context(system_u:object_r:skype_home_t,s0)
/opt/skype/skype -- gen_context(system_u:object_r:skype_exec_t,s0)
/usr/bin/skype -- gen_context(system_u:object_r:skype_exec_t,s0)
|
El formato del fichero tiene la siguiente sintaxis:
-
La expresión regular que concuerda con el/los fichero/s y directorio/s
afectados por esa línea.
-
Un identificador opcional para diferenciar el tipo de objeto (fichero,
directorio, zócalo o socket, enlace simbólico, etc.)
-
Una línea gen_context que contiene el contexto que se debe
asignar a el/los fichero/s y directorio/s.
Fichero de interfaz
En el fichero .if (que significa interface file o
fichero de interfaz), se declaran las interfaces que pueden usar otros
módulos. Es, mediante el uso de interfaces, la forma en la que una
directriz definida se puede construir de forma adecuada sobre otros
módulos existentes.
Una interfaz podría usarse para permitir a los usuarios llamar y ejecutar
una aplicación. Por ejemplo, podemos encontrar en el módulo skype, la
siguiente interfaz.
Listado de Código 2.3: Extracto de skype.if |
interface(`skype_role',`
gen_require(`
type skype_t, skype_exec_t, skype_tmpfs_t, skype_home_t;
')
role $1 types skype_t;
domtrans_pattern($2, skype_exec_t, skype_t)
allow $2 skype_t:process { ptrace signal_perms };
manage_dirs_pattern($2, skype_home_t, skype_home_t)
manage_files_pattern($2, skype_home_t, skype_home_t)
manage_lnk_files_pattern($2, skype_home_t, skype_home_t)
relabel_dirs_pattern($2, skype_home_t, skype_home_t)
relabel_files_pattern($2, skype_home_t, skype_home_t)
relabel_lnk_files_pattern($2, skype_home_t, skype_home_t)
ps_process_pattern($2, skype_t)
')
|
A través de este skype_role, podemos permitir a los usuarios que
llamen a skype, tal y como se indica en el fichero
unprivuser.te (el cual define el dominio user_t):
Listado de Código 2.4: Extracto de unprivuser.te para llamar a skype |
optional_policy(`
skype_role(user_r, user_t)
')
|
La siguiente tabla muestra algunas interfaces comunes que se podrían
utilizar. Recomendamos echar un vistazo a las interfaces disponibles
cuando cree o mejore sus propios módulos. Asegúrese de elegir la
interfaz que añade exactamente lo que necesita y nada más.
| Plantillas |
| Sufijo |
Ejemplo |
Descripción |
| _template |
virt_domain_template(prefijo) |
No se trata realmente de una interfaz, las plantillas crean dominios
adicionales basados en la información que se les facilita. Esto se
realiza normalmente en plantillas de directriz ajustadas finamente con
un (sub)conjunto de privilegios.
|
| Transformaciones |
| Sufijo |
Ejemplo |
Descripción |
|
miscfiles_cert_type(recurso) |
Las interfaces de transformación, generalmente añaden atributos
específicos a recursos o dominios. Los atributos "transforman" el
recurso dado en algo más. En el ejemplo dado,
miscfiles_cert_type(recurso), asigna el atributo cert_type al
recurso (y también lo marca como un fichero). Las interfaces como
miscfiles_read_all_certs trabajan con estos atributos.
|
| Interfaces de acceso |
| Sufijo |
Ejemplo |
Descripción |
| _<access>_<recurso> |
mta_getattr_spool(dominio) |
Concede acceso al dominio especificado al recurso mostrado. El
recurso normalmente define también el tipo (como
kudzu_getattr_exec_files: concede getattr sobre los ficheros
kudzu_exec_t) a menos que sea obvio a partir del nombre, o cuando
el recurso es un término más específico que el dominio. Puede incluir
también dontaudit (como mta_dontaudit_getattr_spool).
|
| _exec |
dmesg_exec(dominio) |
Concede a un dominio el derecho de ejecutar el fichero ejecutable del
dominio dado (en el ejemplo, permite a "dominio" ejecutar
dmesg_exec_t files), pero sin implicar una transición del dominio.
En otras palabras, dmesg se ejecuta pero está confinado por los
privilegios del dominio fuente.
|
| _domtrans |
dmesg_domtrans(dominio) |
Concede a un dominio privilegios de ejecución y de realizar
transiciones hacia el nuevo dominio. Esta interfaz es comúnmente
utilizada para permitir a los dominios de aplicación realizar
transiciones a otros dominios. En el ejemplo dado, dmesg se ejecuta
con los privilegios del dominio dmesg_t.
|
| _run |
netutils_run(dominio, rol) |
Concede a un rol y dominio dados los derechos para ejecutar y
realizar transiciones hacia el dominio dado. Esto se concede
normalmente a roles y dominios de usuario (ya existentes) y les
da un conjunto de privilegios necesarios para interactuar de forma
segura con el nuevo dominio (interactivo), tal como el acceso a un
terminal.
|
| _role |
xserver_role(rol, dominio) |
Permite al rol y dominio dado los permisos necesarios para
realizar transiciones e interactuar con el dominio dado.
Esta interfaz se ha mejorado con los privilegios para interactuar
de forma más amplia con el dominio (y sus ficheros correspondientes),
y normalmente se asigna a los nuevos usuarios y roles creados en la
directriz (en lugar de mejorar los dominios y roles de usuario ya
existentes).
|
| _admin |
aide_admin(dominio) |
Concede al dominio dado los derechos para administrar el entorno
del dominio objetivo. Esto normalmente involucra privilegios para
gestionar y reetiquetar todos los ficheros, directorios, zócalos
(sockets), etc. asociados.
|
5.c. Utilizar audit2allow
Introducción
Cuando lea los recursos disponibles en línea sobre SELinux, observará
que hay muchas referencias a una herramienta llamada audit2allow.
El propósito de esta herramienta es leer los mensajes de denegación AVC
del registro de auditoría y transformarlos en un módulo de directriz
que se pueda cargar. La ventaja aquí es que hace bastante más fácil
la escritura de directrices. La parte mala es que la salida (a menos
que utilice la opción -R) no se puede utilizar en el fichero
Makefile que utilizamos anteriormente para construir
módulos.
Otra desventaja es que la herramienta no actúa inteligentemente ante los
cambios. Acepta las denegaciones a ciegas y las trata como si debieran
ser permitidas en lugar de investigar si se deberían asignar otros
contextos al fichero, etc.
Usar audit2allow
El uso de audit2allow es bastante simple. Se le envían las
denegaciones que quiere corregir y se almacena el resultado en un
fichero .te. Puede entonces convertir este fichero a
un formato intermedio que se puede traducir a un fichero
.pp para cargarlo finalmente con semodule.
Por ejemplo, para capturar todas las denegaciones y transformarlas en
sentencias válidas para las denegaciones relacionadas con firefox:
Listado de Código 3.1: Generar una nueva directriz utilizando audit2allow |
# grep firefox /var/log/avc.log | audit2allow -m firefoxmod > firefoxmod.te
# checkmodule -m -o firefoxmod.mod firefoxmod.te
# semodule_package -o firefoxmod.pp -m firefoxmod.mod
# semodule -i firefoxmod.pp
|
El nombre del módulo (indicado mediante la opción -m) debe ser
sencillo: únicamente utilice caracteres ([a-z]) y números
([0-9]), y comience el nombre del módulo con un carácter.
5.d. Crear roles adicionales
Crear el rol y el dominio
Si desea crear roles adicionales en el sistema, en primer lugar
necesitará crear un módulo SELinux que cree ese rol, a la vez que su
dominio principal. Abajo se muestra un ejemplo muy sencillo para un
rol de administración de base de datos, el cual ofrecemos a
través del paquete sec-policy/selinux-dbadm:
Listado de Código 4.1: Ejemplo de definición de dbadm_r y dbadm_t |
policy_module(dbadm, 1.0.0)
#######################################
#
# Declaraciones
#
role dbadm_r;
# Crear un dominio de usuario (dbadm_t)
userdom_base_user_template(dbadm)
#######################################
#
# Directriz local dbadm
#
allow dbadm_t self:capability { dac_override dac_read_search sys_ptrace };
files_dontaudit_search_all_dirs(dbadm_t)
files_delete_generic_locks(dbadm_t)
files_list_var(dbadm_t)
selinux_get_enforce_mode(dbadm_t)
logging_send_syslog_msg(dbadm_t)
userdom_dontaudit_search_user_home_dirs(dbadm_t)
optional_policy(`
# Conceder al usuario privilegios de administración de PostgreSQL
# (sobre todos los procesos)
postgresql_admin(dbadm_t, dbadm_r)
')
|
Construya y cargue el módulo y verifique que el rol está disponible:
Listado de Código 4.2: Construya y verifique |
# make -f /usr/share/selinux/strict/include/Makefile dbadm.pp
# semodule -i dbadm.pp
# seinfo -r | grep dbadm
dbadm_r
|
Asignar el rol a los usuarios
A continuación, asigne a los usuarios el rol que acaba de crear. Puede
hacerlo con usuarios SELinux ya existentes, pero, en este caso,
crearemos un usuario SELinux adicional para el rol.
Listado de Código 4.3: Conceder el rol al usuario |
# semanage user -a -R "staff_r dbadm_r system_r" dbadm_u
|
Lo siguiente es mapear el usuario(s) a este usuario SELinux.
Listado de Código 4.4: Mapear un conjunto de usuarios al usuario dbadm_u |
# semanage login -a -s dbadm_u david
# semanage login -a -s dbadm_u laura
|
También se debe cargar la siguiente directriz para dar soporte a
la transición hacia el rol dbadm_r para el rol staff_r:
Listado de Código 4.5: Permitir la transición a dbadm_r |
dbadm_role_change(staff_r)
|
En la primera orden semanage, en la que creamos el usuario dbadm_u,
puede observarse que le hemos concedido el rol system_r. Esto se
debe a que al usuario se le concede el rol postgresql_admin,
permitiendo a ese usuario la manipulación del guión de inicio de
postgresql:
Listado de Código 4.6: Usario reiniciando el servicio postgresql |
$ ls -Z /etc/init.d/postgresql
system_u:object_r:postgresql_initrc_exec_t /etc/init.d/postgresql
$ sudo -r dbadm_r -t dbadm_t /etc/init.d/postgresql restart
|
Gracias al soporte SELinux en sudo, puede también mencionar
el rol y tipo en el fichero sudoers:
Listado de Código 4.7: Usar el fichero sudoers para roles específicos |
david ALL=(ALL) ROLE="dbadm_r" TYPE="dbadm_t" NOPASSWD: /etc/init.d/postgresql [a-z]*
|
Con este ajuste, el usuario puede ejecutar simplemente
sudo /etc/init.d/postgresql restart.
Utilizando sudo de forma correcta, se puede conceder al usuario
derechos completos de administración sobre un demonio (incluyendo la
edición de ficheros), con bastante menor riesgo de que el usuario pueda
escalar sus privilegios a un rol administrativo con más privilegios sobre
el sistema.
La idea detrás de este enfoque es que el usuario permanezca en su dominio
principal (como staff_t) pero que se le permita realizar acciones
administrativas a través de sudo lo que le permite (de forma
temporal) realizar la transición al rol dbadm_r.
role.
6. Solucionando problemas con SELinux
6.a. No se puede cargar la directriz de SELinux
Descripción del problema
Si observa que SELinux no está funcionando, puede ejecutar
sestatus para ser informado rápidamente si SELinux está
habilitado y cargado o no. Si obtiene la siguiente salida, entonces
ninguna directriz de SELinux se ha cargado:
Listado de Código 1.1: Salida de sestatus |
SELinux status: disabled
|
Si éste es el caso, continúe leyendo esta sección para averiguar cómo
corregir esta situación.
No hay ninguna directriz instalada
Una raíz potencial de este problema es que no hay ninguna directriz con
la que comenzar. Eche un vistazo a /usr/share/selinux/strict
o a /usr/share/selinux/targeted (dependiendo de su
configuración) y busque un fichero llamado base.pp. Si no
existe este fichero, necesitará instalar la directriz base. Esta
directriz se ofrece con el paquete
sec-policy/selinux-base-policy, pero es mejor leer el
capítulo relacionado con la Instalación de
Gentoo SELinux / Conversión ya que podría pasar por alto detalles
importantes.
La directriz no se ha cargado
Si existe el fichero base.pp en
/usr/share/selinux/strict (o en targeted/),
eche un vistazo a /etc/selinux/strict/policy. Esta
localización también debería contener un módulo de directriz
base.pp (cuando se carga una directriz de SELinux, se
copia desde la primera localización a la segunda).
Si no existe el fichero base.pp, instale la directriz y
cárguela:
Listado de Código 1.2: Instalar la directriz base |
~# semodule -n -B
|
Esto es una operación que se realiza solo en una ocasión. Una vez
instalada y cargada, ésta será recargada en cada reinicio.
Init no puede cargar la directriz SELinux
Durante el inicio del sistema, el proceso init es el responsable
de cargar e interactuar con la directriz SELinux en memoria. Si
init no soporta SELinux, su entorno no dispondrá de soporte
para SELinux.
Para verificar si init soporta SELinux, necesitamos comprobar si
utiliza el objeto compartido libselinux.so:
Listado de Código 1.3: Comprobar si init soporta SELinux |
~# ldd /sbin/init
linux-vdso.so.1 => (0x00006ace30e84000)
libselinux.so.1 => /lib/libselinux.so.1 (0x00006ace30a46000)
libc.so.6 => /lib/libc.so.6 (0x00006ace306e9000)
libdl.so.2 => /lib/libdl.so.2 (0x00006ace304e5000)
/lib64/ld-linux-x86-64.so.2 (0x00006ace30c68000)
|
Si éste no es el caso, asegúrese de que emerge --info muestra que
el ajuste USE selinux está en su sitio y reinstale
sys-apps/sysvinit. Si este ajuste no está definido,
compruebe su perfil Gentoo y asegúrese de que apunta a un perfil
selinux/v2refpolicy/....
El almacén de directices está corrupto
Si aparecen problemas en el inicio del sistema o en operaciones
semodule que fallan con problemas en la carga pero no se
puede resolver con la solucón de arriba, entonces necesitará reinstalar
las directrices una vez eliminado el almacén corrupto.
Listado de Código 1.4: Recuperarse de un almacén corrupto |
~# semodule -n -B
libsemanage.semanage_load_module: Error while reading from module file
/etc/selinux/targeted/modules/tmp/base.pp. (No such file or directory)
~# setenforce 0
~# mv /etc/selinux/targeted /etc/selinux/targeted.old
~# FEATURES="-selinux" emerge -1av $(qlist -IC sec-policy)
~# restorecon -R /etc/selinux
|
Esto desactivará efectivamente el almacén corrupto actual de la directriz
de SELinux y utilizará Portage para reinstalar todos los paquetes de
directriz que se han instalado en el sistema. Cuando haya terminado, los
contextos de fichero de /etc/selinux serán restaurados,
después de lo cual podrá continuar.
6.b. No se puede ingresar en el sistema
Descripción del problema
Si no puede ingresar en el sistema en una situación en particular
(en remoto, en local, como root, como usuario regular,...) puede que
se esté encontrando con algún problema sin mucha importancia. Sin
embargo, para resolverlo tendrá que ingresar en el sistema como
sysadm_r de un modo u otro.
Si no puede ingresar como un usuario sysadm_r, deshabilite
SELinux (arranque con enforcing=0) de este modo no se realiza
ningún forzado SELinux. Los cambios que haga en modo permisivo son
igual de efectivos que en el modo forzado (enforcing).
Contexto incorrecto
En la mayoría de los casos encontrará que el problema es un contexto de
seguridad incorrecto. Ejecute sestatus -v y compare los
contextos de proceso o los contextos de fichero que
observe con los dados en la siguiente tabla.
| Proceso |
Contexto |
Si el contexto no es el adecuado... |
| Contexto init |
system_u:system_r:init_t |
En primer lugar, verifique que el propio init está correctamente
etiquetado. Compruebe la salida de la ejecución anterior de
la orden sestatus -v para el fichero
/sbin/init y asegúrese de que está ajustado a
system_u:object_r:init_exec_t. Si este no es el caso, etiquete de
nuevo sys-apps/sysvinit usando rlpkg sysvinit.
Haga las mismas comprobaciones que se realizan en la sección
No se puede cargar la directriz de SELinux
. Reinicie su sistema e inténtelo de nuevo.
|
| Contexto agetty |
system_u:system_r:getty_t |
Asegúrese de que el binario /sbin/agetty esta etiquetado
como system_u:object_r:getty_exec_t. Si no es así, etiquete de nuevo
el paquete sys-apps/util-linux usando
rlpkg util-linux. A continuación reinicie todos los procesos
agetty usando pkill agetty (estos procesos se pondrán en
marcha de nuevo automáticamente).
|
| Fichero |
Contexto |
Si el contexto no es el adecuado... |
| /bin/login |
system_u:object_r:login_exec_t |
El binario login forma parte de sys-apps/shadow.
Ejecute rlpkg shadow para etiquetar de nuevo los ficheros de
este paquete y reintente el ingreso en el sistema.
|
| /sbin/unix_chkpwd |
system_u:object_r:chkpwd_exec_t |
Este binario es parte del paquete sys-libs/pam y SSH lo
utiliza cuando se configura para que use PAM a la hora de realizar
la autenticación de usuarios. Etiquete de nuevo el paquete usando
rlpkg pam e intente de nuevo el ingreso en el sistema.
|
| /etc/passwd |
system_u:object_r:etc_t |
Tanto /etc/passwd como /etc/shadow deben
estar etiquetados correctamente, de lo contrario PAM no podrá
autenticar a ningún usuario. Etiquete de nuevo los ficheros con
restorecon /etc/passwd /etc/shadow e intente de nuevo el
ingreso en el sistema.
|
| /etc/shadow |
system_u:object_r:shadow_t |
| /bin/bash |
system_u:object_r:shell_exec_t |
El intérprete de comandos del usuario (en este caso, bash)
se debe etiquetar correctamente de modo que el usuario pueda cambiar
al dominio de usuario cuando ingrese en el sistema. Para hacer esto,
etiquete de nuevo el paquete app-shells/bash usando
rlpkg bash. Entonces puede intentar de nuevo el ingreso en el
sistema.
|
6.c. No se puede hacer emerge de ningún paquete (OSError: [Errno 22] Invalid argument)
Descripción del problema
Cuando se intenta instalar software con Portage, se obtiene un volcado
enorme de la pila de python y finalmente el mensaje de error
OSError: [Errno 22] Invalid argument:
Listado de Código 3.1: Volcado de la traza de la pila cuando falla portage al instalar software |
Traceback (most recent call last):
File "/usr/bin/emerge", line 43, in <module>
retval = emerge_main()
File "/usr/lib64/portage/pym/_emerge/main.py", line 1906, in emerge_main
myopts, myaction, myfiles, spinner)
File "/usr/lib64/portage/pym/_emerge/actions.py", line 437, in action_build
retval = mergetask.merge()
...
File "/usr/lib64/portage/pym/portage/package/ebuild/doebuild.py", line 104, in _doebuild_spawn
return spawn(cmd, settings, **kwargs)
File "/usr/lib64/portage/pym/portage/package/ebuild/doebuild.py", line 1255, in spawn
return spawn_func(mystring, env=mysettings.environ(), **keywords)
File "/usr/lib64/portage/pym/portage/_selinux.py", line 105, in wrapper_func
setexec(con)
File "/usr/lib64/portage/pym/portage/_selinux.py", line 79, in setexec
if selinux.setexeccon(ctx) < 0:
OSError: [Errno 22] Invalid argument
|
Contexto erróneo
El error de arriba se produce cuando se lanza portage (mediante
emerge) y no nos encontramos en el contexto sysadm_t.
Puede verificar esto con id -Z:
Listado de Código 3.2: Comprobando el contexto actual |
~# id -Z
system_u:system_r:local_login_t
|
Portage fallarán mientras el contexto utilizado no sea sysadm_t.
Esto es debido a que Portage quiere cambiar su contexto de ejecución de
portage_t a portage_sandbox_t, sin embargo no puede
conseguirlo (para empezar, no está en portage_t debido a que
el usuario que lanzó Portage no está en sysadm_t).
Por favor, compruebe la sección No se puede
ingresar en el sistema de arriba en primer lugar. También,
asegúrese de que puede hacer dispatch-conf o etc-update
después de instalar SELinux de modo que se actualice
/etc/pam.d/system-login con las llamadas correctas a
pam_selinux.so.
Forzar la instalacilón
Si necesita forzar a Portage para que continúe a pesar de todo
(por ejemplo, se encontraba en medio de una instalación de SELinux por
lo que no puede resolver esas cuestiones ahora), ejecute la orden
emerge pero con FEATURES="-selinux". Esto deshabilitará
efectivamente la integración de SELinux en Portage y permitirá continuar
con la instalación del software.
Listado de Código 3.3: Correr emerge sin soporte selinux |
~# FEATURES="-selinux" emerge -u world
|
¡Asegúrese de que etiqueta de nuevo todo el sistema de ficheros después
de aplicar este enfoque!. Portage no etiquetará correctamente los ficheros
instalados en el sistema si deshabilita el soporte SELinux. Para etiquetar
de nuevo todo el sistema de ficheros, utilice rlpkg -a -r.
7. Historial de cambios
7.a. Introducción
Acerca de este documento
Este documento ofrece una vista rápida de todos los cambios en SELinux
documentados y que se han realizado en fechas particulares y que por
tanto pueden ser de importancia para los usuarios hagan un seguimiento
de los mismos.
Los cambios que únicamente afectan a los usuarios con instalaciones
de prueba (~arch) se documentarán abajo y se moverán más arriba en el
documento cuando se realice su estabilización. Sin embargo, es posible
que estos cambios se "corrijan" de forma automática y por tanto se
eliminen de esta página.
7.b. Vista rápida de los cambios para usuarios de instalaciones estables
16/04/2013 - Presentar el guión de inicio selinux_gentoo
Con el paquete policycoreutils-2.1.13-r8 y los posteriores, ofrecemos
nuestro propio guión de inicio selinux_gentoo, el cual
incluye el soporte necesario para los usuarios con initramfs en sus
sistemas, también reinicia los contextos de los recursos generados
dinámicamente (en pseudo sistemas de ficheros) que son distintos
de los ajustes por defecto.
El primer usuario a tener en cuenta es
/sys/devices/system/cpu/online el cual obtiene
labeled cpu_online_t (desde la revisión 13 de la directriz SELinux,
o cuando se están utilizando ebuilds live para la directriz).
El guión de inicio también restaurará por defecto los contextos
de todos los dispositivos /dev (a menos que el
sistema se inicie con la opción norestorecon) y
cambiará al modo forzado (enforcing) si
/etc/selinux/config tiene definido
SELINUX=enforcing y el usuario inició el sistema
con enforcing=0 (a menos que inicie con la opción
nosetenforce).
Esto significa que ahora se recomienda a los usuarios que
añadan este guión al nivel de ejecución boot:
Listado de Código 2.6: Añadir selinux_gentoo al nivel de ejecución |
# rc-update add selinux_gentoo boot
|
04/12/2012 - Presentar USE=unconfined
A partir de la versión selinux-base-2.20120725-r9, se da
soporte al ajuste USE=unconfined. Cuando éste se habilita,
configurará su directriz SELinux para dar soporte a dominios no
confinados. Si su directriz es targeted, este comportamiento
estará implícito, mientras que la directriz strict no
considerará este ajuste USE de ningún modo (no activará dominios
no confinados en strict).
El soporte de este ajuste USE, nos permite diferenciar entre
dominios no confinados y dominios regulares cuando utilizamos
los tipos de directriz mls o mcs. Cuando está
definido, se construirá también el paquete
selinux-unconfined, y el módulo se cargará, e
igualmente, se actualizará el fichero de directriz
seusers (el cual contiene los mapeas de los
dominios por defecto para los usuarios) para utilizar el
usuario SELinux unconfined_u para root y otros
usuarios.
16/08/2012 - Añadir el rol system_r a los administradores
Desde la versión selinux-base-2.20120725-r3 y en las
posteriores, los guiones de inicio ahora ofrecen soporte al enfoque
"etiquetado" (labeled) del guión de inicio ofrecido por el equipo
de desarrollo principal. Esto implica que los servicios cuyo guión de
inicio siguen la convención de nombres
<domain>_initrc_exec_t se pueden asignar ahora
a usuarios específicos (permitiendo a éstos gestionar servicios
sin necesidad de concederles privilegios de administración del sistema).
Lo malo de este enfoque es que el propio administrador del sistema
(que utiliza el dominio sysadm_t) ahora necesita que se le
conceda el privilegio de gestionar esos servicios. Y el hecho de
concederle este privilegio implica que el usuario SELinux (sea
root o staff_u) necesita que se le conceda el rol
system_r:
Listado de Código 2.2: Conceder el rol system_r |
# semanage user -a -R "staff_r sysadm_r system_r" root
# semanage user -a -R "staff_r sysadm_r system_r" staff_u
|
24/06/2012 - Definición de /run en fstab
Se necesita montar la localización /run con el contexto
var_run_t. Para hacer esto, se debe modificar
/etc/fstab según las instrucciones dadas en
Ajustar los contextos del
sistema de ficheros.
26/05/2012 - Soporte de initramfs
Los usuarios que inician su sistema con un initramfs necesitarán iniciar
en primer lugar en modo permisivo, y a continuación cambiar a modo forzado.
Esto se puede realizar de forma automática utilizando un guión de inicio,
tal y como se documenta en
Usuarios de Initramfs.
26/05/2012 - Soporte para gestores gráficos de ingreso en el sistema
Los usuarios que inicien en un entorno gráfico (como GDM) tendrán que
editar sus ficheros de configuración PAM de forma adecuada para dar
soporte a las definiciones de contexto de seguridad de SELinux. Esto
está documentado en
Usuarios de entornos gráficos.
18/05/2012 - Ya no es necesario configurar sandbox
La edición previa de la documentación de /etc/sandbox.conf
para permitir la escritura abierta de
/sys/fs/selinux/context se puede eliminar ya que el perfil
de SELinux lo hace ahora de forma automática.
29/04/2012 - No es necesario editar los guiones lvm-start/stop
Cuando el usuario instala las nuevas directrices estables 2.20120215,
la edición documentada de /lib/rcscripts/addons/lvm-st*.sh
ya no es necesaria.
21/02/2012 - La línea de montaje /dev en fstab ya no es necesaria
La documentación previa de la línea de montaje /dev mount in
/etc/fstab ya no es necesaria ya que
util-linux-2.20.1-r1 se ha marcado como estable (la cual
ya contiene la corrección correcta).
10/12/2011 - Depreciación de los perfiles selinux/v2refpolicy/*
Los antiguos perfiles de SELinux (los que comienzan por
selinux/v2refpolicy) ya no tienen soporte. Se recomienda
encarecidamente a los usuarios que cambien a los nuevos perfiles (los que
terminan en /selinux).
22/07/2011 - Introducción del soporte para MLS/MCS
Actualmente ofrecemos soporte para MLS y MCS, para los tipos de
directriz SELinux targeted y strict SELinux. Cuando utilice
MLS o MCS, necesitará actualizar la entrada /tmp
en su /etc/fstab para que utilice
rootcontext=system_u:object_r:tmp_t:s0 (observe el :s0
al final).
7.c. Vista rápida para los usuarios de instalaciones de prueba (~Arch)
19/04/2013 - Presentar la orden selocal
Con la aparición de policycoreutils-2.1.13-r11 y versiones posteriores,
se dispone de una nueva orden llamada selocal. Esta orden
permite a los usuarios añadir fácilmente a la directriz local,
reglas de directriz SELinux adicionales sin tener que realizar
la tarea de mantener y construir sus propios ficheros
.te. En lugar de eso, esta orden hace todo el trabajo.
Las reglas que se añaden a la directriz local (de ahí su nombre,
selocal) se pueden acompañar de un pequeño comentario
para que los usuarios describan porqué realizan determinado cambio
(o para hacer referencia a un identificador de incidencia en
el bugzilla de Gentoo).
Listado de Código 3.1: Añadir una regal a la directriz local |
# selocal -a "rpcbind_stream_connect(sysadm_t)" -c "Permitir las llamadas a a exportfs (NFS)"
# selocal --build --load
|
Con --list se muestran las reglas que se han añadido a
la directriz local, y con --delete se pueden eliminar
de la directriz local. Cuando quiera que los cambios tengan
efecto, ejecute selocal --build --load para construir
la nueva directriz local y cargarla en memoria.
El contenido de este documento, a no ser que se especifique
expresamente, está registrado bajo los términos de la licencia
CC-BY-SA-2.5. Se aplican las
Pautas de
Utilización del logotipo y nombre de Gentoo.
|