Por qué su VPN es un riesgo: Acceso a la red de confianza cero (Zero-Trust) en SaaS modernos
Acceso a la red de confianza cero (Zero-Trust) en SaaS modernos: derribe sus VPN
Tenemos que hablar de su seguridad perimetral. Si en 2026 todavía depende de una Red Privada Virtual (VPN) tradicional para asegurar los servicios internos, está creando un riesgo de seguridad. El clásico modelo de "castillo y foso" está muerto. Una vez que un atacante supera el foso, tiene movimiento lateral ilimitado por toda su red interna. Esto es inaceptable para los entornos modernos de Software como Servicio (SaaS).
El único camino viable a seguir es el Acceso a la red de confianza cero (Zero-Trust Network Access - ZTNA). En un modelo de confianza cero (zero-trust), la red misma se considera hostil. Cada solicitud, ya sea que se origine de un trabajador remoto en una cafetería o de un microservicio dentro de su propio clúster de Kubernetes, debe ser explícitamente autenticada, autorizada y validada continuamente.
Esta publicación analiza el problema de los perímetros tradicionales, el cambio arquitectónico requerido para ZTNA y una estrategia concreta de implementación utilizando proxies modernos conscientes de la identidad (identity-aware proxies).
El problema: La seguridad perimetral es una fantasía
La seguridad de red tradicional se basa en direcciones IP y límites de red. Se coloca un firewall en el borde de su infraestructura y una puerta de enlace (gateway) VPN para el acceso remoto. Una vez que un usuario se autentica en la VPN, se le asigna una dirección IP interna y se le otorga un acceso amplio a la red local (LAN) corporativa.
Esta arquitectura tiene tres fallas fatales:
- Confianza implícita: El sistema confía implícitamente en cualquier entidad que opere desde una dirección IP interna. Si la computadora portátil de un desarrollador se ve comprometida, el atacante tiene un túnel directo a su entorno de producción.
- Falta de granularidad: Las VPN operan en la capa 3 o 4 del modelo OSI. Otorgan acceso a segmentos de red enteros (subredes), no a aplicaciones individuales. No se puede decir fácilmente: "Alice puede acceder al panel de métricas interno, pero no a la API de facturación", sin gestionar un laberinto de complejas ACL de red.
- Mala experiencia de usuario: Enrutar todo el tráfico a través de una puerta de enlace VPN centralizada introduce una latencia masiva y cuellos de botella en el ancho de banda.
Está protegiendo el elemento equivocado. Está protegiendo la red, cuando debería estar protegiendo la aplicación.
Por qué es difícil: La complejidad del acceso consciente de la identidad
Si el acceso a la red de confianza cero es tan superior, ¿por qué no lo hace todo el mundo? Porque pasar de una seguridad centrada en la red a una seguridad centrada en la identidad es difícil conceptual y operativamente.
Requiere abandonar las direcciones IP como unidad de confianza y reemplazarlas con identidad y contexto criptográficos.
Esto es lo que hace que la transición sea dolorosa:
- Federación de identidades: Debe centralizar la gestión de identidades. Cada aplicación debe integrarse con su Proveedor de Identidades (IdP), generalmente Google Workspace, Okta o Azure AD. Adaptar herramientas internas heredadas que solo admiten Basic Auth o que no tienen autenticación es un dolor de cabeza enorme.
- Gestión de políticas: En un entorno de VPN, el acceso es binario: está en la red o no lo está. En un entorno ZTNA, las políticas de acceso son altamente granulares y contextuales. Debe definir reglas basadas en el rol del usuario, el estado del dispositivo (¿es un dispositivo administrado por la empresa? ¿está habilitado el cifrado de disco?), la hora del día y la sensibilidad de la aplicación.
- Rendimiento y latencia: Cada solicitud debe ser interceptada, autenticada y autorizada. Si su proxy consciente de la identidad es lento, todo su conjunto de aplicaciones se sentirá lento.
A pesar de estos desafíos, el cambio es obligatorio. Un perímetro comprometido es una cuestión de "cuándo", no de "si".
Arquitectura: El diseño de acceso a la red de confianza cero
Una arquitectura robusta de acceso a la red de confianza cero en un entorno SaaS reemplaza la puerta de enlace VPN con un Proxy Consciente de la Identidad (Identity-Aware Proxy - IAP). El proxy se ubica directamente frente a sus aplicaciones internas, mediando cada solicitud HTTP.
Los componentes principales de esta arquitectura son:
- Proveedor de Identidad (IdP): La fuente de verdad para las identidades de los usuarios y las pertenencias a grupos (por ejemplo, Okta).
- Proveedor de confianza del dispositivo (Device Trust Provider): Un sistema que evalúa el estado de salud y seguridad de los endpoints (por ejemplo, CrowdStrike, Kolide).
- Motor de políticas (Policy Engine): Un servicio centralizado que almacena y evalúa las reglas de acceso.
- Proxy consciente de la identidad (IAP): El punto de aplicación de políticas. Intercepta las solicitudes, consulta al motor de políticas y reenvía la solicitud a la aplicación ascendente (upstream) o la rechaza.
El flujo de solicitudes
Cuando un desarrollador intenta acceder a un servicio interno (por ejemplo, metrics.internal.yourcompany.com), se produce el siguiente flujo:
- El DNS del usuario resuelve el nombre de host a la IP pública del Proxy Consciente de la Identidad.
- El navegador del usuario inicia una conexión TLS con el proxy.
- El proxy busca una cookie de sesión criptográfica válida. Si no existe ninguna, redirige al usuario al IdP a través de OpenID Connect (OIDC).
- El usuario se autentica con el IdP (lo que requiere una MFA resistente al phishing, como una YubiKey).
- El IdP redirige al usuario de vuelta al proxy con un token de identidad.
- El proxy pasa la identidad del usuario, el contexto del dispositivo y la URL solicitada al motor de políticas.
- El motor de políticas evalúa la solicitud en comparación con las reglas definidas (por ejemplo, "Solo los ingenieros en dispositivos propiedad de la empresa pueden acceder a las métricas").
- Si está autorizado, el proxy reenvía la solicitud a la aplicación ascendente (upstream). Fundamentalmente, el proxy inyecta una aserción (a menudo un JWT firmado) en los encabezados de la solicitud.
- La aplicación ascendente valida el JWT para asegurarse de que la solicitud provino del proxy de confianza, y no de un proceso malicioso dentro del clúster.
Esta arquitectura proporciona verificación continua en la Capa 7.
Implementación: Construcción de ZTNA con Pomerium y Kubernetes
Veamos una implementación concreta. Utilizaremos Pomerium como nuestro proxy consciente de la identidad, implementándolo en un clúster de Kubernetes (v1.29+). Pomerium es una excelente opción porque es de código abierto, increíblemente rápido y se integra de forma nativa con IdP estándar.
Asumimos que tiene un clúster de Kubernetes en funcionamiento y un servicio que desea exponer de forma segura, como un panel de Grafana.
Paso 1: Implementación de Pomerium
Primero, necesitamos configurar Pomerium para conectarse a nuestro IdP. Usamos un chart de Helm estándar. Aquí hay un ejemplo de configuración de values.yaml para Pomerium, vinculándolo a Google Workspace.
# pomerium-values.yaml
authenticate:
idp:
provider: google
clientID: "YOUR_GOOGLE_CLIENT_ID"
clientSecret: "YOUR_GOOGLE_CLIENT_SECRET"
serviceAccount: "base64_encoded_service_account_json"
ingress:
enabled: true
className: "nginx"
hosts:
- authenticate.internal.yourcompany.com
tls:
- secretName: pomerium-tls
hosts:
- authenticate.internal.yourcompany.com
config:
# El secreto compartido para la comunicación entre los componentes de Pomerium
sharedSecret: "generar_una_cadena_base64_aleatoria_aquí"
cookieSecret: "generar_otra_cadena_base64_aleatoria_aquí"
Aplique el chart de helm:
helm repo add pomerium https://helm.pomerium.io
helm install pomerium pomerium/pomerium -f pomerium-values.yaml --namespace pomerium --create-namespace
Paso 2: Definición de políticas de acceso
Ahora necesitamos asegurar nuestra instancia de Grafana. Hacemos esto definiendo un recurso Ingress con anotaciones específicas que Pomerium entiende. En lugar de un Ingress de Kubernetes estándar, utilizaremos la definición de recurso personalizado (CRD) de Pomerium, PomeriumRoute.
Aquí es donde brilla el poder de ZTNA. Definimos la política como código junto con la implementación de nuestra aplicación.
# grafana-route.yaml
apiVersion: ingress.pomerium.io/v1
kind: PomeriumRoute
metadata:
name: grafana-secure-route
namespace: monitoring
spec:
from: https://metrics.internal.yourcompany.com
to: http://grafana.monitoring.svc.cluster.local:80
policy:
- allow:
and:
- domain:
is: yourcompany.com
- claim/groups:
has: "engineering-team@yourcompany.com"
Esta configuración establece: Permitir el acceso a https://metrics.internal.yourcompany.com SOLO SI el usuario se autentica con una dirección de correo electrónico @yourcompany.com Y es miembro del grupo engineering-team.
Aplique la ruta:
kubectl apply -f grafana-route.yaml
Paso 3: Validación ascendente (El paso crítico)
Si se detiene en el Paso 2, tiene una vulnerabilidad. ¿Qué sucede si un atacante compromete un pod dentro de su clúster de Kubernetes? Podría omitir Pomerium por completo y enviar solicitudes directamente a http://grafana.monitoring.svc.cluster.local:80.
Para lograr un verdadero Acceso a la red de confianza cero, la aplicación ascendente (Grafana) debe verificar que cada solicitud haya pasado por Pomerium.
Pomerium inyecta un encabezado X-Pomerium-Jwt-Assertion en cada solicitud que realiza como proxy. Este JWT está firmado por la clave privada de Pomerium.
Su aplicación debe validar este JWT. Si está construyendo microservicios personalizados en Go (por ejemplo, usando Go 1.22), implementa un middleware para realizar esta comprobación.
package main
import (
"context"
"crypto/rsa"
"fmt"
"net/http"
"strings"
"github.com/golang-jwt/jwt/v5"
"github.com/lestrrat-go/jwx/v2/jwk"
)
// URL de JWKS para Pomerium
const pomeriumJWKSURL = "https://authenticate.internal.yourcompany.com/.well-known/pomerium/jwks.json"
func requirePomeriumAssertion(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assertion := r.Header.Get("X-Pomerium-Jwt-Assertion")
if assertion == "" {
http.Error(w, "Missing Pomerium Assertion", http.StatusUnauthorized)
return
}
// Obtener y almacenar en caché las claves públicas de Pomerium
ctx := context.Background()
set, err := jwk.Fetch(ctx, pomeriumJWKSURL)
if err != nil {
http.Error(w, "Failed to fetch keys", http.StatusInternalServerError)
return
}
// Analizar y validar el JWT
token, err := jwt.Parse(assertion, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodES256); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
kid, ok := token.Header["kid"].(string)
if !ok {
return nil, fmt.Errorf("missing kid header")
}
key, ok := set.LookupKeyID(kid)
if !ok {
return nil, fmt.Errorf("key %v not found", kid)
}
var rawKey interface{}
if err := key.Raw(&rawKey); err != nil {
return nil, err
}
return rawKey, nil
})
if err != nil || !token.Valid {
http.Error(w, "Invalid Assertion", http.StatusForbidden)
return
}
// Continuar con la aplicación
next.ServeHTTP(w, r)
})
}
Al imponer la validación de JWT en la capa de aplicación, hace que los límites de red sean irrelevantes. Incluso si un atacante está en la misma subred, no puede eludir las verificaciones de autorización.
Errores comunes: Dónde fallan las implementaciones de ZTNA
Implementar un proxy consciente de la identidad es sencillo. Transicionar realmente a una organización a un modelo de confianza cero es lo difícil. Estos son los modos de falla comunes.
1. Ignorar las aplicaciones heredadas
Las aplicaciones SaaS modernas hablan HTTP y entienden de forma nativa OAuth u OIDC. Las herramientas internas heredadas a menudo no lo hacen. Pueden depender de direcciones IP codificadas de forma fija o de autenticación básica.
No intente reescribir estas aplicaciones de inmediato. En su lugar, use su proxy para inyectar encabezados o realizar traducciones de autenticación básica. Si una aplicación utiliza un protocolo que no es HTTP (como SSH o RDP), necesita un proxy que admita la tunelización (Pomerium y Teleport manejan esto muy bien).
2. El antipatrón de "romper el vidrio" (Break Glass)
Los equipos a menudo implementan políticas ZTNA estrictas, pero dejan una VPN de respaldo (backdoor) funcionando "solo en caso de" que el proveedor de identidad se caiga. Esto derrota el propósito. Los atacantes encontrarán la VPN.
En lugar de una red paralela insegura, diseñe su arquitectura ZTNA para una alta disponibilidad. Utilice IdP redundantes o asegúrese de que su proxy pueda almacenar en caché las decisiones de políticas y las claves criptográficas para sobrevivir a breves interrupciones del IdP.
3. Fatiga por alertas
Una arquitectura de confianza cero genera un volumen inmenso de registros. Cada solicitud es un evento de autorización. Si descarga todos estos registros en un SIEM sin un filtrado y correlación agresivos, su equipo de seguridad se verá abrumado por la fatiga por alertas.
Concéntrese en registrar las solicitudes denegadas que se originan en dispositivos corporativos conocidos, o escenarios de viajes imposibles dentro de sus registros de identidad.
Resultado: Un SaaS moderno y resiliente
Moverse al acceso a la red de confianza cero es una inversión de ingeniería significativa. Requiere volver a capacitar a los equipos, actualizar la infraestructura y adoptar nuevas mentalidades operativas.
Pero el resultado es una organización fundamentalmente más resiliente.
Cuando elimina the VPN, elimina el concepto de redes internas versus externas. Otorga acceso según la identidad y el contexto, no según las direcciones IP. Obtiene una visibilidad microscópica de quién accede a qué y cuándo.
Lo más importante es que reduce drásticamente el radio de impacto de un endpoint comprometido. En un mundo basado en perímetros, una computadora portátil robada de un desarrollador es una brecha catastrófica. En un mundo de confianza cero, es un incidente contenido.
Derribe sus fosos. Asegure sus aplicaciones. Comience a construir una arquitectura de confianza cero hoy mismo.
Servicio de Seven Labs
Pruebas de Penetración VAPT y Ciberseguridad
