IPSec Todopoderoso

Buenas tardes amigos. No es ningún secreto que muchos de nosotros tenemos al menos una vez, pero hemos tenido que lidiar con la necesidad de configurar una VPN. Siendo un lector activo de Habr, noté que a pesar de la abundancia de artículos sobre IPSec, para muchos todavía parece ser algo complicado y sobrecargado. En este artículo intentaré disipar estos mitos usando mi propia configuración completamente funcional como ejemplo. En cuatro ejemplos, revisaremos completamente la configuración de la solución Linux (Strongswan) más popular, comenzando desde un túnel simple con autenticación de clave PSK de las partes hasta una conexión de host a host con autenticación de ambos lados basada en certificados de Let's Encrypt. ¿Interesante? ¡Bienvenido a cat!

Antecedentes


Inicialmente, la VPN se planificó solo para la organización del canal entre el mini-enrutador de los padres y el servidor doméstico "cabecera", que al mismo tiempo actúa como un enrutador.

Después de un corto período de tiempo, Keenetic fue agregado a esta compañía desde dos dispositivos.
Pero una vez que comenzó, resultó ser difícil de detener, y pronto aparecieron teléfonos y una computadora portátil en el diagrama, que querían esconderse del ojo publicitario que todo lo ve de MT_Free y otras redes WiFi no encriptadas.

Luego, el amado ILV finalmente se fortaleció, el Banhammer, de quien se enamoró increíblemente de hacer pivotar públicamente en todas las direcciones, y para neutralizar su preocupación por los simples mortales, tuvo que apoyar al sector de TI extranjero para adquirir VPS en el extranjero.
Además, un cierto ciudadano que se parece a Shapoklyak, correteando por todas partes con su retícula junto al Paquete, y probablemente cree que "Quién ayuda a las personas, está perdiendo el tiempo". No puedes volverte famoso por las buenas acciones ”. Quería mirar en secreto el tráfico de otra persona y tomarlo con lápiz. También tendremos que defendernos de tal amor no solicitado y VPN en este caso exactamente lo que recetó el médico.

Para resumir un breve resumen. Era necesario encontrar una solución que idealmente pudiera cerrar varias tareas a la vez:

  • Interconexión entre enrutadores Linux
  • Construye un túnel entre Linux y Keenetic Household
  • Dar acceso a los recursos domésticos e Internet a dispositivos portátiles (teléfonos, computadoras portátiles) desde redes no confiables
  • Cree un túnel cifrado de forma segura para el VPS remoto

No te olvides del maravilloso principio KISS: Keep It Simple, Stupid. Cuantos menos componentes se involucren y más fácil sea configurar cada uno de ellos, más confiable será.

Resumen de soluciones existentes


Repase brevemente lo que es ahora:

PPTP

Abuelo Lenin de todos los protocolos. Murió: "Decaído en el moho y la miel de tilo".

L2TP

¿Alguien más que un proveedor usa esto?

El

proyecto Wireguard se está desarrollando. Aserrado activamente. Es fácil crear un túnel entre dos pares que tienen una IP estática. En otros casos, las muletas, las bicicletas con ruedas cuadradas y una cinta aislante azul siempre están listas para ayudar, pero este no es nuestro camino.

OpenVPN

Pros:

  • Soporte para múltiples plataformas: Windows, Linux, OpenWRT y sus derivados, Android
  • Fuerte encriptación y soporte de certificados.
  • Flexibilidad de personalización.

Y contras:

  • Trabajar completamente en espacio de usuario.
  • Soporte limitado de enrutadores domésticos: krenenko-kosenko en Mikrotik (sin restar valor a las otras ventajas de las glándulas) y normal en OpenWRT.
  • Dificultades con la configuración de clientes móviles: necesita descargar o crear su propio instalador, copiar configuraciones en algún lugar.
  • Si hay varios túneles, los bailes esperan con la edición de las unidades systemd en el servidor.

OpenConnect (implementación de código abierto del protocolo Cisco Anyconnect)
Una solución muy interesante sobre la cual, desafortunadamente, hay bastante información.

Pros:

  • El soporte relativamente amplio para varias plataformas (Windows, Android, Mac basado en la aplicación nativa Cisco Anyconnect de la tienda) es una opción ideal para proporcionar acceso a la red interna de dispositivos portátiles.
  • Cifrado fuerte, soporte de certificado, conectividad 2FA
  • El protocolo en sí está completamente basado en TLS (a diferencia de OpenVPN, que se detecta fácilmente en el puerto 443). Además de TLS, DTLS también es compatible: durante la sesión establecida, el cliente puede cambiar a la transmisión de datos a través de UDP y viceversa.
  • Excelente coexistencia en un puerto de una VPN y un servidor web completo con sniproxy.
  • Fácil configuración tanto del servidor como de los clientes.

Aquí, también, no estaban exentos de contras:

  • Trabajar completamente en espacio de usuario.
  • TCP sobre TCP es una mala idea.
  • No hay soporte de equipos de grado del cliente.
  • La complejidad de instalar túneles entre dos Linux: teóricamente posible, prácticamente, es mejor pasar tiempo en algo más útil.
  • Si hay varios túneles, los bailes con varias configuraciones y unidades de sistema de edición están esperando.

Parecería un callejón sin salida, pero después de mirar más de cerca y pasar un poco de tiempo estudiando, me di cuenta de que IPSec basado en IKEv2 puede reemplazar todo lo demás.

IKEv2 IPSEC

Pros:

  • Con la llegada de IKEv2, el protocolo en sí se ha vuelto más fácil de configurar, en comparación con la versión anterior, pero a costa de perder la compatibilidad con versiones anteriores.
  • Gracias a la estandarización, el trabajo se proporciona en cualquier lugar y en cualquier cosa: la lista se puede mantener indefinidamente. Linux, Mikrotik (en las últimas versiones de RouterOS), OpenWRT, Android, iPhone. Windows también tiene soporte nativo que comienza con Windows 7.
  • Alta velocidad: procesamiento de tráfico completamente en kernel-space. La parte del espacio de usuario solo se necesita para establecer parámetros de conexión y monitorear el estado del canal.
  • La capacidad de usar varios métodos de autenticación: usando tanto PSK como certificados, y en cualquier combinación.
  • Varios modos de funcionamiento: túnel y transporte. En qué se diferencian se puede leer incluso en Habré.
  • Configuraciones poco exigentes para nodos intermedios: si en la primera versión de IKE hubo problemas causados ​​por NAT, IKEv2 tiene mecanismos incorporados para superar NAT y la fragmentación nativa de los mensajes IKE, lo que le permite establecer una conexión en canales con una curva MTU. Mirando hacia el futuro, diré que en la práctica nunca he encontrado una red WiFi, donde un cliente pueda establecer una conexión.

Contras, sin embargo, también tienen:

  • Necesita pasar un tiempo estudiando y entendiendo cómo funciona.
  • Una característica que puede confundir a un novato: IPSec, a diferencia de las soluciones VPN convencionales, no crea interfaces de red. Solo se establecen políticas de procesamiento de tráfico, todo lo demás se resuelve mediante firewall.

Antes de continuar con la configuración, suponemos que el lector ya está un poco familiarizado con los conceptos y términos básicos. Para ayudar a un principiante, puede recomendar un artículo de Wikipedia y el propio Habr, en el que ya hay artículos bastante interesantes y útiles sobre este tema.

Comenzar a configurar


Habiendo decidido la decisión, procedemos a la configuración. El diagrama de red en mi caso tiene la siguiente forma (eliminada bajo el spoiler)

Diagrama de Red

ipsecgw.example.com es el servidor doméstico que es el centro de la red. IP externa 1.1.1.1. Una red interna 10.0.0.0/23 y otra dirección 10.255.255.1/30 para configurar una sesión privada de BGP con VPS;
Mamá es un enrutador Linux basado en una pequeña red silenciosa instalada por los padres. El ISP emite una dirección IP dinámica. Red interna 10.0.3.0/24;
keenetic : enrutador Keenetic con IPSec instalado. El ISP emite una dirección IP dinámica. Red interna 10.0.4.0/24;
road-warriors : dispositivos portátiles que se conectan desde redes no confiables. Las direcciones se emiten a los clientes dinámicamente cuando se conectan desde el grupo interno (10.1.1.0/24);
rkn.example.com- VPS fuera de la jurisdicción de un ILV respetado. IP externa: 5.5.5.5, dirección interna 10.255.255.2/30 para configurar una sesión privada de BGP.

Primer paso. De simple a complejo: túneles con claves precompartidas (PSK)


En ambas cajas de Linux instalamos los paquetes necesarios:

sudo yum install strongswan

En ambos hosts, abra los puertos 500 / udp, 4500 / udp y permita el paso del protocolo ESP.
Edite el archivo /etc/strongswan/ipsec.secrects (en el lado del host ipsecgw.example.com) y agregue la siguiente línea:

mama@router.home.local: PSK "Very strong PSK"

En el segundo lado, de manera similar:

root@root.mama.local: PSK "Very strong PSK"

En este caso, la identificación es una dirección de correo electrónico ficticia. Se puede encontrar más información en la wiki oficial .

Secretos guardados, avanzando.

En el host ipsecgw.example.com, edite el archivo /etc/strongswan/ipsec.conf:

config setup //   charon
    charondebug = "dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0" //  
conn %default //    
    reauth = yes
    rekey = yes
    keyingtries = %forever
    keyexchange = ikev2 //      - IKEv2
    dpdaction = hold
    dpddelay = 5s // 5   DPD (Dead Peer Detection)   
    mobike = yes // Mobile IKE -     IP    
conn mama //  
    left = %defaultroute //Left -  .  %defaultroute       IKE- ,    default route
    right = %any //     IP-
    authby = psk //   -   
    leftid = mama@router.home.local // ID,   ipsec.secrets
    rightid = root@router.mama.local //ID  
    leftsubnet = 10.0.0.0/23,10.1.1.0/24 
    rightsubnet = 10.0.3.0/24
    type = tunnel 
    ike = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha384-x25519!
    esp = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha256-sha384-x25519! 
    auto = add //  charon        

Del mismo modo, editamos en el par remoto /etc/strongswan/ipsec.conf:

config setup
    charondebug = "dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"
conn %default
    reauth = yes
    rekey = yes
    keyingtries = %forever
    keyexchange = ikev2
    dpdaction = restart
    dpddelay = 5s
    mobike = yes
conn mama
    left = %defaultroute
    right = ipsecgw.example.com
    authby = psk
    leftid = root@router.mama.local
    rightid = mama@router.home.local
    leftsubnet = 10.0.3.0/24
    rightsubnet = 10.0.0.0/23,10.1.1.0/24
    type = tunnel
    ike = aes128gcm16-sha384-x25519!
    esp = aes128gcm16-sha384-x25519!
    auto = route

Si compara las configuraciones, puede ver que están casi reflejadas, solo las definiciones de pares se intercambian.

La directiva auto = route hace que charon establezca una trampa para el tráfico que cae en las directivas left / rightsubnet (selectores de tráfico). La coordinación de los parámetros del túnel y el intercambio de claves comenzarán inmediatamente después de la aparición del tráfico que cae bajo las condiciones dadas.

En el servidor ipsecgw.example.com en la configuración del firewall, prohibimos enmascarar una red 10.0.3.0/24. Permitir el reenvío de paquetes entre 10.0.0.0/23 y 10.0.3.0/24 y viceversa. En el host remoto, realizamos configuraciones similares deshabilitando el enmascaramiento para la red 10.0.0.0/23 y configurando el reenvío.

Reiniciamos strongswan en ambos servidores e intentamos hacer ping al nodo central:

sudo systemctl restart strongswan
ping 10.0.0.1


Asegúrate de que todo funcione:
sudo strongswan status
Security Associations (1 up, 0 connecting):
        mama[53]: ESTABLISHED 84 minutes ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{141}:  INSTALLED, TUNNEL, reqid 27, ESP in UDP SPIs: c4eb45fe_i ca5ec6ca_o
        mama{141}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24


También será útil asegurarse de que el parámetro make_before_break esté establecido en yes en el archivo /etc/strongswan/strongswan.d/charon.conf en todos los pares. En este caso, el demonio charon que sirve el protocolo IKEv2 no eliminará la asociación de seguridad actual durante el procedimiento de cambio de clave, pero creará una nueva primero.

Segundo paso La aparición de Keenetic


Una agradable sorpresa fue la VPN IPSec incorporada en el firmware oficial de Keenetic. Para activarlo, solo vaya a la Configuración de componentes KeeneticOS y agregue el paquete IPSec VPN .

Preparamos la configuración en el nodo central, para esto:

Edite /etc/strongswan/ipsec.secrects y agregue el PSK para el nuevo par:

keenetic@router.home.local: PSK "Keenetic+PSK"

Edite /etc/strongswan/ipsec.conf y agregue otra conexión al final:

conn keenetic
    left = %defaultroute
    right = %any
    authby = psk
    leftid = keenetic@router.home.local
    rightid = root@router.keenetic.local
    leftsubnet = 10.0.0.0/23
    rightsubnet = 10.0.4.0/24
    type = tunnel
    ike = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha384-x25519!
    esp = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha256-sha384-x25519!
    auto = add

En el lado de Keenetic, la configuración se realiza en la WebUI a lo largo de la ruta: Internet -> Conexiones ->
Otras conexiones
. Es bastante simple
(3 fotos)






Si planea conducir grandes volúmenes de tráfico a través del túnel, puede intentar habilitar la aceleración de hardware, que es compatible con muchos modelos. Habilitado por el comando de hardware del motor de cifrado en la CLI. Para deshabilitar y procesar los procesos de cifrado y hash utilizando instrucciones generales de la CPU: software de motor de cifrado

Después de guardar la configuración, restauramos strongswan y dejamos que Keenetic piense durante medio minuto. Luego en la terminal vemos una conexión exitosa:

Todo esta funcionando:
sudo strongswan status
Security Associations (2 up, 0 connecting):
    keenetic[57]: ESTABLISHED 39 minutes ago, 1.1.1.1[keenetic@router.home.local]...3.3.3.3[root@router.keenetic.local]
    keenetic{146}:  INSTALLED, TUNNEL, reqid 29, ESP SPIs: ca8f556e_i ca11848a_o
    keenetic{146}:   10.0.0.0/23 === 10.0.4.0/24
        mama[53]: ESTABLISHED 2 hours ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{145}:  INSTALLED, TUNNEL, reqid 27, ESP in UDP SPIs: c5dc78db_i c7baafd2_o
        mama{145}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24


Paso tres Proteger dispositivos móviles


Después de leer un montón de manuales y un montón de artículos, se decidió detenerse en un montón de un certificado gratuito de Let's Encrypt para autenticar el servidor y la autorización clásica mediante inicio de sesión y contraseña para los clientes. Por lo tanto, nos deshacemos de la necesidad de mantener nuestra propia infraestructura PKI, monitorear la caducidad de las claves y realizar gestos innecesarios con dispositivos móviles mediante la instalación de certificados autofirmados en la lista de confianza.

Instale los paquetes faltantes:

sudo yum install epel-release
sudo yum install certbot

Obtenemos el certificado independiente (no olvide abrir primero 80 / tcp en la configuración de iptables):

sudo certbot certonly --standalone -d ipsecgw.example.com

Después de que certbot haya completado su trabajo, debemos enseñar a Strongswan a ver nuestro certificado:

  • en el directorio /etc/strongswan/ipsec.d/cacerts cree 2 enlaces simbólicos: uno para el almacén raíz de certificados de confianza en / etc / pki / tls / certs; y un segundo con el nombre ca.pem apuntando a /etc/letsencrypt/live/ipsecgw.example.com/chain.pem
  • También se crean dos enlaces simbólicos en el directorio /etc/strongswan/ipsec.d/certs: el primero, con el nombre certificate.pem, se refiere al archivo /etc/letsencrypt/live/ipsecgw.example.com/cert.pem. Y el segundo, llamado fullchain.pem, que enlaza con /etc/letsencrypt/live/ipsecgw.example.com/fullchain.pem
  • En el directorio /etc/strongswan/ipsec.d/private, coloque el enlace simbólico key.pem apuntando a la clave privada generada por certbot y situada en la ruta /etc/letsencrypt/live/ipsecgw.example.com/privkey.pem

Agregue autenticación a través de RSA a ipsec.secrets y un montón de inicios de sesión / contraseñas para nuevos usuarios:

ipsecgw.example.com     : RSA key.pem
username phone          : EAP "Q1rkz*qt"
username notebook       : EAP "Zr!s1LBz"

Reiniciamos Strongswan y al llamar a sudo strongswan listcerts deberíamos ver la información del certificado:

List of X.509 End Entity Certificates

  subject:  "CN=ipsecgw.example.com"
  issuer:   "C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3"
  validity:  not before May 23 19:36:52 2020, ok
             not after  Aug 21 19:36:52 2020, ok (expires in 87 days)
  serial:    04:c7:70:9c:a8:ce:57:cc:bf:6f:cb:fb:d3:a9:cf:06:b0:a8
  altNames:  ipsecgw.example.com
  flags:     serverAuth clientAuth
  OCSP URIs: http://ocsp.int-x3.letsencrypt.org
  certificatePolicies:
             2.23.140.1.2.1
             1.3.6.1.4.1.44947.1.1.1
             CPS: http://cps.letsencrypt.org

Luego describimos la nueva conexión en ipsec.conf :

conn remote-access
    dpddelay = 30s //   DPD ,     
    left = %defaultroute
    leftid = "CN=ipsecgw.example.com"
    leftcert = fullchain.pem //         
    leftsendcert = always
    leftsubnet = 0.0.0.0/0 //      
    right = %any
    rightid = %any
    rightauth = eap-mschapv2 // ,  EAP-MSCHAP2
    rightsendcert = never
    eap_identity = %identity 
    rightsourceip = 10.1.1.0/24 //Strongswan       
    rightdns = 10.0.0.1,10.0.0.3 //   DNS
    type = tunnel
    ike = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha384-x25519!
    esp = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha256-sha384-x25519!
    auto = add //      
    dpdaction = restart // ,      DPD

No olvide editar el archivo / etc / sysconfig / certbot que indica que también actualizaremos el certificado como independiente, agregando CERTBOT_ARGS = "- independiente".

Además, no olvide activar el temporizador certbot-renew.timer y configurar el enlace para reiniciar Strongswan en caso de emitir un nuevo certificado. Para hacer esto, coloque un script bash simple en / etc / letsencrypt / renewal-hooks / deploy /, o edite el archivo / etc / sysconfig / certbot nuevamente.

Reiniciamos Strongswan, activamos el enmascaramiento para la red 10.1.1.0/24 en iptables y configuramos dispositivos móviles.

Androide


Instala la aplicación Strongswan desde Google Play .

Lanzamos y creamos un nuevo

perfil


Guardamos el perfil, nos conectamos y, después de un segundo, no tenemos que preocuparnos de que alguien pueda espiarnos.

Verificamos:
sudo strongswan statusall
Security Associations (3 up, 0 connecting):
remote-access[109]: ESTABLISHED 2 seconds ago, 1.1.1.1[CN=ipsecgw.example.com]...4.4.4.4[phone]
remote-access{269}:  INSTALLED, TUNNEL, reqid 55, ESP in UDP SPIs: c706edd1_i e5c12f1d_o
remote-access{269}:   0.0.0.0/0 ::/0 === 10.1.1.1/32
        mama[101]: ESTABLISHED 34 minutes ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{265}:  INSTALLED, TUNNEL, reqid 53, ESP in UDP SPIs: c8c83342_i c51309db_o
        mama{265}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24
    keenetic[99]: ESTABLISHED 36 minutes ago, 1.1.1.1[keenetic@router.home.local]...3.3.3.3[root@router.keenetic.local]
    keenetic{263}:  INSTALLED, TUNNEL, reqid 52, ESP SPIs: c3308f33_i c929d6f1_o
    keenetic{263}:   10.0.0.0/23 === 10.0.4.0/24


Ventanas


Windows de las versiones actuales se sorprendió gratamente. Toda la configuración de la nueva VPN se realiza llamando a dos cmdlets de PowerShell:

Add-VpnConnection -Name "IKEv2" -ServerAddress ipsecgw.example.com -TunnelType "IKEv2"
Set-VpnConnectionIPsecConfiguration -ConnectionName "IKEv2" -AuthenticationTransformConstants SHA256128 -CipherTransformConstants AES128 -EncryptionMethod AES128 -IntegrityCheckMethod SHA256 -PfsGroup PFS2048 -DHGroup Group14 -PassThru -Force

Y una cosa más, si Strongswan está configurado para emitir direcciones IPv6 a los clientes (sí, él también puede hacerlo):

Add-VpnConnectionRoute -ConnectionName "IKEv2" -DestinationPrefix "2000::/3"

Cuarta parte, final. Cortamos una ventana a Europa


Habiendo visto los talones del proveedor "El sitio fue bloqueado por la decisión del talón izquierdo del quinto fiscal adjunto de la aldea Trudovye Mozoli del condado de Bogozabyt", apareció un VPS pequeño y discreto (con el nombre de dominio que suena bien rkn.example.com) a miles de kilómetros de monos a los que les gusta agitar con un martillo y bloquear redes de tamaño / 16 a la vez. Y girar sobre este pequeño VPS fue una creación maravillosa de colegas de NIC.CZ llamada BIRD. El pájaro de la primera versión murió constantemente en pánico por la actividad de los monos con bastones, que prohibieron casi el 4% de Internet en el pico de su actividad laboral, dejando una profunda reflexión durante la reconfiguración, por lo tanto, se actualizó a la versión 2.0.7. Si los lectores están interesados, publicaré un artículo sobre la transición de BIRD a BIRD2, en el que el formato de configuración ha cambiado drásticamente,pero la nueva versión se ha vuelto mucho más rápida y no hay problemas con la reconfiguración con una gran cantidad de rutas. Y dado que usamos el protocolo de enrutamiento dinámico, debe haber una interfaz de red a través de la cual usted necesita enrutar el tráfico. Por defecto, IPSec no crea interfaces, pero debido a su flexibilidad, podemos usar los túneles GRE clásicos, que protegeremos en el futuro. Como beneficio adicional, los hosts ipsecgw.example.com y rkn.example.com se autenticarán entre sí utilizando Lets Encrypt certificados de renovación automática. Sin PSK, solo certificados, solo hardcore, no hay mucha seguridad.Por defecto, IPSec no crea interfaces, pero debido a su flexibilidad, podemos usar los túneles GRE clásicos, que protegeremos en el futuro. Como beneficio adicional, los hosts ipsecgw.example.com y rkn.example.com se autenticarán entre sí utilizando Lets Encrypt certificados de renovación automática. Sin PSK, solo certificados, solo hardcore, no hay mucha seguridad.Por defecto, IPSec no crea interfaces, pero debido a su flexibilidad, podemos usar los túneles GRE clásicos, que protegeremos en el futuro. Como beneficio adicional, los hosts ipsecgw.example.com y rkn.example.com se autenticarán entre sí utilizando Lets Encrypt certificados de renovación automática. Sin PSK, solo certificados, solo hardcore, no hay mucha seguridad.

Creemos que el VPS está preparado, Strongswan y Certbot ya están instalados.

En el host ipsecgw.example.com (su IP es 1.1.1.1), describimos la nueva interfaz gif0:
sudo vi /etc/sysconfig/network-scripts/ifcfg-gif0
DEVICE="gif0"
MY_OUTER_IPADDR="1.1.1.1"
PEER_OUTER_IPADDR="5.5.5.5"
MY_INNER_IPADDR="10.255.255.1/30"
PEER_INNER_IPADDR="10.255.255.2/30"
TYPE="GRE"
TTL="64"
MTU="1442"
ONBOOT="yes"

Reflejado en el host vps.example.com (su IP es 5.5.5.5):

sudo vi /etc/sysconfig/network-scripts/ifcfg-gif0
DEVICE="gif0"
MY_OUTER_IPADDR="5.5.5.5"
PEER_OUTER_IPADDR="1.1.1.1"
MY_INNER_IPADDR="10.255.255.2/30"
PEER_INNER_IPADDR="10.255.255.1/30"
TYPE="GRE"
TTL="64"
MTU="1442"
ONBOOT="yes"

Elevamos las interfaces, pero dado que iptables no tiene una regla que permita el protocolo GRE, el tráfico no irá (que es lo que necesitamos, ya que no hay protección dentro de GRE contra los fanáticos de ningún tipo de "paquetes" legislativos).

Cooking VPS


Primero, obtenemos otro certificado para el nombre de dominio rkn.example.com. Cree enlaces simbólicos en /etc/strongswan/ipsec.d como se describe en la sección anterior.

Edite ipsec.secrets agregándole una sola línea:

rkn.example.com     : RSA key.pem

Edite ipsec.conf:

config setup
    charondebug = "dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"
    strictcrlpolicy = yes
conn %default
    reauth = yes
    rekey = yes
    keyingtries = %forever
    keyexchange = ikev2
    dpdaction = restart
    dpddelay = 5s
    mobike = yes
conn rkn
    left = %defaultroute
    right = ipsecgw.example.com
    authby = pubkey
    leftcert = fullchain.pem
    leftsendcert = always
    leftauth = pubkey
    rightauth = pubkey
    leftid = "CN=rkn.example.com"
    rightid = "CN=ipsecgw.example.com"
    rightrsasigkey = /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem
    leftsubnet = %dynamic
    rightsubnet = %dynamic
    type = transport
    ike = aes256gcm16-sha384-x25519!
    esp = aes256gcm16-sha384-x25519!
    auto = route

En el lado del host, ipsecgw.example.com también se agrega a ipsec.conf en la sección de configuración el parámetro strictlycrlpolicy = yes, que incluye una estricta comprobación de CRL. Y describa otra conexión:

conn rkn
    left = %defaultroute
    right = rkn.example.com
    leftcert = fullchain.pem
    leftsendcert = always
    leftauth = pubkey
    rightauth = pubkey
    rightrsasigkey = /etc/strongswan/ipsec.d/certs/rkn.exapmle.com.pem
    leftid = "CN=ipsecgw.example.com"
    rightid = "CN=rkn.example.com"
    leftsubnet = %dynamic
    rightsubnet = %dynamic
    type = transport
    ike = aes256gcm16-sha384-x25519!
    esp = aes256gcm16-sha384-x25519!
    auto = route
    dpdaction = restart

Las configuraciones casi se reflejan. El lector atento ya podría prestar atención a un par de puntos:

  • left / rightsubnet =% dynamic: indica a Strongswan que aplique políticas a todos los tipos de tráfico entre pares
  • rightrsasigkey. IKE SA IKE AUTH ERROR , Strongswan RSA- . openssl. (ipsecgw RKN) sudo /usr/bin/openssl rsa -in /etc/letsencrypt/live/ipsecgw.example.com/privkey.pem -pubout > ~/ipsecgw.example.com.pem sudo /usr/bin/openssl rsa -in /etc/letsencrypt/live/rkn.example.com/privkey.pem -pubout > ~/rkn.example.com.pem, scp ,

No olvide configurar el firewall y los certificados de renovación automática. Después de reiniciar Strongswan en ambos servidores, comience a hacer ping en el extremo más alejado del túnel GRE y vea una conexión exitosa. En VPS (rkn):

sudo strongswan status
Routed Connections:
         rkn{1}:  ROUTED, TRANSPORT, reqid 1
         rkn{1}:   5.5.5.5/32 === 1.1.1.1/32
Security Associations (1 up, 0 connecting):
         rkn[33]: ESTABLISHED 79 minutes ago, 5.5.5.5[CN=rkn.example.com]...1.1.1.1[CN=ipsecgw.example.com]
         rkn{83}:  INSTALLED, TRANSPORT, reqid 1, ESP SPIs: cb4bc3bb_i c4c35a5a_o
         rkn{83}:   5.5.5.5/32 === 1.1.1.1/32


Y en el lado del host ipsecgw
debajo del spoiler
Routed Connections:
         rkn{1}:  ROUTED, TRANSPORT, reqid 1
         rkn{1}:   1.1.1.1/32 === 5.5.5.5/32
Security Associations (4 up, 0 connecting):
remote-access[10]: ESTABLISHED 5 seconds ago, 1.1.1.1[CN=ipsecgw.example.com]...4.4.4.4[phone]
remote-access{12}:  INSTALLED, TUNNEL, reqid 7, ESP in UDP SPIs: c7a31be1_i a231904e_o
remote-access{12}:   0.0.0.0/0 === 10.1.1.1/32
    keenetic[8]: ESTABLISHED 22 minutes ago, 1.1.1.1[keenetic@router.home.local]...3.3.3.3[root@router.keenetic.local]
    keenetic{11}:  INSTALLED, TUNNEL, reqid 6, ESP SPIs: cfc1b329_i c01e1b6e_o
    keenetic{11}:   10.0.0.0/23 === 10.0.4.0/24
        mama[4]: ESTABLISHED 83 minutes ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{8}:  INSTALLED, TUNNEL, reqid 3, ESP in UDP SPIs: c4a5451a_i ca67c223_o
        mama{8}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24
         rkn[3]: ESTABLISHED 83 minutes ago, 1.1.1.1[CN=ipsecgw.example.com]...5.5.5.5[CN=rkn.example.com]
         rkn{7}:  INSTALLED, TRANSPORT, reqid 1, ESP SPIs: c4c35a5a_i cb4bc3bb_o
         rkn{7}:   1.1.1.1/32 === 5.5.5.5/32


El túnel está instalado, los pings van, en tcpdump es visible que solo ESP pasa entre los hosts. Parece posible alegrarse. Pero no puedes relajarte sin revisar todo hasta el final. Estamos intentando volver a emitir el certificado para VPS y ...

Chef, todo está roto


Comenzamos a comprender y tropezar con una característica desagradable de Let's Encrypt, que es hermosa en todo lo demás: con cualquier reemisión del certificado, la clave privada asociada con él también cambia. La clave privada ha cambiado, y la pública ha cambiado. A primera vista, la situación es desesperada para nosotros: incluso si podemos extraer fácilmente la clave pública durante la nueva emisión del certificado utilizando el gancho en certbot y pasarlo al lado remoto a través de SSH, no está claro cómo hacer que el remoto Strongswan lo vuelva a leer. Pero la ayuda vino de donde no esperaban: systemd puede monitorear los cambios en el sistema de archivos y ejecutar los servicios asociados con el evento. Esto es lo que usaremos.

Crearemos un usuario del servicio keywatcher en cada uno de los hosts con los derechos más restringidos, generaremos claves SSH para cada uno de ellos y los intercambiaremos entre los hosts.

En el host ipsecgw.example.com, cree el directorio / opt / ipsec-pubkey en el que colocamos 2 scripts.

sudo vi /opt/ipsec-pubkey/pubkey-copy.sh

#!/bin/sh
if [ ! -f /home/keywatcher/ipsecgw.example.com.pem ]; then
  /usr/bin/openssl rsa -in /etc/letsencrypt/live/ipsecgw.example.com/privkey.pem -pubout > /home/keywatcher/ipsecgw.example.com.pem;
  /usr/bin/chown keywatcher:keywatcher /home/keywatcher/ipsecgw.example.com.pem;
  /usr/bin/chmod 0600 /home/keywatcher/ipsecgw.example.com.pem;
  sudo -u keywatcher /usr/bin/scp /home/keywatcher/ipsecgw.example.com.pem rkn.example.com:/home/keywatcher/ipsecgw.example.com.pem;
  status=$?;
  if [ $status -eq 0 ]; then
    rm -f /home/keywatcher/ipsecgw.example.com.pem;
    logger "Public key ipsecgw.example.com.pem has been successfully uploaded to remote host";
  else
    logger "Public key ipsecgw.example.com.pem has not been uploaded to remote host due to error";
  fi
  else
    logger "Public key ipsecgw.example.com.pem already exist on /home/keywatcher directory, something went wrong";
fi
exit 0

sudo vi /opt/ipsec-pubkey/key-updater.sh

#!/bin/sh
/usr/bin/cp /home/keywatcher/rkn.example.com.pem /etc/strongswan/ipsec.d/certs/rkn.example.com.pem
/usr/bin/chown root:root /etc/strongswan/ipsec.d/certs/rkn.example.com.pem
/usr/bin/chmod 0600 /etc/strongswan/ipsec.d/certs/rkn.example.com.pem
logger "Public key of server rkn.example.com has been updated, restarting strongswan daemon to re-read it"
/usr/bin/systemctl restart strongswan
exit 0

En VPS (el host rkn.example.com), creamos de manera similar un directorio con el mismo nombre, en el que también creamos scripts similares, cambiando solo el nombre de la clave. Código, para no abarrotar el artículo, bajo

revelación
sudo vi /opt/ipsec-pubkey/pubkey-copy.sh
#!/bin/sh
if [ ! -f /home/keywatcher/rkn.example.com.pem ]; then
  /usr/bin/openssl rsa -in /etc/letsencrypt/live/rkn.example.com/privkey.pem -pubout > /home/keywatcher/rkn.example.com.pem;
  /usr/bin/chown keywatcher:keywatcher /home/keywatcher/rkn.example.com.pem;
  /usr/bin/chmod 0600 /home/keywatcher/rkn.example.com.pem;
  sudo -u keywatcher /usr/bin/scp /home/keywatcher/rkn.example.com.pem ipsecgw.example.com:/home/keywatcher/rkn.example.com.pem;
  status=$?;
  if [ $status -eq 0 ]; then
    rm -f /home/keywatcher/rkn.example.com.pem;
    logger "Public key rkn.example.com.pem has been successfully uploaded to remote host";
  else
    logger "Public key rkn.example.com.pem has not been uploaded to remote host";
  fi
  else
    logger "Public key rkn.example.com.pem already exist on /home/keywatcher directory, something went wrong";
fi
exit 0

sudo vi /opt/ipsec-pubkey/key-updater.sh


#!/bin/bash
/usr/bin/cp /home/keywatcher/ipsecgw.example.com.pem /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem;
/usr/bin/chown root:root /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem
/usr/bin/chmod 0600 /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem
logger "Public key of server ipsecgw.example.com has been updated, restarting connection"
/usr/bin/systemctl restart strongswan
exit 0


El script pubkey-copy.sh es necesario para extraer la parte pública de la clave y copiarla al host remoto al emitir un nuevo certificado. Para hacer esto, en el directorio / etc / letsencrypt / renewal-hooks / deploy en ambos servidores, cree otro microscript:


#!/bin/sh
/opt/ipsec-pubkey/pubkey-copy.sh > /dev/null 2>&1
/usr/bin/systemctl restart strongswan
exit 0

La mitad del problema se resuelve, los certificados se vuelven a emitir, las claves públicas se extraen y copian entre los servidores, y ha llegado el momento de systemd con sus unidades de ruta.

En el servidor ipsecgw.example.com en el directorio / etc / systemd / system, cree el archivo keyupdater.path

[Unit]
Wants=strongswan.service
[Path]
PathChanged=/home/keywatcher/rkn.example.com.pem
[Install]
WantedBy=multi-user.target

Del mismo modo en el host VPS:

[Unit]
Wants=strongswan.service
[Path]
PathChanged=/home/keywatcher/ipsecgw.example.com.pem
[Install]
WantedBy=multi-user.target

Y finalmente, en cada servidor creamos un servicio asociado con esta unidad, que se lanzará cuando se cumpla la condición (PathChanged): cambiar el archivo y cerrarlo después de la grabación. Creamos los archivos /etc/systemd/system/keyupdater.service y escribimos:

[Unit]
Description= Starts the IPSec key updating script
Documentation= man:systemd.service
[Service]
Type=oneshot
ExecStart=/opt/ipsec-pubkey/key-updater.sh
[Install]
WantedBy=multi-user.target

No olvide volver a leer las configuraciones de systemd con sudo systemctl daemon-reload y asignar el inicio automático a las unidades de ruta a través de sudo systemctl enable keyupdater.path && sudo systemctl start keyupdater.

Tan pronto como el host remoto escriba el archivo que contiene la clave pública en el directorio de inicio del usuario de keywatcher y el descriptor de archivo se cierre, systemd iniciará automáticamente el servicio correspondiente, que copiará la clave en la ubicación deseada y reiniciará Strongswan. El túnel se instalará utilizando la clave pública correcta del segundo lado.

Puedes exhalar y disfrutar el resultado.

En lugar de una conclusión


Como acabamos de ver el infierno, IPSec no da tanto miedo como está pintado. Todo lo que se ha descrito es una configuración totalmente operativa que está actualmente en uso. Incluso sin mucho conocimiento, puede configurar una VPN y proteger sus datos de manera confiable.

Por supuesto, los momentos de configuración de iptables quedaron fuera del alcance del artículo, pero el artículo en sí resultó ser voluminoso y se ha escrito mucho sobre iptables.

Hay puntos en el artículo que pueden mejorarse, ya sea la negativa a reiniciar el demonio Strongswan, releyendo sus configuraciones y certificados, pero no pude lograrlo.

Sin embargo, los reinicios del demonio no dieron miedo: se pierden uno o dos pings entre pares, los clientes móviles restauran la conexión ellos mismos.

Espero que los colegas en los comentarios indiquen la solución correcta.

All Articles