Tag Archives: iptables

OpenVZ: Habilitar Acceso A Internet Dentro De Los Containers

Tras crear containers en nuestra máquina OpenVZ puede que necesitemos habilitar acceso a internet dentro de ellos para, por ejemplo, realizar actualizaciones.

Para habilitar que los containers, que sólo tienen IP privadas, tengan acceso a Internet deberemos configurar SNAT (Source Network Address Translation, también conocido como enmascaramiento de IP) en el nodo físico. Para esto utilizaremos unas simples reglas de iptables como la que se muestran a continuación:

# iptables -t nat -A POSTROUTING -s private_ip -o eth0 -j SNAT --to public_ip

Por ejemplo, si nuestra máquina física utiliza una IP pública 88.88.88.88 y queremos utilicen una IP privada 192.168.1.0/24 tendriamos que escribir:

# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 88.88.88.88

También tendremos que habilitar una regla para reenvio de paquetes así:

# iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT
# iptables -A FORWARD -d 192.168.1.0/24 -j ACCEPT

Con esto ya podríamos probar como desde dentro de algún container disponemos de acceso completo a Internet

vzctl exec $CTID ping debian.org

Acceder por SSH a Containers OpenVZ

Para acceder a los contenedores de una instalación OpenVZ debemos cambiar el puerto de escucha en la máquina física y con un regla de iptables redirigir la conexión al container que queremos.

Para la numeración de puertos podemos usar la regla que más nos guste, una que se me ocurrió fue concatenar el último octeto de la IP del container con el 22 (puerto por defecto de SSH).

Así para los containers de la 192.168.1.100 al 110 tendriamos los puerto 10022, 10122, 10222,…

Ahora para acceder debemos crear la regla de iptables, una para cada container:

iptables -t nat -A PREROUTING -p tcp --dport 10022 -j DNAT --to-destination 192.168.1.100:22

Evitar ataques DOS con mod_evasive e iptables

Vamos a explicar como proteger un servidor web Apache contra ataques DOS y DDOS mediante el módulo mod_evasive y el firewall nativo de Linux IPTables.

El servidor corre Debian Lenny, y hago incapie en esto porque la configuración de Apache varía mucho según la distribución que estemos utilizando.

Ya tenemos el servidor instalado y configurado y nos interesa protegerlo, para ello instalamos el módulo de Apache mod_evasive:

apt-get install libapache2-mod-evasive

También es posible descargar y compilar, pero prefiero siempre en la medida de lo posible, usar paquetes proporcionados por la distribución.

En Debian Lenny, el archivo de configuración de Apache es /etc/apache2/apache2.conf en el podemos escribir la configuración del módulo, o mejor, comprobar que existe la línea

Include /etc/apache2/mods-enabled/*.conf

y añadir la configuración del módulo en un fichero nuevo dedicado, por mantener el orden, por ejemplo mod-evasive.conf La configuración que viene por defecto es la siguiente.

<IfModule evasive20_module>
  DOSHashTableSize 3097
  DOSPageCount 2
  DOSSiteCount 50
  DOSPageInterval 1
  DOSSiteInterval 1
  DOSBlockingPeriod 300
</IfModule>

Lo primero que debemos observar es el nombre del módulo, es variable según la distribución en la que nos encontremos o si lo hemos compilado nosotros eligiendo otro nombre.

La explicación de cada parámetro la transcribo de tail -f | systemadmin

  • DOSHashTableSize <valor> – Establece el número de nodos a almacenar para cada proceso de peticiones de la tabla hash (contenedor asociativo de recuperación de peticiones por medio de claves que agiliza las respuestas del servidor). Si aplicamos un número alto a este parámetro obtendremos un rendimiento mayor, ya que las iteraciones necesarias para obtener un registro de la tabla son menores. Por contra, y de forma evidente, aumenta el consumo de memoria necesario para el almacenamiento de una tabla mayor. Se hace necesario incrementar este parámetro si el servidor atiende un número abultado de peticiones, aunque puede no servir de nada si la memoria de la máquina es escasa.
  • DOSPageCount <valor> – Indica el valor del umbral para el número de peticiones de una misma página (o URI) dentro del intervalo definido en DOSPageInterval. Cuando el valor del parámetro es excedido, la IP del cliente se añade a la lista de bloqueos.
  • DOSSiteCount <valor> – Cuenta cuántas peticiones de cualquier tipo puede hacer un cliente dentro del intervalo definido en DOSSiteInterval. Si se excede dicho valor, el cliente queda añadido a la lista de bloqueos.
  • DOSPageInterval <valor> – El intervalo, en segundos, para el umbral de petición de páginas.
  • DOSSiteInterval <valor> – El intervalo, en segundos, para el umbral de petición de objetos de cualquier tipo.
  • DOSBlockingPeriod <valor> – Establece el tiempo, en segundos, que un cliente queda bloqueado una vez que ha sido añadido a la lista de bloqueos. Como ya se indicó unas líneas atrás, todo cliente bloqueado recibirá una respuesta del tipo 403 (Forbidden) a cualquier petición que realice durante este periodo.
  • DOSEmailNotify <e-mail> – Un e-mail será enviado a la dirección especificada cuando una dirección IP quede bloqueada. La configuración del proceso de envío se establece en el fichero mod_evasive.c de la forma /bin/mail -t %s, siendo %s el parámetro que queda configurado en este parámetro. Será necesario cambiar el proceso si usamos un método diferente de envío de e-mails y volver a compilar el módulo con apxs (por ejemplo, la opción t ha quedado obsoleta en las últimas versiones del comando).
  • DOSSystemCommand <comando> – El comando reflejado se ejecutará cuando una dirección IP quede bloqueada. Se hace muy útil en llamadas a herramientas de filtrado o firewalls. Usaremos %s para especificar la dirección IP implicada. Por ejemplo, podemos establecer su uso con iptables de la forma siguiente:
    DOSSystemCommand “/sbin/iptables –I INPUT –p tcp –-dport 80 –s %s –j DROP”
  • DOSLogDir <ruta> – Establece una ruta para el directorio temporal. Por defecto, dicha ruta queda establecida en /tmp, lo cual puede originar algunos agujeros de seguridad si el sistema resulta violado.
  • DOSWhitelist <IP> – La dirección IP indicada como valor del parámetro no será tenida en cuenta por el módulo en ningún caso. Para cada dirección IP a excluir ha de añadirse una nueva línea con el parámetro. Por ejemplo, dejaremos fuera del chequeo del módulo a un posible bot que use los siguientes rangos de direcciones:
    DOSWhitelist 66.249.65.*
    DOSWhitelist 66.249.66.*
    

Para activar el módulo simplemente

# a2enmod mod-evasive

Como vemos tiene más opciones, la que ahora nos insteresa es la de DOSSystemCommand que es la que permite ejecutar acciones en el sistema.

IPTables es un programa para crear reglas de filtrado de tráfico de red, es un programa que debe ser ejecutado por un usuario con privilegios (root), pero siguiendo la Ley del permiso mínimo el servidor corre bajo un usuario no privilegiado, esta medida protege que ante un desbordamiento no quede una sesión privilegiada colgada.

El usuario que corre el servidor web no puede correr IPTables pero no está todo perdido, lo que tenemos que hacer es pasarle un mensaje a root con la IP que tiene que bloquear, y eso hemos visto ya como se puede hacer.

Primero añadimos la siguiente línea a nuestro fichero de configuración del módulo (en apache2.conf o en mod-evasive.conf)

DOSSystemCommand "/home/$USER/bin/checkIP %s"

En $USER/bin hemos escrito un script que actualizará un registro de IP que están haciendo más peticiones de la cuenta, el script tiene una pinte así

#!/bin/bash
# Este script llevara un fichero de log de los
# intentos de ataques DOS DDOS al servidor

DATE=$(date +%Y-%m-%d-%k-%M-%S);
LOGFILE="/home/$USER/bin/CheckIp.log";

echo $DATE $1 >> $LOGFILE;

Simplemente crea un log de IP’s con este formato:

2010-10-31-20-16-41 1.1.1.2
2010-10-31-20-16-41 86.217.15.159
2010-10-31-20-16-41 92.21.26.197

Ahora entra en juego root, que se encargará de supervisar este fichero y actuar si cambia, para ello nos apoyamos en incron, creamos una nueva regla de supervisión del sistema de fichero así

Abrimos el fichero
# incrontab -e
Editamos el fichero
/home/$USER/bin/CheckIP.log IN_MODIFY /root/bin/banIP

El script que hemos escrito banIP se ejecutará cada vez que se modifique el fichero CheckIP.log y pasara la IP a la lista de IPTables,

#!/bin/bash
LOGFILE="/home/$USER/bin/CheckIP.log";
IP=$(tail -n 1 $LOGFILE | cut -d" " -f 2);
/sbin/iptables -I INPUT -p tcp --dport 80 -s $IP -j DROP;

Para probar si está funcionando podemos ejecutar el script perl que proporciona el paquete mod_evasive, veremos algo como esto:

$ perl /usr/share/doc/libapache2-mod-evasive/examples/test.pl
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
Expiró el tiempo de conexión at test.pl line 12.

Con el reinicio del servidor se perderan las reglas si no se guardan.

Con esto hemos ganado unos cuantos puntos de seguridad, de por sí, mod_evasive evita exceso de peticiones, al combinarlo con IPTables liberamos a Apache de ese trabajo dejandolo en manos de un programa diseñado para eso.