VPN sobre IPsec

This translation may be out of date. To help with the translations please access the FreeBSD translations instance.

Marcas registradas

FreeBSD es una marca registrada de la Fundación FreeBSD

Muchos de los nombres usados por los fabricantes y vendedores para diferenciar sus productos son designados como marcas comerciales. Allí donde estos nombres aparezcan en este documento y el Proyecto FreeBSD fuera consciente de la alegación de marca comercial, los nombres tienen a continuación el símbolo “™” o “®”.


Internet Protocol Security (IPsec) es un conjunto de protocolos que se asientan sobre la capa del Protocolo de Internet (IP). Permite que dos o más máquinas se comuniquen de forma segura autenticando y cifrando cada paquete IP de una sesión de comunicación. La pila de red IPsec de FreeBSD está basada en la implementación https://www.kame.net/ y admite sesiones tanto IPv4 como IPv6.

IPsec está compuesto por los siguientes subprotocolos:

  • Encapsulated Security Payload (ESP): este protocolo protege los datos del paquete IP frente a interferencias de terceros cifrando el contenido mediante algoritmos de criptografía simétrica como Blowfish y 3DES.

  • Authentication Header (AH): este protocolo protege la cabecera del paquete IP frente a interferencias de terceros y suplantación calculando una suma de verificación criptográfica y aplicando una función de hash segura a los campos de la cabecera del paquete IP. A esto le sigue una cabecera adicional que contiene el hash, para permitir que la información del paquete sea autenticada.

  • IP Payload Compression Protocol (IPComp): este protocolo intenta aumentar el rendimiento de la comunicación comprimiendo la carga útil IP con el fin de reducir la cantidad de datos enviados.

Estos protocolos pueden utilizarse juntos o por separado, según el entorno.

IPsec admite dos modos de funcionamiento. El primer modo, Transport Mode, protege las comunicaciones entre dos máquinas. El segundo modo, Tunnel Mode, se utiliza para construir túneles virtuales, conocidos comúnmente como redes privadas virtuales (VPNs). Consulte ipsec(4) para obtener información detallada sobre el subsistema IPsec en FreeBSD.

Este artículo muestra el proceso de configuración de una VPN IPsec entre una red doméstica y una red corporativa.

En el escenario de ejemplo:

  • Ambas sedes están conectadas a Internet a través de una pasarela que ejecuta FreeBSD.

  • La pasarela de cada red tiene al menos una dirección IP externa. En este ejemplo, la dirección IP externa de la LAN corporativa es 172.16.5.4 y la de la LAN doméstica es 192.168.1.12.

  • Las direcciones internas de las dos redes pueden ser direcciones IP públicas o privadas. Sin embargo, el espacio de direcciones no debe solaparse. En este ejemplo, la dirección IP interna de la LAN corporativa es 10.246.38.1 y la de la LAN doméstica es 10.0.0.5.

           corporate                          home
10.246.38.1/24 -- 172.16.5.4 <--> 192.168.1.12 -- 10.0.0.5/24

1. Configurar una VPN en FreeBSD

Para empezar, debe instalarse security/ipsec-tools desde la Colección de Ports. Este software proporciona una serie de aplicaciones que facilitan la configuración.

El siguiente requisito es crear dos pseudo-dispositivos gif(4) que se utilizarán para encapsular paquetes y permitir que ambas redes se comuniquen correctamente. Como root, ejecute el siguiente comando en cada pasarela:

corp-gw# ifconfig gif0 create
corp-gw# ifconfig gif0 10.246.38.1 10.0.0.5
corp-gw# ifconfig gif0 tunnel 172.16.5.4 192.168.1.12
home-gw# ifconfig gif0 create
home-gw# ifconfig gif0 10.0.0.5 10.246.38.1
home-gw# ifconfig gif0 tunnel 192.168.1.12 172.16.5.4

Verifique la configuración en cada pasarela mediante ifconfig gif0. Esta es la salida de la pasarela doméstica:

gif0: flags=8051 mtu 1280
tunnel inet 172.16.5.4 --> 192.168.1.12
inet6 fe80::2e0:81ff:fe02:5881%gif0 prefixlen 64 scopeid 0x6
inet 10.246.38.1 --> 10.0.0.5 netmask 0xffffff00

Esta es la salida de la pasarela corporativa:

gif0: flags=8051 mtu 1280
tunnel inet 192.168.1.12 --> 172.16.5.4
inet 10.0.0.5 --> 10.246.38.1 netmask 0xffffff00
inet6 fe80::250:bfff:fe3a:c1f%gif0 prefixlen 64 scopeid 0x4

Una vez completado, ambas direcciones IP internas deberían ser alcanzables mediante ping(8):

home-gw# ping 10.0.0.5
PING 10.0.0.5 (10.0.0.5): 56 data bytes
64 bytes from 10.0.0.5: icmp_seq=0 ttl=64 time=42.786 ms
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=19.255 ms
64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=20.440 ms
64 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=21.036 ms
--- 10.0.0.5 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 19.255/25.879/42.786/9.782 ms

corp-gw# ping 10.246.38.1
PING 10.246.38.1 (10.246.38.1): 56 data bytes
64 bytes from 10.246.38.1: icmp_seq=0 ttl=64 time=28.106 ms
64 bytes from 10.246.38.1: icmp_seq=1 ttl=64 time=42.917 ms
64 bytes from 10.246.38.1: icmp_seq=2 ttl=64 time=127.525 ms
64 bytes from 10.246.38.1: icmp_seq=3 ttl=64 time=119.896 ms
64 bytes from 10.246.38.1: icmp_seq=4 ttl=64 time=154.524 ms
--- 10.246.38.1 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 28.106/94.594/154.524/49.814 ms

Como era de esperar, ambos lados tienen la capacidad de enviar y recibir paquetes ICMP desde las direcciones configuradas de forma privada. A continuación, hay que indicar a ambas pasarelas cómo enrutar los paquetes para enviar correctamente el tráfico desde las redes que hay detrás de cada pasarela. Los siguientes comandos cumplen este objetivo:

corp-gw# route add 10.0.0.0 10.0.0.5 255.255.255.0
corp-gw# route add net 10.0.0.0: gateway 10.0.0.5
home-gw# route add 10.246.38.0 10.246.38.1 255.255.255.0
home-gw# route add host 10.246.38.0: gateway 10.246.38.1

Las máquinas internas deberían ser alcanzables tanto desde cada pasarela como desde las máquinas que hay detrás de las pasarelas. De nuevo, utilice ping(8) para confirmarlo:

corp-gw# ping -c 3 10.0.0.8
PING 10.0.0.8 (10.0.0.8): 56 data bytes
64 bytes from 10.0.0.8: icmp_seq=0 ttl=63 time=92.391 ms
64 bytes from 10.0.0.8: icmp_seq=1 ttl=63 time=21.870 ms
64 bytes from 10.0.0.8: icmp_seq=2 ttl=63 time=198.022 ms
--- 10.0.0.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.870/101.846/198.022/74.001 ms

home-gw# ping -c 3 10.246.38.107
PING 10.246.38.1 (10.246.38.107): 56 data bytes
64 bytes from 10.246.38.107: icmp_seq=0 ttl=64 time=53.491 ms
64 bytes from 10.246.38.107: icmp_seq=1 ttl=64 time=23.395 ms
64 bytes from 10.246.38.107: icmp_seq=2 ttl=64 time=23.865 ms
--- 10.246.38.107 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 21.145/31.721/53.491/12.179 ms

En este punto, el tráfico fluye entre las redes encapsulado en un túnel gif pero sin ningún tipo de cifrado. A continuación, utilice IPSec para cifrar el tráfico mediante claves precompartidas (PSK). Salvo por las direcciones IP, el fichero /usr/local/etc/racoon/racoon.conf de ambas pasarelas será idéntico y tendrá un aspecto similar a:

path    pre_shared_key  "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file
log     debug;	#log verbosity setting: set to 'notify' when testing and debugging is complete

padding	# options are not to be changed
{
        maximum_length  20;
        randomize       off;
        strict_check    off;
        exclusive_tail  off;
}

timer	# timing options. change as needed
{
        counter         5;
        interval        20 sec;
        persend         1;
#       natt_keepalive  15 sec;
        phase1          30 sec;
        phase2          15 sec;
}

listen	# address [port] that racoon will listen on
{
        isakmp          172.16.5.4 [500];
        isakmp_natt     172.16.5.4 [4500];
}

remote  192.168.1.12 [500]
{
        exchange_mode   main,aggressive;
        doi             ipsec_doi;
        situation       identity_only;
        my_identifier   address 172.16.5.4;
        peers_identifier        address 192.168.1.12;
        lifetime        time 8 hour;
        passive         off;
        proposal_check  obey;
#       nat_traversal   off;
        generate_policy off;

                        proposal {
                                encryption_algorithm    blowfish;
                                hash_algorithm          md5;
                                authentication_method   pre_shared_key;
                                lifetime time           30 sec;
                                dh_group                1;
                        }
}

sainfo  (address 10.246.38.0/24 any address 10.0.0.0/24 any)	# address $network/$netmask $type address $network/$netmask $type ( $type being any or esp)
{								# $network must be the two internal networks you are joining.
        pfs_group       1;
        lifetime        time    36000 sec;
        encryption_algorithm    blowfish,3des;
        authentication_algorithm        hmac_md5,hmac_sha1;
        compression_algorithm   deflate;
}

Para una descripción de cada opción disponible, consulte la página de manual de racoon.conf.

La Base de Datos de Políticas de Seguridad (SPD) debe configurarse para que FreeBSD y racoon sean capaces de cifrar y descifrar el tráfico de red entre las máquinas.

Esto puede lograrse con un script de shell, similar al siguiente, en la pasarela corporativa. Este fichero se utilizará durante la inicialización del sistema y debe guardarse como /usr/local/etc/racoon/setkey.conf.

flush;
spdflush;
# To the home network
spdadd 10.246.38.0/24 10.0.0.0/24 any -P out ipsec esp/tunnel/172.16.5.4-192.168.1.12/use;
spdadd 10.0.0.0/24 10.246.38.0/24 any -P in ipsec esp/tunnel/192.168.1.12-172.16.5.4/use;

Una vez en su sitio, racoon puede arrancarse en ambas pasarelas con el siguiente comando:

# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log

La salida debería ser similar a la siguiente:

corp-gw# /usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf
Foreground mode.
2006-01-30 01:35:47: INFO: begin Identity Protection mode.
2006-01-30 01:35:48: INFO: received Vendor ID: KAME/racoon
2006-01-30 01:35:55: INFO: received Vendor ID: KAME/racoon
2006-01-30 01:36:04: INFO: ISAKMP-SA established 172.16.5.4[500]-192.168.1.12[500] spi:623b9b3bd2492452:7deab82d54ff704a
2006-01-30 01:36:05: INFO: initiate new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=28496098(0x1b2d0e2)
2006-01-30 01:36:09: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=47784998(0x2d92426)
2006-01-30 01:36:13: INFO: respond new phase 2 negotiation: 172.16.5.4[0]192.168.1.12[0]
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 192.168.1.12[0]->172.16.5.4[0] spi=124397467(0x76a279b)
2006-01-30 01:36:18: INFO: IPsec-SA established: ESP/Tunnel 172.16.5.4[0]->192.168.1.12[0] spi=175852902(0xa7b4d66)

Para asegurarse de que el túnel funciona correctamente, cambie a otra consola y utilice tcpdump(1) para ver el tráfico de red con el siguiente comando. Sustituya em0 por la tarjeta de interfaz de red según corresponda:

corp-gw# tcpdump -i em0 host 172.16.5.4 and dst 192.168.1.12

En la consola debería aparecer información similar a la siguiente. Si no es así, hay un problema y será necesario depurar los datos devueltos.

01:47:32.021683 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xa)
01:47:33.022442 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xb)
01:47:34.024218 IP corporatenetwork.com > 192.168.1.12.privatenetwork.com: ESP(spi=0x02acbf9f,seq=0xc)

En este punto, ambas redes deberían estar disponibles y parecer parte de la misma red. Lo más probable es que ambas redes estén protegidas por un cortafuegos. Para permitir que el tráfico fluya entre ellas, es necesario añadir reglas que dejen pasar los paquetes. Para el cortafuegos ipfw(8), añada las siguientes líneas al fichero de configuración del cortafuegos:

ipfw add 00201 allow log esp from any to any
ipfw add 00202 allow log ah from any to any
ipfw add 00203 allow log ipencap from any to any
ipfw add 00204 allow log udp from any 500 to any

Puede que sea necesario modificar los números de regla según la configuración actual de la máquina.

Para usuarios de pf(4) o ipf(8), las siguientes reglas deberían servir:

pass in quick proto esp from any to any
pass in quick proto ah from any to any
pass in quick proto ipencap from any to any
pass in quick proto udp from any port = 500 to any port = 500
pass in quick on gif0 from any to any
pass out quick proto esp from any to any
pass out quick proto ah from any to any
pass out quick proto ipencap from any to any
pass out quick proto udp from any port = 500 to any port = 500
pass out quick on gif0 from any to any

Por último, para permitir que la máquina inicie el soporte para la VPN durante la inicialización del sistema, añada las siguientes líneas a /etc/rc.conf:

ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot
racoon_enable="yes"