Linux Hardening: Fortifica tu distro like a pro

Para llevar a cabo una correcta fortificación de nuestra distribución Linux tenemos que establecer múltiples líneas de defensa y limitar cada usuario o aplicación para que tenga unicamente los privilegios necesarios para ejecutar su tarea. En este post iremos comentando algunas de las líneas de defensa que debemos tener en cuenta para fortificar nuestro sistema siguiendo el orden que se muestra a continuación:

  1. Fortificación del Firmware
  2. Fortificación del Bootloader
  3. Fortificacion del Sistema de ficheros
  4. Fortificación de Cuentas de Usuario
  5. Fortificación de Aplicaciones
  6. Fortificación de Red

Fortificando el firmware

Al encender el equipo se carga un firmware (tipo BIOS o UEFI) que contiene el código necesario para iniciar el proceso de arranque, por lo que la primera medida que podemos aplicar antes del arranque del equipo es proteger el acceso al firmware.

  • Pon contraseña a para acceder a la BIOS y/o para bootear la máquina
  • Deshabilita el arranque desde medios externos

Fortificando el bootloader: grub2

Tras arrancar el firmware se carga el bootloader, que no es más que un programa que carga el kernel del S.O. En Linux el bootloader que se emplea es grub, el cual por defecto tampoco está libre de amenazas. Si alguien tiene acceso al bootloader y pulsa «C» invocará la shell de grub desde la cual podrá leer ficheros del sistema.

Acceso a ficheros desde la shell de grub

Aunque la shell de grub no es lo único a tener en cuenta, ya que se pueden editar las entradas del menú y añadiendo un simple parámetro, podríamos arrancar en modo de usuario sin que se nos solicite una contraseña.

Al llamar desde init a /bin/bash obtendremos una shell. Desde la shell podremos leer los ficheros del equipo. Si aparte de permisos de lectura quisiéramos poder escribir habría que modificar el parámetro ro (read only) a rw (read write).

Para securizarlo buscaremos limitar el acceso a las funcionalidades del grub que nos permite ver ficheros y modificar las entradas del menú de arranque. Para ello en grub2 definiremos una la lista de superusuarios que tendrán acceso a estas funciones. La creación de superusuarios consiste en editar el archivo «/etc/grub.d/40_custom» añadiendo las siguientes líneas:

set superusers="Usuario"
password Usuario contraseña

Como podemos comprobar, al añadir el password directamente este queda almacenado en texto plano, por lo que para guardarlo hasheado en vez de en plano se puede emplear el siguierte comando para generar un hash.

sudo grub-mkpassword-pbkdf2 

Ahora que ya tenemos el hash especificamos el tipo de password y el hash correspondiente, de forma que el contenido del archivo «/etc/grub.d/40_custom» sea parecido a la siguiente imagen.

También podemos limitar la lista de usuarios que pueden utilizar una entrada del menú . Por defecto las entradas del menú sin anotaciones –unrestricted o –users solo pueden ser usadas por el superusuario. Si quisiéramos permitir que una entrada solo sea accesible a un usuario habría que añadir la entrada en el fichero «40_custom», especificando algunas de las siguientes anotaciones:

menuentry "Solo puede iniciarse con superuserio o user1" --users user1 
menuentry "Cualquiera lo puede iniciar" --unrestricted

Hay que tener en cuenta que la configuración de usuarios y contraseñas no deben definirse directamente en el archivo grub.cfg, ya que este archivo se sobrescribe cada vez que se actualice la configuración de grub.

Para finalizar y actualizar los cambios al bootloader se ha de ejecutar el comando:

sudo update-grub2

Fortificando el sistema de ficheros:

Para fortificar el sistema de ficheros hay que tener en cuenta las principales amenazas las cuales son:

  • Acceso sin autorización a la información almacenada
  • Llenar el sistema de archivos evitando así que otros usuarios escriban en el sistema de archivos
  • Corrupción del sistema de ficheros que lo vuelva inestable
  • Obtener acceso a archivos ejecutables maliciosos con mayores privilegios (En sistemas de ficheros extraibles)

Cifrado de particiones y directorios

Para evitar el acceso no autorizado de alguien que obtenga acceso físico a la máquina podemos encriptar nuestros sistemas de archivos. Para ello a la hora de instalar el S.O crearemos un volumen logico (LVM) sobre el que podemos emplear LUKS para el cifrado. No voy a entrar en detalle sobre la configuración, ya que disponeis de un post dedicado al cifrado de particiones.

Al cifrar toda la partición, en muchos casos terminamos cifrando mucha información innecesariamente (principalmente archivos del sistema) por lo que a veces necesitamos una solución más simple. Usando encfs podemos permitir que un usuario pueda encriptar directorios sin ser root.

apt-get install encfs

Al usar encfs crearemos 2 carpetas una que contendra el contenido en claro y otra en donde se almacenara de forma cifrada el contenido de la primera carpeta. A la carpeta con el contenido en claro unicamente puede acceder el usuario.

De forma adicional para cifrar archivos también es posible utilizar gpg , sea de forma manual o automátizada con algún script como el que teneis en el siguiente post.

Cuotas de uso de disco

Para evitar que un usuario (o un grupo de usuarios) llene el sistema de archivos podemos hacer uso de cuotas. La configuración debe hacerse como root, y consite en primer lugar en editar el archivo «/etc/fstab» añadiendo «usrquota» o «grpquota», dependiendo si se desea cuotas por usuario o grupos, o ambas.

 apt-get install quota

Para recargar los cambios en el fstab usaremos el comando:

sudo systemctl daemon-reload

Comandos para la gestión de cuotas:

  • quotacheck: crea, comprueba y/o repara archivos de cuotas en un sistema de archivos
  • quoteon/quotaoff: activa/desactiva las cuotas en un sistema de archivos
  • edquota: permite modificar las cuotas de un usuario (o grupo)
  • repquota: informa el estado de las cuotas en un sistema de archivos

Para crear los ficheros externos donde están las cuotas ejecutamos el comando

sudo quotacheck -ugm /

Activamos las cuotas usando el comando

sudo quotaon -v /

Para editar cuotas usaremos el comando

sudo edquota -u testuser

Protección a la hora de montar dispositivos externos

A la hora de montar los dispositivos existen varias cosas a tener en cuenta, un atacante puede introducir en un pendrive un script con el bit de suid como root para escalar privilegios en el sistema o ejecutar un programa C que ejecute una shell como root.

Ejemplo de escalada de privilegios via suid. Listado de binarios explotables via suid: https://gtfobins.github.io/#+suid

Para evitar este tipo de amenazas hay varias opciones de montaje a tener en cuenta:

  • nodev: Ignora los dispositivos especiales en ese sitema de ficheros
  • nosuid: Ignora los bits suid y sgid
  • noexec: Prohibe la ejecución de programas en ese punto de montaje

La opción de montaje nosuid debería utilizarse siempre en sistemas de archivos en red y extraíbles.Por otro lado la opción noexec es aconsejable utilizarla en sobre dispositivos extraibles. Estas opciones de montaje se añaden en el fichero «/etc/fstab». A parte de los dispositivos extraibles también es buena practica de seguridad añadir estas opciones de montaje sobre las carpetas «/tmp», «/var/tmp» y «/dev/shm», ya que se tratan de directorios de almacenamiento temporal que puden ser aprovechables por parte de un atacante para comprometer el sistema.

 /dev/sda3    /tmp    ext4    defaults,nosuid,noexec,nodev    0    2

Hay que tener en cuenta que muchas distros modernas ya incluyen estas opciones de montaje. Para consultar que opciones de montaje se han aplicado podemos consultar el fichero <</proc/mounts>>

Permisos de los ficheros

En lo que respecta al acceso no autorizado, debemos tener cuidado con los permisos de los ficheros y directorios.Algunos consejos a tener en cuenta son:

  • Los directorios home deben tener permisos 700
  • Los archivos de configuración de los distintos demonios no deben ser leídos por todo el mundo
  • Quitar los permisos de ejecución que no sean estrictamente necesarios.
  • Todos los directorios del sistema deben ser no escribibles excepto para el usuario root
  • /tmp debe tener permisos de escritura en todo el mundo, pero con el sticky bit activado

Fortalecimiento de cuentas de usuario:

Las principales amenazas asociadas a las cuentas de usuario son:

  • Algún usuario no sea quien dice ser
  • Algún usuario esta usando demasiados recursos del sistema impidiendo que funcione correctamente
  • Algún usuario posee mas privilegios de los que realmente necesita
  • Uso de la cuenta root

Autenticación de los usuarios

Para prevenir que un usuario no sea quien dice ser podemos fortalecer el proceso de autenticación usando los módulos PAM. Usar módulos PAM nos permite cambiar el algoritmo de autenticación sin hacer cambios en las aplicaciones, permite añadir nuevos métodos de autenticación de forma sencilla, a parte de permitir modificar las políticas de autenticación imponiendo reglas sobre la generación de contraseñas, limitando los terminales desde los que el usuario puede iniciar sesión y usar los registros para detectar comportamientos extraños.

El formato para configurar un modulo PAM es:

service type control module-path module-arguments

Algunos de los módulos PAM más típicos son:

  • pam_unix – Definición del tipo de hash y características de las contraseñas
  • pam_cracklib – Características adicionales para las contraseñas
  • pam_securetty – Limita el login de root para algunos dispositivos
  • pam_faildelay – Establece una espera tras varios intentos de login fallidos

A modo de ejemplo de la potencia de PAM, estableceremos un doble factor de autenticación con google authenticator para acceder vía ssh. Para ello no hay más que clonar el repositorio de GitHub google-authenticator-libpam y seguir las instrucciones de compilación. Una vez compilado ejecutamos google-authenticator para generar un QR que escanearemos con la aplicación. Para aplicarlo en el servidor ssh únicamente tenemos que modificar la configuración del modulo PAM relativo a sshd añadiendo al final la configuración de google authenticator. Los ficheros de configuración de los módulos PAM los podemos encontrar en la ruta «/etc/pam.d/»

Como podréis observar ahora al acceder vía ssh nos solicita el código de segundo factor de autenticación.

Limitar recursos de usuarios

Utilizando el modulo pam_limit podemos limitar el máximo de sesiones simultáneas de inicio de sesión, el tamaño máximo de archivo, el uso máximo de memoria para un usuario evitando así el uso de recursos en exceso.

Shell restringida

Podemos limitar aún más lo que un usuario puede hacer en el sistema utilizando un shell restringido. Para invocar un shell bash restringido podemos usar bash -r (restricted) o el ejecutable rbash.

sudo useradd user1 -s /bin/rbash

En un shell restringido es posible definir exactamente el conjunto de ejecutables que el usuario puede ejecutar en la máquina. En el caso de rbash podemos crear un directorio «bin» dentro del home del usuario y editando el fichero .bash_profile añadir la variable $PATH=/home/user1/bin. Para añadir los ejecutables que el usuario puede usar crearemos un link simbolico al nuevo path.

sudo ln -s /bin/ls /home/user1/bin

Acceso como root

Usando módulos PAM podemos restringir el acceso a la cuenta root directamente desde la terminal, obligando a iniciar sesión primero como un usuario normal y luego usar el comando su, de esta forma quedara registrado en los logs quien acede como root.

Por ultimo a través del comando sudo y la definición de sudoers es posible definir un acceso de administrador limitado de forma que tan solo pueda realizar algunas tareas.

Fortalecimiento a nivel de aplicación:

Eliminar las aplicaciones que no sean necesarias

En primer lugar, debemos eliminar las aplicaciones que no necesitemos, para identificar estas aplicaciones podemos hacer a ojo o usar utilidades que busquen los paquetes sin usar en base al timestamp de los ejecutables.

Eliminar paquetes

apt-get remove <paquete>

Desactivar con servicios

systemctl disable <service>

Enmascarar servicios para que nada se pueda comunicar con él

systemctl mask <service>

Limita los recursos de las aplicaciones

Por otro lado también podemos limitar los recursos que consumen las aplicaciones con cpulimit (limita la cpu asociada a un proceso), prlimit (limita los recursos asociados a un proceso) y cgroups (limita los recursos para un conjunto de procesos).

cpulimit -p 4112 -l 25
CPU limitada al 25% para el proceso de firefox

Restringiendo aplicaciones

Hay que tener en cuenta que un proceso en Linux conoce solo 2 directorios el actual, y el root.

El comando chrdir nos permite cambiar el directorio actual de un proceso y chroot nos permite cambiar de forma virtual directorio root, creando espacios aislados del sistema de archivos pero ojo la memoria no se aísla! aun puede ser alcanzable por procesos root.

Esto puede ser útil en ftp, web sencillas o incluso si disponemos de algún cliente torrent para evitar que por alguna vulnerabilidad del cliente puedan leer nuestros archivos. Muchas veces chroot no es suficiente, por lo que es conveniente emplear otras técnicas para aislar y restringir las aplicaciones.

AppArmor nos permite restringir el acceso a ciertas aplicaciones, scripts o programas para únicamente hacer ciertas tareas o tener acceso a ciertas partes del sistema. AppArmor nos permite generar un perfil con los datos del funcionamiento normal de la aplicación de forma que no permita a la aplicación realizar cosas fuera del perfil.

En primer lugar descargaremos las utilidades y los perfiles:

sudo apt-get install apparmor-utils apparmor-profiles

Comprobaremos que apparmor se esta ejecutando correctamente:

sudo aa-status

Si queremos restringir una app, podemos generar un perfil ejecutando el siguiente comando.

sudo aa-genprof <path_absoluto_programa>

Los perfiles generados los podemos encontrar en <</etc/apparmor.d/>>. Para pasar a modo estricto los perfiles generados ejecutamos:

sudo aa-enforce /etc/apparmor.d/*

AppArmor no proporciona sandboxing, sino que limita a qué partes del sistema puede acceder la aplicación. Especifica los recursos concretos que una aplicación no puede usar. Sin embargo, estos recursos no están aislados, por lo que dos aplicaciones que se ejecutan con AppArmor con acceso al mismo recurso podrían interactuar.

Ejemplo de perfil de AppArmor para traceroute

Sandboxing

En las técnicas de sandboxing se crea un entorno virtual para ejecutar los procesos de forma aislada. Principalmente nos sirve para ejecutar aplicaciones no confiable de forma segura, ya que al tratarse de un entorno aislado, en caso de una vulnerabilidad o malware existente este no se propagaría por el sistema. Existen diversas opciones de sandboxing como lxc, docker, FireJail..etc.

FireJail aprovecha los espacios de nombres de Linux para proporcionar aislamiento a nivel de usuario, montaje, red y proceso. Este aislamiento proporciona a la aplicación su propia caja de arena para hacer lo que quiera mientras evita que esos cambios afecten al resto del sistema.

apt-get install firejail

Para ejecutar una aplicación de forma segura con firejails podemos usar:

firejail --seccomp --nonewprivs --private-tmp firefox

Fortificando a nivel de red:

Filtrados de paquetes

Las iptables se tratan de un modulo del kernel de Linux que actúa como un firewall de estado filtrando los paquetes de red. Funciona mediante tablas que contienen cadenas que a su vez contienen una agrupación de reglas que indican que paquetes debe permitir entrar y cuales no.

Tablas de Iptables

Consejos de definición de reglas:

  • Desde un servidor no debería ser posible navegar
  • Implementar mecanismo que dropeen Ddos o limiten el ancho de banda
  • Implementar un control de estado
  • Todo lo que no este permitido debe estar bloqueado

Hay que tener en cuenta que el orden de las reglas afecta al funcionamiento, algunas ejemplos de reglas que pueden ser interesantes son:

Bloquear una dirección IP

iptables -A INPUT -s 192.168.0.200 -j DROP

Rechazar todo el tráfico por defecto

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

Permitir el trafico por el puerto 22 (ssh) en la red local

iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 192.168.0.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT

Protección frente a Ddos

iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT

Hacer que las reglas sean persistentes

apt-get install iptables-persistent
iptables-save → Guarda las reglas Iptables
iptables-restore → Carga las reglas del backup

Tcp Wrappers

Un TCP Wrapper provee de un control de acceso simple y administración de logs estandarizada para aplicaciones que soporten y reciban conexiones de red. Son ACL para filtrar accesos de la red a Servicios locales. Funcionan con TCP,UDP e ICMP. Los wrappers no funcionan con servicios de llamadas procedente de remoto; ej: RCP sobre TCP.

Los wrappers trabajan en capa 7 y pueden filtrar consultas aun cuando se utilice cifrados, a diferencia del firewall de iptables que trabaja en capa 3 actuando a nivel de paquetes sin ser consciente de la conexión. Otra diferencia es que con iptables controlamos el trafico tanto entrante como saliente mientras que con los wrapper solo podemos controlar el entrante.

Principalmente posee dos ficheros de configuración:

  • «etc/hosts.allow» : Este archivo contiene los nombres de hosts que tienen permitido utilizar servicios de red.
  • «/etc/hosts.deny» : Este archivo contiene los nombres de hosts que no pueden utilizar servicios de red.
  • El fichero hosts.allow tiene preferencia sobre el hosts.deny.

Sintaxis:

lista_sercicios: lista_cliente [: comando_shell]

Para configurarlo, lo recomendable seria denegar todas las conexiones en el hosts.deny y habilitar en el hosts.allow las conexiones entrantes que permitamos , como por ejemplo las conexiones ssh que provengan de la red local.

Ejemplo hosts.deny

ALL: ALL

Ejemplo de host.allow

sshd: 192.168.0.0/255.255.255.0 EXCEPT 192.168.0.100

Referencias:

Para más información consultar el manual de seguridad de debian

Deja un comentario

Esta web funciona gracias a WordPress.com.

Subir ↑

Diseña un sitio como este con WordPress.com
Comenzar