Gentoo Logo

Manual de Seguridad de Gentoo

Contenido:

A. Seguridad del sistema

1. Consideraciones previas a la instalación

1.a. Seguridad física

No importa cuantas medidas de seguridad implemente: todas pueden ser fácilmente traspasadas por un atacante que tenga acceso físico a su equipo. A pesar de ello, puede tomar algunas medidas que proporcionan un nivel de seguridad contra atacantes con acceso físico a su equipo. Ubicar el hardware en un armario cerrado para servidores previene contra alguien que sencillamente apague el equipo y se lo lleve. Cerrar con llave la caja del ordenador también es una buena idea para asegurarse que el atacante no se vaya con el disco duro bajo el brazo. Para prevenir que un atacante arranque desde otro disco, burlando fácilmente sus permisos y restricciones de acceso, configure en la BIOS el disco duro como primer dispositivo de arranque y ponga una contraseña de acceso a la BIOS. También es importante establecer una contraseña de aranque para LILO o GRUB, y así prevenir que usuarios maliciosos arranquen en modo monousuario y consigan acceso total al sistema. Esto está más detallado en el Capítulo 3, en Contraseña para GRUB y Contraseña para LILO.

1.b. Planificación de Demonios/Servicios

Empiece por documentar qué servicios deberá ejecutar este equipo. Esto le ayudará a definir mejor la estructura de particiones de su sistema, y le permitirá planificar mejor sus medidas de seguridad. Desde luego esto es innecesario si el equipo tiene un único y sencillo propósito, como un puesto de trabajo o un cortafuegos (firewall) dedicado. En todos estos casos no debería ejecutar ningún servicio salvo, quizás, sshd.

Esta lista puede servirle de ayuda al administrador del sistema. Manteniendo una lista puesta al día de versiones encontrará mucho más sencillo mantenerlo todo actualizado si alguien descubre una vulnerabilidad remota en alguno de sus servicios.

1.c. Esquema de particiones

Reglas para crear particiones:

  • Cualquier árbol de directorios en el que un usuario tenga permiso de escritura (por ejemplo /home, /tmp) debería estar en una partición separada y usar cuotas de disco. Esto reduce el riesgo de que un usuario llene por completo el sistema de ficheros. Portage usa /var/tmp para compilar ficheros por lo que esta partición debería ser lo suficientemente grande.
  • Cualquier árbol de directorios donde quiera instalar software que no forme parte de la distribución debería estar en una partición separada. Conforme a la Jerarquía estándar de ficheros estos directorios serían /opt o /usr/local. Si ambos están en particiones separadas no haría falta borrarlos si tiene que reinstalar el sistema.
  • Para mayor seguridad, los datos estáticos pueden ponerse en una partición separada y montada en modo de sólo lectura ("read-only"). El paranoico de verdad puede intentar almacenar los datos estáticos en un medio de sólo lectura, como un CD-ROM.

1.d. El usuario root

El usuario root es el usuario más importante del sistema y no debería usarse para nada más que lo estrictamente necesario. Si un atacante consigue acceso de root, reinstalar es la única forma de volver a confiar en su sistema.

Reglas de oro respecto a 'root'

  • Cree siempre un usuario para la gestión diaria y si este usuario necesita tener acceso de root, añádalo al grupo 'wheel'. Esto posibilita que un usuario normal pueda cambiar su ID a root usando el comando su.
  • Nunca ejecute X u otro software de aplicación como root, root debe usarse sólo cuando sea absolutamente necesario; si existe una vulnerabilidad en una aplicación ejecutándose como usuario, el atacante consigue el nivel de acceso del usuario. Pero si esta aplicación se ejecuta como root, el atacate consigue acceso de root.
  • Use siempre rutas absolutas cuando se conecte como root (o use siempre su -, que reemplaza las variables de entorno del usuario con las de root, estando seguro que el PATH de root sólo contiene directorios protegidos como /bin y /sbin). Es posible engañar a root para que ejecute una aplicación distinta de aquella que pretendía ejecutar. Si el PATH de root está protegido o root sólo usa rutas absolutas, podemos estar seguros de que esto no sucede.
  • Si un usuario sólo necesita ejecutar algunos comandos, en lugar de todo lo que root puede hacer normalmente, considere usar sudo en su lugar. Pero, al final, ¡tenga cuidado a quién le da este acceso!
  • Nunca se deje abierta una terminal donde esté identificado como root.

Gentoo tiene algunas protecciones por defecto para los usuarios normales que intentan hacer su a root. La configuración por defecto de PAM establece que un usuario debe pertenecer al grupo "wheel" para poder ser capaz de usar su.

1.e. Políticas de seguridad

Hay ciertas razones para diseñar un política de seguridad para su(s) sistema(s) y red.

  • Una buena política de seguridad le permite perfilar la seguridad como un "sistema", antes que simplemente como un revoltijo de distintas características. Por ejemplo, sin una política un administrador puede decidir desconectar el telnet, porque transmite las contraseñas sin cifrar, pero puede dejar el acceso FTP, que tiene el mismo problema. Una buena política de seguridad le permite identificar qué medidas de seguridad merecen la pena, y cuáles no.
  • Para diagnosticar problemas, realizar auditorías o localizar intrusos, puede ser necesario interceptar el tráfico de la red, inspeccionar el acceso de los usuarios y su historial de ejecución de comandos, y mirar en sus directorios locales. Sin especificar esto por escrito y sin advertirlo a los usuarios, tales acciones pueden ser actualmente ilegales, y ponerle a usted en un compromiso legal.
  • Uno de los escenarios más comunes en la seguridad del sistema son las cuentas de usuario secuestradas. Sin explicar a los usuarios por qué es importante la seguridad, y cómo practicar una buena seguridad (tal como no escribir las contraseñas en un "post-it" pegado en la mesa), es improbable que tenga alguna esperanza de tener cuentas de usuario seguras.
  • Una red bien documentada y un guión del sistema le ayudará, además de a los expertos forenses de las fuerzas de seguridad, si se necesitan, a seguir una intrusión y a identificar los puntos débiles después del problema. La "publicación" de un aviso de uso, donde se explique que su sistema es privado y que los accesos no autorizados no están permitidos, podrá también ayudarle a asegurarse la posibilidad para procesar correctamente a un intruso, una vez ha sido cogido.

La necesidad de una buena política de seguridad debería estar ahora más que clara.

La "política" o "directiva" por sí misma es un documento, o un conjunto de documentos, que perfilan las características de la red y los sistemas (como los servicios que proporcionan), el uso permitido y prohibido, los "buenos hábitos" de seguridad, y así sucesivamente. Todos los usuarios deben ser concienciados de su política de seguridad, además de mantenerlos al corriente de los cambios que se introduzcan. Es importante tomarse el tiempo necesario para ayudar a los usuarios a comprender la política y por qué las políticas deben ser firmadas, o qué sucedería si ellos actúan en contra de las mismas (lo que también debe recogerse en las políticas). Esto debería hacerse por lo menos una vez al año pues las políticas pueden cambiar (pero también como un simple recordatorio para el usuario).

Nota: Se deben crear políticas fáciles de leer y que sean muy precisas en cada apartado.

Una política de seguridad debería contener, al menos, los siguientes apartados:

  • Uso aceptable
    • Protectores de pantalla
    • Manejo de contraseñas
    • Descarga e instalación de software
    • Información sobre si los usuarios son monitorizados
    • Uso de programas antivirus
  • Manejo de información sensible (en cualquier formato, sea papel o sea electrónico)
    • Limpieza del escritorio y protección de la información confidencial
    • Apagado del PC antes de marcharse
    • Uso de cifrado
    • Manejo de claves para empleados de confianza
    • Tratamiento de los documentos confidenciales durante los viajes
  • Manejo de los equipos informáticos durante los viajes
    • Uso de los portátiles en los viajes y las estancias en los hoteles

Usuarios distintos pueden requerir distintos niveles o tipos de acceso, y como tal, su política puede variar para acomodarse a todos ellos.

Las políticas de seguridad pueden convertirse en algo enorme, y resultar ser información vital que puede fácilmente olvidarse. Las políticas para el equipo de TI pueden contener información confidencial para el usuario normal, por esto se pueden separar en políticas más pequeñas, como por ejemplo, Política de uso aceptable, Política de contraseñas, Política de correo electrónico y acceso remoto.

Puede encontrar ejemplos de políticas en The SANS Security Policy Project. Si tiene una red pequeña y las encuentra demasiado complejas para su realidad, puede mirar en Site Security Handbook.

2. Ajustando la seguridad

2.a. Parámetros USE

El archivo make.conf contiene los parámetros USE definidas por el usuario y /etc/make.profile/make.defaults los parámetros USE por defecto para Gentoo Linux. Para el propósito de esta guía, las opciones importantes son pam (Pluggable Authentication Modules), tcpd (TCP wrappers) y ssl (Secure Socket Layer). Esas tres aparecen en los parámetros USE por defecto.

2.b. Proteger GRUB con contraseña

Grub soporta dos formas diferentes para añadir una contraseña de acceso a su fichero de configuración. La primera usa texto en claro, mientras que la segunda utiliza cifrado md5+salt.

Listado de Código 2.1: /boot/grub/grub.conf

timeout 5
password cámbiame

Esto añadirá la contraseña cámbiame. Si no se teclea ninguna durante el arranque, GRUB usará simplemente la configuración de arranque por defecto.

Cuando añada una contraseña md5, necesita convertirla en un formato cifrado con el mismo formato que se usa en /etc/shadow. Para más información mire man crypt. La contraseña cifrada cámbiame, por ejemplo, se vería así $1$tDa3G0$ex6pzfebFmkeZrGRU1YWe0.

Puede cifrar su contraseña directamente en el shell de grub:

Listado de Código 2.2: md5crypt en el shell de grub

#/sbin/grub

GRUB  version 0.92  (640K lower / 3072K upper memory)

  [ Minimal BASH-like line editing is supported.  For the first word, TAB
    lists possible command completions.  Anywhere else TAB lists the possible
    completions of a device/filename. ]

grub> md5crypt

Password: ********
(Tecleado cámbiame en el prompt)
Encrypted: $1$tDa3G0$ex6pzfebFmkeZrGRU1YWe0

grub> quit

Entonces, corte y pegue la contraseña en /boot/grub/grub.conf.

Listado de Código 2.3: /boot/grub/grub.conf

timeout 5
password --md5 $1$tDa3G0$ex6pzfebFmkeZrGRU1YWe0

Los 5 segundos de espera resultan prácticos si se trata de un sistema remoto y debería poder reiniciarse sin interacción con el teclado. Puede encontrar más información a cerca de las contraseñas de GRUB ejecutando info grub.

2.c. Protegiendo LILO con contraseña

LILO también soporta dos formas de uso de contraseñas: global y por imagen, ambas en texto plano.

La contraseña global se establece en el inicio del fichero de configuración, y se aplica a cada imagen de arranque:

Listado de Código 3.1: /etc/lilo.conf

password=cámbiame
restricted
delay=3

La contraseña por imagen se establece de la siguiente forma:

Listado de Código 3.2: /etc/lilo.conf

image=/boot/bzImage
      read-only
      password=cámbiame
      restricted

Si la opción restricted no es introducida, LILO pedirá la contraseña cada vez.

Para poder almacenar la nueva información en lilo.conf debe ejecutar /sbin/lilo.

2.d. Restricción de uso de la consola

El fichero /etc/securetty le permite especificar desde qué dispositivos tty (terminales) tiene root permitido el inicio de sesión.

Le sugerimos que comente todas las líneas excepto vc/1 si está usando devfs y todas las líneas excepto tty1 si está usando udev. Esto le asegurará que root sólo puede hacer un login y sólo en un terminal.

Nota: Los usuarios del grupo "wheel" podrán continuar haciendo su - para convertirse en root en otras TTYs.

Listado de Código 4.1: /etc/securetty

(Para devfs)
vc/1
(Para udev)
tty1

3. Gestión de registro

3.a. Introducción

Puede conseguir un mayor nivel de detalle en sus registros de sistema para que indiquen un ataque en curso o ya realizado. Los atacantes normalmente escudriñan o investigan las redes antes de actuar.

Es también de vital importancia que sus ficheros de registro de sistema sean fácilmente legibles y manejables. Gentoo Linux le permite elegir durante la instalación entre tres tipos diferentes de gestores de registro.

3.b. Gestión de registro: Syslogd

Syslogd es el gestor de registro más común para Linux y Unix en general. Incorpora algunas utilidades de rotación de logs, pero usar /usr/sbin/logrotate en una tarea programada (logrotate se configura en /etc/logrotate.conf) puede que sea más potente, puesto que logrotate tiene más prestaciones. Cuan a menudo se debe ejecutar la rotación de los registros dependerá de la carga del sistema.

A continuación se encuentra el syslog.conf estándar con algunas características añadidas. Hemos "descomentado" las líneas cron y tty y añadido un gestor de registro remoto. Para mejorar la seguridad usted puede almacenar los registros en dos lugares.

Listado de Código 2.1: /etc/syslog.conf

#  /etc/syslog.conf     Configuration file for syslogd.
#
#                       For more information see syslog.conf(5)
#                       manpage.
#                       This is from Debian, we are using it for now
#                       Daniel Robbins, 5/15/99

#
# Primero algunos ficheros de registro estándar. Registre por servicio.
#

auth,authpriv.*                 /var/log/auth.log
*.*;auth,authpriv.none          -/var/log/syslog
cron.*                         /var/log/cron.log
daemon.*                        -/var/log/daemon.log
kern.*                          -/var/log/kern.log
lpr.*                           -/var/log/lpr.log
mail.*                          /var/log/mail.log
user.*                          -/var/log/user.log
uucp.*                          -/var/log/uucp.log
local6.debug                    /var/log/imapd.log

#
# Registro para el sistema de correo. Divídalo porque
# es fácil escribir guiones para manejar estos ficheros. 
#
mail.info                       -/var/log/mail.info
mail.warn                       -/var/log/mail.warn
mail.err                        /var/log/mail.err

# Registro para el servicio de news INN
#
news.crit                       /var/log/news/news.crit
news.err                        /var/log/news/news.err
news.notice                     -/var/log/news/news.notice

#
# Algunos fichero de registro para todo lo demás
#
*.=debug;\
        auth,authpriv.none;\
        news.none;mail.none     -/var/log/debug
*.=info;*.=notice;*.=warn;\
        auth,authpriv.none;\
        cron,daemon.none;\
        mail,news.none          -/var/log/messages

#
# Las emergencias y alertas son enviadas a todos los
# que han iniciado una sesión.
#
*.emerg                         *
*.=alert                        *

#
# Me gusta que los mensajes se muestren en la consola, pero sólo en una
# consola virtual que normalmente dejo disponible.
#
daemon,mail.*;\
       news.=crit;news.=err;news.=notice;\
       *.=debug;*.=info;\
       *.=notice;*.=warn       /dev/tty8

# Configurando un servidor para gestionar el registro remotamente
*.*                        @logserver

# La 'named pipe' /dev/xconsole es para la utilidad 'xconsole'. Para usarla,
# debe llamar 'xconsole' con la opción '-file':
# 
#    $ xconsole -file /dev/xconsole [...]
#
# NOTA: ajuste la siguiente lista, o podría volverse loco si tiene 
#       un sitio medianamente ocupado...
#
#daemon.*,mail.*;\
#       news.crit;news.err;news.notice;\
#       *.=debug;*.=info;\
#       *.=notice;*.=warn       |/dev/xconsole

local2.*                --/var/log/ppp.log

Los atacantes intentarán borrar sus huellas editando o borrando los ficheros de registro. Usted puede dificultarles la tarea enviando los registros a más de un servidor remoto en máquinas distintas. Encuentre más información sobre syslogd ejecutando man syslog.

3.c. Gestión de registro: Metalog

El Metalog de Frank Dennis no puede enviar los registros a un servidor remoto, pero tiene como ventajas su rendimiento y flexibilidad. Puede registrar por nombre de programa, urgencia, servicio (como syslogd) e incorpora concordancia con expresiones regulares con las que puede ejecutar guiones ("scripts") externos cuando son encontradas determinadas pautas. Es muy bueno realizando acciones cuando se necesitan.

La configuración estándar es normalmente suficiente. Si necesita notificar por correo electrónico cuando ocurre un fallo de contraseña puede utilizar uno de los siguientes guiones.

Para postfix:

Listado de Código 3.1: /usr/local/sbin/mail_pwd_failures.sh para postfix

#! /bin/sh
echo "$3" | mail -s "Warning (program : $2)" root

Para netqmail:

Listado de Código 3.2: /usr/local/sbin/mail_pwd_failures.sh para netqmail

#!/bin/sh
echo "To: root
Subject:Failure (Warning: $2) 
$3
" | /var/qmail/bin/qmail-inject -f root

Recuerde hacer ejecutable el script con /bin/chmod +x /usr/local/sbin/mail_pwd_failures.sh.

Entonces "descomente" la línea de comando debajo de "Password failures" en /etc/metalog/metalog.conf tal que:

Listado de Código 3.3: /etc/metalog/metalog.conf

command  = "/usr/local/sbin/mail_pwd_failures.sh"

3.d. Gestión de registro: Syslog-ng

Syslog-ng proporciona algunas de las mismas características que syslog y metalog con una pequeña diferencia. Puede filtrar mensajes basándose en nivel y contenido (como metalog), proporciona gestión de registro remoto como syslog, mantiene registros de syslogd (incluso descriptores de Solaris), los envía a una TTY, ejecuta programas y puede actuar como un servidor de registro. Básicamente tiene lo mejor de los otros dos gestores de registro combinado con una configuración avanzada.

Seguidamente un fichero de configuración típico ligeramente modificado:

Listado de Código 4.1: /etc/syslog-ng/syslog-ng.conf

options {
        chain_hostnames(no);

        # la acción predeterminada de syslog-ng es registrar 
        # una línea STATS al archivo cada 10 minutos. Eso se pone feo 
        # luego de un rato. Cámbielo a cada 12 horas para obtener una 
        # actualización diaria de los mensajes perdidos por syslog-ng 
        # (0).
        stats_freq(43200);
};

source src {
    unix-stream("/dev/log" max-connections(256));
    internal();
};

source kernsrc { file("/proc/kmsg"); };

# define los destinos
destination authlog { file("/var/log/auth.log"); };
destination syslog { file("/var/log/syslog"); };
destination cron { file("/var/log/cron.log"); };
destination daemon { file("/var/log/daemon.log"); };
destination kern { file("/var/log/kern.log"); };
destination lpr { file("/var/log/lpr.log"); };
destination user { file("/var/log/user.log"); };
destination mail { file("/var/log/mail.log"); };

destination mailinfo { file("/var/log/mail.info"); };
destination mailwarn { file("/var/log/mail.warn"); };
destination mailerr { file("/var/log/mail.err"); };

destination newscrit { file("/var/log/news/news.crit"); };
destination newserr { file("/var/log/news/news.err"); };
destination newsnotice { file("/var/log/news/news.notice"); };

destination debug { file("/var/log/debug"); };
destination messages { file("/var/log/messages"); };
destination console { usertty("root"); };

# los mensajes se registran en el tty12 ...
destination console_all { file("/dev/tty12"); };

# ... si tiene intención de usar /dev/console para programas 
# como like xconsole puede comentar el destino definido arriba que hace 
# referencia a /dev/tty12 y descomentar la siguiente línea.
#destination console_all { file("/dev/console"); };

# crea los filtros
filter f_authpriv { facility(auth, authpriv); };
filter f_syslog { not facility(authpriv, mail); };
filter f_cron { facility(cron); };
filter f_daemon { facility(daemon); };
filter f_kern { facility(kern); };
filter f_lpr { facility(lpr); };
filter f_mail { facility(mail); };
filter f_user { facility(user); };
filter f_debug { not facility(auth, authpriv, news, mail); };
filter f_messages { level(info..warn) 
	and not facility(auth, authpriv, mail, news); };
filter f_emergency { level(emerg); };

filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_crit { level(crit); };
filter f_err { level(err); };
filter f_failed { message("failed"); };
filter f_denied { message("denied"); };

# enlaza filtros con destinos
log { source(src); filter(f_authpriv); destination(authlog); };
log { source(src); filter(f_syslog); destination(syslog); };
log { source(src); filter(f_cron); destination(cron); };
log { source(src); filter(f_daemon); destination(daemon); };
log { source(kernsrc); filter(f_kern); destination(kern); };
log { source(src); filter(f_lpr); destination(lpr); };
log { source(src); filter(f_mail); destination(mail); };
log { source(src); filter(f_user); destination(user); };
log { source(src); filter(f_mail); filter(f_info); destination(mailinfo); };
log { source(src); filter(f_mail); filter(f_warn); destination(mailwarn); };
log { source(src); filter(f_mail); filter(f_err); destination(mailerr); };

log { source(src); filter(f_debug); destination(debug); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_emergency); destination(console); };

# registro predeterminado
log { source(src); destination(console_all); };

syslog-ng es muy sencillo de configurar, pero también es muy fácil olvidar algo en el archivo de configuración, ya que es extenso. El autor promete algunas características extra como cifrado, autentificación, compresión y control MAC (Mandatory Access Control). Con esas opciones se convertirá en el gestor de registro de red perfecto, ya que el atacante no podrá espiar en el registro.

Y syslog-ng tiene otras ventajas: ¡no necesita ejecutarse como root!

3.e. Análisis de registros con Logcheck

Desde luego, mantener los registros sólo es la mitad del trabajo. Un programa como Logcheck puede hacer mucho más fácil el análisis regular de los registros. Logcheck es un guión ("script"), acompañado de un binario llamado logtail, que se ejecuta desde el servicio de cron y comprueba los registros mediante una serie de reglas para detectar actividad sospechosa. Entonces, envía los resultados al buzón de correo de root.

Logcheck y logtail forman parte del paquete app-admin/logsentry.

Logcheck usa cuatro ficheros para separar las líneas del registro importantes de las que no lo son. Estos ficheros son logcheck.hacking, que contiene los mensajes conocidos de ataques de alteración (hacking), logcheck.violations, que contiene los patrones indicadores de compromisos de seguridad, logcheck.violations.ignore, con las palabras claves que probablemente emparejaría el fichero de compromisos de seguridad, pero que permiten que los registros normales sean ignorados, y logcheck.ignore, que casa todas aquellas entradas que deban ser ignoradas.

Aviso: No deje logcheck.violations.ignore vacío, Logcheck usa grep para analizar sintácticamente los registros, y algunas versiones del mismo asumen que un fichero vacío significa un comodín: Todos los compromisos de seguridad serían ignorados.

4. Montaje de particiones

4.a. Montaje de particiones

Al montar una partición ext2, ext3 o reiserfs se pueden aplicar algunas opciones en el fichero /etc/fstab. Las opciones son:

  • nosuid - Ignorará el bit SUID y actúa como si se tratase de un archivo ordinario
  • noexec - Deshabilitará la ejecución de ficheros en esta partición
  • nodev - Ignora dispositivos

Desafortunadamente, esas opciones pueden ser fácilmente burladas ejecutando una trayectoria indirecta. Sin embargo, estableciendo /tmp como noexec parará la mayoría de los intentos de explotación (exploits) diseñados para ser ejecutados directamente desde /tmp.

Listado de Código 1.1: /etc/fstab

/dev/sda1 /boot ext2 noauto,noatime 1 1
/dev/sda2 none swap sw 0 0
/dev/sda3 / reiserfs notail,noatime 0 0
/dev/sda4 /tmp reiserfs notail,noatime,nodev,nosuid,noexec 0 0
/dev/sda5 /var reiserfs notail,noatime,nodev 0 0
/dev/sda6 /home reiserfs notail,noatime,nodev,nosuid 0 0
/dev/cdroms /cdrom0 /mnt/cdrom iso9660 noauto,ro 0 0
proc /proc proc defaults 0 0

Aviso: Estableciendo /tmp en modo noexec puede hacer que ciertos guiones no ejecuten correctamente.

Nota: Referente a las cuotas de disco mire la sección Cuotas.

Nota: Yo no configuro /var en modo noexec o nosuid, incluso si nunca se ejecutan ficheros desde este punto de montaje. La razón de esto es que netqmail se instala en /var/qmail y debe tener permitido ejecutar y acceder a un fichero SUID. Yo establezco /usr en modo de sólo lectura ya que nunca escribo nada en él excepto cuando quiero actualizar Gentoo. Entonces vuelvo a montar el sistema de ficheros en modo de lectura-escritura, actualizo y lo vuelvo a montar nuevamente.

Nota: Incluso si no utiliza netqmail, Gentoo continua necesitando tener activado el bit de ejecución en /var/tmp ya que los ebuilds se construyen ahí. Pero se puede establecer una trayectoria alternativa si insiste en tener /var montado en modo noexec.

5. Limitaciones de usuario/grupo

5.a. /etc/security/limits.conf

El control de uso de recursos puede ser muy efectivo para prevenir denegaciones de servicio locales o limitar el máximo de entradas permitidas a un grupo o usuario. Sin embargo, una configuración demasiado estricta puede dificultar el comportamiento del sistema y causar fallos en los programas por lo que deberá asegurarse de comprobar primero cada configuración.

Listado de Código 1.1: /etc/security/limits.conf

*    soft core      0
*    hard core      0
*    hard nproc     15
*    hard rss       10000
*    -    maxlogins 2
@dev hard core      100000
@dev soft nproc     20
@dev hard nproc     35
@dev -    maxlogins 10

Si quiere establecer nproc o maxlogins a 0, quizás sea mejor borrar el usuario. En el ejemplo anterior se configura el grupo dev para procesos, fichero core y maxlogins. El resto se configura con el valor predeterminado.

Nota: /etc/security/limits.conf forma parte del paquete PAM y será solo aplicable a paquetes que utilicen PAM.

5.b. /etc/limits

/etc/limits es muy similar al fichero de limitaciones /etc/security/limits.conf. Las únicas diferencias son el formato y que solo trabaja con usuarios o comodines (no grupos). Echemos un vistazo a una configuración de ejemplo:

Listado de Código 2.1: /etc/limits

*   L2 C0 U15 R10000
kn L10 C100000 U35

Aquí establecemos la configuración por defecto y una configuración específica para el usuario kn. Limits forma parte del paquete sys-apps/shadow. No es necesario configurar ningún límite en este archivo si se ha habilitado pam en make.conf.

5.c. Cuotas

Importante: Asegúrese que los sistemas de ficheros con los que trabaja soportan cuotas. Las herramientas de usuario están disponibles en El proyecto Linux Cuota de Disco.

Establecer cuotas en un sistema de ficheros restringe el uso de disco en un esquema por usuario o por grupo. Las cuotas se habilitan en el núcleo y se añaden a un punto de montaje en /etc/fstab. La opción del núcleo se habilita en la configuración del núcleo en File systems->Quota support. Aplique la siguiente configuración, recompile el núcleo y reinicie usando el nuevo núcleo.

Empiece instalando cuotas con emerge quota. Entonces modifique el /etc/fstab y añada usrquota y grpquota a las particiones en las que quiera restringir el uso de disco, como en el ejemplo siguiente.

Listado de Código 3.1: /etc/fstab

/dev/sda1 /boot ext2 noauto,noatime 1 1
/dev/sda2 none swap sw 0 0
/dev/sda3 / reiserfs notail,noatime 0 0
/dev/sda4 /tmp ext3 noatime,nodev,nosuid,noexec,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv=1 0 0
/dev/sda5 /var ext3 noatime,nodev,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv1 0 0
/dev/sda6 /home ext3 noatime,nodev,nosuid,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv1 0 0
/dev/sda7 /usr reiserfs notail,noatime,nodev,ro    0 0
/dev/cdroms/cdrom0 /mnt/cdrom iso9660 noauto,ro 0 0
proc /proc proc defaults 0 0

En cada partición en la que haya establecido las cuotas, cree los ficheros de cuota (aquota.user y aquota.group) y guárdelos en la raíz de la partición.

Listado de Código 3.2: Crear los ficheros de cuota

# touch /tmp/aquota.user
# touch /tmp/aquota.group
# chmod 600 /tmp/aquota.user
# chmod 600 /tmp/aquota.group

Este paso debe hacerse en cada partición en la que se hayan activado las cuotas. Después de añadir y configurar los ficheros de cuota, necesitamos añadir el guión quota al nivel de ejecución boot.

Importante: XFS hace todas las comprobaciones de cuota internamente, y no es necesario que se añada el guión quota al nivel de ejecución boot. Puede haber otros sistemas de ficheros no listados en este documento con un comportamiento similar, así que es recomendable que lea las páginas de man de su sistema de ficheros para ver cómo maneja las comprobaciones de cutoa.

Listado de Código 3.3: Añadir cuotas al nivel de ejecución boot

# rc-update add quota boot

El núcleo Linux comprobará el uso de la cuota mientras el sistema está en funcionamiento. Si por cualquier razón los ficheros de cuota se corrompen o cree que los datos son incorrectos, necesitará iniciar el sistema en modo de un solo usuario (single-user) (o al menos, asegurarse de que no se está escribiendo activamente en los sistemas de ficheros) y llamar a continuación a quotacheck -avugm.

Después de reiniciar la máquina, es el momento para establecer las cuotas de usuarios y grupos. edquota -u kn ejecutará el editor definido en $EDITOR (por defecto es nano) y le permitirá editar la cuotas para el usuario kn. edquota -g hará lo mismo para los grupos.

Listado de Código 3.4: Configurar las cuotas para el usuario kn

Quotas for user kn:
/dev/sda4: blocks in use: 2594, limits (soft = 5000, hard = 6500)
 inodes in use: 356, limits (soft = 1000, hard = 1500)

Para más detalles lea man edquota o el Quota mini howto.

5.d. /etc/login.defs

Si las políticas de seguridad indican que los usuarios deben cambiar su contraseña cada dos semanas, cambie el valor PASS_MAX_DAYS a 14 y PASS_WARN_AGE a 7. Es recomendable que use la caducidad de contraseñas puesto que los ataques por fuerza bruta permiten encontrar cualquier contraseña, es solo cuestión de tiempo. También le alentamos a que establezca LOG_OK_LOGINS a sí.

5.e. /etc/security/access.conf

El fichero access.conf también pertenece al paquete sys-libs/pam, que proporciona una tabla de control de acceso por login. La tabla se usa para controlar quien puede y quien no puede acceder basándose en el nombre de usuario, nombre de grupo o nombre de host. Por defecto, todos los usuarios del sistema tienen permitido hacer login por lo que el fichero consiste solo en comentarios y ejemplos. Si está asegurando su servidor o estación de trabajo, le recomendamos que configure este fichero para que nadie más que el administrador del sistema tenga acceso a la consola.

Nota: Esta configuración aplica también al usuario root.

Listado de Código 5.1: /etc/security/access.conf

-:ALL EXCEPT wheel sync:console
-:wheel:ALL EXCEPT LOCAL .gentoo.org

Importante: Tenga cuidado cuando configure estas opciones, puesto que ciertos errores podrán impedirle acceder a la máquina si no tiene acceso de root.

Nota: Estas configuraciones no se aplican a SSH, puesto que SSH no ejecuta por defecto /bin/login. Pero se puede habilitar usando UseLogin yes en /etc/ssh/sshd_config.

Esto permitirá a los miembros del grupo wheel el acceso local o desde el dominio gentoo.org. Puede que sea paranoico, pero mejor prevenir que curar.

6. Permisos de ficheros

6.a. Lectura para todos

Los usuarios normales no deberían tener acceso a los archivos de configuración o contraseñas. Un atacante puede robar contraseñas de bases de datos o sitios web y usarlos para alterar --o incluso peor, borrar-- datos. Por esto es importante que los permisos de ficheros sean correctos. Si usted está seguro que un archivo sólo es usado por root, asígnele los permisos 0600 y asigne el usuario correcto al fichero con chown.

6.b. Escritura para todos/grupos

Listado de Código 2.1: Buscando ficheros y directorios con escritura para todos

# find / -type f \( -perm -2 -o -perm -20 \) -exec ls -lg {} \; 2>/dev/null >writable.txt
# find / -type d \( -perm -2 -o -perm -20 \) -exec ls -ldg {} \; 2>/dev/null >>writable.txt

Esto creará un fichero enorme con los permisos de todos los archivos que tienen tanto permiso de escritura para el grupo a para todos. Verifique los permisos y elimine los permisos de escritura para todos ejecutando /bin/chmod o-w en cada fichero.

6.c. Ficheros SUID/SGID

Los ficheros con el bit SUID o SGID habilitado se ejecutan con los privilegios del usuario o grupo propietario y no del usuario que ejecuta el archivo. Normalmente esos bits se usan en archivos que necesitan ejecutarse como root para hacer su labor. Esos archivos pueden provocar un compromiso de root (si contienen agujeros de seguridad). Los ficheros con el bit SUID o SGID activado resultan peligrosos y deberían ser evitados a toda costa. Si usted no usa estos ficheros utilice en ellos chmod 0 o desinstale (unmerge) el paquete de donde provienen (verifique a qué paquete pertenecen usando equery; si todavía no lo tiene instalado simplemente escriba emerge gentoolkit). En cualquier caso, basta desactivar el bit SUID con chmod -s.

Listado de Código 3.1: Buscando ficheros setuid

# find / -type f \( -perm -004000 -o -perm -002000 \) -exec ls -lg {} \; 2>/dev/null >suidfiles.txt

Esto creará un archivo conteniendo la lista de los ficheros SUID/SGID.

Listado de Código 3.2: Listado de los binarios setuid

/bin/su
/bin/ping
/bin/mount
/bin/umount
/var/qmail/bin/qmail-queue
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/crontab
/usr/bin/chage
/usr/bin/expiry
/usr/bin/sperl5.6.1
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/procmail
/usr/bin/suidperl
/usr/lib/misc/pt_chown
/usr/sbin/unix_chkpwd
/usr/sbin/traceroute
/usr/sbin/pwdb_chkpwd

Por defecto, Gentoo Linux no tiene muchos ficheros SUID (aunque depende de lo que haya instalado), pero usted debería obtener una lista similar a la anterior. Muchos de los comandos no deben ser utilizados por los usuarios normales, sólo por root. Desactive el bit SUID en ping, mount, umount, chfn, chsh, newgrp, suidperl, pt_chown y traceroute usando chmod -s en cada fichero. No desactive el bit en su, qmail-queue o unix_chkpwd. Desactivar setuid de estos ficheros le impedirá hacer 'su' y recibir correo. Desactivando el bit (donde es seguro hacerlo) usted elimina la posibilidad de que un usuario normal (o un atacante) consiga acceso de root a través de estos archivos.

Los únicos ficheros SUID que tengo en mi sistema són su, passwd, gpasswd, qmail-queue, unix_chkpwd y pwdb_chkpwd. Pero si usted está ejecutando X, necesita tener alguno más, puesto que X necesita el privilegiado acceso proporcionado por SUID.

6.d. Binarios SUID/SGID y enlaces rígidos

Sólo se considera borrado un fichero cuando no tiene más enlaces apuntándole. Esto podría sonar un poco raro, pero tenga en cuenta que un nombre de fichero como /usr/bin/perl es actualmente un enlace a el inodo donde los datos están almacenados. Cualquier número de enlaces puede apuntar al fichero, y sólo hasta el último de ellos no desaparezca, el fichero continua existiendo.

Si sus usuarios tienen acceso a una partición que no está montada con nosuid o noexec (por ejemplo, si /tmp, /home o /var/tmp no están en particiones separadas) debe tener cuidado asegurándose que sus usuarios no creen enlaces rígidos (hardlinks, en inglés) a binarios SUID o SGID, porque después que Portage los haya actualizado, los usuarios continuarían teniendo acceso a las versiones antiguas.

Aviso: Si ha recibido una advertencia de Portage acerca de que quedan enlaces rígidos, y sus usuarios pueden escribir en una partición que permita la ejecución de ficheros SUID/SGID, deberá leer esta sección cuidadosamente. Uno de sus usuarios podría intentar burlar una actualización manteniendo una versión antigua de un programa. Si sus usuarios no crean sus propios ficheros SUID, o sólo pueden ejecutar programas mediante el cargador dinámico (particiones montadas como noexec), no tiene por qué preocuparse.

Nota: Los usuarios no necesitan acceso de lectura a un fichero para enlazarlo, sólo necesitan permiso de lectura al directorio que lo contiene.

Para comprobar cuantos enlaces a ficheros tiene, puede usar el comando stat.

Listado de Código 4.1: Comando stat

$ stat /bin/su
  File: `/bin/su'
  Size: 29350           Blocks: 64         IO Block: 131072 regular file
Device: 900h/2304d      Inode: 2057419     Links: 1
Access: (4711/-rws--x--x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2005-02-07 01:59:35.000000000 +0000
Modify: 2004-11-04 01:46:17.000000000 +0000
Change: 2004-11-04 01:46:17.000000000 +0000

Para encontrar los ficheros SUID y SGID con múltiples enlaces, puede usar find.

Listado de Código 4.2: Buscar binarios suid/sgid multi-enlazados

$ find / -type f \( -perm -004000 -o -perm -002000 \) -links +1 -ls

7. PAM (Pluggable Authentication Modules)

7.a. PAM (Pluggable Authentication Modules)

PAM, o Módulos de Autentificación Enlazables, es un conjunto de librerías compartidas que proporcionan una forma alternativa para la autentificación de usuarios en los programas. El parámetro USE pam está activado por defecto. Los parámetros de PAM en Gentoo Linux son bastante razonables, pero siempre se puede mejorar. Primero instale cracklib.

Listado de Código 1.1: Instalación de cracklib

# emerge cracklib

Listado de Código 1.2: /etc/pam.d/passwd

auth     required pam_unix.so shadow nullok
account  required pam_unix.so
password required pam_cracklib.so difok=3 retry=3 minlen=8 dcredit=-2 ocredit=-2
password required pam_unix.so md5 use_authtok
session  required pam_unix.so

Lo que añadirá cracklib y obligará a los usuarios a que utilicen una contraseña con un mínimo de 8 caracteres y que contenga como mínimo 2 números, 2 caracteres de otro tipo y que hayan al menos 3 caracteres distintos respecto a la última contraseña. Lo que fuerza al usuario a elegir una buena contraseña (directriz de contraseñas). Revise la documentación de PAM para más opciones.

Listado de Código 1.3: /etc/pam.d/sshd

auth     required pam_unix.so nullok
auth     required pam_shells.so
auth     required pam_nologin.so
auth     required pam_env.so
account  required pam_unix.so
password required pam_cracklib.so difok=3 retry=3 minlen=8 dcredit=-2 ocredit=-2 use_authtok
password required pam_unix.so shadow md5
session  required pam_unix.so
session  required pam_limits.so

Cada servicio no configurado con un fichero PAM en /etc/pam.d utilizará las reglas de /etc/pam.d/other. Los parámetros por defecto se establecen a deny, como debería ser. Pero me gusta tener muchos logs y esto es por lo que he añadido pam_warn.so. La última configuración es pam_limits que está controlada por /etc/security/limits.conf. Mire la sección /etc/security/limits.conf para más detalles acerca de estas opciones.

Listado de Código 1.4: /etc/pam.d/other

auth     required pam_deny.so
auth     required pam_warn.so
account  required pam_deny.so
account  required pam_warn.so
password required pam_deny.so
password required pam_warn.so
session  required pam_deny.so
session  required pam_warn.so

8. TCP Wrappers

8.a. TCP Wrappers

Esta es una forma de controlar el acceso a los servicios normalmente ejecutados por inetd (del que Gentoo no dispone) pero que también puede ser usado por xinetd y otros servicios.

Nota: El servicio debería ejecutar tcpd en su argumento de servidor (en xinetd). Vea el capítulo de xinetd para más información.

Listado de Código 1.1: /etc/hosts.deny

ALL:PARANOID

Listado de Código 1.2: /etc/hosts.allow

ALL: LOCAL @wheel
time: LOCAL, .gentoo.org

Como puede ver el formato es muy similar al de /etc/security/access.conf. Tcpd soporta un servicio específico; no se solapa con /etc/security/access.conf. Estas configuraciones sólo aplican a los servicios que utilizan tcp wrappers.

También es posible ejecutar comandos cuando se accede a un servicio (puede ser usado cuando se activa el reenvío de llamadas entrantes de usuarios) pero no se recomienda, puesto que se tiende a crear más problemas de los que está tratando de resolver. Un ejemplo podría ser cuando configura un guión ("script") para enviar un mensaje cada vez que alguien entre en un regla de denegación (deny rule), entonces un atacante puede lanzar un ataque de denegación de servicio (DoS) que busque activar dicha regla de denegación. Esto creará un montón de I/O y mensajes. Por tanto ¡no lo haga! Lea man 5 hosts_access para más información.

9. Seguridad del Kernel

9.a. Eliminar funcionalidad

La regla básica cuando se configura el núcleo es eliminar todo lo que no se necesite. Esto no creará solo un núcleo pequeño sino también eliminará las vulnerabilidades que puedan encontrarse en controladores y otras características.

Considere también desactivar el soporte para módulos cargables. Aunque incluso es posible añadir "root kits" sin esta característica activada, se hace más difícil para los atacantes normales instalar "root kits" sin poder hacerlo a través de módulos del núcleo.

9.b. El sistema de ficheros proc

Muchos de los parámetros del núcleo pueden cambiarse a través del sistema de ficheros /proc o usando sysctl.

Para cambiar dinámicamente parámetros y variables del núcleo al vuelo necesita tener definido CONFIG_SYSCTL en el núcleo. Lo que está activado por defecto en un núcleo 2.4 estándar.

Listado de Código 2.1: Desactivar IP forwarding

# /bin/echo "0" > /proc/sys/net/ipv4/ip_forward

Asegúrese que IP forwarding está desactivado. Solo lo queremos en un equipo que tenga más de una conexión de red ("multi-homed host"). Le advertimos que active o desactive este parámetro antes que cualquier otro, puesto que también activa/desactiva otros parámetros.

Listado de Código 2.2: Descartar los paquetes de ping

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all

Esto hará que el núcleo simplemente ignore todos los mensajes de ping (también conocidos como mensajes ICMP tipo 0). La razón para hacer esto está en que el paquete IP que lleva el mensaje ICMP puede contener información distinta de la que debería. Los administradores usan ping como una herramienta de diagnóstico y frecuentemente se quejan si se deshabilita, pero no hay ninguna razón para que alguien desde fuera pueda mandar un ping. Sin embargo, a veces puede ser práctico que desde dentro sí se puedan hacer pings, entonces lo que puede hacer es deshabilitar el ICMP tipo 0 en el cortafuegos (permitiendo continuar utilizando esta herramienta a los administradores locales).

Listado de Código 2.3: Ignorar pings de broadcast

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

Esto deshabilita la respuesta a "broadcasts" ICMP y prevendrá de ataques "Smurf". El ataque Smurf consiste en enviar un ICMP tipo 0 (ping) a la dirección de broadcast de una red. Por regla general el atacante usará una dirección de origen falseada ("spoofed"). Todos los ordenadores de la red responderán al mensaje de ping y de ese modo inundarán al host cuya dirección se ha falsificado.

Listado de Código 2.4: Deshabilitar paquetes enrutados desde el origen

# /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route

No acepte paquetes enrutados desde el origen. Los atacantes pueden usar enrutamiento desde el origen para generar tráfico que pretende ser originado dentro de su red, pero que es actualmente enrutando hacia el origen por el camino por el que ha venido, de esta forma los atacantes pueden comprometer su red. El enrutamiento desde el origen es raramente utilizado para fines legítimos, por ello es seguro desactivarlo.

Listado de Código 2.5: Deshabilitar la aceptación de redirección

# /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects

No acepte paquetes de redirección ICMP. La redirección ICMP puede ser usada para alterar sus tablas de enrutamiento, posiblemente con una una mala finalidad.

Listado de Código 2.6: Protección contra mensajes de error falsos

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

Habilite la protección contra respuestas de mensajes de error falsos.

Listado de Código 2.7: Activar el filtrado inverso de paths

# for i in /proc/sys/net/ipv4/conf/*; do
         /bin/echo "1" > $i/rp_filter
done

Active el filtrado inverso para trayectorias. Esto ayuda a estar seguros que los paquetes usan una dirección de origen legítima rechazando automáticamente los paquetes entrantes si la entrada correspondiente a la dirección origen en la tabla de enrutamiento no coincide con la interfaz de red por la que llegan. Lo cual tiene ventajas de seguridad porque previene el falseamiento de IP ("IP spoofing"). Necesitamos activarlo en cada net/ipv4/conf/*, puesto que en caso contrario la validación del origen no es totalmente funcional.

Aviso: No obstante, activar el filtrado inverso de rutas puede ser un problema si se utiliza el enrutamiento asimétrico (los paquetes que se envía a un host toman un camino diferente que los paquetes que se envían a ese host) o si opera en un host que no enruta y que tiene varias direcciones IP en distintas interfaces.

Listado de Código 2.8: Registre todos los paquetes falsificados (spoofed), enrutados en el origen y paquetes de redirección

# /bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians

Registre todos los paquetes falsificados (spoofed), enrutados en el origen y paquetes de redirección.

Todos estos ajustes se perderán cuando la máquina se reinicie. Le sugiero que los añada a /etc/sysctl.conf el cual es automáticamente inicializado por el guión de inicio /etc/init.d/bootmisc.

La sintaxis para /etc/sysctl.conf es bastante simple. Elimine el /proc/sys/ de los paths anteriormente mencionados y sustituya / por .:

Listado de Código 2.9: Trasladar sysctl.conf

  (Uso manual de echo):
/bin/echo "0" > /proc/sys/net/ipv4/ip_forward

(Automático en sysctl.conf:)
net.ipv4.ip_forward = 0

9.c. Grsecurity

El parche de Grsecurity es un estándar en las fuentes del núcleo sys-kernel/hardened-sources pero está deshabilitado por defecto. Configure su núcleo como lo hace normalmente y luego configure las opciones de Grsecurity. Una explicación en profundidad de las opciones disponibles en Grsecurity (versión 1.9) está disponible en la página del proyecto Gentoo Hardened.

Las recientes hardened-sources proporcionan la versión 2.* de Grsecurity. Para más información de este parche de Grsecurity mejorado, por favor consulte la documentación disponible en Grsecurity home page.

9.d. Otros parches para el núcleo

Y probablemente haya bastantes más.

10. Asegurando los servicios

10.a. Apache

Apache viene con un más que decente fichero de configuración pero todavía necesitamos mejorar algunas cosas, como enlazar Apache a una dirección y prevenir fugas de información. A continuación se describen las opciones que debería aplicar en el fichero de configuración:

Si usted no deshabilita ssl en su /etc/make.conf antes de instalar Apache, debería tener habilitado el acceso al servidor mediante ssl. Dentro de /etc/apache2/vhosts.d podemos encontrar archivos con ejemplos de configuración. Estos son ejemplos funcionales y es mejor verificarlos o deshabilitarlos.

Es importante definir en el archivo de configuració que se escuche a una dirección IP en particular (en vez de todas las direcciones IP de su sistema). Por ejemplo, en el archivo 00_default_vhost.conf:

Listado de Código 1.1: /etc/apache2/vhosts.d/00_default_vhost.conf

# Make it listen on your ip
Listen 127.0.0.1

También recomendamos que deshabilite el despliegue de información sobre la instalación Apache al resto del mundo. Por defecto, la configuración agregará la versión del servidor y nombre del anfitrión virtual a las páginas generadas por el servidor. Para desactivar esta característica, cambie la variable ServerSignature a Off:

Listado de Código 1.2: /etc/apache2/modules.d/00_default_settings.conf

ServerSignature Off

Apache está compilado con --enable-shared=max y --enable-module=all. Esto activará por defecto todos los módulos, así que puede "comentar" todos los módulos en la sección LoadModule (LoadModule y AddModule) que no use en el archivo principal de configuración /etc/apache2/httpd.conf. Reinicie el servicio ejecutando /etc/init.d/apache restart.

Puede encontrar más información en http://www.apache.org.

10.b. Bind

Puede encontrar información en Internet Software Consortium. El Manual de referencia del administrador en BIND 9 lo puede encontrar también en doc/arm.

Los nuevos "ebuilds" de BIND soportan el chrooting fuera del entorno. Después de instalar (emerge) bind siga estos sencillos pasos:

Listado de Código 2.1: Chrooting BIND

# emerge --config bind
(Antes de ejecutar el comando anterior debe tratar de cambiar)
(el directorio de chroot en /etc/conf.d/named.)
(En caso contrario será usado /chroot/dns.)

10.c. Djbdns

Djbdns es una implementación de DNS en cuya seguridad su autor está dispuesto a apostar dinero. Trabaja de forma muy diferente a Bind 9 pero vale la pena probarlo. Puede obtener más información en http://www.djbdns.org.

10.d. FTP

Generalmente, usar FTP (File Transfer Protocol) es una mala idea. Porque no cifra los datos (por ejemplo, las contraseñas circulan en texto claro), escucha en dos puertos (normalmente el 20 y el 21), y los atacantes buscan frecuentemente accesos anónimos para intercambiar warez. Puesto que protocolo FTP tiene varios problemas de seguridad, debería utilizar en su lugar sftp o HTTP . Si no lo hace, asegure tan bien como pueda sus servicios y prepárese.

10.e. Mysql

Si sólo necesita que las aplicaciones locales accedan a la base de datos mysql "descomente" la siguiente línea en /etc/mysql/my.cnf.

Listado de Código 5.1: Deshabilitar el acceso de red

skip-networking

Luego, deshabilitemos el uso del comando LOAD DATA LOCAL INFILE.Lo que nos prevendrá contra la lectura no autorizada de ficheros locales. Esto toma relevancia cuando se encuentran nuevas vulnerabilidades de Inyección SQL en PHP.

Listado de Código 5.2: Deshabilitar LOAD DATA LOCAL INFILE en la sección [mysqld]

set-variable=local-infile=0

A continuación, vamos a borrar la base de datos de ejemplo (test) y todas las cuentas excepto la cuenta local de root.

Listado de Código 5.3: Borrar la base de datos de ejemplo y todos los usuarios innecesarios

mysql> drop database test;
mysql> use mysql;
mysql> delete from db;
mysql> delete from user where not (host="localhost" and user="root");
mysql> flush privileges;

Aviso: Tenga cuidado con lo anterior si usted previamente ya ha configurado cuentas de usuario.

Nota: Si ha cambiado las contraseñas desde la línea de introducción de comandos de MySQL deberá borrar siempre ~/.mysql_history y /var/log/mysql/mysql.log puesto que almacenan los comandos SQL ejecutados con las contraseñas en texto claro.

10.f. Proftpd

Proftpd ha tenido bastantes problemas de seguridad, pero parece que se han resuelto muchos de ellos. Aún así, es buena idea aplicar algunas mejoras:

Listado de Código 6.1: /etc/proftpd/proftpd.conf

ServerName "My ftp daemon"
# No muestre la identidad del servidor
ServerIdent on "Go away"

# Hace más fácil crear usuarios virtuales
RequireValidShell off

# Use unos ficheros de contraseñas y grupos alternativos (passwd usa cifrado)
AuthUserFile "/etc/proftpd/passwd"
AuthGroupFile "/etc/proftpd/group"

# Permisos
Umask 077

# Timeouts y limitaciones
MaxInstances 30
MaxClients 10 "Only 10 connections allowed"
MaxClientsPerHost 1 "You have already logged on once"
MaxClientsPerUser 1 "You have already logged on once"
TimeoutStalled 10
TimeoutNoTransfer 20
TimeoutLogin 20

# Chroot todo el mundo
DefaultRoot ~

# No lo ejecute como root
User  nobody
Group nogroup

# Registre cada transacción
TransferLog /var/log/transferlog

# Problemas con globbing
DenyFilter \*.*/

Puede encontrar más documentación en http://www.proftpd.org.

10.g. Pure-ftpd

Pure-ftpd es una variante del trollftpd original, modificado por Frank Dennis por razones de seguridad y funcionalidad.

Utilice usuarios virtuales (nunca cuentas del sistema) habilitando la opción AUTH. Configure esto con -lpuredb:/etc/pureftpd.pdb y cree sus usuarios mediante /usr/bin/pure-pw.

Listado de Código 7.1: /etc/conf.d/pure-ftpd

AUTH="-lpuredb:/etc/pureftpd.pdb"

## Misc. Others ##
MISC_OTHER="-A -E -X -U 177:077 -d -4 -L100:5 -I 15"

Configure la opción MISC_OTHER para no permitir accesos anónimos (-E), hacer chroot para todos (-A), para que los usuarios no puedan leer o escribir en los archivos que empiezan por . (punto) (-X), el tiempo máximo 'idle' (-I), el límite de recursión (-L), y una razonable umask.

Aviso: ¡No use las opciones -w or -W! Si usted quiere tener un sitio de warez, ¡no lea más esta guía!

Puede encontrar más documentación en http://www.pureftpd.org.

10.h. Vsftpd

Vsftpd (siglas de "very secure ftp", ftp realmente seguro) es un pequeño demonio ftp que se ejecuta con una razonable configuración por defecto. Es sencillo y no tiene algunas de las características de pureftp o proftp.

Listado de Código 8.1: /etc/vsftpd

anonymous_enable=NO
local_enable=YES

#sólo escritura
write_enable=NO

#permite el registro de transacciones
xferlog_std_format=YES

idle_session_timeout=20
data_connection_timeout=20
nopriv_user=nobody

chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chrootlist

ls_recurse_enable=NO

Como puede ver, no hay forma en este servicio de tener permisos individuales, pero cuando se prepara con una configuración anónima es bastante bueno. Algunas veces es bueno tener un ftp anónimo (para compartir programas de código abierto) y entonces vsftpd hace muy buen papel.

10.i. Netqmail

Netqmail está frecuentemente considerado como un servidor de correo muy seguro. Está escrito pensando en la seguridad (y en la paranoia). Por defecto no permite el reenvío y no ha tenido un sólo agujero de seguridad desde 1996. ¡Simplemente instálelo con emerge netqmail y configúrelo!

10.j. Samba

Samba es un protocolo para compartir ficheros con redes Microsoft y Novell y no debería usarse a través de Internet. Aún así, continua necesitando ser asegurado.

Listado de Código 10.1: /etc/samba/smb.conf

[global]
  #Enlace a una interface
  interfaces = eth0 10.0.0.1/32

  #Indica el uso de contraseñas cifradas
  encrypt passwords = yes
  directory security mask = 0700

  #Permite el tráfico desde 10.0.0.*
  hosts allow = 10.0.0.

  #Habilita el modo de autentificación por usuario
  #(no use el modo compartido)
  security = user

  #Deshabilita las cuentas con privilegios
  invalid users = root @wheel

  #Tamaño máximo que smb muestra para un recurso compartido
  #(no es un límite)
  max disk size = 102400

  #Política de contraseñas
  min password length = 8
  null passwords = no

  #Uso de PAM (si se ha añadido su soporte)
  obey pam restrictions = yes
  pam password change = yes

Asegúrese que los permisos están correctamente establecidos en cada recurso compartido y recuerde leer la documentación.

Ahora reinicie el servidor y añada los usuarios que deban tener acceso a este servicio. Esto se hace mediante el comando /usr/bin/smbpasswd con el parámetro -a.

10.k. ssh

La única seguridad que OpenSSH necesita es habilitar la autentificación fuerte basada en cifrado de clave pública. Demasiados sitios (como http://www.sourceforge.net, http://www.php.net yhttp://www.apache.org) han sufrido accesos no autorizados debidos a filtraciones de contraseñas o a malas contraseñas.

Listado de Código 11.1: /etc/ssh/sshd_config

#Sólo habilitar la versión 2
Protocol 2

#No permitir el acceso directo a root
PermitRootLogin no

#Habilitar la autentificación de clave pública
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys

#Deshabilitar los ficheros .rhost y la autentificación normal con contraseña
HostbasedAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no

#Sólo los usuarios en los grupos wheel o admin pueden obtener acceso
AllowGroups wheel admin

#En dichos grupos sólo permite el acceso de los siguienes usuarios
#El @<nombre_de_dominio> es opcional, pero reemplaza la
#anterior directiva AllowHosts
AllowUsers kn@gentoo.org bs@gentoo.org

#Añadir registro de actividad
SyslogFacility AUTH
LogLevel INFO

(Cambie esto con su dirección)
ListenAddress 127.0.0.1

Verifique también que no tiene UsePAM yes en su fichero de configuración porque sobreescribe el mecanismo de autentificación de clave pública, o sino desactive PasswordAuthentication o ChallengeResponseAuthentication. Más información acerca de estas opciones puede encontrarse en la página man de sshd_config.

Ahora todo lo que sus usuarios tienen que hacer es crear una clave (en el ordenador desde el que se van a conectar) usando el comando siguiente:

Listado de Código 11.2: Crea un par de claves DSA

# /usr/bin/ssh-keygen -t dsa

Y teclear una contraseña-frase (passphrase).

Listado de Código 11.3: Salida de ssh-keygen

Generating public/private dsa key pair.
Enter file in which to save the key (/home/kn/.ssh/id_dsa):[Pulse enter]
Created directory '/home/kn/.ssh'.
Enter passphrase (empty for no passphrase): [Escriba la frase de paso]
Enter same passphrase again: [Vuelva a escribir la frase de paso]
Your identification has been saved in /home/kn/.ssh/id_dsa.
Your public key has been saved in /home/kn/.ssh/id_dsa.pub.
The key fingerprint is:
07:24:a9:12:7f:83:7e:af:b8:1f:89:a3:48:29:e2:a4 kn@knielsen

Esto añadirá dos archivos a su directorio ~/.ssh/, llamados id_dsa y id_dsa.pub. El archivo id_dsa es su clave privada y debe ser accesible sólo por usted. El otro fichero id_dsa.pub debe ser distribuido en cada servidor al cual tenga acceso. Añada la clave en el directorio home del usuario en ~/.ssh/authorized_keys y el usuario debería ser capaz de hacer login:

Listado de Código 11.4: Añadir el fichero id_dsa.pub al fichero authorized_keys

$ scp id_dsa.pub other-host:/var/tmp/currenthostname.pub
$ ssh other-host
password:
$ cat /var/tmp/currenthostname.pub >> ~/.ssh/authorized_keys
 

Ahora, sus usuarios deberían salvaguardar su clave privada convenientemente. Poniéndola en un dispositivo que ellos lleven siempre encima o dejarla en su estación de trabajo (añada esto a las políticas de Contraseñas).

Para más información visite la página web de OpenSSH.

10.l. Uso de xinetd

xinetd es un sustituto de inetd (del cual no dispone Gentoo), el demonio de servicios de Internet. Soporta control de acceso basado en la dirección del host remoto y el tiempo de acceso. También proporciona extensas posibilidades de log, incluyendo una hora de arranque del servidor, dirección de host remoto, nombre de usuario remoto, tiempo de ejecución del servidor, y acciones solicitadas.

Como en todos los demás servicios es importante tener una buena configuración por defecto. Pero desde el momento que xinetd se ejecuta como root y soporta protocolos que puede que usted no conozca como funcionan, le recomendamos que no lo utilice. Pero si a pesar de todo lo quiere utilizar, aquí le explicamos como puede añadirle algo de seguridad:

Listado de Código 12.1: Instale xinetd

# emerge xinetd tcp-wrappers

Y edite el fichero de configuración:

Listado de Código 12.2: /etc/xinetd.conf

defaults
{
 only_from      = localhost
 instances      = 10
 log_type       = SYSLOG authpriv info
 log_on_success = HOST PID
 log_on_failure = HOST
 cps    = 25 30
}

# Esto configurará pserver (cvs) via xinetd con los siguientes parámetros:
# un máximo de 10 instancias (10 conexiones simultáneas)
# limita pserver a conexiones tcp solamente
# utiliza el usuario cvs para ejecutar este servicio
# enlaza una sola dirección IP en las interfaces de red
# permite el acceso desde 10.0.0.*
# limita el tiempo que los desarrolladores pueden usar cvs: desde 8am a 5pm
# usa tcpd wrappers (control de acceso especificado en
# /etc/hosts.allow y /etc/hosts.deny)
# la carga máxima del sistema se establece a 1.0
# el disable flag está a no por defecto, pero preferimos tenerlo
# en caso de querer desactivarlo
service cvspserver
{
 socket_type    = stream
 protocol       = tcp
 instances      = 10
 protocol       = tcp
 wait           = no
 user           = cvs
 bind           = 10.0.0.2
 only_from      = 10.0.0.0
 access_times   = 8:00-17:00
 server         = /usr/sbin/tcpd
 server_args    = /usr/bin/cvs --allow-root=/mnt/cvsdisk/cvsroot pserver
 max_load       = 1.0
 log_on_failure += RECORD
 disable        = no
}

Para más información consulte man 5 xinetd.conf.

10.m. X

Por defecto Xorg está configurado para actuar como un servidor X. Esto puede resultar peligroso puesto que X usa conexiones TCP no cifradas y está a la escucha para clientes X.

Importante: Si usted no necesita este servicio, ¡deshabilítelo!

Pero si piensa usar su estación de trabajo como servidor X use el comando /usr/X11R6/bin/xhost con precaución. Este comando permite a clientes desde otros hosts conectarse y usar su pantalla. Lo que puede ser práctico si usted necesita una aplicación X de un equipo diferente y la única manera de utilizarla es a través de la red, pero lo que también puede permitir ser aprovechado por un atacante. La sintaxis es /usr/X11R6/bin/xhost +nombre_de_host

Aviso: ¡No use nunca la opción xhost +! Esto permitirá a cualquier cliente conectarse y tomar el control de sus X. Si un atacante puede tener acceso a sus X, puede registrar lo que teclee y tomar el control de su escritorio. Recuerde especificar siempre un host si usted debe utilizarlo.

Un solución más segura es deshabilitar completamente esta característica arrancando X con startx -- -nolisten tcp o deshabilitándola permanentemente en la configuración.

Listado de Código 13.1: /usr/X11R6/bin/startx

defaultserverargs="-nolisten tcp"

Para asegurarse de que startx no será sobreescrito al 'emerger' una nueva versión de Xorg debe protegerlo. Añada la siguiente línea a /etc/make.conf:

Listado de Código 13.2: /etc/make.conf

CONFIG_PROTECT_MASK="/usr/X11R6/bin/startx"

Si usted usa un gestor gráfico de login necesitará cambiar otros archivos.

Para gdm (Gnome Display Manager):

Listado de Código 13.3: /etc/X11/gdm/gdm.conf

[server-Standard]
command=/usr/X11R6/bin/X -nolisten tcp

Para xdm (X Display Manager) y kdm (Kde Display Manager):

Listado de Código 13.4: /etc/X11/xdm/Xservers

:0 local /usr/bin/X11/X -nolisten tcp

11. Chroot o servidores virtuales

11.a. Chrooting

Hacer chroot (enjaular) a un servicio es la manera de limitar el entorno de un servicio (o usuario) para que acceda sólo a lo que debería y para que no escale acceso (o consiga información) que le permita un acceso de root. Ejecutando el servicio como un usuario distinto de root (nobody, apache, named) un atacante sólo podrá acceder a los ficheros con permisos para dicho usuario. Lo que significa que un atacante no conseguirá el acceso de root incluso si los servicios tuvieran algún defecto de seguridad.

Algunos servicios como pure-ftpd y bind tienen características para hacer chroot, pero otros no. Si el servicio lo soporta, úselo, si no usted tiene que saber como crearse el suyo propio. Veamos como crear un chroot. Para una comprensión elemental de como trabaja un chroot, vamos a probarlo con bash (la manera fácil de aprenderlo)

Cree el directorio /chroot con mkdir /chroot. Y averigüe con qué librerías dinámicas está compilado bash (este paso no es necesario si está compilado con -static).

El siguiente comando creará una lista con las librerías usadas por bash.

Listado de Código 1.1: Obtener la lista de librerías usadas

# ldd /bin/bash
  libncurses.so.5 => /lib/libncurses.so.5 (0x4001b000)
  libdl.so.2 => /lib/libdl.so.2 (0x40060000)
  libc.so.6 => /lib/libc.so.6 (0x40063000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Ahora creemos el entorno para bash.

Listado de Código 1.2: Crear el entorno chroot para bash

# mkdir /chroot/bash
# mkdir /chroot/bash/bin
# mkdir /chroot/bash/lib

Luego copie los ficheros usados por bash (/lib) al directorio lib del chroot y copie también el comando bash al directorio bin del chroot. Esto creará exactamente el mismo entorno, pero con menos funcionalidad. Después de copiarlo pruébelo:chroot /chroot/bash /bin/bash. Si obtiene un prompt indicado / ¡funciona! En caso contrario le informará adecuadamente de qué fichero falta. Algunas librerías compartidas dependen unas de otras.

Se dará cuenta que dentro del chroot sólo funciona echo. Esto ocurre porque no tenemos otros comandos dentro del entorno chroot que no sean bash y echo que es una funcionalidad incorporada.

Esta es básicamente la manera en la que usted podría crear un servicio ejecutado con chroot. La única diferencia es que los servicios a veces depende de servicios y ficheros de configuración en /etc. Simplemente cópielos (los dispositivos pueden copiarse con cp -a) en el entorno de chroot, edite el guión de inicio init para que use chroot antes de ejecutarlo. Puede resultar difícil encontrar qué dispositivos y ficheros de configuración necesita un servicio. Para esto es práctico el comando strace. Inicie el servicio en bash con /usr/bin/strace y busque los open, read, stat y puede que connect. Lo que le dará una pista de qué ficheros copiar. Pero en muchos casos basta copiar el fichero de contraseñas (passwd) (edite la copia y borre los usuarios que no tienen nada que ver con el servicio), /dev/zero, /dev/log y /dev/random.

11.b. User Mode Linux

Otra forma de crear un entorno más seguro es ejecutar una máquina virtual. Una máquina virtual, como su nombre implica, es un proceso que se ejecuta en el nivel más alto de su sistema operativo real, proporcionando un entorno de hardware y sistema operativo que parece ser el propio de una única máquina. Su beneficio de seguridad está en que si es comprometido el servidor ejecutado en la máquina virtual, sólo se ve afectado este servidor virtual no la instalación padre.

Para más información acerca de como instalar User Mode Linux consulte User Mode Linux Guide.

12. Cortafuegos

12.a. Cortafuegos

Mucha gente piensa a menudo que un cortafuegos (firewall) es la máxima expresión de la seguridad, pero están equivocados. En muchos casos un cortafuegos mal configurado da menos seguridad que no tener uno instalado. Un cortafuegos también es un componente de software y debería tratarse de la misma manera que cualquier otro software, porque puede contener agujeros de seguridad.

¡Así que piénselo antes de implementar un cortafuegos! ¿Realmente lo necesita? Si cree que lo necesita, escriba una política sobre cómo debería funcionar, qué tipo de cortafuegos, y cómo debería operar. Pero primero lea esta guía.

Los cortafuegos se usan con dos propósitos:

  • Para mantener a los usuarios (gusanos/atacantes) fuera
  • Para mantener a los usuarios (empleados/niños) dentro

Básicamente hay tres tipos de cortafuegos:

  • Filtrado de paquetes
  • Circuit relay
  • Aplicación de puerta de enlace

Un cortafuegos debería ser una máquina dedicada que no ejecute otros servicios (sshd es el único) y asegurada tal como recomienda esta guía.

12.b. Filtrado de paquetes

Todo el tráfico de la red se transmite como paquetes. Grandes cantidades de tráfico se dividen en paquetes pequeños para un mejor manejo y se juntan cuando llegan a su destino. La cabecera de cada paquete contiene la información de cómo y dónde debe ser entregado. Y estas informaciones son exactamente las que un cortafuegos de filtrado de paquetes utiliza. El filtrado se basa en:

  • Permitir o denegar los paquetes basados en la dirección IP origen/destino
  • Permitir o denegar los paquetes basados en un puerto de origen/destino
  • Permitir o denegar los paquetes basados en un protocolo
  • Permitir o denegar los paquetes basados en parámetros específicos del protocolo

En otras palabras, este filtrado se fundamenta en la información de la cabecera del paquete y no en su contenido.

Debilidades:

  • La dirección de un paquete puede ser potencialmente falsa (o como se suele decir spoofed) por el remitente
  • Los datos o peticiones contenidos en un paquete permitido pueden contener datos no esperados que el atacante puede usar para explotar fallos en servicios en el cortafuegos o a través de él
  • Normalmente es un punto único de fallo

Ventajas:

  • Simple y fácil de implementar
  • Puede avisar de posibles ataques antes de que ocurran (por ejemplo detectando sondeos de puertos)
  • Son buenos para parar ataques SYN

Ejemplos de cortafuegos de filtrado de paquetes libres en Linux:

Nota: Se recomienda utilizar iptables. Ipchains es obsoleto.

12.c. Circuit relay

Un circuito de nivel de puerta de enlace es un cortafuegos que valida las conexiones antes de permitir el intercambio de datos. Esto significa que simplemente no permite o deniega paquetes basándose en su cabecera si no que determina si la conexión entre los dos extremos es válida de acuerdo a las reglas configuradas antes de abrir una sesión y permitir que los datos sean intercambiados. El filtrado está basado en:

  • Dirección IP de origen/destino
  • Puerto de origen/destino
  • Periodo de tiempo
  • Protocolo
  • Usuario
  • Contraseña

Todo el tráfico es validado y monitorizado, y el tráfico no deseado se descarta.

Debilidades:

  • Opera en la Capa de Trasporte y puede requerir una modificación sustancial en el programa que normalmente provee de las funciones de transporte.

12.d. Aplicación de puerta de enlace

La pasarela de aplicación de puerta de enlace es un "proxy" para aplicaciones, que intercambian datos con los sistemas remotos en nombre de sus clientes. Suele estar a salvo detrás de una DMZ ("zona desmilitarizada": la porción de una red privada que es visible a través del cortafuegos) o de un cortafuegos que no permite conexiones desde el exterior. El filtrado está basado en:

  • Permitir o denegar basándose en direcciones IP del origen/destino
  • Basándose en el contenido del paquete
  • Limitar el acceso a ficheros basándose en su tipo o su extensión

Ventajas:

  • Puede hacer "cache" de archivos, incrementando el rendimiento de red
  • Detallado registro de todas las conexiones
  • Crece bien (algunos proxys de servidores pueden "compartir" los datos en cache)
  • No hay acceso directo desde el exterior
  • Pueden alterar el contenido del paquete al vuelo

Debilidades:

  • La configuración es compleja

Las aplicaciones de pasarela están consideradas la mejor solución segura puesto que no tienen que ser ejecutadas como root y los hosts tras ellos no son accesibles desde Internet.

Ejemplo de una aplicación de pasarela libre:

12.e. Iptables

Para poner en funcionamiento iptables, tiene que estar habilitado en el kernel. Yo lo he añadido como módulo (el comando iptables lo cargará como se necesita) y he recompilado mi núcleo (pero puede compilarlo embebido, si quiere deshabilitar los Módulos Cargables del Núcleo como se indicaba anteriormente). Para más información al respecto de como configurar su kernel para iptables vea a Iptables Tutorial Chapter 5: Preparations. Después de que haya compilado su nuevo kernel (o mientras lo compila) tiene que añadir el comando iptables . Simplemente con emerge iptables ya debería funcionar.

Ahora compruebe que funciona ejecutando iptables -L. Si falla, algo está mal y deberá revisar su configuración una vez más.

Iptables es el nuevo y fuertemente mejorado filtro de paquetes en el kernel de Linux 2.4.x. Es el sucesor del anterior filtro de paquetes ipchains del kernel de linux 2.2.x. Una de las más grandes mejoras es que iptables es capaz de realizar filtrado de estado de paquetes. Con el filtrado de estado es posible mantener el registro de cada conexión TCP establecida.

Una conexión TCP consiste en una serie de paquetes que contienen información respecto la dirección IP origen, la IP de destino, puerto de origen, puerto de destino, y un número de secuencia para que los paquetes puedan juntarse sin perder datos. TCP es un protocolo orientado a la conexión en contraste a UDP que es "sin conexión".

Examinando la cabecera del paquete TCP, un filtro de estado de paquetes puede determinar si un paquete TCP recibido es parte de una conexión ya establecida o no y decidir si aceptarlo o rechazarlo.

Es posible engañar a un filtro de paquetes que no verifique el estado de los mismos para que acepte paquetes que deberían ser desechados si se manipula la cabecera del paquete TCP. Esto puede hacerse alterando el indicador SYN u otros indicadores en la cabecera TCP para fabricar un paquete malicioso que parezca formar parte de una conexión establecida (puesto que el filtro de paquetes por si mismo no hace un seguimiento de la conexión). Con un filtro de estado de paquetes es posible descartar aquellos paquetes que no formen parte de una conexión ya establecida. Esto detendrá también la posibilidad de "escaneos pasivos", un tipo de exploración de puertos en la cual quien realiza la exploración envía paquetes con indicadores que están lejos de ser registrados por un cortafuegos ordinario.

Iptables proporciona otras prestaciones como NAT (Network Address Translation) y limitación de tasas. La limitación de tasas es muy práctica para prevenir ciertos ataques DoS ("Denial of Service", denegación de servicio) como las inundaciones SYN ("SYN floods")

Una conexión TCP se establece con una "conversación en tres fases". Para iniciar la conexión TCP la parte de cliente envía un paquete al servidor con el flag SYN habilitado. Cuando el servidor recibe el paquete con el SYN responde enviando un paquete SYN+ACK de vuelta al cliente. Entonces el SYN+ACK es recibido en el cliente que responde con un tercer paquete ACK reconociendo la conexión.

Un ataque de inundación SYN se realiza enviando paquetes SYN de forma que no se responda el correspondiente paquete SYN+ACK. El cliente puede crear un paquete con una dirección IP origen falsa puesto que no necesita la respuesta. El sistema del servidor añadirá una entrada en la cola de las conexiones pendientes de establecer cuando se reciba el paquete SYN y esperará a recibir el paquete final ACK antes de borrar esta entrada de la cola. La cola tiene un número limitado de posiciones (slots) y si todas estas posiciones están ocupadas no podrá abrir nuevas conexiones. Si el paquete ACK no se recibe antes de un tiempo determinado la entrada se borrará automáticamente de la cola. Este tiempo de espera es variable, pero normalmente es de 30 a 60 segundos o incluso más. La parte de cliente inicia el ataque enviando gran número de paquetes SYN con diferentes IP origen y enviándolos a la IP objetivo todo lo rápido que pueda y de ese modo llenará la cola de las conexiones pendientes de establecer y por tanto impedirá que otros clientes establezcan una conexión legítima con el servidor.

Aquí es donde la limitación de tasas se vuelve útil. Es posible limitar la tasa de paquetes SYN aceptados usando -m limit --limit 1/s. Esto limitará el número de paquetes SYN aceptados a uno por segundo y por tanto evitará el riesgo de inundaciones SYN en nuestros equipos.

Nota: Otra opción para prevenir inundaciones SYN es SYN cookies, que permite a su ordenador responder a paquetes SYN sin llenar el espacio de la cola de conexiones. Las galletas (cookies) SYN pueden ser habilitadas en la configuración del Núcleo de Linux, pero hoy en día todavía están consideradas como experimentales.

¡Ahora algunas prácticas!

Cuando iptables se activa en el kernel proporciona 5 lugares donde especificar las reglas. Estos lugares se llaman INPUT, OUTPUT, FORWARD, PREROUTING y POSTROUTING. Cada uno de ellos es a su vez una cadena que consiste en una serie de reglas. Cada regla especifica una cabecera de paquete con la que compararse, después indica qué hacer con el paquete. Si la regla no coincide con el paquete se consulta la siguiente regla en la cadena.

Usted puede añadir reglas directamente en estas 5 cadenas principales o crear nuevas cadenas y añadirlas como si fueran reglas a una cadena existente. Iptables admite las siguientes opciones.

Opción: Descripción:
-A Añadir
-D Borrar
-I Insertar
-R Reemplazar
-L Listar
-F Borra todas las reglas de una o de todas las cadenas
-Z Pone a cero los contadores en una o en todas las cadenas
-C Verifica ese paquete en la cadena
-N Crea una nueva cadena definida por el usuario
-X Borra una cadena definida por el usuario
-P Cambia la forma de actuar de una cadena respecto un objetivo
-E Cambia el nombre de la cadena
-p Protocolo
-s Dirección o máscara de origen
-d Dirección o máscara de destino
-i Nombre de entrada (nombre ethernet)
-o Nombre de salida (nombre ethernet)
-j Salto (objetivo de la regla)
-m Coincidencia extendida (puede usar una extensión)
-n Salida numérica para las direcciones y puertos
-t Tabla a manipular
-v Modo de información detallada
-x Expande los números (muestra valores exactos)
-f Sólo hacer coincidir el segundo fragmento o posteriores
-V Versión de paquete
--line-numbers Muestra los números de línea al listar

Primero trataremos de bloquear todos los paquetes ICMP en nuestra máquina, sólo para familiarizarnos con iptables.

Listado de Código 5.1: Bloquear todos los paquetes ICMP

# iptables -A INPUT -p icmp -j DROP

Primero indicamos la cadena o regla donde debe ser añadida, después el protocolo de los paquetes, y finalmente el destino. El destino puede ser el nombre de una cadena definida por el usuario o uno de los siguientes ACCEPT, DROP, REJECT, LOG, QUEUE, MASQUERADE. En este ejemplo usamos DROP que desechará el paquete sin responder al cliente.

Nota: El destino LOG es del tipo conocido como "non-terminating". Si un paquete concuerda con una regla con el destino LOG, en lugar de para la evaluación, el paquete continua siendo comparado con las otras reglas. Esto le permite registrar el paquete mientras se se procesa con normalidad.

Ahora intente ping localhost. No recibirá ninguna respuesta puesto que iptables desechará todos los paquetes ICMP entrantes. No podrá hacer ping a otras máquinas puesto que los paquetes ICMP de respuesta también son desechados. Ahora elimine la cadena para permitir el tráfico ICMP de nuevo.

Listado de Código 5.2: Elimina todas las reglas

# iptables -F

Ahora veamos el filtrado de paquetes de estado en iptables. Si buscamos activar una inspección de estado en los paquetes entrantes en eth0, podríamos activarlo con el comando:

Listado de Código 5.3: Acepta paquetes originados en una conexión entrante o ya establecida

# iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Esto aceptará cualquier paquete de una conexión ya establecida o con relación a la cadena INPUT. Usted también puede desechar cualquier paquete que no esté en la tabla de estado indicando iptables -A INPUT -i eth0 -m state --state INVALID -j DROP justo antes del comando anterior. Esto habilita el filtrado de estado de paquetes en ipetables cargando la extensión "estate". Si quiere permitir a otros conectarse a su máquina puede usar el indicador --state NEW. Iptables contiene algunos módulos con propósitos diversos. Algunos de ellos son:

Módulo/Concordancia Descripción Opciones extendidas
mac Comprueba la extensión para los paquetes que provienen de esa dirección mac. --mac-source
state Activa la inspección de estado --state (los estados son ESTABLISHED,RELATED, INVALID, NEW)
limit Limitación de tasas --limit, --limit-burst
owner Intenta comparar varias características del creador de los paquetes --uid-owner userid --gid-owner groupid --pid-owner processid --sid-owner sessionid
unclean Varios chequeos aleatorios en los paquetes

Intentemos crear una cadena definida por el usuario y añadirla a una de las ya existentes:

Listado de Código 5.4: Creación de una cadena definida por el usuario

  (Creamos una nueva cadena con una regla)
# iptables -X micadena
# iptables -N micadena
# iptables -A micadena -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
(El comportamiento por defecto es permitir todo el tráfico saliente. El entrante es desechado.)
# iptables -P OUTPUT ACCEPT
# iptables -P INPUT DROP
(Y la añadimos a la cadena INPUT)
# iptables -A INPUT -j micadena

Aplicando la regla a la cadena input obtenemos la política: Se permite todos los paquetes salientes y se desechan todos los entrantes.

Puede encontrar más documentación en Documentación sobre netfilter/iptables.

Veamos ahora un ejemplo completo. En este caso el comportamiento de mi cortafuegos/puerta de enlace indica:

  • Sólo se permiten las conexiones hacia el cortafuegos a través de SSH (puerto 22)
  • La red local debe tener acceso a HTTP, HTTPS y SSH (DNS puede también permitirse)
  • El tráfico ICMP puede contener carga no deseada y no debe ser permitido. Por supuesto deberemos permitir cierto tráfico ICMP
  • Los sondeos de puertos deben ser detectados y registrados
  • Los ataques SYN deben ser prevenidos
  • El tráfico restante debe ser desechado y registrado

Listado de Código 5.5: /etc/init.d/firewall

#!/sbin/runscript
IPTABLES=/sbin/iptables
IPTABLESSAVE=/sbin/iptables-save
IPTABLESRESTORE=/sbin/iptables-restore
FIREWALL=/etc/firewall.rules
DNS1=212.242.40.3
DNS2=212.242.40.51
#interior
IIP=10.0.0.2
IINTERFACE=eth0
LOCAL_NETWORK=10.0.0.0/24
#exterior
OIP=217.157.156.144
OINTERFACE=eth1

opts="${opts} showstatus panic save restore showoptions rules"

depend() {
  need net
}

rules() {
  stop
  ebegin "Estableciendo las reglas internas"

  einfo "Estableciendo la regla por defecto para drop"
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP

  # Regla por defecto
  einfo "Creando las cadenas de estado"
  $IPTABLES -N allowed-connection
  $IPTABLES -F allowed-connection
  $IPTABLES -A allowed-connection -m state --state ESTABLISHED,RELATED -j ACCEPT
  $IPTABLES -A allowed-connection -i $IINTERFACE -m limit -j LOG --log-prefix \ 
      "Bad packet from ${IINTERFACE}:"
  $IPTABLES -A allowed-connection -j DROP

  # Tráfico ICMP
  einfo "Creando la cadena icmp"
  $IPTABLES -N icmp_allowed
  $IPTABLES -F icmp_allowed
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \ 
      time-exceeded -j ACCEPT
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \ 
      destination-unreachable -j ACCEPT
  $IPTABLES -A icmp_allowed -p icmp -j LOG --log-prefix "Bad ICMP traffic:"
  $IPTABLES -A icmp_allowed -p icmp -j DROP

  # Tráfico entrante
  einfo "Creando la cadena para el tráfico ssh entrante"
  $IPTABLES -N allow-ssh-traffic-in
  $IPTABLES -F allow-ssh-traffic-in
  #Protección "Flood"
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL RST --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL FIN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL SYN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT

  # Tráfico saliente
  einfo "Creando la cadena para el tráfico ssh saliente"
  $IPTABLES -N allow-ssh-traffic-out
  $IPTABLES -F allow-ssh-traffic-out
  $IPTABLES -A allow-ssh-traffic-out -p tcp --dport ssh -j ACCEPT

  einfo "Creando la cadena para el tráfico DNS saliente"
  $IPTABLES -N allow-dns-traffic-out
  $IPTABLES -F allow-dns-traffic-out
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS1 --dport domain \ 
      -j ACCEPT
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS2 --dport domain \ 
     -j ACCEPT

  einfo "Creando la regla para el tráfico http/https saliente"
  $IPTABLES -N allow-www-traffic-out
  $IPTABLES -F allow-www-traffic-out
  $IPTABLES -A allow-www-traffic-out -p tcp --dport www -j ACCEPT
  $IPTABLES -A allow-www-traffic-out -p tcp --dport https -j ACCEPT

  # Detección de scanners de puertos
  einfo "Creando la cadena de detección de scanner de puertos"
  $IPTABLES -N check-flags
  $IPTABLES -F check-flags
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -m limit \ 
      --limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS:" 
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -m limit --limit \ 
      5/minute -j LOG --log-level 1 --log-prefix "XMAS:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \ 
      -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -m limit \ 
      --limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -m limit \ 
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit \ 
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

  # Aplicando y añadiendo estados no válidos a las cadenas
  einfo "Aplicando cadenas en INPUT"
  $IPTABLES -A INPUT -m state --state INVALID -j DROP
  $IPTABLES -A INPUT -p icmp -j icmp_allowed
  $IPTABLES -A INPUT -j check-flags
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A INPUT -j allow-ssh-traffic-in
  $IPTABLES -A INPUT -j allowed-connection

  einfo "Aplicando cadenas en FORWARD"
  $IPTABLES -A FORWARD -m state --state INVALID -j DROP
  $IPTABLES -A FORWARD -p icmp -j icmp_allowed
  $IPTABLES -A FORWARD -j check-flags
  $IPTABLES -A FORWARD -o lo -j ACCEPT
  $IPTABLES -A FORWARD -j allow-ssh-traffic-in
  $IPTABLES -A FORWARD -j allow-www-traffic-out
  $IPTABLES -A FORWARD -j allowed-connection

  einfo "Aplicando cadenas en OUTPUT"
  $IPTABLES -A OUTPUT -m state --state INVALID -j DROP
  $IPTABLES -A OUTPUT -p icmp -j icmp_allowed
  $IPTABLES -A OUTPUT -j check-flags
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  $IPTABLES -A OUTPUT -j allow-ssh-traffic-out
  $IPTABLES -A OUTPUT -j allow-dns-traffic-out
  $IPTABLES -A OUTPUT -j allow-www-traffic-out
  $IPTABLES -A OUTPUT -j allowed-connection

  # Permite a los clientes enrutar a través de NAT (Network Address
  # Translation)
  $IPTABLES -t nat -A POSTROUTING -o $OINTERFACE -j MASQUERADE
  eend $?
}

start() {
  ebegin "Iniciando el cortafuegos"
  if [ -e "${FIREWALL}" ]; then
    restore
  else
    einfo "${FIREWALL} no existe. Usando las reglas por defecto."
    rules
  fi
  eend $?
}

stop() {
  ebegin "Parando el cortafuegos"
  $IPTABLES -F
  $IPTABLES -t nat -F
  $IPTABLES -X
  $IPTABLES -P FORWARD ACCEPT
  $IPTABLES -P INPUT   ACCEPT
  $IPTABLES -P OUTPUT  ACCEPT
  eend $?
}

showstatus() {
  ebegin "Estatus"
  $IPTABLES -L -n -v --line-numbers
  einfo "Estatus NAT"
  $IPTABLES -L -n -v --line-numbers -t nat
  eend $?
}

panic() {
  ebegin "Estableciendo reglas 'panic'"
  $IPTABLES -F
  $IPTABLES -X
  $IPTABLES -t nat -F
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  eend $?
}

save() {
  ebegin "Guardando las reglas del cortafuegos"
  $IPTABLESSAVE > $FIREWALL
  eend $?
}

restore() {
  ebegin "Restaurando las reglas del cortafuegos"
  $IPTABLESRESTORE < $FIREWALL
  eend $?
}

restart() {
  svc_stop; svc_start
}

showoptions() {
  echo "Usage: $0 {start|save|restore|panic|stop|restart|showstatus}"
  echo "start)      restaura si existe y si no fuerza las reglas"
  echo "stop)       elimina todas las reglas y lo permite todo"
  echo "rules)      fuerza el establecimiento de nuevas reglas"
  echo "save)       gruada la configuración en ${FIREWALL}"
  echo "restore)    restaura la configuración desde ${FIREWALL}"
  echo "showstatus) muestra el estatus" 
}

Algunos consejos para cuando cree un cortafuegos:

  1. Cree su política de cortafuegos antes de implementarlo
  2. Hágalo simple
  3. Conozca cómo trabajan los protocolos (lea lo más relevante de RFC (Request For Comments))
  4. Tenga bien presente que un cortafuegos sólo es otro software ejecutándose como root
  5. Compruebe su cortafuegos

Si piensa que iptables es difícil de comprender o le lleva mucho tiempo configurar un cortafuegos decente, puede usar Shorewall. Básicamente utiliza iptables para generar las reglas del cortafuegos, pero se concentra en reglas y no en protocolos específicos.

12.f. Squid

Squid es un servidor proxy muy potente. Puede filtrar el tráfico atendiendo a: tiempo, expresiones regulares en la ruta/URI, dirección IP de origen y destino, dominio, navegador, nombre de usuario autentificado, mime-type y número de puerto (protocolo). Probablemente olvido algunas características, pero puede ser pesado cubrir aquí la lista entera de características.

En el ejemplo siguiente he añadido un filtrado de pancartas ("banners") en lugar de un filtro basado en sitios porno. La razón de esto es que Gentoo.org no debe ser catalogado como un sitio pornográfico. Y yo no quiero malgastar mi tiempo intentando buscar algunos buenos sitios para usted.

En este caso, mi política de acceso es:

  • La navegación (HTTP/HTTPS) está permitida durante las horas de trabajo (lunes a viernes de 8 a 17 y sábado de 8 a 13 horas), si alguien está más tarde debería trabajar, no navegar.
  • No está permitido descargar ficheros (.exe, .com, .arj, .zip, .asf, .avi, .mpg, .mpeg, etc.)
  • No nos gustan las pancartas (banners), por lo que son filtradas y reemplazadas por un gif transparente (¡aquí es donde puede ser creativo!)
  • Cualquier otra conexión hacia o desde Internet no está permitida

Esto se implementa en 4 pasos fáciles.

Listado de Código 6.1: /etc/squid/squid.conf

# Enlaza con una IP y un puerto
http_port 10.0.2.1:3128

# Configuración standard 
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY

# Añade listas de control de acceso básico
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255

# Añade quien puede acceder a este servidor proxy
acl localnet src 10.0.0.0/255.255.0.0

# Y los puertos
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl purge method PURGE

# Añade una lista de control de acceso basada en
# expresiones regulares mediante urls
acl archives urlpath_regex "/etc/squid/files.acl"
acl url_ads url_regex "/etc/squid/banner-ads.acl"

# Añade una lista de control de acceso basada en día y hora
acl restricted_weekdays time MTWHF 8:00-17:00
acl restricted_weekends time A 8:00-13:00

acl CONNECT method CONNECT

# Permite el acceso administrativo desde localhost
http_access allow manager localhost
http_access deny manager

# Solo permite purgar peticiones desde localhost
http_access allow purge localhost
http_access deny purge

# Deniega peticiones hacia puertos desconocidos
http_access deny !Safe_ports

# Deniega CONNECT a otros puertos distintos de SSL
http_access deny CONNECT !SSL_ports

# Mis propias reglas

# Añade una página para ser mostrada cuando
# se elimina una pancarta
deny_info NOTE_ADS_FILTERED url_ads

# Entonces lo rechaza
http_access deny url_ads

# Deniega todos los archivos
http_access deny archives

# Restringe el acceso a las horas de trabajo
http_access allow localnet restricted_weekdays
http_access allow localnet restricted_weekends

# Deniega el resto
http_access deny all

Después complete los ficheros que no quiere que sus usuarios descarguen. Yo he indicado zip, viv, exe, mp3, rar, ace, avi, mov, mpg, mpeg, au, ra, arj, tar, gz and z files.

Listado de Código 6.2: /etc/squid/files.acl

\.[Zz][Ii][pP]$
\.[Vv][Ii][Vv].*
\.[Ee][Xx][Ee]$
\.[Mm][Pp]3$
\.[Rr][Aa][Rr]$
\.[Aa][Cc][Ee]$
\.[Aa][Ss][Ff]$
\.[Aa][Vv][Ii]$
\.[Mm][Oo][Vv]$
\.[Mm][Pp][Gg]$
\.[Mm][Pp][Ee][Gg]$
\.[Aa][Uu]$
\.[Rr][Aa]$
\.[Aa][Rr][Jj]$
\.[Tt][Aa][Rr]$
\.[Gg][Zz]$
\.[Zz]$

Nota: Por favor, tenga en cuenta los [ ] con mayúsculas y minúsculas en cada carácter. Esto sirve para que alguien no se salte las reglas accediendo a un fichero llamado AvI en lugar de avi.

Ahora vamos a añadir las expresiones regulares para identificar a las pancartas. Probablemente usted será más creativo que yo:

Listado de Código 6.3: /etc/squid/banner-ads.acl

/adv/.*\.gif$
/[Aa]ds/.*\.gif$
/[Aa]d[Pp]ix/
/[Aa]d[Ss]erver
/[Aa][Dd]/.*\.[GgJj][IiPp][FfGg]$
/[Bb]annerads/
/adbanner.*\.[GgJj][IiPp][FfGg]$
/images/ad/
/reklame/
/RealMedia/ads/.*
^http://www\.submit-it.*
^http://www\.eads.*
^http://ads\.
^http://ad\.
^http://ads02\.
^http://adaver.*\.
^http://adforce\.
adbot\.com
/ads/.*\.gif.*
_ad\..*cgi
/Banners/
/SmartBanner/
/Ads/Media/Images/
^http://static\.wired\.com/advertising/
^http://*\.dejanews\.com/ads/
^http://adfu\.blockstackers\.com/
^http://ads2\.zdnet\.com/adverts
^http://www2\.burstnet\.com/gifs/
^http://www.\.valueclick\.com/cgi-bin/cycle
^http://www\.altavista\.com/av/gifs/ie_horiz\.gif

Y como último paso, queremos que este fichero sea mostrado cuando una pancarta sea eliminada. Básicamente es un medio archivo html con una imagen gif transparente de 4x4 pixels.

Listado de Código 6.4: /etc/squid/errors/NOTE_ADS_FILTERED

<HTML>
<HEAD>
<META HTTP-EQUIV="REFRESH" CONTENT="0; URL=http://localhost/images/4x4.gif">
<TITLE>ERROR: La URL solicitada no puede ser recuperada</TITLE>
</HEAD>
<BODY>
<H1>Anuncio filtrado</H1>

Nota: No cierre los tags <HTML> <BODY>. Eso lo hará squid.

Como puede ver, Squid tiene muchas posibilidades y es muy efectivo tanto como filtro como proxy. Incluso se pueden usar proxies Squid encadenados para escalar en redes muy grandes. La configuración que he indicado aquí es muy conveniente para una pequeña red de 1 a 20 usuarios.

Pero combinar el filtrado de paquetes (iptables) y una pasarela de aplicaciones (Squid) es probablemente la mejor solución, incluso si Squid está ubicado en un lugar seguro y donde nadie pueda acceder desde el exterior. Continuamos teniendo que preocuparnos de los ataques desde dentro.

Ahora tiene que configurar los navegadores en los clientes para usar el servidor proxy. La puerta de enlace evitará que los usuarios tengan cualquier contacto con el exterior salvo que usen el proxy.

Nota: En Mozilla Firefox se consigue en Edición->Preferencias->Advanzadas->Red.

También se conseguir un proxy transparente usando iptables dirigiendo todo el tráfico saliente a un proxy Squid. Esto se hace añadiendo una regla de forwarding/prerouting en la pasarela:

Listado de Código 6.5: Activa el portforwarding hacia nuestro servidor proxy

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to proxyhost:3128
# iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to proxyhost:3128

Nota: Si el proxy se está ejecutando en el host que hace el filtrado de paquetes --y aunque que no se recomienda, puede ser necesario si no tiene suficientes máquinas disponibles-- use un destino REDIRECT en lugar de DNAT (REDIRECT dirige los paquetes al localhost).

12.g. Lecciones aprendidas

Hemos aprendido esto:

  1. Un cortafuegos puede representar un riesgo por si mismo. Un cortafuegos mal configurado es peor que no tenerlo
  2. Cómo configurar una pasarela básica y un proxy transparente
  3. La clave para tener un buen cortafuegos es conocer el protocolo que queremos permitir
  4. Que el tráfico IP puede contener datos no legítimos, por ejemplo los paquetes ICMP pueden llevar una carga oculta
  5. Cómo prevenir un ataque SYN
  6. El filtrado de tráfico HTTP quitando imágenes no adecuadas, descargas de ficheros de virus
  7. Combinar filtros de paquetes y pasarelas de aplicaciones proporcionan mayor control

Entonces si realmente necesita usted un cortafuegos, cree uno que satisfaga sus necesidades.

13. Detección de intrusos

13.a. AIDE (Entorno Avanzado de Detección de Intrusos)

AIDE es un sistema de detección de intrusos basado en host (HIDS, Host-Based Intrusion Detection System), una alternativa libre a Tripwire (si ya conoce Tripwire no debería tener dificultades para aprender a configurar AIDE). Los HIDS se usan para detectar cambios en los ficheros de configuración y binarios importantes, generalmente generando un resumen cifrado ("hash") único de los ficheros a ser verificados, y almacenándolos en un lugar seguro. Con un procedimiento regular (tal que una vez al día), los resúmenes "buenos" se comparan con los generados a partir de la copia actual de cada fichero, para determinar si el fichero ha cambiado. Los HIDS son una gran herramienta para detectar cambios no permitidos en un sistema, pero necesitan un poco de trabajo para implementarlos adecuadamente y hacer un buen uso de ellos.

El fichero de configuración está basado en expresiones regulares, macros y reglas para ficheros y directorios. Tenemos la macros siguientes:

Macro Descripción Sintaxis
ifdef Si está definido @@ifdef "name"
ifndef Si no está definido @@ifndef "name"
define Define una variable @@define "name" "value"
undef Elimina la definición de una variable @@undef "name"
ifhost Si "hostname" @@ifhost "hostname"
ifnhost Si no "hostname" @@ifnhost "hostname"
endif Endif puede ser usado después de cualquiera de las macros anteriores excepto define y undef @@endif

Esas macros se convierten en algo muy práctico si usted tiene más de un sistema Gentoo y quiere usar AIDE en todos ellos, pero no todas las máquinas ejecutan los mismos servicios o incluso tienen los mismos usuarios.

A continuación tenemos conjuntos de marcas ("flags") para comprobar en ficheros y directorios. Son una combinación de permisos, propiedades de archivos y resúmenes criptográficos (es decir, sumas de control).

Flag Descripción
p permisos
i inode
n número de enlaces
u usuario
g grupo
s tamaño
b 'block count'
m mtime
a atime
c ctime
S verifica el tamaño creciente
md5 suma de control md5
sha1 suma de control sha1
rmd160 suma de control rmd160
tiger suma de control tiger
R p+i+n+u+g+s+m+c+md5
L p+i+n+u+g
E Grupo vacío
> Crecimiento del fichero de log p+u+g+i+n+S

Y si AIDE se compila con soporte para mhash también soporta otras características:

Flag Descripción
haval suma de control haval
gost suma de control gost
crc32 suma de control crc32

Ahora puede crear sus propias reglas basadas en los indicadores anteriores, combinándolas tal que así:

Listado de Código 1.1: Creación de un conjunto de reglas para AIDE

All=R+a+sha1+rmd160
Norm=s+n+b+md5+sha1+rmd160

Lo último que necesita para crear su propio fichero de configuración es ver cómo añadir una regla a un fichero o directorio. para introducir una regla, combine el nombre de fichero o directorio y la regla. AIDE añadirá todos los archivos recursivamente a no ser que usted especifique alguna regla alternativa.

Flag Descripción
! No añadir este fichero o directorio.
= Añadir este directorio, pero sin recursividad.

Veamos, pues, un ejemplo completo:

Listado de Código 1.2: /etc/aide/aide.conf

@@ifndef TOPDIR
@@define TOPDIR /
@@endif

@@ifndef AIDEDIR
@@define AIDEDIR /etc/aide
@@endif

@@ifhost smbserv
@@define smbactive
@@endif

# La ubicación de la base de datos a ser leída
database=file:@@{AIDEDIR}/aide.db

# La ubicación de la base de datos donde escribir
database_out=file:aide.db.new

verbose=20
report_url=stdout

# Definición de reglas
All=R+a+sha1+rmd160
Norm=s+n+b+md5+sha1+rmd160

@@{TOPDIR} Norm
!@@{TOPDIR}etc/aide
!@@{TOPDIR}dev
!@@{TOPDIR}media
!@@{TOPDIR}mnt
!@@{TOPDIR}proc
!@@{TOPDIR}root
!@@{TOPDIR}sys
!@@{TOPDIR}tmp
!@@{TOPDIR}var/log
!@@{TOPDIR}var/run
!@@{TOPDIR}usr/portage
@@ifdef smbactive
!@@{TOPDIR}etc/smb/private/secrets.tdb
@@endif
=@@{TOPDIR}home Norm

En el ejemplo anterior especificamos con algunas macros donde comienza el directorio de nivel superior y donde está el directorio de AIDE. AIDE comprueba el fichero /etc/aide/aide.db cuando comprueba la integridad de un fichero. Pero cuando actualiza o crea un nuevo fichero almacena la información en /etc/aide/aide.db.new. Esto se hace porque no se puede sobrescribir automáticamente el antiguo fichero de base de datos. La opción report_URL no está todavía implementada, pero la intención del autor es que sea capaz de enviar correo electrónico o quizá también ejecutar guiones ("scripts").

El ebuild AIDE incluye ahora un fichero de configuración funcional, un guión de ayuda ("helper") y un guión de programación de trabajos ("crontab"). El guión de ayuda realiza ciertas tareas por nosotros y proporciona una interfaz que resulta ser un pequeño guión más amigable. Para ver todas las opciones disponibles, puede ejecutarse aide --help. Para empezar, todo lo que se necesita hacer es aide -i y el guión de programación de trabajos debería detectar la base de datos y enviar los mensajes apropiados cada día. Es recomendable revisar el fichero /etc/aide/aide.conf y asegurarse que la configuración recoge escrupulosamente que todo está en su lugar en la máquina.

Nota: Dependiendo de su CPU, velocidad de acceso a disco y los indicadores configurados para los ficheros, el proceso puede llevar algún tiempo.

Nota: Recuerde establecer una alias para leer los mensajes de correo para root. En caso contrario nunca conocerá lo que está informando AIDE.

Note que almacenar localmente los ficheros de base de datos tiene algunos riesgos, puesto que los atacantes (si conocen que AIDE está instalado) intentarán sin duda alterar el fichero de base de datos, actualizarlo o modificar /usr/bin/aide. Por esto, debería crear un CD o otro medio donde dejar una copia del fichero .db y los binarios de AIDE.

Puede encontrar más información en la página del proyecto AIDE.

13.b. Snort

Snort es un Sistema de Detección de Intrusiones de Red (Network Intrusion Detection System, NIDS). Para instalarlo y configurarlo use los ejemplos siguientes.

Listado de Código 2.1: /etc/conf.d/snort

SNORT_IFACE="eth0"
PIDFILE=/run/snort_eth0.pid
MODE="full"
NETWORK="192.168.0.0/24
LOGDIR="/var/log/snort"
SNORT_CONF=/etc/snort/snort.conf
SNORT_OPTS="-q -D -u snort -d -l $LOGDIR -h $NETWORK -c $SNORT_CONF"

Copie /etc/snort/snort.conf.distrib a /etc/snort/snort.conf.

Listado de Código 2.2: /etc/snort/snort.conf

~# cd /etc/snort && cp snort.conf.distrib snort.conf

Puede que necesite comentar las entradas en las listas blancas y negras si no se creó ninguna lista.

Más información en el sitio web de Snort.

13.c. Detección de malware con chkrootkit

Tanto HIDS como AIDE son una gran forma de detectar cambios en su sistema, pero nunca perjudica tener otra línea de defensas. chkrootkit es una utilidad que que examina los ficheros de sistema comunes buscando rootkits --software diseñado para esconder las acciones de un intruso y permitirle conservar el acceso-- y examina el sistema buscando trazas de registradores de teclados ("keyloggers") y otro "malware". chkrootkit y alternativas como rkhunter son herramientas prácticas, tanto para el mantenimiento del sistema como seguimiento de un intruso tras un ataque, sin embargo no garantizan que su sistema sea seguro.

La mejor manera para emplear chkrootkit como detección de intrusos es ejecutarlo rutinariamente desde cron. Para empezar, instale app-forensics/chkrootkit. chkrootkit puede ejecutarse desde la línea de comandos con el comando homónimo, o desde cron con un línea como ésta:

Listado de Código 3.1: Programar chkrootkit como un cronjob

0 3 * * * /usr/sbin/chkrootkit

14. Manteniendo el sistema actualizado

14.a. Manteniendo el sistema actualizado

Una vez que ha instalado satisfactoriamente su sistema y conseguido un buen nivel de seguridad no lo ha hecho todo. La seguridad es un proceso continuo; la gran mayoría de intrusiones se producen como consecuencia de vulnerabilidades conocidas en sistemas no actualizados. Mantener el sistema actualizado es el único y más valioso paso que se puede dar para obtener la mejor seguridad.

Si tiene una versión reciente del portage instalada, primero debe sincronizar su árbol del portage mediante emerge --sync y entonces ejecutar el comando glsa-check --list para comprobar si su sistema está actualizado en cuanto a la seguridad. glsa-check forma parte de app-portage/gentoolkit.

Listado de Código 1.1: Ejemplo de salida de glsa-check -l

# glsa-check -l
WARNING: This tool is completely new and not very tested, so it should not be
used on production systems. It's mainly a test tool for the new GLSA release
and distribution system, it's functionality will later be merged into emerge
and equery.
Please read http://www.gentoo.org/proj/en/portage/glsa-integration.xml
before using this tool AND before reporting a bug.
  
[A] means this GLSA was already applied,
[U] means the system is not affected and
[N] indicates that the system might be affected.
 
200406-03 [N] sitecopy: Multiple vulnerabilities in included libneon ( net-misc/sitecopy )
200406-04 [U] Mailman: Member password disclosure vulnerability ( net-mail/mailman )
.......

Aviso: glsa-check es todavía experimental, por lo que si la seguridad es realmente su máxima prioridad sería juicioso contrastar la lista con otras fuentes.

Todas las líneas con [A] y [U] pueden ser ignoradas casi sin peligro ya que el sistema no está afectado por este GLSA.

Importante: Hay que tener en cuenta que el habitual emerge -vpuD world no recogerá todas las actualizaciones de paquetes. Tendremos que utilizar glsa-check si queremos asegurarnos que todos los GLSAs son aplicados en el sistema.

Listado de Código 1.2: Verificar todos GLSAs

(Verifica si el sistema está afectado por GLSAs)
# glsa-check -t all
WARNING: This tool is completely new and not very tested, so it should not be
used on production systems. It's mainly a test tool for the new GLSA release
and distribution system, it's functionality will later be merged into emerge
and equery.
Please read http://www.gentoo.org/proj/en/portage/glsa-integration.xml
before using this tool AND before reporting a bug.

This system is affected by the following GLSA:
200504-06
200510-08
200506-14
200501-35
200508-12
200507-16

(Averiguar que paquetes serían actualizados)
# glsa-check -p $(glsa-check -t all)
     (salida parcial)
Checking GLSA 200504-06
The following updates will be performed for this GLSA:
     app-arch/sharutils-4.2.1-r11 (4.2.1-r10)

**********************************************************************

Checking GLSA 200510-08
The following updates will be performed for this GLSA:
     media-libs/xine-lib-1.1.0-r5 (1.1.0-r4)

(Aplicación de los cambios requeridos)
# glsa-check -f $(glsa-check -t all)

Si se ha actualizado un servicio en ejecución, no deberemos olvidar reiniciarlo.

Conservar el núcleo actualizado también es recomendable.

Si usted quiere recibir un mensaje cada vez que se libera un GLSA, subscríbase a la lista de correo gentoo-announce. Las instrucciones para unirse así como otras buenas listas de correo las pude encontrar en Gentoo Linux Mailing List Overview.

Otro buen recurso de seguridad es Bugtraq mailinglist.

Imprimir

Página actualizada 1 de junio, 2014

Sumario: Este manual es una guía paso a paso para asegurar Gentoo Linux.

Kim Nielsen
Autor

John P. Davis
Editor

Eric R. Stockbridge
Editor

Carl Anderson
Editor

Jorge Paulo
Editor

Sven Vermeulen
Editor

Benny Chuang
Editor

Sune Jeppesen
Editor

Tiemo Kieft
Editor

Zack Gilburd
Editor

Dan Margolis
Editor

Joshua Saddler
Editor

John Christian Stoddart
Traductor

José Luis Rivero
Traductor

Postel
Traductor

Carles Ferrer Peris
Traductor

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.