Client VPN entrega una dirección al cliente, el handshake se completa y la conexión sigue sin ir a ninguna parte. Antes de tocar certificados o versiones del cliente, mira la propia tabla de rutas del punto de enlace. Un punto de enlace de AWS Client VPN solo reenvía un paquete cuando una de sus rutas cubre el prefijo de destino; si nada coincide, el paquete se descarta en el punto de enlace y el host de destino nunca ve un SYN.

Eso es una decisión de reenvío, no de autenticación. Ocurre después de que el túnel esté levantado y de que se evalúen las reglas de autorización, por eso un certificado válido y un grupo válido todavía pueden producir una conexión muerta.

El punto de enlace solo reenvía lo que cubre su tabla de rutas

Cada ruta es un CIDR de destino más la subred que debe recibir el tráfico. El punto de enlace compara el destino del cliente con esa lista, elige la entrada coincidente y envía el paquete a la subred asociada. Sin entrada no hay siguiente salto.

Fíjate en lo que la ruta no es. No es una entrada de la tabla de rutas de la VPC y no autoriza nada. Las reglas de autorización deciden si un grupo puede alcanzar un destino; las rutas deciden si el punto de enlace tiene dónde enviar el paquete. Ambas deben coincidir, y fallan con síntomas distintos, así que adivinar cuál está rota desperdicia una tarde.

El desajuste clásico es una VPC con peering. Alguien añade una ruta para 10.20.0.0/24 mientras el host vive en 10.20.4.0/24, así que la dirección queda fuera de todas las entradas. Una captura en el lado del cliente muestra SYN repetidos sin respuesta, y los registros del destino no muestran absolutamente nada.

Lee la lista de rutas antes del certificado

Las rutas del punto de enlace son un objeto propio, así que consúltalas directamente en lugar de leer la tabla de la VPC:

aws ec2 describe-client-vpn-routes --client-vpn-endpoint-id cvpn-endpoint-0123456789abcdef0 --query 'Routes[].{Dest:DestinationCidr,Target:TargetSubnet,Origin:Origin}'

Toma la dirección exacta y la longitud de prefijo del cliente que falla, y luego comprueba la cobertura carácter por carácter. Se aplica la coincidencia de prefijo más largo, así que una ruta más amplia no te salva cuando una más estrecha apunta a otro sitio.

Un recurso por destino con for_each

Los bloques de rutas escritos a mano se desvían en el momento en que alguien añade un prefijo en la consola. Mantén los destinos en un mapa y crea un recurso por clave, para que cada adición o eliminación quede aislada.

variable "client_vpn_routes" {
  type = map(string)
  default = {
    "10.20.0.0/16"  = "subnet-0aa11bb22cc33dd44"
    "172.31.0.0/20" = "subnet-0aa11bb22cc33dd44"
  }
}

resource "aws_ec2_client_vpn_route" "this" {
  for_each               = var.client_vpn_routes
  client_vpn_endpoint_id = var.client_vpn_endpoint_id
  destination_cidr_block = each.key
  target_vpc_subnet_id   = each.value
  depends_on             = [aws_ec2_client_vpn_network_association.this]
}

Conserva la dependencia de la asociación de red. Una ruta necesita una subred asociada, así que un apply que cree ambas cosas debe ordenar primero la asociación, y sin esa referencia Terraform es libre de intentar la ruta primero. Luego lee el plan: el número de adiciones de rutas debe coincidir con los prefijos que añadiste. Si el plan también reemplaza el punto de enlace, el recurso del punto de enlace está mal escrito, y aplicarlo desconecta a todos los clientes conectados.

Adoptar un punto de enlace que no creaste

La mayoría de los equipos heredan un punto de enlace construido en la consola, y por eso no existe código de rutas. No levantes un segundo punto de enlace solo para meter rutas en Terraform.

Importa en su lugar, o pasa los ids como variables y deja los objetos heredados sin gestionar. La importación necesita el formato de identificador que el proveedor documenta para cada tipo de recurso, que codifica el punto de enlace, el prefijo de destino y la subred objetivo. Copia esa cadena de la documentación del recurso en lugar de componerla de memoria, ejecuta un plan y espera que no haya cambios antes de añadir algo nuevo.

Sigue el paquete en el orden en que viaja

Cuando la ruta existe y la conexión sigue fallando, recorre el camino en orden en lugar de adivinar en la capa superior.

  1. Ruta: un prefijo cubre el destino y apunta a una subred asociada al punto de enlace.
  2. Autorización: una regla de autorización permite ese destino para el grupo del usuario. Una ruta sola nunca concede acceso.
  3. Camino de vuelta: la tabla de rutas de la subred de destino envía las respuestas de vuelta hacia el punto de enlace, y el grupo de seguridad permite el puerto desde el grupo de direcciones del cliente.
  4. Aplicación: abre una conexión TCP real desde el cliente y luego confirma que los registros del destino muestran la dirección de origen esperada del grupo.

Cambia un prefijo por apply, vuelve a leer la lista de rutas después y anota juntos el destino, la regla que autoriza y el camino de vuelta. La próxima persona que depure una conexión rechazada debería empezar por ese inventario, no por una teoría sobre certificados.

Artículos relacionados