Control de acceso VPN de oficina: permitir solo lo necesario (no LAN a LAN completo)

¿Te fue útil?

Configuras un acceso VPN “temporal” a la oficina para un proveedor, un contratista o el nuevo equipo de ventas remoto. Funciona. Todos celebran.
Seis meses después miras un incidente de movimiento lateral, una filtración de rutas misteriosa y un firewall que parece un plato de espagueti.
La VPN no falló. Tus límites sí.

El objetivo aquí no es hacer el acceso VPN imposible. Es hacerlo aburrido: solo las aplicaciones requeridas, solo las rutas necesarias,
con protecciones que sigan funcionando cuando la red cambie a las 2 a.m. y tu pager ya esté enfadado contigo.

El principio: la VPN no es un teletransportador a tu LAN

“VPN de oficina” tiende a tratarse como un cable mágico: conecta un portátil remoto y—¡puf!—está “en la oficina”.
Ese es el modelo mental que genera acceso LAN‑a‑LAN completo, rutas amplias y reglas de firewall “any‑any”.
También es el modelo mental que hace que la respuesta a incidentes sea miserable.

Una VPN es solo un transporte. No es un sistema de autorización. Si no colocas deliberadamente autorización encima—rutas,
políticas de firewall y puertas con conocimiento de identidad—estás concediendo lo que la topología de red permita hoy.
Y la topología cambia todo el tiempo.

El modelo correcto es: una VPN es una rampa controlada hacia un conjunto pequeño de servicios. Esos servicios pueden vivir en tu LAN,
en una DMZ/segmento VPN o en redes cloud. Pero la rampa no debe llevar a “todo con una dirección RFC1918”.

Orientación de opinión: trata el “LAN‑a‑LAN completo” como una violación por defecto-denegar. Si lo necesitas, deberías poder defenderlo por escrito.
No en una reunión de comité. En una revisión post‑incidente.

Modelo de amenazas en lenguaje claro: contra qué te defiendes

1) Movimiento lateral desde un endpoint comprometido

Los endpoints remotos son desordenados. Viajan. Se conectan a Wi‑Fi de cafetería. Ejecutan extensiones de navegador que fueron “gratis” por una razón.
Si un endpoint se ve comprometido y tu VPN lo coloca en el mismo alcance L2/L3 que servidores de archivos, impresoras, hipervisores, cajas de backup
y consolas de administración “temporales”, acabas de dar a un atacante una autopista privada.

2) Acceso accidental: el error honesto que aún duele

La mayoría de los “accesos no autorizados” en redes corporativas no son un villano con capucha.
Es un desarrollador que apunta un script a 10.0.0.0/8 porque era más rápido que encontrar la IP correcta.
Es un proveedor “solo revisando algo” en un host al que no debía llegar.
Un diseño VPN de mínimo privilegio previene tanto la malicia como el despiste.

3) Filtraciones de rutas y subredes superpuestas

Si alguna vez fusionaste dos empresas o añadiste una nueva VPC cloud, conoces al villano:
el espacio RFC1918 superpuesto. Con rutas VPN amplias, se vuelve ambiguo a cuál “10.0.12.0/24” te referías,
y a veces la ruta equivocada aún funciona—hasta que deja de funcionar y pasas el fin de semana diffando tablas de enrutamiento.

4) DNS como vector de acceso

El DNS privado puede revelar nombres internos, objetivos de descubrimiento de servicios y puntos de gestión “ocultos”.
No quieres que cada usuario VPN consulte todas las zonas internas, aunque luego no puedan conectar.
El reconocimiento es una fase, no un permiso.

5) Fallo operativo: el modelo de acceso que no puedes depurar

La política VPN demasiado ingeniosa es una amenaza en sí misma. Si la única persona que entiende el enrutamiento está de vacaciones,
tu tiempo medio de reparación pasa a ser “cuando aterrice”. La depurabilidad es una característica de seguridad.

Idea parafraseada (atribución): “La esperanza no es una estrategia.” — a menudo atribuida en la cultura de ops a General Gordon R. Sullivan.
Te guste la frase o no, aplica: no “esperes” que el acceso VPN amplio permanezca seguro.

Hechos históricos e interesantes (porque seguimos reaprendiendo)

  1. Las VPNs se hicieron populares como “extensiones de perímetro” en los 90/principios de 2000, cuando las oficinas tenían un límite claro dentro/fuera y el acceso remoto era raro.
  2. IPsec fue diseñado para seguridad red‑a‑red, no para acceso por aplicación—así que la “alcanzabilidad de subred completa” es un resultado natural (pero anticuado).
  3. El split tunneling se trataba como herejía porque rompe la narrativa de “todo el tráfico pasa por HQ” para inspección; hoy a menudo es necesario por rendimiento y realidad SaaS.
  4. NAT complicó las fusiones: las redes RFC1918 superpuestas se toleraban porque NAT “arreglaba” hasta que intentas unir dos entornos con mucho NAT y todo choca.
  5. El acceso remoto temprano concentraba la confianza en la puerta VPN; los diseños modernos distribuyen la confianza en proveedores de identidad, comprobaciones de postura del dispositivo y proxies a nivel de aplicación.
  6. Las “redes planas” fueron normales porque las amenazas internas estaban subestimadas; el ransomware y el robo de credenciales hicieron que la segmentación interna sea innegociable.
  7. WireGuard popularizó la ruta-como-política: su AllowedIPs es tanto enrutamiento como control de acceso, lo que es elegante y fácil de dispararse en el pie.
  8. El DNS split‑horizon no es nuevo, pero las VPNs lo hicieron ubicuo: los nombres internos para servicios se convirtieron en dependencia, y el DNS mal dimensionado fue una fuga común.
  9. La redes en la nube empujaron el pensamiento “primero el servicio”: los security groups y gateways L7 obligaron a los equipos a nombrar a qué se conectan, no solo qué subred existe.

Si sacas una lección de la historia: las arquitecturas sobreviven a las razones por las que se construyeron. La VPN que heredaste probablemente fue razonable en su día.
Simplemente ya no es razonable.

Arquitecturas de referencia que evitan el LAN‑a‑LAN completo

Arquitectura A: “VPN a un segmento de servicios”, no VPN a toda la LAN

Coloca el terminador VPN (WireGuard, OpenVPN, gateway IPsec) en una subnet/VLAN dedicada para VPN.
Desde allí, permite egress solo a los servicios requeridos: jump host de tickets, Git, CI, un puñado de APIs internas, quizá RDP/SSH a un bastión.
Niega todo lo demás por defecto.

Punto clave: la subnet VPN es una red de clientes, no una LAN par. No enrutes usuarios remotos directamente a “corp‑lan”.
Enrútalos a “vpn-clients” y luego filtralos por firewall hacia destinos concretos.

Arquitectura B: Acceso por aplicación vía bastiones y proxies (aburrido, eficaz)

Si los usuarios necesitan acceso de administración, no necesitan toda la red de admin. Necesitan un jump host con MFA, registro y una lista corta de destinos salientes permitidos.
Los bastiones SSH, puertas RDP y proxies inversos HTTP son tecnología antigua. Por eso funcionan.

La VPN se convierte en un método de acceso a un punto de control (bastión/proxy), no en una ruta global a todo.
Una vez aceptes eso, tu política de firewall se reduce y tus auditorías se vuelven más fáciles.

Arquitectura C: Acceso con conocimiento de identidad (cuando puedas)

Si tus servicios internos pueden estar detrás de un proxy aware de identidad (IAP), hazlo. Reduce la confianza a nivel de red y mueve la autorización a identidad de usuario y dispositivo.
Pero no te engañes: no es “configurar y olvidar”. Aún necesitas segmentación de red para contener lo que sucede cuando la identidad es eludida o mal configurada.

Arquitectura D: Site‑to‑site real, pero con alcance y documentación estrictos

A veces realmente necesitas conectividad site‑to‑site: impresoras de sucursal, controladores industriales o sistemas legacy que no pueden hablar a través de proxies.
Está bien. Pero aún no necesitas “cualquier subred a cualquier subred”.
Escribe los prefijos exactos que deben ser alcanzables y ejecútalos en enrutamiento y capas de firewall.

Broma #1: Una “VPN full‑tunnel any‑any temporal” es como una “contraseña de admin de producción temporal”. Existe para siempre y desarrolla colmillos.

Controles que realmente funcionan: enrutamiento, firewall, identidad, DNS

1) Enrutamiento: elige prefijos explícitos, no “todo lo privado”

El modo de fallo más común es anunciar rangos internos amplios a clientes VPN porque es cómodo:
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16. No lo hagas.
Eso no es enrutamiento; es abdicar.

Haz esto en su lugar:

  • Anuncia solo las subredes de servicios requeridas (o, mejor aún, las IPs de servicio).
  • Mantén la lista corta; si crece, tienes un problema de arquitectura, no de enrutamiento.
  • Para WireGuard, usa AllowedIPs como una lista blanca estricta.
  • Para OpenVPN, empuja solo las rutas que pretendes (push "route ..."), y bloquea client‑to‑client por defecto salvo que sea necesario.

2) Firewall: denegar por defecto, luego permitir por destino y puerto

El enrutamiento decide qué es alcanzable. El firewall decide qué está permitido. Necesitas ambos porque las rutas tienen la costumbre de cambiar,
y porque “alcanzable” es un conjunto mucho mayor que “debería usarse”.

El patrón básico:

  • Define un rango fuente para clientes VPN (p. ej., 10.250.0.0/24).
  • Permite que esa fuente alcance solo destinos/puertos específicos.
  • Registra los denegados (selectivamente; no DDoSees a tu propia canalización de logs).
  • Bloquea east‑west dentro del pool VPN a menos que estés soportando tráfico entre pares intencionalmente.

3) Identidad y postura del dispositivo: la VPN debe saber quién se conecta

Las reglas basadas en IP son frágiles. Ata el acceso a la identidad siempre que sea posible:

  • Certificados por usuario (OpenVPN), claves WireGuard por usuario mapeadas a usuarios, o soluciones VPN integradas con SSO.
  • Credenciales de corta duración si tu tooling lo soporta.
  • Comprobaciones de postura del dispositivo (dispositivo gestionado, cifrado de disco, versión OS) si tu entorno puede aplicarlas.

Incluso si no puedes hacer “zero trust” de extremo a extremo, al menos puedes saber a qué usuario pertenece una clave,
y revocarla sin enviar un correo a toda la empresa.

4) DNS: split‑horizon con bisturí, no con pala

Los clientes VPN a menudo necesitan DNS interno para un subconjunto de zonas. Dales esas zonas, no todo tu espacio de nombres corporativo.
Si tu solución VPN puede hacer reenvío condicional (enviar solo corp.example a resolvers internos), úsalo.
Si no, ten cuidado: empujar servidores DNS internos a los clientes puede accidentalmente enrutar todas las consultas DNS por la VPN y crear problemas de privacidad, rendimiento y depuración.

5) Observabilidad: registra lo que importa y hazlo consultable

Necesitas responder, rápido:

  • ¿Quién se conectó? ¿Desde dónde? ¿Con qué dispositivo/clave?
  • ¿Qué rutas se asignaron?
  • ¿Qué fue permitido/denegado en el firewall?
  • ¿Qué consultas DNS se realizaron (al menos para zonas internas)?

Si tu respuesta es “probablemente podemos grepear el servidor VPN”, estás a un incidente de aprender la definición de “probablemente”.

Tareas prácticas (comandos, salidas, decisiones)

Estos son los movimientos del día a día que mantienen el “VPN de mínimo privilegio” fuera de una diapositiva.
Cada tarea incluye: un comando, qué significa una salida típica y la decisión que tomas.
Los ejemplos asumen gateways VPN basados en Linux y herramientas comunes.

Task 1: Confirmar qué rutas está anunciando realmente el servidor VPN

cr0x@server:~$ sudo ip route show
default via 203.0.113.1 dev eth0 proto static
10.0.10.0/24 dev lan0 proto kernel scope link src 10.0.10.1
10.250.0.0/24 dev wg0 proto kernel scope link src 10.250.0.1
172.16.50.0/24 via 10.0.10.2 dev lan0 proto static

Qué significa: El servidor tiene la LAN local 10.0.10.0/24, el pool VPN 10.250.0.0/24 y una subred enrutada 172.16.50.0/24.
Este es el enrutamiento del lado servidor, no las “rutas empujadas” al cliente, pero indica lo que podrías estar habilitando.

Decisión: Si ves rutas amplias (como 10.0.0.0/8) en el gateway, para y justifícalas.
Ajusta para solo las subredes que alojan los servicios que pretendes exponer.

Task 2: Para WireGuard, listar peers y sus AllowedIPs (tu política real de acceso)

cr0x@server:~$ sudo wg show
interface: wg0
  public key: G2h9l8mRkQhYtYc9o2b1...
  listening port: 51820

peer: M4x9Vt2g9bBv7hPpP3c0...
  preshared key: (hidden)
  endpoint: 198.51.100.24:53321
  allowed ips: 10.250.0.10/32, 10.0.30.15/32
  latest handshake: 1 minute, 12 seconds ago
  transfer: 128.21 MiB received, 44.02 MiB sent

peer: Q7u1kL0pZz2nWc3aY1r5...
  endpoint: 203.0.113.77:59610
  allowed ips: 10.250.0.11/32, 10.0.40.0/24
  latest handshake: 2 hours, 4 minutes ago
  transfer: 2.10 MiB received, 1.54 MiB sent

Qué significa: El Peer 1 puede enrutar a un único host interno 10.0.30.15.
El Peer 2 puede enrutar a una subred entera 10.0.40.0/24. Esa diferencia de política merece documentación.

Decisión: Prefiere rutas a hosts o subredes de servicio ajustadas. El acceso a subredes debe requerir un propietario explícito y una razón.
Si no puedes nombrar la razón, elimina la subred.

Task 3: Comprobar si el forwarding IP está habilitado (y si debería estarlo)

cr0x@server:~$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Qué significa: El host enrutará paquetes entre interfaces. Eso es necesario para muchos diseños de gateway VPN.
También es el interruptor que convierte “servidor VPN” en “router hacia todo”.

Decisión: Si estás ejecutando acceso por proxy/bastión por aplicación y no necesitas enrutamiento L3, ponlo a 0.
Si necesitas enrutamiento, compénsalo con reglas estrictas de firewall en el camino de forwarding.

Task 4: Inspeccionar la política nftables para asegurar denegar por defecto en forwarding desde la VPN

cr0x@server:~$ sudo nft list ruleset
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    iif "lo" accept
    ct state established,related accept
    tcp dport { 22, 51820 } accept
  }

  chain forward {
    type filter hook forward priority 0; policy drop;
    ct state established,related accept
    iif "wg0" oif "lan0" ip daddr 10.0.30.15 tcp dport 443 accept
    iif "wg0" oif "lan0" ip daddr 10.0.40.0/24 tcp dport 5432 accept
  }

  chain output {
    type filter hook output priority 0; policy accept;
  }
}

Qué significa: El forwarding está por defecto en drop. Existen dos permisos explícitos: HTTPS a un host y Postgres a una subred.
Esta es la forma que quieres: excepciones estrechas, reglas legibles.

Decisión: Si la política de la cadena forward es accept, estás haciendo “LAN‑a‑LAN completo” por accidente.
Cámbiala a drop y enumera lo que debe ser alcanzable.

Task 5: Identificar qué intentan (y fallan) alcanzar los clientes VPN

cr0x@server:~$ sudo nft add rule inet filter forward iif "wg0" counter log prefix "VPN-FWD-DROP " level info drop
cr0x@server:~$ sudo journalctl -n 5 -k
Aug 14 10:21:19 gw kernel: VPN-FWD-DROP IN=wg0 OUT=lan0 SRC=10.250.0.11 DST=10.0.10.25 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=51234 DPT=445 WINDOW=64240 SYN
Aug 14 10:21:20 gw kernel: VPN-FWD-DROP IN=wg0 OUT=lan0 SRC=10.250.0.11 DST=10.0.10.53 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=UDP SPT=55911 DPT=53

Qué significa: Un cliente intentó SMB (445) a 10.0.10.25 y DNS a 10.0.10.53, y ambos fueron descartados.
Eso es o acceso no autorizado (bien) o una regla faltante (también bueno descubrirlo pronto).

Decisión: Decide si esos destinos son una necesidad legítima de negocio. Si no, sigue negando y considera bloquearlo también a nivel de política de cliente.
Si sí, añade un permiso estrecho: servidor específico, puerto específico, con registro.

Task 6: Verificar comportamiento NAT (NAT puede ocultar problemas y a veces crearlos)

cr0x@server:~$ sudo nft list table ip nat
table ip nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    oif "lan0" ip saddr 10.250.0.0/24 masquerade
  }
}

Qué significa: El tráfico de clientes VPN hacia la LAN está enmascarado. Los hosts LAN verán la IP del gateway, no la IP del cliente.
Eso puede simplificar el enrutamiento en el lado LAN pero destruye la atribución por cliente en el destino.

Decisión: Evita NAT para entornos sensibles a auditoría/admin. Prefiere pools enrutados con rutas de retorno explícitas para que los logs muestren IPs reales de clientes.
Si debes NATear (restricciones legacy), compensa con logging en el gateway y mapeo por usuario.

Task 7: Comprobar filtraciones de rutas hacia clientes (ejemplo OpenVPN vía status)

cr0x@server:~$ sudo tail -n 12 /var/log/openvpn/status.log
OpenVPN CLIENT LIST
Updated,2025-08-14 10:20:10
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
alice,198.51.100.24:53321,134507892,46158212,2025-08-14 08:12:03

ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
10.250.0.10,alice,198.51.100.24:53321,2025-08-14 10:20:09
GLOBAL STATS
Max bcast/mcast queue length,0
END

Qué significa: Puedes ver qué usuario tiene qué IP VPN. Esto es lo mínimo necesario para correlación en respuesta a incidentes.

Decisión: Si no puedes mapear usuarios a IPs VPN de forma fiable, arregla eso antes de “optimizar” cualquier otra cosa.
Control de acceso sin atribución es un truco de confianza.

Task 8: Confirmar la configuración DNS en el camino del cliente (qué resolver se usa)

cr0x@server:~$ resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 3 (wg0)
    Current Scopes: DNS
         Protocols: +DefaultRoute
Current DNS Server: 10.0.10.53
       DNS Servers: 10.0.10.53
        DNS Domain: corp.example

Qué significa: Solo corp.example se enruta al DNS interno, vía el enlace wg0.
Eso es scoping DNS condicional; evita secuestrar todas las consultas DNS hacia la oficina.

Decisión: Si ves DNS interno configurado globalmente sin scoping por dominio, espera rarezas: fallos en logins SaaS, portales cautivos rotos y latencias difíciles de depurar.
Arregla el scoping antes de que los usuarios “lo arreglen” ellos mismos fijando resolvers públicos.

Task 9: Probar alcanzabilidad vs permiso (ping funciona, TCP no)

cr0x@server:~$ ping -c 2 10.0.30.15
PING 10.0.30.15 (10.0.30.15) 56(84) bytes of data.
64 bytes from 10.0.30.15: icmp_seq=1 ttl=63 time=3.21 ms
64 bytes from 10.0.30.15: icmp_seq=2 ttl=63 time=3.08 ms

--- 10.0.30.15 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
cr0x@server:~$ nc -vz 10.0.30.15 443
Connection to 10.0.30.15 443 port [tcp/https] succeeded!

Qué significa: Tanto ICMP como TCP/443 están permitidos, así que el servicio es alcanzable y permitido.
Si ping funciona pero TCP falla, probablemente tengas un problema de firewall/SG/política de la aplicación. Si ping falla pero TCP funciona, alguien está filtrando ICMP (aceptable, pero sé consistente).

Decisión: Usa ICMP solo como señal tosca. Toma decisiones basadas en el puerto real de la aplicación.

Task 10: Identificar qué lado está descartando paquetes con tcpdump

cr0x@server:~$ sudo tcpdump -ni wg0 host 10.0.30.15 and tcp port 443 -c 3
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:24:10.102345 IP 10.250.0.10.51522 > 10.0.30.15.443: Flags [S], seq 1987654321, win 64240, options [mss 1360,sackOK,TS val 123 ecr 0,nop,wscale 7], length 0
10:24:11.110221 IP 10.250.0.10.51522 > 10.0.30.15.443: Flags [S], seq 1987654321, win 64240, options [mss 1360,sackOK,TS val 1123 ecr 0,nop,wscale 7], length 0
10:24:13.126019 IP 10.250.0.10.51522 > 10.0.30.15.443: Flags [S], seq 1987654321, win 64240, options [mss 1360,sackOK,TS val 3123 ecr 0,nop,wscale 7], length 0

Qué significa: Las SYNs llegan en wg0, pero no se ve SYN‑ACK de vuelta (al menos en wg0).
O bien el forwarding/firewall está bloqueando, la ruta de retorno está rota, o el destino está abajo/rechazando.

Decisión: Captura en ambas interfaces (wg0 y lan0). Si sale por lan0 pero no vuelve respuesta, es ruta de retorno o firewall del destino.
Si nunca sale por lan0, es tu firewall/forwarding del gateway.

Task 11: Comprobar subredes superpuestas y “rutas en sombra”

cr0x@server:~$ ip route get 10.0.40.10
10.0.40.10 via 10.0.10.2 dev lan0 src 10.0.10.1 uid 0
    cache

Qué significa: El tráfico a 10.0.40.10 va vía 10.0.10.2. Si esperabas que fuera local o por otro router, tienes un desacuerdo de rutas.

Decisión: Si un prefijo puede alcanzarse por múltiples caminos, hazlo explícito y documenta cuál eliges.
En diseño VPN, la ambigüedad es tiempo de inactividad.

Task 12: Validar MTU y detectar problemas de fragmentación

cr0x@server:~$ ip link show wg0
6: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/none
cr0x@server:~$ ping -M do -s 1380 -c 2 10.0.30.15
PING 10.0.30.15 (10.0.30.15) 1380(1408) bytes of data.
1388 bytes from 10.0.30.15: icmp_seq=1 ttl=63 time=3.45 ms
1388 bytes from 10.0.30.15: icmp_seq=2 ttl=63 time=3.39 ms

--- 10.0.30.15 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms

Qué significa: MTU en wg0 es 1420. Un payload de 1380 bytes con DF funciona; probablemente no verás problemas PMTUD para tráfico típico.
Si esto falla, paquetes TLS grandes pueden quedarse colgados y los usuarios reportarán “conecta pero se agota el tiempo aleatoriamente”.

Decisión: Si ves agujeros negros de MTU, ajusta una MTU VPN menor y limita TCP MSS en el gateway.
No lo “arregles” permitiendo acceso LAN completo; eso no es una solución, es rendición.

Task 13: Confirmar que el tráfico cliente‑a‑cliente está bloqueado (prevenir movimiento lateral entre pares)

cr0x@server:~$ sudo nft list chain inet filter forward
table inet filter {
  chain forward {
    type filter hook forward priority 0; policy drop;
    ct state established,related accept
    iif "wg0" oif "lan0" ip daddr 10.0.30.15 tcp dport 443 accept
    iif "wg0" oif "lan0" ip daddr 10.0.40.0/24 tcp dport 5432 accept
  }
}

Qué significa: No hay regla que permita iif wg0 a oif wg0. Los clientes VPN no pueden hablar entre sí a través del gateway.
Eso es bueno: un portátil comprometido no puede escanear casualmente el resto del pool VPN.

Decisión: Solo permite tráfico entre pares si tienes un requisito de producto claro (p. ej., herramientas de pair programming remoto) y una historia de contención.

Task 14: Asegurar que los logs muestran identidad, no solo IPs (sanidad del mapeo WireGuard)

cr0x@server:~$ sudo grep -R "M4x9Vt2g9bBv7hPpP3c0" -n /etc/wireguard/
 /etc/wireguard/wg0.conf:18:PublicKey = M4x9Vt2g9bBv7hPpP3c0...
 /etc/wireguard/wg0.conf:19:# owner=alice purpose=vendor-api access=10.0.30.15:443

Qué significa: La clave del peer está anotada con propiedad y propósito. Esto no es sofisticado. Es operativamente invaluable.

Decisión: Si los peers son blobs anónimos, dudarás en revocar acceso porque no sabrás a quién afectas.
Añade metadata de propiedad y hazla obligatoria para cambios.

Broma #2: La forma más rápida de aprender redes es permitir 10.0.0.0/8 por VPN y esperar tu primer incidente.
La segunda más rápida es no hacer eso.

Guion de diagnóstico rápido

Cuando el acceso VPN está “lento”, “roto” o “funciona para algunos usuarios”, no empieces reescribiendo configs.
Comienza por encontrar la capa que está fallando: transporte, enrutamiento, firewall, DNS o la app.
Aquí está el orden que mantiene tu tiempo‑a‑la‑verdad corto.

Primero: ¿el túnel está arriba y estable?

  • Comprueba estado de handshake/conexión (wg show / estado OpenVPN / estado SA IPsec).
  • Busca reconexiones frecuentes (normalmente timeouts NAT, endpoints que cambian de red o problemas de MTU).
  • Confirma que el cliente obtuvo la IP VPN esperada.

Segundo: ¿la ruta es correcta para el destino específico?

  • Desde el cliente: verifica que la ruta al IP del servicio use la interfaz VPN.
  • Desde el gateway: ip route get <dest> y asegúrate que apunte donde crees.
  • Observa subredes superpuestas y rutas más específicas accidentales.

Tercero: ¿el firewall permite la tupla exacta (src, dst, proto, puerto)?

  • En el gateway: comprueba reglas forward y contadores.
  • Añade temporalmente una regla de drop con registro para ver qué se intenta.
  • Confirma que el firewall del destino/grupos de seguridad también permitan la fuente del pool VPN.

Cuarto: DNS y enrutamiento por nombre

  • Resuelve el nombre del servicio desde el cliente y confirma que devuelve el IP previsto (interno vs externo).
  • Confirma que solo las zonas internas necesarias se enrutan a resolvers internos.
  • Si los usuarios reportan “algunos sitios fallan”, sospecha secuestro DNS full‑tunnel o timeouts DNS por la VPN.

Quinto: MTU y “solo falla con respuestas grandes”

  • Ejecuta pings con DF para encontrar un tamaño de payload seguro.
  • Limita MSS si es necesario.
  • Los síntomas suelen ser “la página de login carga, luego gira para siempre”.

Sexto: aplicación y autenticación

  • Una vez que transporte/enrutamiento/firewall/DNS son correctos, depura el servicio en sí (TLS, auth, logs de la app).
  • No culpes a la VPN por un 401. Es inocente hasta que se demuestre lo contrario.

Tres microhistorias corporativas desde el terreno

Incidente causado por una suposición errónea: “Es solo la subred dev”

Una empresa mediana desplegó WireGuard para contratistas que trabajaban en una migración. El ingeniero de red hizo lo “razonable”:
añadir 10.20.0.0/16 a AllowedIPs porque era “el entorno dev”.
Todos podían alcanzar el clúster dev y el host Git interno. Los tickets dejaron de llegar.

La suposición fue que 10.20.0.0/16 era exclusivamente dev. Antes lo era. Luego alguien añadió unos endpoints de administración “temporales” en ese rango:
una consola de virtualización, una UI de backup y una caja de monitorización antigua con cuentas locales.
Nadie actualizó la política VPN porque a nadie recordaba que la política VPN existía como política.

El portátil de un contratista se infectó por una explotación de navegador. El atacante no necesitó “romper la VPN”.
Simplemente usó el túnel establecido del contratista y escaneó IPs alcanzables.
Encontró la UI de backup. Probó stuffing de credenciales. Tuvo suerte.

La revisión post‑incidente fue dolorosa pero esclarecedora: la VPN no estaba mal configurada; estaba subespecificada.
“Subred dev” era una historia que la gente se contaba, no un límite aplicado. Lo arreglaron moviendo servicios expuestos detrás de un bastión y reemplazando la /16 por media docena de /32.
También forzaron propietarios para cada destino permitido. De repente, los “endpoints temporales” dejaron de ser invisibles.

Una optimización que salió mal: centralizar todo a través de la oficina

Otra organización tenía mezcla de apps SaaS y herramientas internas. Alguien decidió que la VPN full‑tunnel “estandarizaría la seguridad”:
todo el tráfico cliente pasaría por HQ, para inspección y políticas consistentes.
En papel, limpio. En práctica, convirtió el gateway VPN en un cuello de botella y el enlace a internet de la oficina en la columna vertebral no oficial de la empresa.

Los primeros síntomas fueron sutiles: llamadas de video “a veces tartamudean”, cargas grandes “a veces fallan” y la gente culpa su Wi‑Fi doméstico porque eso hace todo el mundo.
Luego el cambio se desplegó a más usuarios. El DNS se volvió más lento por el hairpin.
Las apps SaaS empezaron a limitar tasas porque las peticiones parecían venir de una o dos IPs de egress.

El equipo de seguridad respondió añadiendo más reglas de inspección. La latencia subió otra vez.
Eventualmente el ingeniero on‑call recibió el temido ticket: “La VPN funciona pero internet es inusable.”
Eso no es un puzzle de redes; es deuda técnica acumulada por la arquitectura.

Volvieron a split tunneling para el tráfico a internet y mantuvieron solo un conjunto ajustado de rutas internas.
Para inspección, aplicaron controles en endpoints y en la capa de aplicación cuando fue posible.
La lección: empujar todo el tráfico por un único lugar es una apuesta por la disponibilidad. La disponibilidad es parte de la seguridad, aunque la hoja de cumplimiento no lo vea así.

La práctica aburrida pero correcta que salvó el día: listas blancas explícitas y notas de cambio

Una compañía ligada a finanzas tenía una postura estricta: los usuarios VPN tenían un pool dedicado y la cadena forward del firewall era default deny.
Cada regla allow tenía tres metadatos: propietario del servicio, propósito de negocio y fecha de revisión/expiración.
Sonaba burocrático hasta que dejó de serlo.

Una organización socia reportó que de repente podía alcanzar un servicio interno que no debía. Empezó el pánico, como siempre.
El ingeniero on‑call no empezó a “apagar la VPN”. Comprobó los contadores de la cadena forward y vio golpes en una regla añadida recientemente.
El comentario de la regla incluía la referencia del ticket y el propietario.

El propietario confirmó: durante una ventana de mantenimiento ampliaron temporalmente el acceso de un /32 a un /24 “para facilitar pruebas” y olvidaron revertir.
Como la regla estaba anotada y el cambio era trazable, la corrección tomó minutos: revertir la regla al /32 original y redeploy.

Sin depuración heroica, sin guerra de salas de varias horas, sin culpas vagas. Solo higiene aburrida que rinde frutos.
Si quieres fiabilidad, haz que la reversibilidad sea barata y la responsabilidad normal.

Errores comunes: síntoma → causa raíz → solución

1) “Ahora puedo acceder a todo en 10.x”

Síntoma: Un usuario VPN puede navegar por shares, páginas de administración de impresoras y UIs aleatorias nunca mencionadas en requisitos.

Causa raíz: Rutas amplias empujadas a clientes y política de forward permisiva (a menudo default‑accept) en el gateway VPN.

Solución: Elimina anuncios de rutas amplias; fija la política forward a drop; añade allows explícitos por destino y puerto. Bloquea cliente‑a‑cliente salvo que sea necesario.

2) “La VPN funciona, pero una app interna es inaccesible”

Síntoma: El túnel está arriba, DNS resuelve, pero TCP se agota al conectar a un servicio específico.

Causa raíz: Falta de allow en firewall para ese servicio/puerto, o el firewall/grupo de seguridad del destino no permite la fuente del pool VPN.

Solución: Verifica la tupla en reglas forward del gateway; revisa contadores/logs; añade un allow mínimo; actualiza ACLs del destino. Evita abrir subredes enteras “solo para probar”.

3) “Todo va lento con la VPN; Zoom muere; logins SaaS son raros”

Síntoma: Tras conectar, el rendimiento de internet se degrada; SaaS se comporta de forma impredecible.

Causa raíz: Enrutamiento full‑tunnel más DNS hairpin por HQ; concentración de IPs de egress dispara controles de riesgo SaaS; el gateway es un cuello de botella.

Solución: Usa split tunneling para tráfico a internet; empuja solo rutas internas; scopea DNS a zonas internas; si se requiere inspección, usa controles en endpoints y proxies selectivos.

4) “Funciona para algunos usuarios, falla para otros”

Síntoma: Misma configuración, resultados distintos entre usuarios.

Causa raíz: Diferencias de NAT/firewall en redes cliente, agujeros negros MTU o enrutamiento/AllowedIPs inconsistentes por usuario.

Solución: Compara configs de peers; prueba MTU con pings DF; considera keepalives; evita rutas singulares por usuario salvo que sean necesarias y documentadas.

5) “No podemos saber quién accedió a qué”

Síntoma: Logs muestran solo la IP del gateway por NAT, o usuarios comparten claves.

Causa raíz: Mascarada oculta IPs de clientes; falta de credenciales por usuario; mala correlación de logs.

Solución: Prefiere pools enrutados sin NAT; exige claves/certs por usuario; anota claves; registra eventos de conexión/desconexión con identidad y IP asignada.

6) “Tras la fusión, la VPN se rompió y ahora las rutas fluctúan”

Síntoma: Algunos rangos internos se enrutan intermitentemente al lugar equivocado; la resolución de nombres apunta a IPs inalcanzables.

Causa raíz: Rangos RFC1918 superpuestos combinados vía VPN; rutas ambiguas; DNS split‑horizon no alineado con la alcanzabilidad real.

Solución: Renumera cuando sea posible; si no, usa NAT en límites claros con logging fuerte; haz el enrutamiento más específico; alinea vistas DNS con redes alcanzables.

7) “Los clientes VPN pueden escanearse entre sí”

Síntoma: Un cliente puede conectarse a puertos expuestos de otro cliente vía IPs VPN.

Causa raíz: Cliente‑a‑cliente permitido (OpenVPN client-to-client activado, o reglas forward permiten wg0→wg0).

Solución: Desactiva client‑to‑client; bloquea forwarding wg0→wg0; si se requiere tráfico entre pares, aplica política explícita y considera pools/grupos separados.

Listas de verificación / plan paso a paso

Paso a paso: migrar de LAN‑a‑LAN completo a VPN de mínimo privilegio

  1. Inventaria qué necesitan realmente los usuarios

    • Lista apps/servicios, no subredes. “Git sobre HTTPS”, “RDP a jump host”, “Postgres a BD de reporting”.
    • Identifica propietarios para cada servicio y una razón de negocio.
  2. Define un pool y segmento dedicado para clientes VPN

    • Elige un rango no superpuesto (p. ej., 10.250.0.0/24).
    • Enrútalo correctamente (sin NAT si puedes evitarlo).
  3. Activa denegar por defecto para forwarding desde la VPN

    • Política de forward drop, permitir established/related.
    • Permitir explícitamente los mínimos destinos/puertos.
  4. Reduce las rutas empujadas a los clientes

    • Para WireGuard: ajusta AllowedIPs por peer/grupo.
    • Para OpenVPN: push solo rutas específicas.
  5. Pon el acceso administrativo detrás de bastiones

    • Prefiere gateways SSH/RDP con MFA y logging.
    • Luego permite bastión → destino, no cliente → destino.
  6. Acota el DNS

    • Zonas internas solo; evita forzar todo el DNS por la VPN salvo que sea necesario.
    • Haz que los nombres internos resuelvan a IPs alcanzables para clientes VPN (no registros de split‑horizon muertos).
  7. Añade mapeo de identidad y higiene de claves

    • Claves/certs por usuario, nada de secretos compartidos.
    • Anota propiedad, propósito y fecha de revisión junto a la config.
  8. Añade logging que realmente usarás

    • Eventos de conexión + IP asignada, denegados de firewall (muestreado), consultas DNS para zonas internas (si es factible).
    • Hazlo buscable por usuario, IP VPN y destino.
  9. Despliega en fases

    • Comienza con un grupo piloto y los 5 servicios principales.
    • Mantén el acceso amplio antiguo detrás de un conmutador de emergencia, pero pon una fecha de expiración en el conmutador.
  10. Realiza un ejercicio de mesa para incidentes

    • Practica: “Clave de contratista comprometida, ¿a qué pueden llegar?”
    • Si la respuesta es “la mayor parte de la LAN”, no has terminado.

Checklist operativo: agregar un nuevo servicio permitido

  • El propietario del servicio aprueba y proporciona IP/hostname destino y puerto(s).
  • Decide: acceso directo vs vía bastión/proxy.
  • Confirma que los ACLs del destino permiten el pool VPN (enrutado, no NATeado, idealmente).
  • Añade regla allow en firewall con comentario que incluya propietario/propósito y fecha de revisión.
  • Añade solo la ruta necesaria (prefiere /32 o la subred más pequeña que aloje el servicio).
  • Prueba desde una red cliente representativa (NAT doméstico, hotspot móvil, Wi‑Fi corporativa).
  • Confirma que los logs muestran identidad de usuario para intentos de acceso y denegados.

Checklist de seguridad: mantener el modelo cerrado con el tiempo

  • Revisión trimestral de destinos permitidos por grupo/peer.
  • Acceso a vendors expira automáticamente salvo renovación.
  • Alerta por nuevos anuncios de rutas amplias o cambios en políticas por defecto.
  • Bloquear protocolos peligrosos conocidos (SMB, RPC) desde la VPN salvo que sean requeridos y bien restringidos.
  • Aplicar baselines OS y de seguridad en endpoints gestionados.

Preguntas frecuentes

1) ¿No es “LAN‑a‑LAN completo” más simple y por tanto más seguro?

Es más simple en la misma forma que quitar los frenos simplifica un coche.
Menos piezas, menos decisiones—hasta la primera vez que necesitas frenar. El LAN‑a‑LAN completo amplía el radio de impacto y complica auditorías y respuesta a incidentes.
La simplicidad que aumenta el riesgo no es simplicidad operativa.

2) El split tunneling da sensación de riesgo. ¿No debería todo el tráfico ir por las herramientas de seguridad corporativas?

Si puedes garantizar capacidad, fiabilidad e inspección correcta sin romper SaaS, el full‑tunnel puede ser defendible.
La mayoría no puede. Un enfoque pragmático es split tunnel para internet, rutas estrictas para servicios internos y controles de seguridad en endpoints para el resto.
Centralizar todo por HQ es una apuesta por la disponibilidad que haces cada día laborable.

3) ¿Puedo fiarme solo de WireGuard AllowedIPs para control de acceso?

AllowedIPs es necesario pero no suficiente. Es una palanca potente, pero aún quieres reglas de firewall en el gateway y ACLs en el destino.
La defensa en profundidad importa porque alguien eventualmente añadirá una ruta “temporal”.

4) ¿Los clientes VPN deberían ser NATeados al gateway?

Evita NAT cuando puedas: mata la atribución en el destino y complica las auditorías.
Usa pools enrutados y enseña al lado LAN cómo devolver tráfico al subnet VPN. NAT a veces es necesario por redes legacy,
pero trátalo como compromiso y añade controles compensatorios.

5) ¿Cómo evito que los usuarios VPN descubran nombres de host internos?

Acota el DNS. No entregues un resolver que pueda responder todo el namespace interno si los usuarios solo necesitan una zona.
Usa reenvío condicional o DNS por enlace, y evita filtrar zonas “mgmt” a usuarios generales.

6) ¿Y si la app usa puertos dinámicos?

Eso es una fuerte señal de que no deberías permitir la app directamente por la VPN.
Ponla detrás de un gateway que normalice el acceso (proxy, bastión, publicar puertos fijos), o rediseña la exposición del servicio.
Los puertos dinámicos están bien dentro de un segmento controlado; no están bien como requisito de política VPN.

7) ¿Cómo manejamos proveedores que necesitan acceso “solo por una semana”?

Trata el acceso de proveedores como expiratorio por defecto. Emite credenciales por proveedor, restringe rutas al servicio específico y fija una fecha de revisión/expiración.
Si el trabajo se extiende, renueva deliberadamente. “Sigue siendo necesario” debe ser una elección, no consecuencia de olvido.

8) ¿Cuál es la configuración mínima viable si somos pequeños y ocupados?

Pool VPN dedicado, forwarding por defecto deny y un bastión para acceso admin.
Añade un puñado pequeño de allows explícitos. Anota todo con propiedad.
Puedes evolucionar hacia acceso aware de identidad más adelante, pero no puedes reducir retroactivamente una red plana sin dolor.

9) ¿Cómo evitamos que el mínimo privilegio se convierta en un ping‑pong infinito de tickets?

Crea un camino estándar de onboarding de servicios: los propietarios proporcionan destino/puertos, implementas una plantilla de regla y revisas trimestralmente.
Además, empuja a los equipos hacia proxies/bastiones para que el “acceso” se conceda en un punto de control, no difundiendo reglas de firewall por toda la LAN.
El objetivo es menos decisiones, no más.

Conclusión: próximos pasos prácticos

La VPN de oficina no es la extensión de tu LAN. Es un producto de acceso y, como todo producto, necesita un contrato claro:
quién puede alcanzar qué, por qué rutas, con qué logs y con qué expiración.
Si no puedes declarar el contrato, no tienes control—tienes conectividad.

Próximos pasos que puedes hacer esta semana:

  1. Elige un grupo VPN (proveedores o contratistas son ideales) y reemplaza rutas amplias por destinos explícitos.
  2. Cambia forwarding a denegar por defecto y añade solo las reglas allow requeridas con comentarios y fechas de revisión.
  3. Decide si NAT está ocultando tu capacidad de auditar; si es así, planifica migrar a un pool enrutado.
  4. Acota el DNS a las zonas internas realmente requeridas.
  5. Escribe el guion de “Diagnóstico rápido” y mantenlo cerca del runbook on‑call, no en la cabeza de alguien.

Hazlo bien y tu VPN se convertirá en infraestructura aburrida: predecible, explicable e ininteresante.
Ese es el mayor cumplido que pueden recibir los sistemas en producción.

← Anterior
Ubuntu 24.04: endurecimiento SSH que no te dejará fuera — lista pragmática
Siguiente →
Debian 13: NTP funciona pero persiste la deriva — Ajustes del reloj de hardware y Chrony (Caso #79)

Deja un comentario