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.
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.
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.
Se incrementa el número de secuencia de la SA y se almacena en la cabecera ESP.
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.
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
Tomando la dirección destino, protocolo (ESP/AH) y SPI se busca SA en SAD. Si no existe, se tira el paquete.
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.
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.
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.
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íaleft
yright
hace referencia a máquina local y máquina remota respectivamente. Como estamos configurando enr1
:r1
será el ladoleft
o local yr2
será el ladoright
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 der1
.rightcert
es el certificado remoto der2
.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íaleft
yright
hace referencia a máquina local y máquina remota respectivamente. Como estamos configurando enr2
:r2
será el ladoleft
o local yr1
será el ladoright
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 der2
.rightcert
es el certificado remoto der1
.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íticain
(por ejemplo un paquete dirigido a la interfaz 10.1.0.1 delr1
, si no van dirigidos ar1
se aplica políticafwd
(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)
.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 destinor1
, 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 origenpc2
y dirección IP destinopc1
.
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)
.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 destinor2
, 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 origenpc1
y dirección IP destinopc2
.
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.
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.
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 r1
y r2
se 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)
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)
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 dex
genera el número:X=g^x mod p
r1
envía X ar2
.Extremo
r2
: a partir dey
genera el número:Y=g^y mod p
r2
envía Y ar1
.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
yr2
son el mismo:g^{xy} mod p
y se denomina el secreto compartido de Diffie-Hellman.
Segundo mensaje: Initiator <- Responder
El segundo mensaje lo envía el
Responder
y es una respuesta al primer mensaje. Se ha generado elResponder 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 enviadoInitiator
.
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
Tercer mensaje: Initiator -> Responder El
Initiator
tiene que tener la clave pública deResponder
. En el caso de que elResponder
tenga varias claves, se incluirá en el mensajes un hash del certificado que elInitiator
está usando para cifrar los datos. De esta forma, elResponder
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
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ámetrokey
, utilizada para generar una salida determinista del mensajemsg
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-R
son 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 cifrandoHASH_I
con la clave privada de I.SIG_R
se consigue cifrandoHASH_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 delInitiator
.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 elInitiator
como elResponder
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 delResponder
.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 elInitiator
como elResponder
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
.
Primer mensaje: Initiator -> Responder
Segundo mensaje: Initiator <-Responder
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ódulomultiport
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ódulopolicy
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óduloaddrtype
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/