Guía Grsecurity v2 de Gentoo
1.
Acerca de Grsecurity
El Proyecto Grsecurity
El proyecto grsecurity, alojado en http://www.grsecurity.org, ofrece
varios parches al núcleo de Linux que mejoran la seguridad global de su
sistema. En el siguiente capítulo se discuten las variadas características
provistas por grsecurity, una lista completa de estas se encuentra en la
página de características
de grsecurity.
Como la características de grsecurity están basadas principalmente en el núcleo,
la mayor parte de este documento explica las diversas características del núcleo
y sus respectivos operandos "sysctl" (si es aplicable).
Integración a Gentoo Hardened
El Proyecto Gentoo Hardened
mantiene las características de mejoras de seguridad para Gentoo, incluyendo
pero no limitándose a grsecurity.
Configuración del Núcleo
A lo largo de este documento hablaremos sobre la configuración del núcleo usando
las variables de este, por ejemplo: CONFIG_GRKERNSEC_PAX_NO_ACL_FLAGS.
Estas son las variables que usa el proceso de construcción del núcleo para
determinar si cierta característica necesita ser compilada.
Cuando configure su núcleo mediante make menuconfig o algo similar, puede
observar una interfaz de usuario a través de la cual puede seleccionar las
opciones del núcleo. Si elige el botón de Ayuda (Help) en alguna
característica del núcleo, verá en la parte superior que menciona el nombre de
la variable.
Por lo tanto, puede configurar su núcleo como guste - pensando un poco. Si no
puede encontrar cierta opción, siempre está la posibilidad de editar a mano el
archivo /usr/src/linux/.config
Por supuesto, para seleccionar las variadas opciones del núcleo de
grsecurity debe activarlo en su núcleo:
Listado de Código 1.1: Activando grsecurity |
CONFIG_GRKERNSEC=y
CONFIG_GRKERNSEC_CUSTOM=y
|
2.
PaX
Luchando contra la explotación de bugs en el software
PaX introduce un par de mecanismos de seguridad que hacen más difíciles a los
atacantes explotar bugs de software que involucren corrupción de memoria (pero
note que PaX no protege contra todos los posibles bugs de software). El documento introductorio a
PaX habla sobre tres técnicas posibles de explotación:
- introducir/ejecutar código arbitrario
- ejecutar código existente fuera del orden del programa original
- ejecutar código existente en el orden original del programa con datos
arbitrarios
Un método de prevención no permite que se almacene código ejecutable en la
memoria modificable (writable). Cuando miramos un proceso, este requiere de
cinco regiones de memoria:
-
Una sección de datos que contiene los datos asignados estáticamente y
los datos globales
-
Una región BSS (Block Started by Symbol) que contiene información de
los datos inicializados en cero del proceso
-
Una región de código, también llamada segmento de texto, que
contiene las instrucciones ejecutables
-
El heap que contiene la memoria asignada dinámicamente
-
Una pila que contiene las variables locales
El primer método de prevención de PaX, llamado NOEXEC, tiene como
objetivo dar control sobre la generación de código en tiempo de ejecución. Este
marca como "no ejecutable" a las páginas de memoria que no contienen código
ejecutable. Esto significa que el heap y la pila, que solamente contienen datos
variables y no deberían contener código ejecutable, sean marcadas como "no
ejecutables". Los exploits que coloque código en esas áreas con la intención de
ejecutarlo simplemente fallarán.
NOEXEC hace más que eso en realidad, los lectores interesados deberían enfocar
su atención a la
documentación de NOEXEC de PAX (en inglés).
El segundo método de prevención de PAX, denominado ASLR (Address Space
Layout Randomization, Aleatorización de Distribución del Espacio de
Memoria), aleatoriza las direcciones dadas a peticiones de memoria. ASLR
aleatoriza la asignación donde la memoria era previamente asignada contiguamente
(lo que significa que los exploits saben donde están situadas las regiones de
memoria de las tareas), haciendo inútiles las técnicas que dependen de esta
información.
Se puede encontrar más información sobre ASLR en línea.
Activando PaX
La configuración del núcleo recomendada para PaX es:
Listado de Código 2.1: Configuración del núcleo recomendada para PaX |
CONFIG_GRKERNSEC_PAX_EI_PAX=y
CONFIG_GRKERNSEC_PAX_PT_PAX_FLAGS=y
CONFIG_GRKERNSEC_PAX_NO_ACL_FLAGS=y
CONFIG_GRKERNSEC_PAX_NOEXEC=y
CONFIG_GRKERNSEC_PAX_SEGMEXEC=y
CONFIG_GRKERNSEC_PAX_EMUTRAMP=y
CONFIG_GRKERNSEC_PAX_MPROTECT=y
CONFIG_GRKERNSEC_PAX_ASLR=y
CONFIG_GRKERNSEC_PAX_RANDKSTACK=y
CONFIG_GRKERNSEC_PAX_RANDUSTACK=y
CONFIG_GRKERNSEC_PAX_RANDMMAP=y
CONFIG_GRKERNSEC_PAX_RANDEXEC=y
CONFIG_GRKERNSEC_PROC_MEMMAP=y
CONFIG_GRKERNSEC_HIDESYM=y
|
Si está usando un sistema no x86, observará que no existe
CONFIG_GRKERNSEC_PAX_NOEXEC. Debería en cambio seleccionar
CONFIG_GRKERNSEC_PAX_PAGEEXEC ya que es la única implementación de NOEXEC que
hay por el momento.
Controlando PaX
No todas las aplicaciones de Linux están contentas con las restricciones de
seguridad de PaX. Entre estas están xorg-x11, java, mplayer, xmms y otros. Si
planea usarlas puede alzar las protecciones para esas aplicaciones usando
chpax y paxctl.
Listado de Código 2.2: Instalando las herramientas chpax y paxctl |
# emerge app-admin/chpax
# emerge app-admin/paxctl
|
chpax provee un script de inicio que maneja por Ud. la mayoría de
configuraciones de las aplicaciones más conocidas:
Listado de Código 2.3: Agregando el script de inicio chpax al nivel de ejecución default |
# rc-update add chpax default
|
pax-utils en un pequeño conjunto de utilitarios que contiene aplicaciones
útiles para administrar un servidor que use PaX.
Listado de Código 2.4: Instalando pax-utils |
# emerge pax-utils
|
Entre sus interesantes herramientas están scanelf y pspax:
-
Con scanelf puede revisar los directorios de bibliotecas y binarios y
listar los diferentes permisos y tipos ELF relevantes para correr una
configuración ideal de pax/grsec.
-
Con pspax puede desplegar las banderas/capacidades/xattr PaX desde la
perspectiva del núcleo.
Verificando las configuraciones de PaX
Peter Busser escribió una suite de pruebas de regresión llamada paxtest.
Esta herramienta chequeará diversos casos de posibles vectores de ataque y le
informa del resultado. Cuando la ejecuta, dejará un archivo de bitácora
denominado paxtest.log en el directorio de trabajo actual.
Listado de Código 2.5: Instalando y corriendo paxtest |
# emerge paxtest
# paxtest
Executable anonymous mapping : Killed
Executable bss : Killed
Executable data : Killed
Executable heap : Killed
Executable stack : Killed
Executable anonymous mapping (mprotect) : Killed
Executable bss (mprotect) : Killed
Executable data (mprotect) : Killed
Executable heap (mprotect) : Killed
Executable stack (mprotect) : Killed
Executable shared library bss (mprotect) : Killed
Executable shared library data (mprotect): Killed
Writable text segments : Killed
Anonymous mapping randomisation test : 16 bits (guessed)
Heap randomisation test (ET_EXEC) : 13 bits (guessed)
Heap randomisation test (ET_DYN) : 25 bits (guessed)
Main executable randomisation (ET_EXEC) : 16 bits (guessed)
Main executable randomisation (ET_DYN) : 17 bits (guessed)
Shared library randomisation test : 16 bits (guessed)
Stack randomisation test (SEGMEXEC) : 23 bits (guessed)
Stack randomisation test (PAGEEXEC) : No randomisation
Return to function (strcpy) : Vulnerable
Return to function (memcpy) : Vulnerable
Return to function (strcpy, RANDEXEC) : Killed
Return to function (memcpy, RANDEXEC) : Killed
Executable shared library bss : Killed
Executable shared library data : Killed
|
Del ejemplo mostrado arriba puede observar que:
-
strcpy y memcpy se listan como Vulnerables. Esto es esperable y
normal - simplemente muestra la necesidad de usar una tecnología comoj
ProPolice/SSP.
-
No hay aleatorización para PAGEEXEC. Esto es normal debido a que nuestra
configuración recomendada para el núcleo x86 no activó la opción de
PAGEEXEC. Sin embargo, en las arquitecturas que soporten (casi todas
incluyendo x86_64) realmente el bit NX (no ejecutable), PAGEEXEC es el único
método disponible para NOEXEWC y no afecta el rendimiento.
3.
RBAC
Control de Acceso Basado en Roles (Role Based Access Control)
Existen dos tipos de mecanismos de control de acceso usados para prevenir el
acceso desautorizado a archivos (o información en general): DAC (Control de
Acceso Discrecional) y MAC (Control de Acceso Obligatorio). Linux usa por
defecto un mecanismo DAC: el creador del archivo puede definir quién tiene
acceso a este. Un sistema MAC por su parte fuerza a que todos sigan las reglas
establecidas por el administrador.
La implementación MAC que soporta grsecurity es llamada Control de Acceso Basado
en Roles. RSBAC asocia roles a cada usuario. Cada rol define qué
operaciones pueden ser llevadas a cabo sobre ciertos objetos. Dada una colección
bien escrita de roles y operaciones, sus usuarios estarán restringidos a hacer
solamente aquellas tareas que Ud. le dice que pueden hacer. La restricción
por defecto "deny-all" (negar todo) le asegura que un usuario no pueda realizar
una acción de la cual no haya pensado.
Configurando el Núcleo
La configuración del núcleo recomendada para RBAC es:
Listado de Código 3.1: Configuración del núcleo recomendada para RBAC |
CONFIG_GRKERNSEC_ACL_HIDEKERN=y
CONFIG_GRKERNSEC_ACL_MAXTRIES=3
CONFIG_GRKERNSEC_ACL_TIMEOUT=30
|
Trabajando con gradm
gradm es una herramienta que le permite administrar y mantener un
política para su sistema. Con ella puede activar o desactivar el sistema RBAC,
recargar los roles RBAC, cambiar su rol, configurar un contraseña para el modo
de administración, etcétera.
Cuando instala gradm se dejará la política por defecto en
/etc/grsec/policy:
Listado de Código 3.2: Instalando gradm |
# emerge gradm
|
Por defecto, las políticas RBAC no están activadas. Es tarea del administrador
y no de Gentoo determinar cuándo el sistema debería poner en vigor una política
RBAC. Antes de activar el sistema RBAC debería ajustar una contraseña de
administración.
Listado de Código 3.3: Activando el sistema RBAC |
# gradm -P admin
Setting up grsecurity RBAC password
Password:
Re-enter Password:
Password written in /etc/grsec/pw
# gradm -E
|
Para desactivar el sistema RBAC, ejecute gradm -D. Si no se le permite,
primero necesita cambiarse al rol de administrador:
Listado de Código 3.4: Desactivando el sistema RBAC |
# gradm -a admin
Password:
# gradm -D
|
Si desea salir del rol de administrador, ejecute gradm -u admin:
Listado de Código 3.5: Saliendo del rol de administrador |
# gradm -u admin
|
Generando una Política
El sistema RBAC viene con una excelente característica denominada "modo de
aprendizaje". Dicho modo puede generar una política previsora de mínimos
privilegios para su sistema. Esto permite ahorros de tiempo y dinero para poder
instalar múltiples servidores seguros.
Para usar el modo de aprendizaje, actívelo usando gradm:
Listado de Código 3.6: Activanado el modo de aprendizaje de RBAC |
# gradm -F -L /etc/grsec/learning.log
|
Ahora use sistema, haga las cosas que normalmente haría. Intente evitar hacer
una resincronizacion, ejecutar locate u otra operación de archivos pesada en
términos de E/S ya que esto realmente puede ralentizar el tiempo de
procesamiento.
Cuando crea que ha usado su sistema lo suficiente para obtener una buena
política, deje que gradm la procese y le preponga roles en
/etc/grsec/learning.roles:
Listado de Código 3.7: Procesando las bitácoras del modo de aprendizaje |
# gradm -F -L /etc/grsec/learning.log -O /etc/grsec/learning.roles
|
Audite el archivo /etc/grsec/learning.roles y guárdelo como
/etc/grsec/policy (con permisos 0600) cuando esté listo.
Listado de Código 3.8: Guardando las políticas |
# mv /etc/grsec/learning.roles /etc/grsec/policy
# chmod 0600 /etc/grsec/policy
|
Ahora ya puede activar el sistema RBAC con su nueva e instruida política.
Refinando su Política
Una interesante característica de grsecurity2 es el Soporte de Operación
de Conjuntos en el archivo de configuración.
Actualmente se reconocen uniones, intersecciones y diferencias de conjuntos (de
objetos en este caso).
Listado de Código 3.9: Conjuntos de ejemplo |
define objset1 {
/root/blah rw
/root/blah2 r
/root/blah3 x
}
define somename2 {
/root/test1 rw
/root/blah2 rw
/root/test3 h
}
|
Aquí hay un ejemplo de uso, y los objetos resultantes que serán añadidos a su
sujeto:
Listado de Código 3.10: Ejemplo de intersección |
subject /somebinary o
$objset1 & $somename2
|
Lo de arriba se expandiría a:
Listado de Código 3.11: Ajustes de resultado al sujeto |
subject /somebinary o
/root/blah2 r
|
Este es el resultado del operador de intersección & el cual toma ambos
conjuntos y retorna los archivos que existen en ambos conjuntos y los permisos
para esos archivos que existen en ambos conjuntos.
Listado de Código 3.12: Ejemplo de unión |
subject /somebinary o
$objset1 | $somename2
|
Este ejemplo se expandiría a:
Listado de Código 3.13: Ajustes de resultado al sujeto |
subject /somebinary o
/root/blah rw
/root/blah2 rw
/root/blah3 x
/root/test1 rw
/root/test3 h
|
Este es el resultado del operador de unión "|" el cual toma ambos conjuntos y
entrega los archivos que existen en alguno de los conjuntos. Si un archivo
existe en ambos conjuntos también se retorna y el modo contiene las banderas que
existen en alguno de los conjuntos.
Listado de Código 3.14: Ejemplo de diferencia |
subject /somebinary o
$objset1 - $somename2
|
Este ejemplo se expandiría a:
Listado de Código 3.15: Ajustes de resultado al sujeto |
subject /somebinary o
/root/blah rw
/root/blah2 h
/root/blah3 x
|
Este es el resultado del operador de diferencia "-" que toma dos conjuntos y
retorna los archivos que existen en el conjunto de la izquierda pero no en el
calce del archivo en el conjunto de la derecha. Si un archivo existe en el
conjunto izquierdo y se encuentra un calce en el de la derecha (ya sea que los
nombres de archivos son iguales, o el directorio padre existe en el conjunto de
la derecha) entonces se retorna el archivo y el modo del segundo conjunto se
borra del primero, y ese archivo se retorna.
En algún oscuro pseudo lenguaje podría ver esto como:
Listado de Código 3.16: Explicación en Pseudolenguaje |
si ( ($objset1 contiene /tmp/blah rw) y
($objset2 contiene /tmp/blah r) )
entonces
$objset1 - $objset2 contendría /tmp/blah w
si ( ($objset1 contiene /tmp/blah rw) y
($objset2 contiene/ rwx) )
entonces
$objset1 - $objset2 contendría /tmp/blah h
|
El orden de prioridad (de mayor a menor) es: "-, & |".
Si no quiere preocuparse de recordar la precedencia, también se incluye
reconocimiento de paréntesis, así que puede hacer cosas como:
Listado de Código 3.17: Ejemplo de uso de paréntesis |
(($set1 - $set2) | $set3) & $set4
|
4.
Protección del Sistema de Archivos
Luchando contra el enjaulamiento (chroot) y abuso del sistema de archivos
Grsecurity2 incluye muchos parches que prohiben a los usuarios de obtener
conocimiento innecesario acerca del sistema. Estos incluyen restricciones sobre
el uso de /proc, enjaulado (chrooting), enlazado, etcétera.
Configuración del Núcleo
Recomendamos la siguiente configuración de grsecurity en el núcleo para
protección del sistema de archivos:
Listado de Código 4.1: Activando la protección del sistema de archivos |
CONFIG_GRKERNSEC_PROC=y
CONFIG_GRKERNSEC_PROC_USERGROUP=y
CONFIG_GRKERNSEC_PROC_GID=10
CONFIG_GRKERNSEC_PROC_ADD=y
CONFIG_GRKERNSEC_LINK=y
CONFIG_GRKERNSEC_FIFO=y
CONFIG_GRKERNSEC_CHROOT=y
CONFIG_GRKERNSEC_CHROOT_MOUNT=y
CONFIG_GRKERNSEC_CHROOT_DOUBLE=y
CONFIG_GRKERNSEC_CHROOT_PIVOT=y
CONFIG_GRKERNSEC_CHROOT_CHDIR=y
CONFIG_GRKERNSEC_CHROOT_CHMOD=y
CONFIG_GRKERNSEC_CHROOT_FCHDIR=y
CONFIG_GRKERNSEC_CHROOT_MKNOD=y
CONFIG_GRKERNSEC_CHROOT_SHMAT=y
CONFIG_GRKERNSEC_CHROOT_UNIX=y
CONFIG_GRKERNSEC_CHROOT_FINDTASK=y
CONFIG_GRKERNSEC_CHROOT_NICE=y
CONFIG_GRKERNSEC_CHROOT_SYSCTL=y
CONFIG_GRKERNSEC_CHROOT_CAPS=y
|
Gatillando el mecanismo de seguridad
Cuando está usando el núcleo compilado con las opciones mostradas arriba (o
similares), obtendrá la opción de activar/desactivar muchas de las opciones a
través del sistema de archivos /proc o vía sysctl.
El ejemplo a continuación muestra un extracto típico de
/etc/sysctl.conf:
Listado de Código 4.2: Ejemplo de configuraciones dentro de /etc/sysctl.conf |
kernel.grsecurity.chroot_deny_sysctl = 1
kernel.grsecurity.chroot_caps = 1
kernel.grsecurity.chroot_execlog = 0
kernel.grsecurity.chroot_restrict_nice = 1
kernel.grsecurity.chroot_deny_mknod = 1
kernel.grsecurity.chroot_deny_chmod = 1
kernel.grsecurity.chroot_enforce_chdir = 1
kernel.grsecurity.chroot_deny_pivot = 1
kernel.grsecurity.chroot_deny_chroot = 1
kernel.grsecurity.chroot_deny_fchdir = 1
kernel.grsecurity.chroot_deny_mount = 1
kernel.grsecurity.chroot_deny_unix = 1
kernel.grsecurity.chroot_deny_shmat = 1
|
Puede activar o desactivar a voluntad las opciones usando el comando
sysctl:
Listado de Código 4.3: Activando las opciones vía sysctl |
# sysctl -w kernel.grsecurity.exec_logging = 1
# sysctl -w kernel.grsecurity.exec_logging = 0
|
Existe una opción de configuración muy importante de sysctl, a saber,
kernel.grsecurity.grsec_lock. Cuando está activada, no es posible hacer
futuros cambios.
Listado de Código 4.4: Cerrando la posibilidad de usar la interfaz sysctl |
# sysctl -w kernel.grsecurity.grsec_lock = 1
|
5.
Auditando el Núcleo
Extendiendo las facilidades de generación de bitácoras (logging) de su
sistema
grsecurity añade a su núcleo funcionalidad extra relativa a la generación de
bitácoras. Con la Auditoría del Núcleo de grsecurity, el núcleo le
informa cuando se inician las aplicaciones, si los dispositivos son
(des)montados, etc.
Las diversas configuraciones de Auditoría del Núcleo
La siguiente sección de configuración del núcleo puede ser usada para activar
las opciones de Auditoría del Núcleo:
Listado de Código 5.1: Activando la Auditoría del Núcleo |
CONFIG_GRKERNSEC_EXECLOG=y
CONFIG_GRKERNSEC_RESLOG=y
CONFIG_GRKERNSEC_CHROOT_EXECLOG=y
CONFIG_GRKERNSEC_AUDIT_CHDIR=y
CONFIG_GRKERNSEC_AUDIT_MOUNT=y
CONFIG_GRKERNSEC_AUDIT_IPC=y
CONFIG_GRKERNSEC_SIGNAL=y
CONFIG_GRKERNSEC_FORKFAIL=y
CONFIG_GRKERNSEC_TIME=y
CONFIG_GRKERNSEC_PROC_IPADDR=y
CONFIG_GRKERNSEC_AUDIT_TEXTREL=y
|
6.
Restricciones a los procesos
Protección a los ejecutables
Con grsecurity puede restringir los ejecutables. Debido a que la mayoría de los
exploits funcionan mediante uno o más procesos en ejecución, esta protección
puede salvar la salud de su sistema.
Protección de la red
La pila TCP/IP de Linux es vulnerable a ataques basados en predicciones.
Grsecurity incluye parches de aleatorización para contrarrestar esos ataques.
Aparte de esos parches, también puede activar restricciones a los sockets, con
lo que se prohibe completamente el acceso a la red a ciertos grupos.
Configuraciones del Núcleo
Las siguientes opciones del núcleo activan varias protecciones de red y
ejecutables:
Listado de Código 6.1: Configuraciones del Núcleo |
CONFIG_GRKERNSEC_EXECVE=y
CONFIG_GRKERNSEC_DMESG=y
CONFIG_GRKERNSEC_RANDPID=y
CONFIG_GRKERNSEC_TPE=y
CONFIG_GRKERNSEC_TPE_ALL=y
CONFIG_GRKERNSEC_TPE_GID=100
CONFIG_GRKERNSEC_RANDNET=y
CONFIG_GRKERNSEC_RANDISN=y
CONFIG_GRKERNSEC_RANDID=y
CONFIG_GRKERNSEC_RANDSRC=y
CONFIG_GRKERNSEC_RANDRPC=y
|
7.
El toolchain de Hardened
Aunque está fuera del alcance de este documento, mencionamos el uso del
toolchain de Hardened que completa el modelo grsec/PaX desde el espacio del
usuario (userspace). Como consejo rápido puede hacer:
Listado de Código 7.1: Usando el toolchain de Hardened |
# cd /etc
# rm make.profile
# ln -s ../usr/portage/profiles/hardened/x86 make.profile
# emerge -e world
|
Si no quiere usar este perfil, agregue estas banderas USE hardened pic a
su variable USE en /etc/make.conf.
8.
Recursos
|