Configurando servidor IPsec para datacenter con OpenStack, StrongSwan y #FirewallManager de #CoreAdmin


#1

1. Introducción

El siguiente artículo explica cómo desplegar un servidor IPsec para conectar redes a ambos extremos, entre un cliente IPSEC y el servidor IPsec que estamos a punto de desplegar de manera que sea posible una visibilidad completa entre la red del cliente y un conjunto de servidores en datacenter (OpenStack).

El artículo explica cómo desplegar el servidor IPsec (StrongSwan). A continuación explica cómo configurar accesos para que los clientes IPsec puedan conectar y qué datos necesitamos de ellos.

2. Despliegue básico del servidor IPsec

  1. Instalamos los paquetes necesarios:

    # apt-get install strongswan strongswan-pki libcharon-extra-plugins
    
  2. Configuración de StrongSwan, creando una copia de seguridad primero:

    # cp /etc/ipsec.conf /etc/ipsec.conf.old
    # touch /var/lib/strongswan/ipsec.secrets.inc
    

    …y editamos el fichero /etc/ipsec.conf para que tenga el siguiente contenido:

    # ipsec.conf - strongSwan IPsec configuration file
    # basic configuration
    
    config setup
    
    conn %default
        ikelifetime=60m
        keylife=20m
        rekeymargin=3m
        keyingtries=1
        keyexchange=ikev1
        authby=secret
     
    conn net-net
         # server public ip
         # Definimos la IP pública del servidor (server) donde estamos    
         # configurando strongswan
         left=<public-server-ip>                           
         # server network behind ipsec router
         # Definimos la red ipsec sobre la que trabajaremos en nuestro extremo 
         # y la que tendrá que configurar el cliente
         leftsubnet=<local-network-behind-public-server>   
         # server ipsec id        
         # Se define una IP o nombre que identifica al servidor. Usar el fqnd
         leftid=@router01-domain.asplhosting.com
            
         # remote client network behind ipsec connecting client 
         # Se define la red desde la que el cliente nos enviará el tráfico. 
         # Será la red que se genere en la pila del servidor una vez 
         # desencapsulado el tráfico UDP. 
         rightsubnet=<remote-client-network>               
         auto=add
         include /var/lib/strongswan/ipsec.conf.inc
    
  3. A continuación editamos el fichero /etc/ipsec.secrets para declarar la IP cliente remota que conectará y la clave compartida (Pre-Shared-Key, PSK), añadiendo una línea como sigue. Si no tenemos la IP del cliente que conectará en este momento, podemos saltar este paso y luego regresar al él más tarde:

    <ip-cliente> : PSK "contraseña-compartida"
    

    NOTA: es muy importante respetar el formato, espacios y posiciones. La declaración tiene que empezar con una ip, sin espacios por delante, y separarla de la contraseña con " : PSK ". Ejemplo:

    # acceso IPsec con clave compartida desde la ip 89.89.89.89
    89.89.89.89 : PSK "klsajdfjkhSGwer__2323"
    

    NOTA: Las contraseñas las podemos generar con el siguiente comando:

    >> head -c 12 /dev/urandom | base64
    
  4. A continuación reiniciamos el servidor IPsec para comprobar que no haya ningún error:

    >> tail -f /var/log/syslog &
    >> /etc/init.d/ipsec restart
    
  5. Si todo va correcto, deberíamos poder ejecutar lo siguiente sin errores:

    # ipsec statusall
    Security Associations (0 up, 0 connecting):
      no match
    
  6. Por último, si la máquina está ejecutando en cluster OpenStack, tendrás que desactivar la opción de “Puerto de seguridad” para desactivar las medidas anti-spoofing que impedirán que el tráfico generado por el servidor IPsec, pueda ser recibido tal cual por los equipos de la red de destino, debido a que las ips de origen no serán reconocidas por plano de red OVN. Para ello:

      Dentro del horizon -> 
      Seleccionas el proyecto -> 
        Red -> 
          Redes -> 
            Seleccionar la red provider (o la que tenga el proyecto) -> 
              Seleccionar el puerto asociado a la máquina ->
                Editamos el puerto -> 
                  Desmarcamos la opción [ ] Puerto de seguridad (reglas anti-spoofing)
    
    

3. Integración con Firewall Manager de Core-Admin

Ahora, para aumentar la seguridad, desplegaremos el #FirewallManager de core-admin, o un firewall de su elección, donde se apliquen las siguientes indicaciones generales:

  1. Hay que permitir acceso al puerto 500 y 4500 UDP. En firewall manager, dentro
    de la sección [Reglas de interfaz], añadir declaraciones:

    • interfaz=any, tipo-de-trafico=server, protocolo=udp, puerto=500, descripción=Trafico entrada UDP/500 IPsec
    • interfaz=any, tipo-de-trafico=server, protocolo=udp, puerto=4500, descripción=Trafico entrada UDP/4500 IPsec
  2. Limitar el acceso al puerto 22/tcp SSH al grupo de administradores:

    [admin_ips]

  3. Crear un grupo [clientes_ipsec], que contenga las IPs a las que daremos acceso y el grupo
    [admin_ips]. Si no tenemos las IPs cliente desde donde conectarán, simplemente añadir el grupo: [admin_ips]
    De esta manera, las IPs autorizadas y los administradores podrán iniciar conexiones IPsec

  4. Ahora, configurar el grupo [clientes_ipsec] en las reglas que hemos creado de tráfico udp/500 y udp/4500, como direcciones de origen aceptadas.

  5. Al mismo tiempo, en el caso de servidores montados sobre OpenStack es necesario configurar la instancia para que no haga supervisión de redes. De lo contrario no permitirá inyectar tráfico de las redes ipsec del cliente debido a que no las reconoce. Ver opción Puerto de seguridad de OpenStack mencionada en secciones anteriores.

4. Dando de alta un cliente IPsec y redes remotas asociadas a ese cliente.

Llegados a este punto ya tenemos el servidor IPsec montado. Ahora necesitamos que el cliente que vaya
a conectar nos de:

  • Las ips desde donde conectarán
  • Las redes en su lado que exportarán por IPsec.

Con esto identificado, seguimos los siguientes pasos:

  1. Nos vamos al /etc/ipsec.secrets y añadimos una entrada por cada IP
    que queramos autorizada con la contraseña que queramos ponerle (atención al formato):

    <ip cliente> : PSK "contraseña-conexión"
    

    Si hay varias Ips, añadir una línea por cada IP, con la misma o contraseñas distintas (no es obligatorio que sean iguales).

  2. A continuación actualizamos la declaración rightsubnet dentro de /etc/ipsec.conf para configurar ahí la red que tiene el cliente en su lado.

  3. Reiniciamos el ipsec para que coja los cambios y comprobamos que está todo correcto:

    >> tail -f /var/log/syslog &
    >> /etc/init.d/ipsec restart
    
  4. Tras esto actualizamos el firewall, en las reglas de rutado para permitir todo el tráfico
    de origen de las redes del cliente con destino a los servidores que el router IPsec debe dar
    acceso. Crear las reglas usando grupos que contengan las redes del cliente y los servidores
    de destino:

    • interfaz-de-entrada=any, interfaz-de-salida=any, origen=[redes_ipsec_cliente], destino=[servidores_cliente], protocolo=all, comentario=ipsec
  5. Tráfico de vuelta: Ahora, en los servidores que recibirán el tráfico IPsec, hay que
    meter una ruta para que sepan devolver el tráfico que reciban desde la IPsec, para que
    lo devuelvan por el router IPsec que estamos levantando:

    >>  route add -net <redes-ipsec-del-cliente> gw <ip-local-servidor-ipsec>
    

    NOTA: Meter esta regla el post-up de la interfaz del servidor que recibirá el tráfico
    para que esté disponible la regla de rutado tras reinicios.

Llegados a este punto, ya debería estar todo configurado a falta de revisar detalles.

5. Qué datos comunicar al crear una conexión Ipsec cliente

Una vez configurado todo, los datos que hay que comunicar para que el cliente IPsec pueda ser configurado son:

IP pública del servidor IPsec:
Redes del servidor IPsec:
Clave compartida (PSK): <contraseña-conexión-ipsec>

6. Recomendaciones generales y notas a tener en cuenta

  1. IPsec no genera una interfaz de red por donde el tráfico VPN aparece (como el tun0 de OpenVPN).

  2. El tráfico VPN que se recibe en el servidor simplemente aparece en el stack de routing de la máquina con origen de la red del cliente IPsec (o la red vpn que se haya configurado).

  3. Para instalaciones OpenStack es necesario configurar la máquina para que haga rutado sin supervisión de OvN o similar (opción Puerto de seguridad). De lo contrario no funcionará correctamente o forzaría a usar NAT/MASQUERADE, lo cual complica la administración del servidor IPsec y la política de seguridad en los servidores de destino.

  4. De manera general evitar usar NAT/MASQUERADE en el router IPsec. Sólo dará problemas con la identificación y el ajustado fino de reglas de seguridad y autorizaciones.

7. Errores conocidos

  1. Feb 10 18:05:20 oberon charon: 00[CFG] line 5: missing ’ : ’ separator

    Esto es debido a que no se ha respetado el formato en /etc/ipsec.secrets. El formato es:

    <ip> : PSK "contraseña"  
    

    Muy importante la parte " : " de separación entre usuario y clave.

  2. Errores con el apparmor que no tienen importancia en el lado cliente:

    Feb 10 18:06:48 oberon kernel: [2962679.236409] audit: type=1400 audit(1612976808.107:728): apparmor="DENIED" operation="unlink" profile="/usr/lib/ipsec/charon" name="/etc/resolv.conf" pid=27160 comm="charon" requested_mask="d" denied_mask="d" fsuid=0 ouid=0
    Feb 10 18:06:48 oberon kernel: [2962679.236413] audit: type=1400 audit(1612976808.107:729): apparmor="DENIED" operation="open" profile="/usr/lib/ipsec/charon" name="/etc/resolv.conf" pid=27160 comm="charon" requested_mask="wc" denied_mask="wc" fsuid=0 ouid=0
    Feb 10 18:06:48 oberon kernel: [2962679.236437] audit: type=1400 audit(1612976808.107:730): apparmor="DENIED" operation="unlink" profile="/usr/lib/ipsec/charon" name="/etc/resolv.conf" pid=27160 comm="charon" requested_mask="d" denied_mask="d" fsuid=0 ouid=0
    Feb 10 18:06:48 oberon kernel: [2962679.236442] audit: type=1400 audit(1612976808.107:731): apparmor="DENIED" operation="open" profile="/usr/lib/ipsec/charon" name="/etc/resolv.conf" pid=27160 comm="charon" requested_mask="wc" denied_mask="wc" fsuid=0 ouid=0
    
  3. No matching proposal found

    Si vemos este tipo de errores en el log:

    Jun 23 15:19:58 router01-router charon: 11[CFG] received proposals: ESP:AES_CBC_256/HMAC_SHA2_256_128/MODP_2048/NO_EXT_SEQ
    Jun 23 15:19:58 router01-router charon: 11[CFG] configured proposals: ESP:AES_CBC_128/AES_CBC_192/AES_CBC_256/HMAC_SHA2_256_128/HMAC_SHA2_384_192/HMAC_SHA2_512_256/HMAC_SHA1_96/AES_XCBC_96/NO_EXT_SEQ
    Jun 23 15:19:58 router01-router charon: 11[IKE] no matching proposal found, sending NO_PROPOSAL_CHOSEN
    

    Es porque no coinciden los algoritmos de cifrado, debería de salir algo así:

    Jun 23 15:38:06 charon: 13[CFG] selected proposal: IKE:AES_CBC_256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
    

    En este caso, nos proponen usar aes256-sha256-modp2048, y nosotros tenemos configurado aes128-sha256. Para resolverlo, simplemente sería editar el ipsec.conf y dentro de la conexión en cuestión (net-net del ejemplo), añadir lo siguiente:

    esp=aes256-sha256-modp2048
    
  4. Vueltas de routing mal configuradas o inexistentes

    Si llega el tráfico correctamente a la máquina de destino, después de haber sido gestionado correctamente por el servidor IPsec, pero las vueltas no se reciben, a pesar de ser vistas con un tcpdump, entonces revisar que dicha máquina tenga una regla para devolver las vueltas por el router IPsec, a la red IPsec del otro extremo:

    >> route add -net <red-ip-ssec-otro-extremo>/prefijo gw <router-ipsec>