jueves, 15 de mayo de 2008

Seguridad IP (IPSec)

Seguridad IP (IPSec) es el cifrado del tráfico de red. No se puede cifrar la información de la cabecera ni el trailer (p. ej. la dirección IP y puerto de donde viene el paquete y su destino, los checksums de CRC, etc.), pero se puede cifrar la carga útil. Esto permite asegurar protocolos como POP/WWW sin tener que cambiarlos de ninguna forma, puesto que el cifrado se hace en el nivel IP. También permite conectar de forma segura LANs y clientes entre sí, sobre redes inseguras (como Internet). En la actualidad, IPSec para Linux está en fase de pruebas, sin embargo ya se han lanzado varias versiones estables, y yo mismo he desarrollado servidores seguros basados en IPSec. IPSec es un standard, y parte el protocolo IPv6, de modo que ya se puede comprar software IPSec para Windows 95/98/NT, Solaris y otros Unix, que interoperarán con Linux IPSec.



Soporte IPSec del kernel

Para utilizar IPSec es necesario tener soporte IPSec en el kernel. Desafortunadamente, ninguna distribución Americana de Linux puede exportar criptografía robusta fuera de Norte América, de modo que en general, suelen escoger no incluirla en absoluto, de las distribuciones extranjeras de Linux, en la actualidad ninguna viene con soporte IPSec dentro del kernel. Es necesario conseguir el código fuente del kernel (recomiendo la 2.2.10, la más reciente a la hora de escribir esto), y el código fuente del Linux IPSec, disponible en: http://www.xs4all.nl/~freeswan/∞

Instala el fuente del kernel (generalmente en /usr/src/linux) y compila el nuevo kernel, instálalo, arráncalo y pruébalo. Asegúrate de que tus redes funcionan correctamente, si no funcionan, hacer que lo haga IPSec será imposible. Ahora hay que descargar la última instantánea de IPSec (la versión 1.0 NO funcionará con los kernels 2.2.x). Después ir a /usr/local/src (o dondequiera que hayas puesto el código fuente de tus programas), desempaquetar el fuente y ejecutar el programa de instalación (make menugo suele ser lo habitual para la configuración basada en ncurses). Lo cual parcheará los ficheros del kernel, luego ejecuta la configuración del kernel y después construye las herramientas IPSec y el kernel.

cd /usr/local/src/

tar –zvvxf /path/del/tarball/snapshot.tar.gz

chown –R root:root freeswan-snap1999Jun14b

cd freeswan-snap1999Jun14b

make menugo

asegúrate de guardar la configuración del kernel, incluso aunque se hayan elegido las opciones, no han sido guardadas. También tendrás que reconstruir el kernel, puesto que el comando "make menugo" ejecuta un "make zImage", lo cual suele fallar, debido a los grandes tamaños del kernel de la 2.2.x. Una vez que se ha hecho la compilación, debería dar uno o dos mensajes de error, simplemente haz:

cd /usr/src/linux

make bzImage

cp /usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz-2.2.10-ipsec

Ahora hay que editar lilo.conf, ejecutar lilo de nuevo y reiniciar para hacer uso del nuevo kernel.

lilo.conf debería tener el siguiente aspecto:

boot=/dev/hda

map=/boot/map

install=/boot/boot.b

prompt

timeout=100

image=/boot/vmlinuz-2.2.10-ipsec

label=linux-ipsec

root=/dev/hda1

read-only

image=/boot/vmlinuz-2.2.10

label=linux

root=/dev/hda1

read-only

vuelve a ejecutar lilo y verás:

linux-ipsec *

linux

después reinicia y deberías estar ejecutando el kernel 2.2.10 con soporte IPSec. A medida que la máquina se reinicia y empieza el IPSec se verán varios errores, por defecto IPSec está configurado para utilizar el interfaz eth999, el cual por supuesto no existe. Deberías añadir /usr/local/lib/ipsec en la frase del path o si no tendrás que escribir el path completo un montón.



Configuración de redes IPSec

Tendrás que habilitar el TCP-IP forwarding en el servidor de enlace, en Red Hat Linux se hace cambiando la línea de /etc/sysconfig/network:

FORWARD_IPV4="false"

por:

FORWARD_IPV4="yes"

o se puede habilitar vía sistema de ficheros en /proc:

cat 1 > /proc/sys/net/ipv4/ip_forward

Puesto que la mayoría de la gente tiene por defecto políticas de denegación de paquetes de forwarding, tendrás que permitir que los paquetes atraviesen la rede remota / máquina de tu red / máquina y vice versa. Además de esto, cualquier regla de enmascaramiento para redes internas que también estén usando IPSec debe venir después de las reglas que permiten el tráfico IPSec, o la máquina intentará enmascarar los paquetes, en lugar de pasarlos al IPSec.

El siguiente ejemplo es para dos redes protegidas (usando direcciones IP no rutables, escondidas tras máquinas Linux haciendo enmascaramiento de IPs) conectadas vía Internet:

10.0.0.2 192.168.0.2

10.0.0.1 192.168.0.1

1.2.3.4 5.6.7.8

1.2.3.1 5.6.7.1

2.3.4.5 6.7.8.9

INTERNET



Conexión manual de llaves

Primero configuraremos un enlace utilizando la conexión manual de llaves (por simplicidad), hay que editar ipsec.conf, y las reglas del cortafuegos. La mayoría de las opciones por defecto del fichero ipsec.conf son correctas, pero hay que cambiar lo siguiente:

conn ejemplo

type=tunnel

left=

leftnexthop=

leftsubnet=

right=

rightnexthop=

rightsubnet=

spibase=0x200

esp=3des-md5-96

espenckey=

espauthkey=

reemplaza la espenckey y la espauthkey con las nuevas llaves (utilizando ranbits para generar un número, recuerda dejar el 0x por delante, que especifica que es un número hexadecimal) de modo que es algo así:

conn mi-tunel

type=tunnel

left=1.2.3.4

leftnexthop=1.2.3.1

leftsubnet=10.0.0.0/24

right=5.6.7.8

rightnexthop=5.6.7.1

rightsubnet=192.168.0.0/24

spibase=0x200

esp=3des-md5-96

espenckey=cualquier_llave_de_autentificación (ranbits 192)

espauthkey=cualquier_otra_llave (ranbits 128)

Una vez que has acabado, copia los ficheros ipsec.conf e ipsec.secrets desde la máquina en que los editaste hasta el otro servidor, de forma segura. Ahora, lo único que queda es añadir reglas al cortafuegos para que no se enmascaren los paquetes (en lugar de eso lo que queremos es redirigirlos, hacer un forward).

En el servidor 1.2.3.4 se deberían añadir las siguientes reglas:

ipchains –A forward –p all –j ACCEPT –s 10.0.0.0/24 –d 192.168.0.0./24

ipchains –A forward –p all –j ACCEPT –s 192.168.0.0/24 –d 10.0.0.0/24

asegúrate de que estas reglas aparecen antes de la regla de enmascaramiento, algo así:

#

# FORWARD RULES

#

ipchains –P forward DENY

#

ipchains –A forward –p all –j ACCEPT –s 10.0.0.0/24 –d 192.168.0.0/24

ipchains –A forward –p all –j ACCEPT –s 192.168.0.0/24 –d 10.0.0.0/24

ipchains –A forward –p all –j MASQ –s 10.0.0.0/24 –d 0.0.0.0/0

Y en el servidor 5.6.7.8 se repetiría el proceso:

ipchains –A forward –p all –j ACCEPT –s 192.168.0.0/24 –d 10.0.0.0/24

ipchains –A forward –p all –j ACCEPT –s 10.0.0.0/24 –d 192.168.0.0/24

asegúrate de que estas reglas aparecen antes de la regla de enmascaramiento, algo así:

#

# FORWARD RULES

#

ipchains –P forward DENY

#

ipchains –A forward –p all –j ACCEPT –s 192.168.0.0/24 –d 10.0.0.0/24

ipchains –A forward –p all –j ACCEPT –s 10.0.0.0/24 –d 192.168.0.0/24

ipchains –A forward –p all –j MASQ –s 192.168.0.0/24 –d 0.0.0.0/0

Ahora deberías ser capaz de establecer el túnel ipsec manualmente en ambas máquinas, y las máquinas de la Red A deberían ser capaces de hablar con las máquinas de la red B sin problemas.

ipsec manual –up mi-tunel

lo cual mostraría una salida similar a:

/usr/local/lib/ipsec/spi: message size is 36

/usr/local/lib/ipsec/spi: message size is 132

/usr/local/lib/ipsec/spi: message size is 132

Para probarlo, haz un ping a 192.168.0.2 desde el cliente 10.0.0.2. Si funciona, lo has configurado correctamente. Si no funciona, verifica tu red para asegurarte de que 1.2.3.4 puede ver 5.6.7.8 y que está habilitado el TCP-IP forwarding, y asegúrate de que no hay reglas del cortafuegos que estén bloqueando paquetes o intentando enmascararlos. Una vez que has establecido y probado la conexión con éxito, deberías pasar a la conexión automática de llaves (especialmente en entornos de producción).



Conexión automática de llaves

Si se intenta usar IPSec en un entorno de producción, la conexión manual de llaves es una mala idea, en términos generales. Con la conexión automática se tiene un secreto compartido de 256bit que se copia a ambos lados del túnel, el cual se utiliza durante el intercambio de llaves para asegurarse que no se dan ataques del tipo "man in the middle, hombre de por medio". Con la conexión automática, la vida media de una llave es de 8 horas, lo cual se puede ajustar a cualquir intervalo, y si alguien se las arregla para atacar por fuerza bruta la llave, sólo será válida durante ese período de tráfico de 8 horas. El ejemplo siguiente se construye sobre el anterior:

ipsec.secrets contiene el secreto compartido. Este fichero debe ser puesto a salvo a toda costa. Para una conexión entre los servidores 1.2.3.4 y 5.6.7.8 se necesitaría una línea como:

1.2.3.4 5.6.7.8

"0xa3afb7e6_20f10d66_03760ef1_9019c643_a73c7ce0_91e46e84_ef6281b9_812392bf"



Esta línea necesita estar en ambos ficheros ipsec.secrets. Después se necesitaría editar la configuración del túnel en ipsec.conf por la siguiente:

conn mi-tunel

type=tunnel

left=1.2.3.4

leftnexthop=1.2.3.1

leftsubnet=10.0.0.0/24

right=5.6.7.8

rightnexthop=5.6.7.1

rightsubnet=192.168.0.0/24

keyexchange=ike

keylife=8h

keyingtries=0

Entonces se arrancaría el demonio pluto, intenta conectar al demonio Pluto desde el otro extremo del túnel, y establece una conexión. Una advertencia, Pluto se ejecuta en el puerto 500, udp, de modo que lo más probable es que tengas que abrir un hueco en el cortafuegos para permitirle pasar:

ipchains –A input –p udp –j ACCEPT –s 0.0.0.0/0 –i eth0 –d 0.0.0.0/0 500



Encuentro conveniente el uso de la clave "%search" en lugar de listar el túnel a arrancarse, añadiendo:

auto=start

para cada configuración del túnel y editar el ipsec.secrets:

plutoload=%search

plutostart=%search

Lo cual a la larga te hará la vida más fácil. Si todo va bien, deberías ver algo parecido a esto en /var/log/messages:

|| Jun 26 02:10:41 server ipsec_setup: Starting FreeS/WAN IPSEC... Jun 26 02:10:41 server ipsec_setup: /usr/local/lib/ipsec/spi: message size is 28 Jun 26 02:10:41 server ipsec_setup: KLIPS debug ‘none’ Jun 26 02:10:41 server ipsec_setup: KLIPS ipsec0 on eth0 1.2.3.4/255.255.255.0 broadcast 24.108.11.255 Jun 26 02:10:42 server ipsec_setup: Disabling core dumps: Jun 26 02:10:42 server ipsec_setup: Starting Pluto (debug ‘none’): Jun 26 02:10:43 server ipsec_setup: Loading Pluto database ‘mi-tunel’: Jun 26 02:10:44 server ipsec_setup: Enabling Pluto negotiation: Jun 26 02:10:44 server ipsec_setup: Routing for Pluto conns ‘mi-tunel’: Jun 26 02:10:45 server ipsec_setup: Initiating Pluto tunnel ‘mi-tunel’: Jun 26 02:10:45 server ipsec_setup: 102 "mi-tunel" #1: STATE_MAIN_I1: initiate Jun 26 02:10:45 server ipsec_setup: 104 "mi-tunel" #1: STATE_MAIN_I2: from STATE_MAIN_I1; sent MI2, expecting MR2 Jun 26 02:10:45 server ipsec_setup: 106 "mi-tunel" #1: STATE_MAIN_I3: from STATE_MAIN_I2;sent MI3, expecting MR3 Jun 26 02:10:45 server ipsec_setup: 003 "mi-tunel" #1: STATE_MAIN_I4: SA established Jun 26 02:10:45 server ipsec_setup: 110 "mi-tunel" #2: STATE_QUICK_I1: initiate Jun 26 02:10:45 server ipsec_setup: 003 "mi-tunel" #2: STATE_QUICK_I2: SA established Jun 26 02:10:46 server ipsec_setup: ...FreeS/WAN IPSEC started ||

Y en el fichero /var/log/secure se debería ver algo parecido a esto:

|| Jun 26 02:10:42 server Pluto[25157]: Starting Pluto (FreeS/WAN Version snap1999Jun14b Jun 26 02:10:42 server Pluto[25157]: added connection description "mi-tunel" Jun 26 02:10:42 server Pluto[25157]: listening for IKE messages Jun 26 02:10:42 server Pluto[25157]: adding interface ipsec0/eth0 1.2.3.4 Jun 26 02:10:42 server Pluto[25157]: loading secrets from "/etc/ipsec.secrets" Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #1: initiating Main Mode Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #1: ISAKMP SA established Jun 26 02:10:42 server Pluto[25157]: "seifried-mosqueado" #2: initiating Quick Mode POLICY_ENCRYPT+POLICY_TUNNEL+POLICY_PFS Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #2: sent QI2, IPsec SA established Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #3: responding to Main Mode Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #3: sent MR3, ISAKMP SA established Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #4: responding to Quick Mode Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #4: IPSec SA established Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #5: responding to Main Mode Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #5: sent MR3, ISAKMP SA established Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #6: responding to Quick Mode Jun 26 02:10:42 server Pluto[25157]: "mi-tunel" #6: IPsec SA established ||

Además de esto se puede ver la salida de "eroute" para asegurarse de que los túneles están correctamente configurados:

10.0.0.0/24 -> 192.168.0.0/24 => tun0x114@1.2.3.4

Y si le echas un vistazo a tus rutas ("route"), deberías ver:

Kernel IP routing table

Destination Gateway Genmask Flags Metric Ref Use Iface

1.2.3.4 0.0.0.0 255.255.255.255 UH 0 0 0 eth0

10.0.0.1 0.0.0.0 255.255.255.255 UH 0 0 0 eth1

1.2.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

1.2.3.0 0.0.0.0 255.255.255.0 UG 0 0 0 ipsec0

192.168.0.0 1.2.3.1 255.255.255.0 UG 0 0 0 ipsec0

10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1

127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo

0.0.0.0 1.2.3.1 0.0.0.0 UG 0 0 0 eth0



Productos IPSec comerciales

He pensado que sería interesante hacer un breve listado de los productos IPSec comerciales, por supuesto haciendo énfasis en los basados en Linux y FreeS/WAN

i-data

i-data desarrolla una línea de productos que incluyen un servidor VPN, basado en Linux y en FreeS/WAN. Están ubicados en Dinamarca, lo cual les permite que su producto esté disponible para todo el mundo. El sitio web está en: http://www.i-data.com/networks/∞

Productos IPSec para Windows

También existen paquetes de software que proporcionan capacidad de IPSec para Windows, uno de los cuales incluso es gratuito.

PGP VPN

Los autores de PGP (Network Associates) han creado un paquete de software "PGP VPN" (que tiene muy poco que ver con PGP). Soporta IPSec y se dice que también opera con Linux FreeS/WAN. Se puede conseguir en: http://www.nai.com/asp_set/products/tns/pgp_vpn.asp∞

IRE

http://www.ire.com∞

No hay comentarios: