Administración del sistema operativo Unix

Víctor Manuel Jáquez Leal


Tabla de contenidos
1. Seguridad en cómputo
1.1. Políticas de seguridad
1.2. La seguridad es un proceso
1.3. Defensa en niveles
1.4. Problemas técnicos
2. Seguridad en el Kernel
2.1. ¿Qué es el kernel?
2.1.1. kernel monolítico
2.1.2. Módulos del kernel
2.1.3. Peligros de seguridad en un kernel modular
2.1.4. La secuencia de arranque en Unix
2.1.5. Parches de seguridad extra para Linux
2.2. Opciones de seguridad del sistema en el kernel
2.2.1. El directorio /proc de Linux
2.2.2. Entradas relacionadas con el cortafuegos
2.3. Preguntas de investigación
3. Auditoría del Sistema
3.1. Seguridad general en bitácoras
3.2. Configuración del Syslog
3.3. Otros sistemas para Syslog
3.4. Monitoreo de Bitácoras
3.5. Preguntas de investigación
4. Firewalls (Cortafuegos)
4.1. ¿Qué es un firewall?
4.2. ¿Qué es un Stateful Firewall?
4.2.1. Ventajas de un Stateful Firewall
4.2.2. Stateless Firewall
4.3. ¿Qué es netfilter/iptables?
4.3.1. Flujo de un paquete en iptables
4.4. Preguntas de investigación
Bibliografía
Tabla de ejemplos
3-1. /etc/syslog.conf

Capítulo 1. Seguridad en cómputo

"Una computadora es segura si puedes confiar en que ella y su software se comportan como esperas." - Practical UNIX and Internet Security

"Seguridad es: disponibilidad, consistencia, control de acceso, confidencialidad de los datos, autenticación." - http://www.sun.com/security/overview.html

"El principal objetivo de la seguridad en cómputo es proteger y asegurar la confidencialidad, integridad y disponibilidad de los sistemas de información automáticos y de los datos que ellos contienen." - http://csrc.nist.gov/publications/secpubs/cslaw.txt

Hay varios definiciones para "seguridad de cómputo", y la mayoría de ellas son correctas. Esencialmente la seguridad en cómputo significa imponer el uso de políticas, esto debe hacerse desde que las personas y el software tienen fallas que pueden resultar en accidentes, pero también porque alguien puede querer robar tu información, usar tus recursos inapropiadamente o simplemente negarte el uso de tus recursos..


1.1. Políticas de seguridad

Una política de seguridad es una expresión de los objetivos de seguridad de tu organización. Los objetivos de seguridad varían grandemente entre organizaciones. No puedes implementar apropiadamente la tecnología de seguridad sin una sólida idea de tus objetivos.


1.2. La seguridad es un proceso

Sólo necesitas cometer un error o dejar una falla disponible para que un atacante entre. Esto, claro, significa que todos los sitios serán eventualmente exitosamente atacados. Es por eso que la seguridad debe considerarse como un proceso continuo e iterativo:

  • Aplicar y probar los parches de seguridad distribuidos por el fabricante del software.

  • Regularmente explorar tu red en busca de puertos abiertos.

  • Regularmente explorar tus servidores con software de análisis de intrusión, tal como Nessus.

  • Auditar los permisos de archivos y asegurarse que no existen binarios con setuid o seguid inesperados.


1.3. Defensa en niveles

Todas las medidas técnicas de seguridad fallarán eventualmente o serán vulnerables a un ataque. Por esta razón se deben implementar varios niveles de protección. Los cortafuegos (firewalls) no son suficientes, puedes accidentalmente olvidar una regla o estar expuesto al reiniciar un conjunto de reglas:

  • Utiliza tcp_wrappers (Programa que provee servicios de cortafuegos para los demonios de Unix. Trabaja en el espacio del usuario, a diferencia del cortafuegos del sistema que funciona en el espacio de kernel.)

  • Restringe qué usuarios pueden accesar a qué servicios, especialmente si sólo pocos usuarios necesitas accesar.

  • Cifra el tráfico donde sea posible, así los atacantes no podrán olfatear fácilmente nombres de usuarios y contraseñas o secuestrar (hijack) sesiones.

  • Dado que las medidas de seguridad fallarán, también necesitas un proceso fuerte de auditoría y registro (logging) para que puedas encontrar qué ocurrió cuando algo ocurre mal.


1.4. Problemas técnicos

No obstante siempre nos toparemos con dificultades a la hora de implementar mecanismos de seguridad, los más comunes son:

  • Conectividad de red

  • Parámetros por defecto inseguros

  • Acceso legítimo vs Ataque

  • Minimizar el acceso y el privilegio


Capítulo 2. Seguridad en el Kernel

2.1. ¿Qué es el kernel?

El kernel es software de muy bajo nivel que maneja el hardware de tu computador, las multitareas de varios programas que corren en cualquier momento dado, y otras cosas esenciales. Estas funciones de bajo nivel son usadas por otros programas, así su autores pueden concentrarse en la funcionalidad específica que desean proveer.

Un kernel moderno provee, entre otras, estas características: multitareas real, hilos, memoria virtual, bibliotecas compartidas, carga en demanda, ejecutables "copy-on-write" compartidos, administración de memoria adecuada, carga de módulos manejadores de dispositivos, manejo de la memoria de vídeo, y la pila de red TCP/IP.

Importante

El kernel es el núcleo del sistema, es mejor que este seguro o estas en graves problemas.


2.1.1. kernel monolítico

El enfoque monolítico define una interfaz virtual de alto nivel sobre el hardware, con un conjunto de primitivas o llamadas al sistema para implementar los servicios del sistema operativo, tal como administración de procesos, concurrencia y administración de memoria, en varios módulos que corren en modo supervisor

Aún si cada módulo que sirve a estas operaciones estuviera separado del todo, el código integrador es muy estrecho y difícil de hacer correctamente, y como todos los módulos corren en el mismo espacio, un error de programación en uno de ellos puede tumbar todo el sistema. Sin embargo, cuando la implementación es completa y confiable, la estrecha integración interna de los componentes permite explotar efectivamente las características de bajo nivel del sistema.

Un kernel monolítico híbrido es aquel que puede cargar módulos en tiempo de ejecución.


2.1.2. Módulos del kernel

Se puede añadir código a un kernel mientras esta ejecutándose. Un pedazo de código que añades de esta manera es llamado como módulo de kernel cargable. Estos módulos pueden hacer muchas cosas, entre las cuales podemos contar:

  • Manejadores de dispositivos.

  • Manejadores de sistemas de archivos.

  • Llamadas a sistema.

  • Manejadores de red.

  • Intérpretes de ejecutables.

Los módulos de kernel tiene muchas ventajas en lugar de un kernel monolítico puro:

  • No hay que reconstruir el kernel a cada cambio del sistema.

  • Ayudan a diagnosticar los problemas del sistema, ya que es más fácil rastrear el problema y eliminar el módulo problemático al siguiente arranque del sistema.

  • Ahorran memoria al sólo cargarse el módulo cuando es necesario.


2.1.3. Peligros de seguridad en un kernel modular

Después de introducirse en un sistema, normalmente el intruso instalará un "rootkit"[1] para asegurar futuros accesos al sistema. Tales rootkits están disponibles en Internet y están diseñados para ser usados incluso por los usuarios menos experimentados.

Los rootkits contienen normalmente herramientas para eliminar rastros de intrusiones de las bitácoras de auditoría, "puertas traseras" que permiten fácil acceso una vez que han sido instalados, y medios para ocultar el rootkit de los administradores, tales como ejecutables modificados de "ps" y "ls" que ocultarán procesos y archivos del rootkit. Existen rootkits avanzados que instalarán tales ejecutables con el mismo tamaño que los archivos originales, lo cual es en realidad fácil pues se puede agrandar el tamaño de cualquier ejecutable simplemente añadiendo basura aleatoria al final.

Para detectar tales rootkits, es necesario tener una base de datos de checksums criptográficos[2] de archivos críticos y compararlos contra los archivos actuales. Los checksums criptográficos más útiles incluyen MD5, SHA-1, TIGER pero no CRC, que no puede ser falsificado.

Cualquier programa de aplicación es controlada por el kernel, y cualquier acceso al sistema (como escribir o leer del disco) es ejecutada por el kernel. La aplicación ejecutará una llamada al sistema del kernel y el kernel hará el trabajo y entregará el resultado de vuelta a la aplicación. Desde el punto de vista de los usuarios, estas llamadas al sistema son las funciones de más bajo nivel, y proveen acceso a los sistemas de archivos, conexiones de red, entre otras cosas. Modificando las llamadas al sistema del kernel, los rootkits de kernel pueden esconder archivos, directorios, procesos o conexiones de red sin modificar cualquier binario del sistema. Obviamente, los checksums para confirmar la integridad de un sistema son inútiles en esta situación.

Para detectar la presencia de rootkits como módulos del kernel podemos utilizar chkrootkit


2.1.4. La secuencia de arranque en Unix

Una vez que un atacante ha logrado entrar al sistema como administrador, intentará modificar los scripts de arranque para cargar automáticamente, y sin aviso al administrador, las puertas traseras, los rootkits y los servicios ilícitos que instale. Es por esto que debemos comprender la secuencia de arranque de nuestro sabor de Unix y poder así detectar modificaciones.

Para limitar la presentación se mostrará la secuencia de booteo de dos sistemas Unix populares y libres: Linux y FreeBSD.


2.1.4.1. El proceso de arranque de Linux

The Linux Boot Process

  • BIOS

    Carga el sector de arranque de alguno dispositivo como:

    • Floppy

    • CDROM

    • Disco Duro

    El orden de arranque puede ser alterado dentro del BIOS. Se accede al BIOS por medio de una tecla oprimida en el momento de encendido. La tecla exacta depende del tipo de BIOS, pero generalmente son o Supr, F1, F2 o F10.

  • (DOS) Master Boot Record (MBR)

    El contexto del DOS incluye MS-DOS, Win95 y Win98

    • El BIOS carga y ejecuta los primeros 512 bytes del disco.

    • Un DOS MBR estándar hará las siguientes tareas:

      • Buscará una partición primaria marcada como "de arranque"

      • Cargará y ejecutará los primeros 512 bytes de esa partición

    • Puede ser restaurada (para DOS) con fdisk /mbr

  • LILO

    • No entiende a los sistemas de archivos.

    • El código y la imagen del kernel a cargar es almacenada como desplazamientos crudos en el disco.

    • Utiliza las rutinas de BIOS para cargar.

    Secuencia de carga

    • carga el código del menú, típicamente /boot/boot.b

    • Pregunta por una partición o por un kernel (o cae dentro de uno por defecto)

  • GRUB

    • Entiende sistemas de archivos

    • La configuración vive en /boot/grub/menu.lst

  • Kernel

    • Inicializar dispositivos

    • Opcionalmente carga initrd

    • monta el sistema de archivos raíz

      • Especificado por lilo con el parámetro root=

      • El kernel imprime en monitor: VFS: Mounted root (ext2 filesystem) readonly.

    • Ejecuta /sbin/init que tiene como número de proceso 1 (PID=1)

      • init imprime en monitor: INIT: version 2.76 booting

      • pude ser cambiado con el parámetro boot= del lilo, por ejemplo boot=/bin/sh puede ser útil para rescatar un sistema con problemas de arranque.

  • initrd

    Permite la ejecución de tareas previas al montado del sistema de archivos

    • lilo carga la imagen del disco ram fijado

    • El kernel ejecuta /linuxrc

      • carga módulos

      • inicializa dispositivos

    • la raíz "real" se monta

    • El kernel ejecuta /sbin/init

    Detalles en /usr/src/linux/Documentation/initrd.txt

  • /sbin/init

    Lee /etc/inittab (vea man inittab)

    • Ejecuta los scripts de arranque:

      • debian: ejecuta /etc/init.d/rcS el cual ejecuta:

        • /etc/rcS.d/S*

        • /etc/rc.boot/* (obsoleto)

      • redhat: /etc/rc.d/rc.sysinit el cual carga módulos, checa el sistema de archivos raíz y lo monta como de lectura y escritura, monta el sistema de archivos local, levanta la red y monta sistemas de archivos remotos.

    • Ejecuta /etc/rc3.d/S*

    • Ejecuta programas especificados en /etc/inittab

  • Niveles de ejecución

    • Los niveles definidos de ejecución son:

      • 0 apagar

      • 1 mono-usuario

      • 2-4 definido por el usuario

      • 5 sólo X11

      • 6 Reinicio

    • Por defecto esta en /etc/inittab, por ejemplo: id:3:initdefault:

    • El nivel de ejecución actual puede cambiarse corriendo /sbin/telinit # donde # es el nuevo número de nivel.

  • Programas de nivel de ejecución

    • Scripts en /etc/rc*.d/* son ligas simbólicas a /etc/init.d

      • Scripts con prefijo S serán iniciados cuando el nivel de ejecución entre.

      • Scripts con prefijo K serán eliminados cuando entre la nivel de ejecución.

    • Ejecutar programas para un nivel de ejecución especificado

    • líneas del /etc/inittab:

      • 1:2345:respawn:/sbin/getty 9600 tty1

      • ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now


2.1.4.2. Proceso de arranque de FreeBSD

The FreeBSD Booting Process

Muy similar a de Linux, sólo cambia los nombres de los programas.

El sistema de inicio de FreeBSD se divide en tres etapas. La primer etapa es ejecutada por el MBR, que conoce sólo lo suficiente para poner a la computadora en un estado específico y pasa al a segunda etapa. La segunda etapa hace un poco más, antes de ejecutar la tercer etapa. La tercer etapa finaliza la tarea de cargar el sistema operativo. El trabajo se divide en estas tres etapas porque las computadoras personales estándar ponen límites al tamaño de los programas que pueden ejecutarse en las etapas uno y dos. Encadenando las tareas permite al FreeBSD proveer de un cargador más flexible.

El kernel luego es ejecutado y comienza a probar los dispositivos y a inicializarlos para su uso. Una vez que el proceso de arranque del kernel termina, el kernel pasa el control al proceso del usuario init(8), el cual se asegura luego de que los discos estén en un estado utilizable. init(8) luego comienza la configuración a nivel de usuario la cual monta sistemas de archivos, levanta las interfaces de red, y generalmente comienza todos los procesos que usualmente son ejecutados en un sistema FreeBSD el momento de inicio.

  • MBR

    /boot/boot0

    Permite la selección de distintos sistemas operativos.

  • Etapa 1 y 2

    /boot/boot1 y /boot/boot2

    Conceptualmente las etapas uno y dos son parte de un mismo programa, en la misma área del disco. Por restricciones de espacio han sido divididos en dos, pero siempre se instalan juntos.

    boot1 es muy simple, ya que sólo puede tener 512 bytes de tamaño, y conoce sólo lo suficiente acerca del disco de FreeBSD, el cual almacena información acerca de la partición para encontrar y ejecutar boot2

    boot2 es ligeramente más sofisticado, y entiendo el sistema de archivos de FreeBSD lo suficiente para encontrar archivos y puede proveer una interfaz simple para escoger el kernel o el cargado a ejecutar.

  • Etapa 3

    /boot/loader

    El cargador es la etapa final de la secuencia de arranque, y esta localizado en el sistema de archivos.

    El cargado tiene la intención de ser un método de configuración amigable para el usuario, usando un conjunto de comandos fáciles de usar.

  • Carga y ejecución del kernel

    Inicializa dispositivos

  • Init

    /sbin/init

    Una vez que el kernel ha terminado de arrancar, pasa el control al proceso de usuario init(8), o al programa especificado en la variable init_path en el cargador.

  • rc (configuración de recursos)

    Si el sistema no fue arrancado en modo monousuario, el sistema lee los archivos de configuración de recursos y ejecuta los scripts de configuración.

    El sistema configuración de recursos lee la configuración por defecto de /etc/defaults/rc.conf, y los detalles específicos del sistema en /etc/rc.conf, y luego procede a montar los sistema de archivos mencionados en /etc/fstab, levanta los servicios de red, levanta los servicios del sistema y finalmente ejecuta los scripts de inicio de los paquetes instalados localmente.

    La página de manual rc(8) es una buena referencia para sistema de configuración de recursos, así como examinar los scripts.


2.1.5. Parches de seguridad extra para Linux

Linux, debido a su ingeniería de desarrollo, esta abierto a la innovación de cualquier persona en el mundo, aunque finalmente es Linus Torvalds quien decide qué entra y que no en las versiones oficiales. No obstante muchas mejoras son ofrecidas libremente en Internet. En el área de seguridad la siguientes son las más conocidas en el medio.


2.1.5.1. SE Linux

Security-Enhaced Linux

SE Linux es un prototipo de investigación del kernel Linux y un número de utilerías con funcionalidad de seguridad mejorada, diseñado simplemente para demostrar el valor de los controles de acceso mandatorios a la comunidad Linux, y cómo tales controles pueden ser añadidos a Linux. Estos componentes arquitectónicos proveen de soporte general para el cumplimiento de varios tipos de políticas de control de acceso mandatorias, incluyendo aquellas basadas en conceptos de Cumplimiento de Tipos, Control de Acceso basado en Roles, Seguridad Multinivel.

El kernel de SE Linux impone políticas de control de acceso mandatorias que confinan al usuario y a los servicios a una mínima cantidad de privilegios que requieren para hacer sus tareas. Cuando se confinan de esta manera, la habilidad de los usuarios o los servicios de causar daño cuando son comprometidos (a través de buffer overflows[3] o malas configuraciones, por ejemplo) sea reducida o eliminada. Estos mecanismos de confinamientos operan independientemente de los mecanismos de control de acceso tradicionales de Linux. No tiene un concepto de super-usuario, y no comparte las debilidades de los mecanismos de seguridad tradicionales (como la dependencia en setuid/setgid).

Las nuevas características de SE Linux están diseñadas para asegurar la separación de la información basada en los requerimientos de confidencialidad e integridad.


2.1.5.2. OpenWall

OpenWall

Este parche es una colección de opciones de seguridad para el kernel de Linux. En adición a las nuevas características, algunas versiones del parche traen correcciones de seguridad. El número de tales correcciones cambian de versión a versión, tal como sean vuelto obsoletas, mientras que otros problemas de seguridad son descubiertos.

  • Área no ejecutable en la pila del usuario

    La mayoría de los agujeros de seguridad por derrame de la pila, están basados en la sobre escritura de una dirección de retorno de una función en la pila para apuntar a algún código arbitrario, el cual también es puesto en la pila. Si el área de la pila es no-ejecutable, la vulnerabilidades de buffer overflow serían más difíciles de explotar.

  • Restricción de ligas en /tmp

    Previene el uso de ligas duras en un ataque, rechazando a los usuarios regulares crear ligas duras a archivos que no poseen, a menos que puedan leer y escribir en el archivos.

  • Restricción de tuberías en /tmp

    Restringe la escritura de tuberías con nombre por quienes no sean su dueño.

  • Directorio /proc restringido

    Restringe el acceso al directorio especial /proc a los usuarios no administradores, sólo a archivos que describen sus proceso.

  • Procura RLIMIT_NPROC en execve(2)

  • Destruye segmentos de memoria compartida que no este en uso.


2.1.5.3. Linux Intrusion Detection System

LIDS Project

Las instalaciones actuales de Linux tiene muchos problemas inherentes a muchas versiones de Unix. Probablemente el único y mayor problema es la "toda poderosa" cuenta de root. Cuando un proceso o usuario tiene privilegios de root, no hay nada que prevenga a ese proceso o usuario destruir todo el sistema. Un usuario o intruso malicioso con acceso de root pude causar muchos dolores de cabeza a los administradores. LIDS implementa listas de controles de acceso que previenen aún a aquellos con acceso a la cuenta de root destruir todo el sistema. Estas ACLs permiten que LIDS proteja archivos así como procesos.

LIDS es un parche y una herramienta administrativas par mejorar la seguridad del kernel de Linux.

Implementa un monitor de referencia en el kernel.

Control de Acceso Mandatorio en el kernel.

Entre sus características podemos citar:

  • Protección de archivos. Nadie, incluyendo root, puede modificar los archivos protegidos por LIDS. Los archivos pueden ser escondidos.

  • Protección de procesos. Nadie, incluido root, puede matar procesos protegidos. Los procesos pueden ser escondidos.

  • Controles de acceso finamente granulados con ACLs

  • Usar y extender la capacidad de controlar todo el sistema

  • Alertas de seguridad desde el kernel

  • Detección de escaneo de puertos en el kernel

  • Restricción a los proceso de acceso a red


2.1.5.4. GRSecurity

grsecurity

GRSecurity es un sistema completo de seguridad para el kernel de Linux 2.4.x, el cual implementa estrategias de detección, prevención y contención. Previene la mayoría de las formas de modificación de direccionamiento, confina a los programas a su mínimo privilegio a través de un sistema MAC basado en procesos, endurece las llamadas a sistema, provee de auditorías con muchas características, e implementa muchas de las características de aleatoriedad de OpenBSD. Esta escrito con el desempeño, facilidad de uso y seguridad en mente.


2.2. Opciones de seguridad del sistema en el kernel

2.2.1. El directorio /proc de Linux

Linux Firewall-related /proc Entries

Existen muchas opciones dentro del kernel de Linux que pueden variar de máquina a máquina. Tradicionalmente estas opciones son fijadas al momento de compilación, o algunas veces son modificadas a través de llamadas al sistema esotéricas.

En los kerneles modernos de Linux existen muchas opciones que pueden ser modificables. Proveiendo o sobrecargando una plétora de llamadas al sistema se vuelve algo extenso, y forza al administrador a a escribir código en C para cambiarlos en tiempo de ejecución, lo cual es muy complicado. En lugar de esto, el sistema de archivo /proc fue creado. /proc es un sistema de archivos virtual (no reside en ningún disco físico o remoto) que provee una vista de la configuración y el estado del sistema en tiempo de ejecución.

El sistema de archivos /proc puede navegarse como cualquier otro sistema de archivos. Las opciones aparecen como archivos comunes, directorios y ligas simbólicas, pero en realidad son vistas a la información del kernel mismo. Algunas pueden ser modificables por root, pero la mayoría son de sólo lectura. Con los comando cat o more se puede visualizar esta información.

Todas las entradas en /proc/sys pueden ser modificadas. Puedes modificar de dos maneras: usando comandos estándares de Unix y a través del sysctl.


2.2.2. Entradas relacionadas con el cortafuegos

Existen diferentes variables del kernel que pueden modificarse. En este documento se discutirán aquellos específicamente relacionadas con la protección de una máquina Linux de ataques por red.

Si estas interesado en aprender acerca de otras variables del kernel, lee la página de manual proc(5). También hay varios archivos en el código fuente del kernel.

/proc/sys/net/ipv4/icmp_echo_ignore_all

Cuando esta habilitado, ignora todos los paquetes ICMP ECHO REQUEST (ping). No hace nada en realidad para incrementar la seguridad, pero puede esconderte de los barridos por ping, lo cual te previene de escaneos de puertos. Sin embargo también bloqueará pruebas de conectividad normales.

/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

Cuando esta habilitado, ignora los pings a broadcast y a multicast. Es buena idea ignorar esto para evitar convertirse inadvertidamente en un participante de ataques de negación de servicio distribuidos.

/proc/sys/net/ipv4/conf/*/accept_source_route

Cuando los paquetes ruteados por origen son permitidos, un atacante puede falsificar la dirección IP fuente de conexiones diciendo explícitamente cómo los paquetes deberían ser ruteados a través de Internet. Esto puede habilitarlos para abusar de relaciones de confianza o saltarse listas de acceso. Ya no existe razón de ser en Internet actualmente para habilitarlo.

/proc/sys/net/ipv4/conf/*/rp_filter

Cuando está habilitado, si un paquete viene a una interfaz, pero su respuesta es por otra interfaz diferente, el paquete se desecha. Es innecesario en computadoras con una única interfaz, pero recuerda que las conexiones PPP y VPN usualmente tienen su propia interfaz, así que es buena idea habilitarlo de cualquier manera. Puede haber un problema para ruteadores de redes que dinámicamente están cambiando rutas. No obstante, en firewalls o ruteadores con una solo conexión entre redes, esta opción automáticamente ofrece una protección contra el spoofing[4].

/proc/sys/net/ipv4/conf/*/accept_redirects

Cuando envías un paquete destinado a una máquina remota, usualmente lo envías a un ruteador por defecto. Si esta máquina envía una redirección ICMP, te permite saber que es un ruteador diferente a quién deberías dirigir el paquete para un mejor ruteo, y tu máquina enviará el paquete ahí en lugar del primero. Un cracker puede usar redirecciones ICMP para engañarte y enviar paquetes a través de una máquina que él controle y ejecute ataques hombre-en-medio[5] . Esto ciertamente jamás deberá estar habilitado en un ruteador bien configurado.

/proc/sys/net/ipv4/conf/*/secure_redirects

Acepta redirecciones ICMP cuando vienen de un ruteador que esta fijo como un gateway por defecto. Deberá ser habilitado sólo si tienes múltiples ruteadores en una red. Si tu red es razonablemente estática y estable, es mejor dejarlo deshabilitado.

/proc/sys/net/ipv4/conf/*/send_redirects

Si eres un ruteador y existen rutas alternativas que deberías informar a tus clientes (si tienes múltiples ruteadores en tus redes), querrás habilitar esto. Si tienes una red estable donde los hosts ya tienen las rutas correctas, no será necesario, y nunca es necesario para máquinas que no hacer labores de ruteo.

/proc/sys/net/ipv4/ip_forward

Si es un ruteador, debe estar activado. Aplica para interfaces VPN (Redes Virtuales Privadas) también. Si requieres el reenvío de paquetes de una interfaz a otra, asegurate de que tienes un conjunto apropiado de listas de control de acceso que permitan el tráfico que tu deseas reenviar.

/proc/sys/net/ipv4/ipfrag_high_thresh

El kernel necesita solicitar memoria para ser capaz de reensamblar paquetes fragmentados. Una vez que este límite se ha alcanzado el kernel comenzará a descartar paquetes fragmentados. Fijando esto muy bajo o muy alto puede dejarte vulnerable a un ataque de negación de servicio. Durante un ataque de muchos paquetes fragmentados, un valor muy bajo causarán que paquetes fragmentados legítimos sean desechados, un valor muy alto puede causar un uso excesivo de la memoria y del CPU para defragmentar los paquetes atacantes.

/proc/sys/net/ipv4/ipfrag_low_thresh

Similar a ip_frag_high_tresh, el tamaño mínimo de memoria que deseas permitir para el reensamblado de fragmentos.

/proc/sys/net/ipv4/ipfrag_time

El número de segundos que el kernel puede mantener los fragmentos IP antes de descartarlos. Treinta segundos es normalmente un buen tiempo. Increméntalo si los atacantes están falsificando fragmentos y quieres seguir siendo capaz de dar servicios a las conexiones legítimas.

/proc/sys/net/ip_always_defrag

Siempre defragmenta paquetes fragmentados antes de dejarlos pasar a través del Firewall. Linux 2.4 y posteriores no tienen esta opción, defragmentan por defecto.

/proc/sys/net/ipv4/tcp_max_orphans

El número de sockets locales que yo no están sujetos a un proceso. Estos sockets son usualmente resultado de conexiones fallidas, como el estado FIN-WAIT donde el punto remoto no tiene conocimiento de la caída de la conexión TCP. Después de que este límite es alcanzado, las conexiones huérfanas son removidas del kernel inmediatamente. Si tu Firewall es actuando como un filtro de paquetes estándar, esta variable no viene a juego, pero es útil en conexiones finales como servidores Web. Esta variables se fija en tiempo de arranque a un valor apropiado al tamaño de la memoria en el sistema.

/proc/sys/net/ipv4/icmp_ratelimit /proc/sys/net/ipv4/icmp_ratemask

Juntas, estas dos variables te permiten limitar qué tan frecuentemente paquetes ICMP son generados. Si incrementas el límite, puedes bajar o potencialmente confundir los escaneos de puertos, pero también puedes inhibir los indicadores de error legítimos de la red.

/proc/sys/net/ipv4/conf/*/log_martians

El kernel envía mensajes al syslog cuando recibe paquetes con direcciones ilegales.

/proc/sys/net/ipv4/neigh/*/locktime

Rechaza cambios en la dirección ARP si existe una entrada previa con varios jiffies de antiguedad. Si un atacante es un LAN utiliza envenenamiento de ARP para ejecutar ataques de hombre-en-medio, aumentando esta variable puede prevenir el trashing del cache ARP.

/proc/sys/net/ipv4/neigh/*/gc_stale_time

Qué tan seguido en segundos limpiar las viejas entradas ARP y hacer nuevas peticiones ARP. Valores bajos permitirán ajustar rápidamente una nueva migración de IP o un ataque de envenenamiento de ARP.

/proc/sys/net/ipv4/conf/*/proxy_arp

Contesta a las peticiones ARP si tienes una ruta al host en cuestión. Puede ser necesaria esta opción en algunos firewalls o VPN, pero generalmente es una mala idea en hosts.

/proc/sys/net/ipv4/tcp_syncookies

Un muy popular ataque de negación de servicio involucra a un cracker que envíe muchos (posiblemente falsificados) paquetes SYN a tu servidor, pero nunca completar el handshake de tres vías TCP. Esto rápidamente usa espacio en kernel, prohibiendo que conexiones legítimas puedan establecerse. Desde que una conexión no necesita completarse, no hay mucho requerimiento de recursos en la máquina atacante, por lo que es fácil de ejecutar y mantener.

Si la variable tcp_syncookies esta puesta entonces el kernel maneja los paquetes TCP SYN normalmente hasta que la cola esta llena, en este punto la función de cookies SYN entra.

Las cookies SYN no usan la cola SYN para nada. En lugar el kernel responderá a cualquier paquete SYN con un normal SYN|ACK, pero presentar un número de secuencia TCP especialmente hecho que codifica la dirección IP fuente y destino y el número de puerto y el tiempo en que el paquete fue enviado. Un atacante ejecutando una inundación SYN nunca tendrán este paquete si están haciendo spoofing, así que nunca responderán. Una conexión legítima intentará enviar el tercer paquete del handshake incluyendo este número de secuencia, y el servidor puede verificar que es en respuesta a una cookie SYN permitiendo la conexión, aún no habiendo espacio en la cola SYN.

Para más información acerca del funcionamiento de las cookies SYN ver http://cr.yp.to/syncookies.html


2.3. Preguntas de investigación

  • ¿Qué información nos provee el comando uname?

  • ¿Qué comandos nos proveen información sobre los módulos del kernel de Linux?

  • ¿Cuales son las diferencias entre el syslinux, lilo y grub?

  • Mencione algunos rootkits conocidos

  • Describa como un atacante puede hacer que un rootkit se active siempre que arranca la máquina

  • Describa lo que es un ataque de desbordamiento de pila.


Capítulo 3. Auditoría del Sistema

Una parte integral de cualquier sistema UNIX son sus facilidades de manejo de bitácoras. La mayoría del manejo de bitácoras esta provisto por dos programas principales: sysklogd y klogd. El primero provee de un sistema de bitácoras para los programas y las aplicaciones, mientras que el segundo provee del manejo de bitácoras para el kernel. Klogd actualmente envía la mayoría de los mensajes al syslogd, pero en ocasiones enviará mensajes a la consola (p.ej. pánicos del kernel). Sysklogd actualmente maneja las tareas de procesar la mayoría de los mensajes y enviarlos al archivo o dispositivo apropiado; esto se configura dentro del archivo /etc/syslog.conf. Por defecto la mayoría de los archivos de bitácora están situados en /var/log, y generalmente los programas con su sistemas de bitácora internos (los servidores httpd en su mayoría) guardan sus archivos de bitácora en /var/log/nombre-de-programa, lo que permite centralizar los archivos de bitácora y hace fácil ponerlos en una partición separada (algunos ataques pueden llenar tus logs muy rápido, y una partición llena no es nada bueno). Adicionalmente existen programas que manejas su propio intervalo de registro de bitácoras, uno de los más interesantes es el shell bash. Por defecto el bash guarda un archivo histórico de los comandos ejecutados en ~usuario/.bash_history, este archivo pude ser extremadamente interesante de leer, porque en muchas ocasiones muchos administradores escriben accidentalmente sus contraseñas en la línea de comandos. El Apache maneja todas sus bitácoras internamente, configurable desde httpd.conf. Sendmail maneja sus bitácoras a través del syslogd pero también tiene la opción de mandar a bitácora todas la transacciones SMTP directamente a un archivo.


3.1. Seguridad general en bitácoras

Generalmente no deseamos permitir a los usuarios ver los archivos de bitácoras de un servidor, y especialmente no queremos que sean capaces de modificarlos o borrarlos. Normalmente la mayoría de los archivos de bitácoras serán poseídos por el usuario y grupo root, y no tendrán permisos asignados para otros, así que en la mayoría de los casos el único usuario capaz de modificar los archivos de bitácoras será el usuario root.


3.2. Configuración del Syslog

SYSLOG es la principal herramienta de UNIX para llevar la bitácora de eventos. Con este sistema, puedes configurar el manejo de bitácoras a un nivel extremadamente alto de detalle y cada flujo de registros puede ir a un archivo diferente.

Una habilidad muy buscada y muy potente del syslog es su capacidad de enviar registros de bitácoras a computadoras remotas. Esto te permite centralizar las bitácoras en un solo servidor y fácilmente checar los archivos de bitácora por razones de violaciones de seguridad y otras cosas extrañas en toda tu red.

Sin embargo existen varios problemas con el syslogd y el klogd, la principal es que si un atacante logra acceso de root, podrá modificar los archivos de bitácoras y nadie lo notará.

Cada mensaje enviado al sistema de bitácoras tiene dos clasificadores: el servicio y el nivel. El servicio indica el tipo de programa que envió el mensaje y el nivel es el orden de importancia.

La lista de servicios disponibles en el syslogd es:

AUTH

Para mensajes de seguridad/autorización (obsoleto, ahora se utiliza AUTHPRIV)

AUTHPRIV

Mensaje de seguridad/autorización

CRON

Para los servicios de tareas programadas (cron y at)

DAEMON

Servicios del sistema sin un servicio especificado

FTP

Servicio de ftp

KERN

Mensajes del kernel

LOCAL0 a LOCAL7

Reservados para uso local del equipo

LPR

Subsistema de impresión

MAIL

Subsistema de correo electrónico

NEWS

Subsistema de USENET

SYSLOG

Mensajes generados internamente por el syslogd

USER

Mensajes genéricos a nivel de usuario

UUCP

Subsistema de UUCP

La lista de niveles disponibles para el syslogd es:

EMERGE

El sistema esta inservible

ALERT

Alguna acción debe ser tomada inmediatamente

CRIT

Condiciones críticas

ERR

Condiciones de error

WARNING

Condiciones de advertencia

NOTICE

Condición normal pero significativa

INFO

Mensaje informativo

DEBUG

Mensaje de depuración

Ejemplo 3-1. /etc/syslog.conf

$ cat /etc/syslog.conf 
kern.*             /var/log/kernel.log
*.emerg            /dev/console
*.info;mail.none   @syslog.bogus-domain

En el ejemplo anterior todo los registros de bitácoras producidos por el kernel serán escritos en el archivos /var/log/kernel.log, mientras que los mensajes con nivel de emerg, ya sean del kernel o de cualquier otro servicio, serán escritos en el dispositivo de consola. Finalmente todos los mensajes con nivel info, excepto aquellos generados por el servicio mail, serán reenviados a un servidor remoto.


3.3. Otros sistemas para Syslog

sysklogd y klogd no son los únicos sistemas para el seguimiento de bitácoras, existen otros, entre los cuales podemos nombrar:

  • modular syslog. Firma digitalmente los registros de bitácora para que cualquier alteración en ellos sea inmediatamente detectable.

  • next generation syslog. Permite el firmado digital y además puede clasificar los registros de otras maneras (como patrones en los registros) además del tipo de servicio y el nivel.

  • Nsyslogd. Añade soporte para SSL (Secure Socket Layer) en la transmisión de bitácoras a una computadora remota.


3.4. Monitoreo de Bitácoras

Es fácil ver la importancia del tratamiento de las bitácoras en un sistema seguro. Supon que un sistema esta configurado y un 99% seguro. Si la posibilidad del 1% de ataque ocurriera, y no existen medidas de seguridad para detectarlo y levantar alarmas, el sistema no esta seguro en lo absoluto.

Existen mucha información respecto al análisis de bitácoras, una buena fuente de información es Counterpane. En cualquier caso, aún las herramientas automáticas aún no superan a la mejor herramienta de análisis: tu cerebro.

Sin embargo, debido a la cantidad de información que se genera en la bitácoras, siempre es bueno adoptar algún sistema automático de monitoreo, que levante las alarmas necesarias para cuando algún evento extraño suceda.

El sistema operativo Debian utiliza LogCheck para realizar el análisis y monitoreo de bitácoras, RedHat emplea LogWatch, etc.


3.5. Preguntas de investigación

  • ¿Cómo configuraría un sistema de syslog para que los mensajes informativos del kernel vayan a un archivo /var/log/firewall.log?

  • ¿Cómo funciona el LogCheck?


Capítulo 4. Firewalls (Cortafuegos)

4.1. ¿Qué es un firewall?

Un firewall es un sistema o grupo de sistemas que impone una política de control de acceso entre dos redes de computadoras. La manera actual de cómo esto es logrado varía ampliamente, pero en principio, el firewall puede ser visualizado como un par de mecanismos: uno que bloquea el tráfico, y otro que permite el tráfico.

Es importante reconocer que un firewall implementa una política de acceso. Si no tenemos una buena idea de qué tipo de acceso permitiremos, un firewall realmente no nos será de utilidad.


4.2. ¿Qué es un Stateful Firewall?

Un stateful firewall es un firewall que provee de herramientas como el seguimiento y control del flujo de una sesión de datos dentro y fuera de la red. La información concerniente a cada conexión es almacenada en memoria. Cuando un paquete cruza el filtro, la decisión de desechar o enviar es realizada usando la información de conexión almacenada en memoria (p. ej. dirección del destino, número de puerto, información de la secuencia TCP y banderas adicionales).


4.2.1. Ventajas de un Stateful Firewall

En lugar de abrir puertos de red permanentemente para ciertos protocolos que solicitan puertos arbitrarios, este nuevo tipo de firewalls solo abrirán estos puertos durante el tiempo suficiente para que el paquete pase. Esto disminuye drásticamente la oportunidad de un cracker para introducir código destructivo a la red.

Además permite definir un límite de tasa de conexión para defenderse en contra de ataques de negación de servicio (DoS), tal como la inundación de paquetes SYN.

Para más información acerca de este tema vea Anatomía de un Stateful Firewall.


4.2.2. Stateless Firewall

Las primeras implementaciones de cortafuegos son considerados stateless, ya que, al contrario de los stateful, no llevan un seguimiento de las sesiones, por lo cual cada paquete se analiza con las reglas definidas. Esto hace más complicada su elaboración, ya que hay que tomar en cuenta todos los tipos de paquetes tanto entrantes como salientes. Generalmente son más rápidos y consumen menos recursos, sin embargo, con el poder de cómputo actual, esto ya no es una ventaja significativa, teniendo en cuenta de dificulta de configuración.


4.3. ¿Qué es netfilter/iptables?

El proyecto netfilter/iptables es el subsistema de firewalling de Linux 2.4.x/2.5.x. Ofrece la funcionalidad de filtrado de paquetes (ya sea stateless o stateful), todos los diferentes tipos de NAT (Network Address Translation), la manipulación de paquetes (modificar TOS -Type of Service- y encabezados) y también facilita el trabajo al subsistema de QoS (Quality of Service) de Linux.

netfilter es un conjunto de ganchos dentro de la pila de red del kernel Linux 2.4.x, que le permite a los módulos del kernel registrar funciones callback que se mandan llamar cada vez que un paquete atraviesa alguno de esos ganchos.

iptables es una estructura genérica tipo tabla para la definición de reglas de firewall. Cada regla dentro de una tabla IP consiste en un número de clasificadores y una acción asociada.

Para más información sobre netfilter/iptables refiera http://www.netfilter.org


4.3.1. Flujo de un paquete en iptables

El kernel comienza con tres listas de reglas en la tabla de filtrado; estas listas son llamadas cadenas de firewall o simplemente cadenas. Estas tres cadenas son INPUT, OUTPUT y FORWARD.

Incoming                 /     \         Outgoing
       -->[Routing ]--->|FORWARD|------->
          [Decision]     \_____/        ^
               |                        |
               v                       ____
              ___                     /    \
             /   \                  |OUTPUT|
            |INPUT|                  \____/
             \___/                      ^
               |                        |
                ----> Local Process ----

Los tres círculos representan las tres cadenas mencionadas. Cuando un paquete entra a un círculo en el diagrama, la cadena es examinada y decide el destino del paquete. Si la cadena dice que el paquete debe ir a DROP, el paquete ese muere ahí, pero si la cadena dice ACCEPT, el paquete continua recorriendo el diagrama.

Una cadena es una lista de reglas. Cada regla dice "si el encabezado del paquete se parece a esto, entonces aquí esta lo que se hace con el paquete". Si la regla no concuerda con el paquete, entonces la siguiente regla en la cadena es consultada. Finalmente, si no hay más reglas para consultar, el kernel aplica la política de la cadena para decidir. En un sistema consciente de la seguridad, la política usualmente dice al kernel que deseche el paquete.


4.4. Preguntas de investigación

  • ¿Cuál es la sintaxis del comando iptables?

  • Investigue el esquema de cortafuegos en el sistema operativo FreeBSD

  • ¿Qué hacen las siguientes instrucciones de iptables?

    # chain policies
    # set default policies
    /sbin/iptables -P INPUT DROP
    /sbin/iptables -P OUTPUT ACCEPT
    /sbin/iptables -P FORWARD DROP
     
    # flush tables
    /sbin/iptables -F
    /sbin/iptables -F INPUT
    /sbin/iptables -F OUTPUT
    /sbin/iptables -F FORWARD
    /sbin/iptables -F -t mangle
    /sbin/iptables -X
    /sbin/iptables -F -t nat
     
    # create DUMP table
    /sbin/iptables -N DUMP > /dev/null
    /sbin/iptables -F DUMP
    /sbin/iptables -A DUMP -p tcp -j REJECT --reject-with tcp-reset
    /sbin/iptables -A DUMP -p udp -j REJECT --reject-with icmp-port-unreachable
    /sbin/iptables -A DUMP -j DROP
     
    # Stateful table
    /sbin/iptables -N STATEFUL > /dev/null
    /sbin/iptables -F STATEFUL
    /sbin/iptables -I STATEFUL -m state --state ESTABLISHED,RELATED -j ACCEPT
    /sbin/iptables -A STATEFUL -m state --state NEW -i ! eth0 -j ACCEPT
    /sbin/iptables -A STATEFUL -j DUMP
     
    # loopback rules
    /sbin/iptables -A INPUT -i lo -j ACCEPT
    /sbin/iptables -A OUTPUT -o lo -j ACCEPT
     
    # drop reserved addresses incoming
    /sbin/iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DUMP
    /sbin/iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DUMP
    /sbin/iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DUMP
    /sbin/iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DUMP
     
    # allow certain inbound ICMP types
    /sbin/iptables -A INPUT -i eth0 -p icmp --icmp-type destination-unreachable -j ACCEPT
    /sbin/iptables -A INPUT -i eth0 -p icmp --icmp-type time-exceeded -j ACCEPT
    /sbin/iptables -A INPUT -i eth0 -p icmp --icmp-type echo-reply -j ACCEPT
     
    # opened ports
     
    # push everything else to state table
    /sbin/iptables -A INPUT -j STATEFUL

Bibliografía

Linux Administrator's Security Guide, Kurt Seifried.

Securing & Optimizing Linux: The Ultimate Solution, Gerhard Mourani.

Internet Firewalls: Frenquently Asked Questions.

Securing Debian Manual.

TrinityOS: A Guide to Configuring Your Linux Server for Performance, Security, and Manageability.

Notas

[1]

Un rootkit es una colección de herramientas que un atacante utiliza para enmascarar su intrusión. El intruso instala un rootkit en una computadora después de obtener acceso administrativo, ya sea explotando alguna vulnerabilidad conocida o rompiendo un contraseña. El rootkit entonces colecciona identificadores de usuario y contraseñas de otras máquinas en la red, obteniendo así acceso privilegiado.

Un rootkit puede consistir de utilerías que también monitoreen el tráfico y teclazos, crear un "puerta trasera" en el sistema, alterar bitácoras, atacar a otras máquinas en la red y alterar herramientas del sistema para burlar la detección.

[2]

Un checksum criptográfico es un valor matemático que es asignado a un archivo y usado para "probar" el archivo en una fecha posterior con el fin de verificar que la información contenida en el archivo no halla sido maliciosamente alterada. Un checksum criptográfico es creada ejecutando una complicada serie de operaciones matemáticas que traduce la información en el archivo en una cadena fija de dígitos llamada "hash", el cual es usado como un checksum.

[3]

Un buffer overflow ocurre cuando un programa o proceso intenta almacenar más información en un buffer (área de almacenamiento de datos temporal) de la que fue diseñada contener. Desde que los buffers son creados para contener una cantidad finita de datos, la información extra -la cual tiene que ir a algún lado- puede inundar buffers adyacentes, corrompiendo o sobreescribiendo datos válidos. En ataques de buffer overflow, los datos extras pueden contener códigos diseñados para disparar acciones específicas.

[4]

Genéricamente se designa spoofing a aquella técnica computacional destinada a enmascarar la verdadera identidad del origen del ataque. Existe email spoofing, donde se esconde el verdadero origen del correo; IP spoofing, donde un atacante gana acceso no autorizado a una computadora o a una red haciendo parecer que un mensaje malicioso viene de una máquina confiable haciendo "spoofing" de la dirección IP de esa máquina.

[5]

Es un tipo de spoofing. En este ataque una persona maliciosa intercepta una comunicación legítima entre dos personas. La computadora maliciosa entonces controla el flujo de la comunicación y puede eliminar o alterar la información enviada por uno de los participantes originales sin el conocimiento de ninguno de los emisores originales.