Configuración de VPN con IPsec (ESP en modo túnel)

Introducción

Utilizaremos el software de strongswan para configurar una VPN.

strongswan es un demonio para la gestión automática de las claves. Se negociarán los SA entre dos extremos y las políticas de seguridad utilizando IKE. El tráfico IPsec lo gestiona la implementación de IPsec del sistema operativo.

Vamos a configurar ESP en modo túnel, utilizando AES para el cifrado y firmas como algoritmo para la autenticación (RSA-SIG). Para ello hay que crear los certificados X.509 necesarios para los dos extremos de la comunicación. La creación de certificados se encuentra en la sección de certificados.

En la siguiente figura se muestra el detalle del paquete ESP en modo túnel, donde todo el paquete original queda cifrado dentro de la parte protegida. La cabecera ESP está formada por el SPI y el número de secuencia que permite detectar duplicados.

Paquete encapsulado con ESP.<span
data-label="fig:detalleESP"></span>

Procesar la salida de un paquete IPsec

Cuando un datagrama está preparado en la cola de salida, se comprueba si necesita ser procesado por IPsec. Si se necesita encapsulado ESP, su configuración dependerá de lo que haya en la SA, modo transporte o túnel.

  1. Se consulta SDP para saber si existe una política aplicable al paquete (se busca por direcciones IP origen y destino, protocolo, etc.) para determinar la SA. Si es necesario aplicar IPsec y no se encuentra SA, se negocia una SA.

  2. Se incrementa el número de secuencia de la SA y se almacena en la cabecera ESP.

  3. Se añade la cola ESP: relleno (si es necesario), longitud del relleno y el campo siguiente cabecera. Se cifran los datos y la cola ESP utilizando el algoritmo especificado en SA.

  4. Se calcula una función de integridad de datos sobre la cabecera ESP, datos y cola ESP y se almacena en la parte de autenticación de datos. El algoritmo utilizado es el que está especificado en SA.

Procesar la entrada de un paquete IPsec

  1. Tomando la dirección destino, protocolo (ESP/AH) y SPI se busca SA en SAD. Si no existe, se tira el paquete.

  2. Si está activado el servicio de detección de duplicado, se comprueba que el número de secuencia cae dentro de la ventana de detección de duplicados.

  3. El paquete es autenticado: se calcula la función de integridad especificada en SA sobre la cabecera ESP, datos y cola ESP y se comprueba que es igual a los datos de autenticación recibidos. Si es correcto, se actualiza la ventana de detección de duplicados.

  4. Se descifra el paquete: datos y cola ESP utilizando el algoritmo especificado en SA. Se reconstruye el datagrama original a partir del paquete ESP.

VPN entre subredes, modo túnel{#vpn-tunel)

En la siguiente figura se muestra el escenario donde se va a probar la VPN en modo túnel entre las subredes 10.1.0.0/24 y 10.2.0.0/24.

Escenario para una VPN entre dos subredes<span
data-label="fig:VPN-subredes"></span>

Utilizaremos para el cifrado AES128 y para la autenticación certificados. El algoritmo de hash será SHA256.

VPN en lado servidor (r1)

Configuración

Para ello editaremos los siguientes ficheros en r1:

  • El fichero /etc/ipsec.conf La terminología left y right hace referencia a máquina local y máquina remota respectivamente. Como estamos configurando en r1:

    • r1 será el lado left o local y r2 será el lado right o remoto.

    • leftsubnet es la subred local que queremos conectar a través de la VPN 10.1.0.0/24.

    • rightsubnet es la subred remota que queremos conectar a través de la VPN 10.2.0.0/24.

    • leftcert es el certificado local de r1.

    • rightcert es el certificado remoto de r2.

    • leftid es la identidad a la cuál está asociada el certificado local, r1.

    • rightid es la identidad a la cuál está asociada el certificado remoto, r2.

    r1:~# less /etc/ipsec.conf
    # /etc/ipsec.conf - strongSwan IPsec configuration file
    
    config setup 
            # En esta sección se describen los parámetros generales de la comunicación
    
    conn %default
        # Esta sección define parámetros que heredan todas las conexiones definidas posteriormente
            ikelifetime=60m
            keylife=20m
            rekeymargin=3m
            keyingtries=1
            keyexchange=ikev1
            ike=aes128-sha256-modp3072!
            esp=aes128-sha256-modp3072!
    
    conn net-net
            left=192.168.0.1
            leftcert=r1Cert.pem
            leftfirewall=yes
            leftid=@r1
            leftsubnet=10.1.0.0/24
            right=192.168.0.2
            rightid=@r2
            rightsubnet=10.2.0.0/24
            type=tunnel
            auto=add
    

    La sección conn define las conexiones que utilizarán IPsec.

  • El fichero /etc/ipsec.secrets

    r1:~#  less /etc/ipsec.secrets
    # This file holds shared secrets or RSA private keys for inter-Pluto
    # authentication.  See ipsec_pluto(8) manpage, and HTML documentation.
    
    # RSA private key for this host, authenticating it to any other host
    # which knows the public part.  Suitable public keys, for ipsec.conf, DNS,
    # or configuration of other implementations, can be extracted conveniently
    # with "ipsec showhostkey".
    
    # this file is managed with debconf and will contain the automatically created private key
    #include /var/lib/strongswan/ipsec.secrets.inc
    
    : RSA r1Key.pem
    
  • El fichero hosts

    r1:~#  less /etc/hosts
    127.0.0.1 localhost localhost.localdomain
    192.168.0.1 r1
    
    ::1     ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    ff02::3 ip6-allhosts
    

Activar IPsec

Para activar IPsec:

r1:~#  ipsec start

Para ver la claves cargadas en IPsec:

r1:~# ipsec secrets
002 forgetting secrets
002 loading secrets from "/etc/ipsec.secrets"
002   loaded private key from 'r1Key.pem'

Para comprobar el estado de IPsec:

root@r1:~# ipsec status
000 "net-net": 10.1.0.0/24===192.168.0.1[r1]...192.168.0.2[r2]===10.2.0.0/24;
                       unrouted; eroute owner: #0
000 "net-net":   newest ISAKMP SA: #0; newest IPsec SA: #0; 
000 
Security Associations:
  none

Donde se indica que aún no hay SAs para la comunicación net-net donde está activado ISAKMP.

VPN en lado cliente (r2)

Configuración

Para ello editaremos los siguientes ficheros en r2:

  • El fichero /etc/ipsec.conf La terminología left y right hace referencia a máquina local y máquina remota respectivamente. Como estamos configurando en r2:

    • r2 será el lado left o local y r1 será el lado right o remoto.

    • leftsubnet es la subred local que queremos conectar a través de la VPN 10.2.0.0/24.

    • rightsubnet es la subred remota que queremos conectar a través de la VPN 10.1.0.0/24.

    • leftcert es el certificado local de r2.

    • rightcert es el certificado remoto de r1.

    • leftid es la identidad a la cuál está asociada el certificado local, r2.

    • rightid es la identidad a la cuál está asociada el certificado remoto, r1.

    r2:~# less /etc/ipsec.conf
    # /etc/ipsec.conf - strongSwan IPsec configuration file
    
    config setup
    
    conn %default
            ikelifetime=60m
            keylife=20m
            rekeymargin=3m
            keyingtries=1
            keyexchange=ikev1
            ike=aes128-sha256-modp3072!
            esp=aes128-sha256-modp3072!
    
    conn net-net
            left=192.168.0.2
            leftfirewall=yes
            leftcert=r2Cert.pem
            leftsubnet=10.2.0.0/24
            leftid=@r2
            right=192.168.0.1
            rightsubnet=10.1.0.0/24
            rightid=@r1
            auto=add
    
  • El fichero /etc/ipsec.secrets

    r2:~#  less /etc/ipsec.secrets
    # This file holds shared secrets or RSA private keys for inter-Pluto
    # authentication.  See ipsec_pluto(8) manpage, and HTML documentation.
    
    # RSA private key for this host, authenticating it to any other host
    # which knows the public part.  Suitable public keys, for ipsec.conf, DNS,
    # or configuration of other implementations, can be extracted conveniently
    # with "ipsec showhostkey".
    
    # this file is managed with debconf and will contain the automatically created private key
    #include /var/lib/strongswan/ipsec.secrets.inc
    
    : RSA r2Key.pem
    
  • El fichero hosts

    r2:~#  less /etc/hosts
    127.0.0.1 localhost localhost.localdomain
    192.168.0.1 r1
    
    ::1     ip6-localhost ip6-loopback
    fe00::0 ip6-localnet
    ff00::0 ip6-mcastprefix
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    ff02::3 ip6-allhosts
    

Activar IPsec y crear la VPN con el servidor

Para activar IPsec:

r2:~#  ipsec start

Para ver la claves cargadas en IPsec:

r2:~# ipsec secrets
002 forgetting secrets
002 loading secrets from "/etc/ipsec.secrets"
002   loaded private key from 'r2Key.pem'

Para comprobar el estado de IPsec:

r2:~# ipsec status
000 "net-net": 10.2.0.0/24===192.168.0.2[r2]...192.168.0.1[r1]===10.1.0.0/24; 
                       unrouted; eroute owner: #0
000 "net-net":   newest ISAKMP SA: #0; newest IPsec SA: #0; 
000 
Security Associations:
  none

Para conectarse con el lado servidor de la VPN utilizando IPsec:

r2:~# ipsec up net-net

Comprobación del establecimiento de la VPN

Para comprobar el estado de IPsec en r1:

r1:~# ipsec status
000 "net-net": 10.1.0.0/24===192.168.0.1[r1]...192.168.0.2[r2]===10.2.0.0/24; 
                erouted; eroute owner: #2 
000 "net-net":   newest ISAKMP SA: #1; newest IPsec SA: #2;
000 
000 #2: "net-net" STATE_QUICK_R2 (IPsec SA established); 
                  EVENT_SA_REPLACE in 988s; newest IPSEC; eroute owner
000 #2: "net-net" [email protected] (840 bytes, 81s ago) 
                  [email protected] (840 bytes, 81s ago); tunnel
000 #1: "net-net" STATE_MAIN_R3 (sent MR3, ISAKMP SA established); 
                  EVENT_SA_REPLACE in 3387s; newest ISAKMP
000  
Security Associations:
  none

Donde se está utilizando ESP en modo túnel destino=192.168.0.2, SPI=ce835c0f y origen=192.168.0.1, SPI=c8cf0f4f.

Para comprobar el estado de IPsec en r2:

r2:~# ipsec status
000 "net-net": 10.2.0.0/24===192.168.0.2[r2]...192.168.0.1[r1]===10.1.0.0/24; 
                erouted; eroute owner: #2
000 "net-net":   newest ISAKMP SA: #1; newest IPsec SA: #2; 
000 
000 #2: "net-net" STATE_QUICK_I2 (sent QI2, IPsec SA established); 
                 EVENT_SA_REPLACE in 584s; newest IPSEC; eroute owner
000 #2: "net-net" [email protected] (840 bytes, 325s ago) 
                 [email protected] (840 bytes, 325s ago); tunnel
000 #1: "net-net" STATE_MAIN_I4 (ISAKMP SA established); 
                 EVENT_SA_REPLACE in 2902s; newest ISAKMP
000 Security Associations:
  none

Donde se está utilizando ESP en modo túnel destino=192.168.0.1, SPI=cefc64a5 y origen=192.168.0.2, SPI=cc6d4e5e.

SAD

xfrm (transform) es un framework utilizado para manipular paquetes a la entrada y salida de una máquina. Gestiona SAD (Security Asociation Database) y la SPD (Security Policy Database).

Una vez establecida la comunicación entre los dos extremos del túnel, se puede consultar la información de SAs. Deben existir en cada extremo 2 SAs, uno para cada sentido de la comunicación.

En r1:

r1:~# ip xfrm state
src 192.168.0.1 dst 192.168.0.2
        proto esp spi 0xce835c0f reqid 16384 mode tunnel
        replay-window 32 flag af-unspec
        auth-trunc hmac(sha256) 0x972feeb4fa34659af67b1cb1a2f0988331b61c5f2f16961782ad6202db5cd62e 128
        enc cbc(aes) 0xf024505f8f456a6a0f78a6cb8c5386b4
src 192.168.0.2 dst 192.168.0.1
        proto esp spi 0xc8cf0f4f reqid 16384 mode tunnel
        replay-window 32 flag af-unspec
        auth-trunc hmac(sha256) 0x91aa030b659b33a4d829b4aee2945f266a050a750323171e31fc3d063544de52 128
        enc cbc(aes) 0x782ef28cdbbfd53e5272a1316af9eb6f

Donde SPI=0xce835c0f desde 192.168.0.1 a 192.168.0.2 y SPI=0xc8cf0f4f desde 192.168.0.2 a 192.168.0.1. El identificador reqid=16384 debe ser igual al que se muestre en SP almacenada en SPD. Este identificador relaciona la SA con la SP.

En r2:

r2:~# ip xfrm state
src 192.168.0.2 dst 192.168.0.1
        proto esp spi 0xc8cf0f4f reqid 16384 mode tunnel
        replay-window 32 flag af-unspec
        auth-trunc hmac(sha256) 0x91aa030b659b33a4d829b4aee2945f266a050a750323171e31fc3d063544de52 128
        enc cbc(aes) 0x782ef28cdbbfd53e5272a1316af9eb6f
src 192.168.0.1 dst 192.168.0.2
        proto esp spi 0xce835c0f reqid 16384 mode tunnel
        replay-window 32 flag af-unspec
        auth-trunc hmac(sha256) 0x972feeb4fa34659af67b1cb1a2f0988331b61c5f2f16961782ad6202db5cd62e 128
        enc cbc(aes) 0xf024505f8f456a6a0f78a6cb8c5386b4

Donde SPI=0xc8cf0f4f desde 192.168.0.2 a 192.168.0.1 y SPI=0xce835c0f desde 192.168.0.1 a 192.168.0.2.

SPD

También se puede consultar en el lado del servidor la SPD (Security Policy Database).

En r1:

r1:~# ip xfrm policy
src 10.1.0.0/24 dst 10.2.0.0/24
        dir out priority 1859 ptype main
        tmpl src 192.168.0.1 dst 192.168.0.2
                proto esp reqid 16384 mode tunnel
src 10.2.0.0/24 dst 10.1.0.0/24
        dir fwd priority 1859 ptype main
        tmpl src 192.168.0.2 dst 192.168.0.1
                proto esp reqid 16384 mode tunnel
src 10.2.0.0/24 dst 10.1.0.0/24
        dir in priority 1859 ptype main
        tmpl src 192.168.0.2 dst 192.168.0.1
                proto esp reqid 16384 mode tunnel
src ::/0 dst ::/0
        socket out priority 0 ptype main
src ::/0 dst ::/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src ::/0 dst ::/0
        socket in priority 0 ptype main
src ::/0 dst ::/0
        socket out priority 0 ptype main
src ::/0 dst ::/0
        socket in priority 0 ptype main
src ::/0 dst ::/0
        socket out priority 0 ptype main
src ::/0 dst ::/0
        socket in priority 0 ptype main
src ::/0 dst ::/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main

Donde se han definido 3 políticas:

  • Los paquetes entrantes cifrados se descifran utilizando la SA (se hace búsqueda en SAD por dirección destino, SPI y protocolo=ESP) y después se comprueban las políticas: si van dirigidos a una dirección IP de r1 se aplica política in (por ejemplo un paquete dirigido a la interfaz 10.1.0.1 del r1, si no van dirigidos a r1 se aplica política fwd (por ejemplo un paquete dirigido a la interfaz 10.1.0.10, pc1).

  • En los paquetes salientes primero se consulta la política out para ver si encaja alguna regla, en cuyo caso se cifra el paquete utilizando la información de SA.

En r2:

r2:~# ip xfrm policy
src 10.2.0.0/24 dst 10.1.0.0/24
        dir out priority 1859 ptype main
        tmpl src 192.168.0.2 dst 192.168.0.1
                proto esp reqid 16384 mode tunnel
src 10.1.0.0/24 dst 10.2.0.0/24
        dir fwd priority 1859 ptype main
        tmpl src 192.168.0.1 dst 192.168.0.2
                proto esp reqid 16384 mode tunnel
src 10.1.0.0/24 dst 10.2.0.0/24
        dir in priority 1859 ptype main
        tmpl src 192.168.0.1 dst 192.168.0.2
                proto esp reqid 16384 mode tunnel
src ::/0 dst ::/0
        socket out priority 0 ptype main
src ::/0 dst ::/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src ::/0 dst ::/0
        socket in priority 0 ptype main
src ::/0 dst ::/0
        socket out priority 0 ptype main
src ::/0 dst ::/0
        socket in priority 0 ptype main
src ::/0 dst ::/0
        socket out priority 0 ptype main
src ::/0 dst ::/0
        socket in priority 0 ptype main
src ::/0 dst ::/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket in priority 0 ptype main
src 0.0.0.0/0 dst 0.0.0.0/0
        socket out priority 0 ptype main

Tráfico encapsulado en ESP

Al ejecutar ping desde pc2 hacia pc1, si capturamos el tráfico, éste muestra para el tráfico de entrada tanto el paquete cifrado como el descifrado y para el tráfico de salida sólo muestra el paquete cifrado.

  • Tráfico capturado en r1(eth1).

    En la figura [fig:r1-eth1] se muestra la captura de tráfico en r1(eth1).

    Tráfico capturado en la interfaz eth1 de r1<span
data-label="fig:r1-eth1"></span>

    Los paquetes 4 y 5 en realidad son el mismo mensaje ICMP echo request, siendo el paquete 4 el mensaje cifrado y el paquete 5 el mensaje descifrado:

    • El paquete 4 muestra en su cabecera IP que el paquete tiene como origen r2 y destino r1, los extremos del túnel ESP. Se puede ver que está usando SPI=0xc8cf0f4f que es la información que habíamos visto en esta SA. También se puede ver el número de secuencia, en este caso 2 (porque previamente se ha transmitido otro paquete, comienza en 1). Cada paquete enviado a través del túnel aumenta en uno el número de secuencia.

    • El paquete 5 está descifrado y lleva la información del paquete original creado por pc2: dirección IP origen pc2 y dirección IP destino pc1.

    El paquete 6 es la respuesta ICMP echo reply cifrada, por ello, las direcciones IP que se muestran son las de los extremos del túnel cuyo SPI=0xce835c0f se corresponde con el que se ha seleccionado para la comunicación en ese sentido en la SA.

  • Tráfico capturado en r2(eth0).

    En la figura [fig:r2-eth0] se muestra la captura de tráfico en r2(eth0).

    Tráfico capturado en la interfaz eth0 de r2<span
data-label="fig:r2-eth0"></span>

    El paquete 4 es el mensaje ICMP echo request que se envía inicialmente desde r2 cifrado (sólo muestra el tráfico cifrado en los paquetes de salida), usando SPI=0xc8cf0f4f.

    Los paquetes 5 y 6 en realidad son el mismo mensaje ICMP echo reply, siendo el paquete 5 el mensaje cifrado y el paquete 6 el mensaje descifrado:

    • El paquete 5 muestra en su cabecera IP que el paquete tiene como origen r1 y destino r2, los extremos del túnel ESP. Se puede ver que está usando SPI=0xce835c0f que es la información que habíamos visto en esta SA. También se puede ver el número de secuencia, en este caso 2 (porque previamente se ha transmitido otro paquete, comienza en 1). Cada paquete enviado a través del túnel aumenta en uno el número de secuencia.

    • El paquete 6 está descifrado y lleva la información del paquete original creado por pc1: dirección IP origen pc1 y dirección IP destino pc2.

Como puede observarse en los paquetes que van encapsulados utilizando ESP, los campos visibles son SPI y el número de secuencia. El resto de los campos van cifrados y no pueden interpretarse. En la figura anterior puede observarse en la representación hexadecimal como después del campo número de secuencia (marcado en naranja) hay más campos cifrados en ese mismo mensaje.

Para conocer un poco mejor cómo funciona el encapsulado ESP se puede seleccionar como algoritmo de cifrado ESP=null, de esta forma, se utilizaría el encapsulado ESP pero los campos no viajarían cifrados y se podrían ver en la captura. Para realizar esta prueba, sólo es necesario añadir en el fichero ipsec.conf de ambos extremos de la VPN:

esp=null

En la figura [fig:icmp-req-null] se muestra el paquete ICMP echo request desde pc2 a pc1, encapsulado en ESP=null.Se observa las siguientes cabeceras:

  • Cabecera externa que lleva la direcciones IP de los extremos del túnel: desde 192.168.0.2 a 192.168.0.1

  • Cabecera ESP: SPI, número de secuencia.

  • Datos protegidos ESP=null: paquete ICMP request con la cabecera original desde 10.2.0.10 a 10.1.0.10, relleno, siguiente cabecera (IPIP)

  • Datos de autenticación.

ICMP echo request, esp=null<span
data-label="fig:icmp-req-null"></span>

En la siguiente figura se muestra el paquete ICMP echo reply desde pc1 a pc2, encapsulado en ESP=null. Se observa las siguientes cabeceras:

  • Cabecera externa que lleva la direcciones IP de los extremos del túnel: desde 192.168.0.1 a 192.168.0.2

  • Cabecera ESP: SPI, número de secuencia.

  • Datos protegidos ESP=null: paquete ICMP reply con la cabecera original desde 10.1.0.10 a 10.2.0.10, relleno, siguiente cabecera (IPIP)

  • Datos de autenticación.

ICMP echo reply, esp=null<span
data-label="fig:icmp-rep-null"></span>

IKE

El IETF ha definido IKE (Internet Key Exchange) para la gestión automática de claves y el establecimiento de los SAs. IKE es un protocolo híbrido resultado de la integración de Oakley, Skeme y ISAKMP.

ISAKMP (RFC-2408) (Internet Security Association and Key Management Protocol): Este protocolo define una serie de fases para establecer una SA (Security Association), el establecimiento y mantenimiento de todas las claves necesarias para la familia de protocolos TCP/IP en modo seguro.

Se utiliza UDP con puerto origen y destino 500.

ISAKMP está dividido en 2 fases.

Si al activar el túnel en el lado cliente (ipsec up net-net), capturamos el tráfico intercambiado entre r1y r2se observarían los mensajes de las 2 fases.

Fase 1: autenticación con firmas

       Initiator                        Responder
       -----------                      -----------
        HDR, SA                   -->
                                  <--    HDR, SA

Donde HDR es la cabecera ISAKMP que indica el tipo de intercambio o modo (Main Mode o Agressive Mode).

En Main Mode, la fase 1 proporciona protección de la identidad de las dos partes. En Agressive Mode las partes no se intercambian la identidad y se reduce el número de mensajes que se intercambian, optimizando el tiempo de negociación entre ambas partes. Nótese que si se utiliza cifrado de clave pública para la autenticación en Agressive Mode también se proporcionará protección de identidad.

Negociación de parámetros de seguridad (2 mensajes)

  1. Primer mensaje: Initiator -> Responder

    El primer mensaje lo envía el Initiator y lleva la siguiente información:

    • Initiator SPI (Security Parameter Index, 8 bytes)=a72d06230045d07f. Es la Cookie CKY-I.

    • Responder SPI vacío

    • Tipo de intercambio que se va a realizar (Main Mode, 2)

    • Next Payload = SA.

    • Type Payload: Security Association

    • Type Payload: Vendor ID: strongSwan

    • Type Payload: Vendor ID: XAUTH

    • Type Payload: Vendor ID: RFC 3706 DPD (Dead Peer Detection)

      image

    En la información SA se muestra la/s propuesta/s que se hace/n (en este caso sólo 1):

    • IKEv1

    • Duración 3600 seg

    • Algoritmo de cifrado: AES-CBC

    • Algoritmo Hash: SHA2-256 (si no existe negociación de PRF (pseudo random function) se utiliza la que esté definida en este apartado).

    • Longitud de la clave 128

    • Modo de autenticación: RSA-SIG

    • Descripción de grupo 3072 bit MODP (Modular Exponential Diffie-Hellman groups): especifica el primo y el generador para crear el secreto compartido.

      • primo p

        p=2^{3072} - 2^{3008} - 1 + 2^{64} x [ [2^{2942} x pi] + 1690314 ]

      • generador g=2

      Cada lado de la comunicación generará un número a partir de un secreto individual:

      • Extremo r1: a partir de x genera el número:

        X=g^x mod p

        r1 envía X a r2.

      • Extremo r2: a partir de y genera el número:

        Y=g^y mod p

        r2 envía Y a r1.

      • El secreto compartido por ambos y que entre ellos pueden calcular es el siguiente:

        • r1 calcula:

          Y^x mod p= g^{y^x} mod p
          
        • r2 calcula:

          X^y mod p = g^{x^y} mod p
          

        Ambos números calculados por r1 y r2 son el mismo:

        g^{xy} mod p

        y se denomina el secreto compartido de Diffie-Hellman.

    image

  2. Segundo mensaje: Initiator <- Responder

    El segundo mensaje lo envía el Responder y es una respuesta al primer mensaje. Se ha generado el Responder SPI y además lleva la siguiente información:

    • Initiator SPI=a72d06230045d07f. Es la Cookie CKY-I.

    • Responder SPI =c8252a582ba06f1a. Es la Cookie CKY-R.

    • Tipo de intercambio que se va a realizar (Main Mode, 2)

    • Next Payload = SA

    • Type Payload: Security Association

    • Type Payload: Vendor ID: strongSwan

    • Type Payload: Vendor ID: XAUTH

    • Type Payload: Vendor ID: RFC 3706 DPD (Dead Peer Detection)

    El SA lleva una de las propuestas realizadas por Initiator, en este caso, como sólo llevaba una propuesta, se incluye lo mismo que había enviado Initiator.

Intercambio de Diffie-Hellman y Nonce (2 mensajes)

Se envían los datos KE para el cálculo de la clave secreta compartida de Diffie-Hellman y el Nonce (número muy grande aleatorio).

 Initiator                 Responder
-----------               -----------
 HDR, KE, Ni        -->
                    <--    HDR, KE, Nr
  1. Tercer mensaje: Initiator -> Responder El Initiator tiene que tener la clave pública de Responder. En el caso de que el Responder tenga varias claves, se incluirá en el mensajes un hash del certificado que el Initiator está usando para cifrar los datos. De esta forma, el Responder podrá saber con qué clave privada tendrá que descifrar los datos.

    • Initiator SPI=a72d06230045d07f. Es la Cookie CKY-I.

    • Responder SPI =c8252a582ba06f1a. Es la Cookie CKY-R.

    • Tipo de intercambio que se va a realizar (Main Mode, 2)

    • Next Payload = Key Exchange

    • Type Payload: Key Exchange: KE=g^x mod p

    • Type Payload: Nonce de Initiator: N_i

  2. Cuarto mensaje: Initiator <- Responder

    • Initiator SPI=a72d06230045d07f. Es la Cookie CKY-I.

    • Responder SPI =c8252a582ba06f1a. Es la Cookie CKY-R.

    • Tipo de intercambio que se va a realizar (Main Mode, 2)

    • Next Payload = Key Exchange

    • Type Payload: Key Exchange: KE=g^y mod p

    • Type Payload: Nonce de Responder: N_r

    • Type Payload: Certificate Request

Autenticación mutua (2 mensajes)

Los dos lados de la comunicación pueden calcular el secreto compartido Diffie-Hellman g^{xy}mod p que llamaremos g^{xy}.

Ahora se generan las claves que intervendrán en la comunicación. Usaremos la siguiente notación:

prf(key, msg): prf es la función pseudo-aleatoria con clave (keyed pseudo-random function), cuya clave se proporciona en el parámetro key, utilizada para generar una salida determinista del mensaje msg y que parece pseudo-aleatoria. prf se utilizan para el cálculo de claves y para la autenticación (por ejemplo keyed MAC).

Para la autenticación con firmas, se calcula la clave SKEYID aplicando prf a la clave Diffie-Hellman compartida utilizando como clave la concatenación de los Nonce:

 SKEYID = prf(Ni | Nr, g^{xy})

El valor $SKEYID$ se utilizará como clave en prf para crear 3 claves para la autenticación y cifrado: SKEYID_d, SKEYID_a y SKEYID_e.

  • Clave para el cálculo de claves de asociaciones de seguridad que no sean ISAKMP:

    SKEYID_d = prf(SKEYID, g^{xy} | CKY-I | CKY-R | 0)
    
  • Clave de autenticación:

    SKEYID_a = prf(SKEYID, SKEYID_d | g^{xy} | CKY-I | CKY-R | 1)
    
  • Clave de cifrado:

    SKEYID_e = prf(SKEYID, SKEYID_a | g^{xy} | CKY-I | CKY-R | 2)
    

Donde CKY-I y CKY-Rson las cookies de Initiator y Responder respectivamente y que ambos extremos conocen porque se las están intercambiando en la fase 1.

Para autenticar el intercambio de mensajes es necesario calcular:

  • HASH_I = prf(SKEYID, g^{xi} | g^{xr} | CKY-I | CKY-R | SAi | IDii )

  • HASH_R = prf(SKEYID, g^{xr} | g^{xi} | CKY-R | CKY-I | SAi | IDir )

El intercambio de los mensajes 5 y 6 es el siguiente:

 Initiator                          Responder
-----------                        -----------
 HDR*, IDii, [ CERT, ] SIG_I -->
                             <--    HDR*, IDir, [ CERT, ] SIG_R

SIG_I/SIG_R se calcula aplicando el algoritmo de firma negociado sobre HASH_I /HASH_R, es decir:

  • SIG_I se consigue cifrando HASH_I con la clave privada de I.

  • SIG_R se consigue cifrando HASH_R con la clave privada de R.

  • Quinto mensaje: Initiator -> Responder El Initiator envía su identificación y hash del payload que permiten realizar la identificación y autenticación del Initiator.

    • Initiator SPI=a72d06230045d07f. Es la Cookie CKY-I.

    • Responder SPI =c8252a582ba06f1a. Es la Cookie CKY-R.

    • Tipo de intercambio que se va a realizar (Main Mode, 2)

    • Next Payload = Identification

    • Datos cifrados con SKEYID_E:

      • Identity Payload: identificación del Initiator, IDii, como el nombre del host o la dirección IP.

      • Signature Payload: HASH_I cifrado con la clave privada de I.

      • Certificate Data: certificado de I, que se identifica con el nombre de la máquina. Este certificado incluye la clave pública de I que se utiliza para extraer HASH_I del campo Signature Payload. Tanto el Initiator como el Responder deben tener un certificado generado por la misma CA (Certification Authority).

  • Sexto mensaje: Initiator <- Responder El Responder envía su identificación y hash del payload que permiten realizar la identificación y autenticación del Responder.

    • Initiator SPI=a72d06230045d07f. Es la Cookie CKY-I.

    • Responder SPI =c8252a582ba06f1a. Es la Cookie CKY-R.

    • Tipo de intercambio que se va a realizar (Main Mode, 2)

    • Next Payload = Identification

    • Datos cifrados con SKEYID_E:

      • Identity Payload: identificación del Initiator, IDir, como el nombre del host o la dirección IP.

      • Signature Payload: HASH_R cifrado con la clave privada de R.

      • Certificate Data: certificado de R, que se identifica con el nombre de la máquina. Este certificado incluye la clave pública de R que se utiliza para extraer HASH_R del campo Signature Payload. Tanto el Initiator como el Responder deben tener un certificado generado por la misma CA (Certification Authority).

Una vez intercambiado estos mensajes en cada extremo es necesario comprobar que el ID del otro lado está configurado por el administrador de red como un ID válido para establecer la comunicación. A continuación, cada extremo debe proceder a la autenticación, utilizando la clave pública (recibida en el certificado) para extraer HASH_R/HASH_I. Por tanto:

  • El Initiator:

    • Descifra el mensaje usando SKEYID_E.

    • Extrae el certificado de R y de ahí extrae su clave pública.

    • Descifra HASH_R con la clave pública de R.

    • Calcula HASH_R con sus propios datos.

    • Si HASH_R calculada es igual a la obtenida, la autenticación es válida.

  • El Responder:

    • Descifra el mensaje usando SKEYID_E.

    • Extrae el certificado de I y de ahí extrae su clave pública.

    • Descifra HASH_I con la clave pública de I.

    • Calcula HASH_I con sus propios datos.

    • Si HASH_I calculada es igual a la obtenida, la autenticación es válida.

Fase 2: Quick Mode

Se utiliza para calcular claves y negociar políticas para SA que no son ISAKMP. La información que viaja en los mensajes de esta fase tiene que estar cifrada con la clave calculada en fase 1, SKEYID_e.

  1. Primer mensaje: Initiator -> Responder

  2. Segundo mensaje: Initiator <-Responder

  3. Tercero mensaje: Initiator -> Responder

Apéndice: creación de certificados

Los certificados deberán estar firmados por una autoridad de certificación (CA, certification authority). Por ello, crearemos primero el certificado de la CA y después los certificados de los extremos 1

Certificado de la autoridad de certificación

Para crear una clave privada RSA de 4096 bits y un certificado autofirmado que será el certificado de la CA:

$ cd /etc/ipsec.d/
$ ipsec pki --gen --type rsa --size 4096  --outform pem \
    > private/strongswanKey.pem
$ chmod 600 private/strongswanKey.pem
$ ipsec pki --self --ca --lifetime 3650 \
    --in private/strongswanKey.pem --type rsa \
    --dn "C=ES, O=strongSwan, CN=strongSwan Root CA" \
    --outform pem \
    > cacerts/strongswanCert.pem

Donde private/strongswanKey.pem es la clave privada de la CA y cacerts/strongswanCert.pem es el certificado de la CA con una validez de 10 años (3650 días). Los ficheros se almacenan en el formato de codificación PEM (Privacy Enhanced Mail), que está codificado en Base64, para incluirlo como texto ASCII en documentos, p ej. correo electrónico. Usado por OpenSSL y otras herramientas SSL.

El parámetro --dn (distinguished name) contiene los siguientes campos: país (C, country), organización (O, organization) y nombre común (CN, common name).

Como el formato PEM está codificado en base64 el contenido del fichero se mostrará de la siguiente forma:

$ less /etc/ipsec.d/cacerts/strongswanCert.pem
-----BEGIN CERTIFICATE-----
MIIFOTCCAyGgAwIBAgIIIifkzk0SZQwwDQYJKoZIhvcNAQEFBQAwKjELMAkGA1UE
BhMCQ0gxGzAZBgNVBAoTEnN0cm9uZ1N3YW4gUm9vdCBDQTAeFw0xNjA1MjAxOTQz
MjZaFw0yNjA1MTgxOTQzMjZaMCoxCzAJBgNVBAYTAkNIMRswGQYDVQQKExJzdHJv
bmdTd2FuIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC
3Pelz6x0AT94DYnnypSVRwpJjHzgCmyWlqVjMS4A4dd1mSR09a8QCl1b/rmHp+N2
2L9AlKoNmXi9b2L0jWH5+x+LAoTRikae7pnm2B4ytu47QWEepopK4DoBJbGlw8FC
O/+EoUG5UoOuQFunK20nQ7/D367qTOVy+mCeFI2hApINYOyWWqs+/Ca7BvQp4SEc
zbHx83wVqGpHUOcsdkR+b+2pjASQ9BqFAYdf8Qpn5/5uh5frpw8QEDYsmmeMZVB3
TAkzuOIinQu5mRaOz1KPoNmb3lPxSw4RIBcE0i1cUCo4fIjkq024CAsXMHWDOsHq
U+zu6IltqM6EIv0iysapyPHFVC0TdmhDOu2SLMAvvKy/CCZASEJoqPp35A+sWAtr
YfZTqEA/Xq/y/JnP/qNW5DTKl3VEXUuRyhypk3YKq6AuLk/YG8S6hW1J+daoiY/o
OlZiBzq+Ak6OxlwFd4nI1wHrka9rXtc8x75aB28erblMHU+ImEfh5V+FY57JQTT/
neS/1DFuTwCWi5sKse1l9jg2tIiHNWQ2TK4WWdvofGICRd6vTqeISMA5m+ESl3n7
ODCwgJJBik+nny2plC9319sRFRleRYbxViLu+cchI/iXe9d7Quc9Pae1NT9vm4MW
RSnI5fRiMtO3apJJCWBFi/XETV+tUO5sFJsw8ddprwIDAQABo2MwYTAPBgNVHRMB
Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUGCRFi/UK2gW3gzmw
dh+WQewqUNMwHwYDVR0jBBgwFoAUGCRFi/UK2gW3gzmwdh+WQewqUNMwDQYJKoZI
hvcNAQEFBQADggIBAHPf0OKphH2NQG/FzbiLvePa9oTYpPRYLrTzoC4jHzpwt/6r
aIYP991FsgHyMqGK4VzbY+RtMWBgaHREMjoc+sy5FXUcJ8UH0nG9CmC4N8QWFamg
alHAk8XZ5oLaMd0uMQBAsNGynB4i3/QiQo0kEjKbEMmhmCfhX7TMtaKCi0degdHV
zv6xTlkYI/j1/DCWWEZR/cK1OL7plcE7MTlD/JyrEhtHhCSa817ksxEQS3Z7ezvE
x+tKqQhPe56JymOjGXp3UPCILl10ggU+h3gLusSfsw15aJcUZdmIcVAgOZjKUwmo
axfY0lhJhZ2/NO4JkBsQSrgWOs5TzFsDZW8HYO6o9Jh77j/QRK7x+pgLEdtIS0/G
mF4+9bjmEVQA562GG2qLRuiuPKozJrC0MD0+Yt5f+NyE6WgDjeEzaUCHrKyq1Nh0
w0eSXZRkRXpnHNt1VuPtpjkUWCiaJaN0cTYCP6rD9dVgEExWN/wPbw8MivNI6PVo
Xo6H811lqYKDo0VRdbBWEy2hxkbME3Bm6LW5iGzdSaHvEloKhrAqTG09cQUuabdF
7U6lmpC1BNP4xO1sss9syCuavcX1zP8fkN15IFrYe+lohkSOEy681c3r1AcdmGh+
EztgE8pdKBSUooi92CarOt2SPN7FXJfB4qOUJjCvQLy2huftptwcMHUjwjVW
-----END CERTIFICATE-----

Para ver los campos del contenido del certificado:

$ ipsec pki --print --in /etc/ipsec.d/cacerts/strongswanCert.pem
cert:      X509
subject:  "C=ES, O=strongSwan Root CA"
issuer:   "C=ES, O=strongSwan Root CA"
validity:  not before May 20 21:43:26 2016, ok
           not after  May 18 21:43:26 2026, ok (expires in 3644 days)
serial:    22:27:e4:ce:4d:12:65:0c
flags:     CA CRLSign self-signed 
authkeyId: 18:24:45:8b:f5:0a:da:05:b7:83:39:b0:76:1f:96:41:ec:2a:50:d3
subjkeyId: 18:24:45:8b:f5:0a:da:05:b7:83:39:b0:76:1f:96:41:ec:2a:50:d3
pubkey:    RSA 4096 bits
keyid:     ee:df:fd:15:86:7a:35:c9:8f:83:49:a1:15:3a:ff:70:85:54:d6:9a
subjkey:   18:24:45:8b:f5:0a:da:05:b7:83:39:b0:76:1f:96:41:ec:2a:50:d3

Certificado de la máquina servidor de la VPN

Se crea la clave privada private/r1Key.pem utilizando RSA de 2048 bits. Para crear su certificado firmado por la CA primero se extrae la clave pública asociada a clave privada anterior y se firma por la CA.

Es muy importante que en el campo --dn (distinguised name) se indique el FQDN de la máquina que funcionará como servidor de la VPN, para que el certificado identifique esa identidad. Este FQDN es el que utilizará el cliente de la VPN cuando se conecte al servidor. También se puede incluir ese FQDN en el parámetro --san (subject alternative name).

$ cd /etc/ipsec.d/
$ ipsec pki --gen --type rsa --size 2048 \
    --outform pem \
    > private/r1Key.pem
$ chmod 600 private/r1Key.pem
$ ipsec pki --pub --in private/r1Key.pem --type rsa | \
    ipsec pki --issue --lifetime 730 \
    --cacert cacerts/strongswanCert.pem \
    --cakey private/strongswanKey.pem \
    --dn "C=ES, O=strongSwan, CN=r1" \
    --san r1 \
    --flag serverAuth --flag ikeIntermediate \
    --outform pem > certs/r1Cert.pem

El certificado r1Cert.pem tiene una validez de 2 años (730 días).

$ ipsec pki --print --in /etc/ipsec.d/certs/r1Cert.pem
cert:      X509
subject:  "C=ES, O=strongSwan, CN=pc1"
issuer:   "C=ES, O=strongSwan Root CA"
validity:  not before May 21 10:18:26 2016, ok
           not after  May 21 10:18:26 2018, ok (expires in 725 days)
serial:    ec:f9:09:9b:36:72:b3:a5
altNames:  r1
flags:     serverAuth 
authkeyId: 18:24:45:8b:f5:0a:da:05:b7:83:39:b0:76:1f:96:41:ec:2a:50:d3
subjkeyId: e5:72:0f:60:c9:68:0f:21:f9:de:83:eb:ad:5a:9d:ff:4a:98:99:84
pubkey:    RSA 2048 bits
keyid:     12:ba:41:a8:19:64:85:69:e2:3d:df:98:5c:86:2b:d0:72:3e:33:18
subjkey:   e5:72:0f:60:c9:68:0f:21:f9:de:83:eb:ad:5a:9d:ff:4a:98:99:84

Certificado del usuario en la máquina cliente de la VPN

Se crea la clave privada private/user1Key.pem utilizando RSA de 2048 bits. Para crear su certificado firmado por la CA user1Cert.pem primero se extrae la clave pública asociada a clave privada anterior y se firma por la CA.

El proceso es equivalente al del servidor, salvo que en este caso se utiliza la dirección de correo electrónico para identificar al cliente.

$ cd /etc/ipsec.d/
$ ipsec pki --gen --type rsa --size 2048 \
    --outform pem \
    > private/user1Key.pem
$ chmod 600 private/user1Key.pem
$ ipsec pki --pub --in private/pc1Key.pem --type rsa | \
    ipsec pki --issue --lifetime 730 \
    --cacert cacerts/strongswanCert.pem \
    --cakey private/strongswanKey.pem \
    --dn "C=ES, O=strongSwan, CN=user1@pc1" \
    --san user1@pc1 \
    --flag serverAuth --flag ikeIntermediate \
    --outform pem > certs/user1Cert.pem

El lado cliente necesita tener almacenada su clave privada y su certificado.

Para revocar un certificado, por ejemplo, si se desea cancelar un certificado de user1 (user1Cert.pem):

$ cd /etc/ipsec.d/
$ ipsec pki --signcrl --reason key-compromise \
    --cacert cacerts/strongswanCert.pem \
    --cakey private/strongswanKey.pem \
    --cert certs/user1Cert.pem \
    --outform pem > crls/crl.pem

Se genera una lista de certificados revocados en /etc/ipsec.d/crls/crl.pem. Si alguien intenta autenticarse con dicho certificado revocado, debería obtener un error como el siguiente:

charon: 13[CFG] certificate was revoked 
    on May 22 10:31:20 UTC 2016, reason: key compromise

Si se desea añadir otro certificado como revocado user2Cert.pem, habría que copiar el fichero actual previamente:

$ cd /etc/ipsec.d/
$ cp crls/crl.pem crl.pem.tmp
$ ipsec pki --signcrl --reason key-compromise \
    --cacert cacerts/strongswanCert.pem \
    --cakey private/strongswanKey.pem \
    --cert certs/user2Cert.pem \
    --lastcrl crl.pem.tmp \
    --outform pem > crls/crl.pem
$ rm crl.pem.tmp

Apéndice: Captura de paquetes cifrados con tcpdump

Si se utiliza tcpdump/wireshark para capturar tráfico en una determinada interfaz de red, se obtienen los paquetes cifrados y no cifrados sólo para el tráfico entrante en la máquina. El tráfico de salida se captura cifrado. El procesado de paquetes IPsec se realiza en el kernel. Para poder capturar el tráfico cifrado y descifrado entrante y saliente en una determinada interfaz se puede usar nflog dentro de iptables.

Las reglas nflog envían logs a un grupo de multicast interno del kernel, que es identificado por un número entero.

  • Para almacenar el tráfico IPsec e IKE entrante

    iptables -t filter -I INPUT -p esp -j NFLOG --nflog-group 5
    iptables -t filter -I INPUT -p ah -j NFLOG --nflog-group 5
    iptables -t filter -I INPUT -p udp -m multiport --dports 500,4500 -j NFLOG --nflog-group 5
    

    Donde -m utiliza el módulo multiport para poder usar la opción --dports con un conjunto de puertos destino.

  • Para almacenar el tráfico IPsec e IKE saliente

    iptables -t filter -I OUTPUT -p esp -j NFLOG --nflog-group 5
    iptables -t filter -I OUTPUT -p ah -j NFLOG --nflog-group 5
    iptables -t filter -I OUTPUT -p udp -m multiport --dports 500,4500 -j NFLOG --nflog-group 5
    
  • Para almacenar el tráfico IPsec descifrado.

    iptables -t mangle -I PREROUTING -m policy --pol ipsec --dir in -j NFLOG --nflog-group 5
    iptables -t mangle -I POSTROUTING -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5
    

    Donde -m utiliza el módulo policy para utilizar la opción --pol ipsec para indicar tráfico IPsec y --dir in/--dir out para tráfico entrante/saliente.

  • Para almacenar el tráfico IPsec destinado a la máquina local (iptables INPUT chain)

    iptables -t filter -I INPUT -m addrtype --dst-type LOCAL -m policy --pol ipsec --dir in \
        -j NFLOG --nflog-group 5
    

    Donde -m utiliza el módulo addrtype para utilizar la opción --dst-type LOCAL que indica que la dirección destino del paquete es una dirección configurada localmente en la máquina (no es una dirección de multicast, broadcast, etc).

  • Para almacenar el tráfico IPsec que hay que reenviar (iptables FORWARD chain)

    iptables -t filter -I INPUT -m addrtype ! --dst-type LOCAL -m policy --pol ipsec --dir in \
        -j NFLOG --nflog-group 5
    
  • Para almacenar el tráfico IPsec de salida (iptables OUTPUT chain)

    iptables -t filter -I OUTPUT -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5
    

Se captura el tráfico de la siguiente manera:

r1:~# tcpdump -s 0 -n -i nflog:5
1. Información extraída:
https://www.zeitgeist.se/2013/11/22/strongswan-howto-create-your-own-vpn/

results matching ""

    No results matching ""