Has arrancado un servicio perfectamente válido en WSL2—una API, un endpoint de Prometheus, una base de datos de desarrollo—y funciona desde el host Windows.
Luego alguien en la LAN intenta acceder y no obtiene más que un timeout y una vaga sensación de traición.
Esto no es un problema de Linux. Ni siquiera es realmente un problema de Windows. Es un problema de gestión de expectativas con una VM en NAT
que cambia de IP, además de un firewall que te trata como extraño hasta que demuestras lo contrario.
El modelo mental: qué es realmente la “red de WSL2”
WSL2 no es “procesos Linux en Windows” como lo era WSL1. WSL2 es una VM ligera que ejecuta un kernel Linux real.
Esa VM se sitúa detrás de un switch virtual y típicamente detrás de un NAT. Traducción: tu instancia WSL2 tiene su propia dirección IP, normalmente en una red privada
de Hyper-V, y esa dirección puede cambiar cada vez que WSL se reinicia.
Cuando usas localhost en Windows, WSL2 intenta ayudar. Existe una función comúnmente llamada
“reenvío de localhost” que hace que los puertos sean accesibles desde el host Windows sin que configures enrutamiento explícito.
Pero “accesible desde el host Windows” no es lo mismo que “accesible desde el resto de tu red”.
Para que la LAN alcance un servicio dentro de WSL2 necesitas un punto de entrada en el host Windows (que sí tiene una IP accesible por la LAN),
y luego un reenvío o proxy desde ese host hacia la IP/puerto privado de la VM. Ese es todo el juego.
Piensa en Windows como tu nodo de borde, y en WSL2 como un servicio backend en una subred privada. De repente se parece a cualquier otro entorno
que hayas soportado en producción. Felicidades: estás ejecutando un pequeño centro de datos con NAT en tu portátil.
Datos interesantes y breve historia
- WSL1 y WSL2 tienen redes fundamentalmente diferentes. WSL1 compartía la pila de red del host; WSL2 no. Por eso exponer puertos se volvió “más difícil”.
- WSL2 usa un kernel Linux real. Por eso iptables, sysctl y las herramientas habituales de depuración Linux vuelven a ser relevantes.
- El switch virtual de Hyper-V es la tubería. Incluso en ediciones de Windows donde nunca abriste Hyper-V Manager, WSL2 sigue dependiendo de componentes de Hyper-V.
- La IP de la VM WSL2 suele ser efímera. Se asigna al iniciar; apagar/reiniciar suele cambiarla, lo que rompe reenvíos estáticos si los codificas.
netsh interface portproxyexiste desde antes de WSL2. Es una herramienta antigua pero efectiva de reenvío TCP que volvió a ponerse de moda porque funciona.- Portproxy es solo TCP. Si necesitas UDP tendrás que usar otro enfoque (o rediseñar).
- El Firewall de Windows trata los puertos reenviados como servicios entrantes reales. Si el firewall bloquea el puerto en Windows, tu plan de reenvío está muerto al nacer.
- “Funciona en localhost” es una trampa. El éxito en localhost a menudo solo demuestra que el reenvío Windows→WSL está activo—no que tu servicio escuche en la interfaz correcta.
Guion de diagnóstico rápido
Cuando alguien dice “no puedo alcanzar mi servicio WSL2 desde la LAN”, la ruta más rápida es identificar el primer salto donde los paquetes se detienen.
No adivines. No reinicies. Mide.
1) Primera comprobación: ¿el servicio escucha en Linux en la interfaz correcta?
Si solo escucha en 127.0.0.1 dentro de WSL, el reenvío desde Windows no ayudará. Estarás reenviando hacia un muro de ladrillos.
2) Segunda comprobación: ¿puede Windows alcanzar el servicio por la IP de WSL?
Si Windows no puede conectar a WSL_IP:PORT, tu problema no es la LAN. Es el binding del servicio, el firewall de Linux o el enrutamiento entre host y VM.
3) Tercera comprobación: ¿Windows escucha en la IP/puerto de la LAN y el firewall está abierto?
Si Windows no está escuchando (o el firewall lo bloquea), la LAN hará timeout. Si Windows escucha pero el reenvío está mal, verás fallos rápidos o resets.
4) Cuarta comprobación: ¿falla solo desde algunos clientes de la LAN?
Eso es una pista de firewall del cliente/VPN con split tunneling, perfil de subred mal configurado (Público vs Privado), o una política corporativa en el endpoint.
Tareas básicas: demuestra dónde mueren los paquetes
Estas son las tareas que ejecuto en orden. Cada una tiene: comando, ejemplo de salida, qué significa y qué decisión tomas después.
La meta es dejar de discutir con tu yo futuro.
Tarea 1: Encuentra tu IP LAN en Windows (el verdadero punto de entrada)
cr0x@server:~$ ipconfig
Windows IP Configuration
Ethernet adapter Ethernet:
IPv4 Address. . . . . . . . . . . : 192.168.1.40
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.1.1
Significado: Los clientes de la LAN deben dirigirse a 192.168.1.40 (o tu IP Wi‑Fi) para alcanzar algo en esta máquina.
Decisión: Usa esta IP en tu prueba desde otro equipo. No uses la IP de WSL; la LAN no puede enrutar hacia ella por defecto.
Tarea 2: Encuentra la IP de la VM WSL2 (el objetivo backend)
cr0x@server:~$ wsl.exe -e bash -lc "ip -4 addr show eth0 | sed -n 's/.*inet \\([0-9.]*\\).*/\\1/p'"
172.24.181.166
Significado: Esta es la dirección a la que Windows debe reenviar.
Decisión: Si implementas portproxy, la apuntarás a esta IP. Además: espera que cambie más adelante.
Tarea 3: Confirma que el servicio está escuchando en WSL2, y dónde
cr0x@server:~$ wsl.exe -e bash -lc "ss -lntp | head -n 20"
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.1:8000 0.0.0.0:* users:(("python3",pid=2217,fd=3))
LISTEN 0 4096 0.0.0.0:9090 0.0.0.0:* users:(("prometheus",pid=1022,fd=7))
Significado: El puerto 8000 está ligado a 127.0.0.1 solamente (loopback). El puerto 9090 está ligado a 0.0.0.0 (todas las interfaces).
Decisión: Cualquier cosa ligada a 127.0.0.1 no será accesible mediante un reenvío hacia eth0. Arregla la configuración del servicio primero.
Tarea 4: Prueba desde Windows a la IP de WSL directamente (salta portproxy)
cr0x@server:~$ powershell.exe -NoProfile -Command "Test-NetConnection -ComputerName 172.24.181.166 -Port 9090"
ComputerName : 172.24.181.166
RemoteAddress : 172.24.181.166
RemotePort : 9090
InterfaceAlias : vEthernet (WSL)
SourceAddress : 172.24.176.1
TcpTestSucceeded : True
Significado: Windows puede alcanzar el servicio dentro de WSL. Eso es bueno.
Decisión: Ahora solo necesitas solucionar el ingreso LAN→Windows + reenvío.
Tarea 5: Si la prueba Windows→WSL falla, revisa el firewall de Linux dentro de WSL
cr0x@server:~$ wsl.exe -e bash -lc "sudo iptables -S | head -n 30"
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
Significado: No hay bloqueo en iptables aquí (política ACCEPT).
Decisión: Si tu política es DROP o tienes rechazos explícitos, arréglalo antes de tocar Windows.
Tarea 6: Comprueba si Windows ya está escuchando en el puerto objetivo
cr0x@server:~$ powershell.exe -NoProfile -Command "Get-NetTCPConnection -LocalPort 9090 -State Listen | Format-Table -AutoSize"
LocalAddress LocalPort RemoteAddress RemotePort State OwningProcess
----------- --------- ------------- ---------- ----- -------------
0.0.0.0 9090 0.0.0.0 0 Listen 1234
Significado: Algo ya está escuchando en Windows en el puerto 9090. Portproxy no puede enlazar un puerto que está ocupado.
Decisión: Elige un puerto externo diferente o detén el proceso en conflicto.
Tarea 7: Comprueba reglas portproxy existentes (porque existen fantasmas)
cr0x@server:~$ powershell.exe -NoProfile -Command "netsh interface portproxy show v4tov4"
Listen on ipv4: Connect to ipv4:
Address Port Address Port
--------------- ---------- --------------- ----------
0.0.0.0 8080 172.24.181.166 8000
Significado: Windows escucha en 0.0.0.0:8080 y reenvía a WSL 172.24.181.166:8000.
Decisión: Valida que WSL realmente esté escuchando en 8000 en una interfaz no loopback, o este reenvío te está mintiendo.
Tarea 8: Confirma que Windows está escuchando después de añadir portproxy
cr0x@server:~$ powershell.exe -NoProfile -Command "netstat -ano | findstr :8080"
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 4
Significado: PID 4 es el proceso System que aloja el listener de portproxy. Eso es normal.
Decisión: Si no ves LISTENING, portproxy no está activo o el puerto está bloqueado/ocupado.
Tarea 9: Prueba desde otra máquina de la LAN (la única prueba que importa)
cr0x@server:~$ curl -I http://192.168.1.40:8080
HTTP/1.1 200 OK
Server: uvicorn
Date: Tue, 06 Feb 2026 11:20:14 GMT
Content-Type: text/html; charset=utf-8
Significado: La LAN puede alcanzar Windows, Windows reenvía a WSL y la aplicación responde.
Decisión: Envíalo. Luego hazlo persistente, porque las IPs de WSL son volubles.
Tarea 10: Si la prueba desde la LAN hace timeout, revisa el estado de la regla del Firewall de Windows
cr0x@server:~$ powershell.exe -NoProfile -Command "Get-NetFirewallRule -DisplayName 'WSL2 8080 Inbound' -ErrorAction SilentlyContinue | Select-Object DisplayName, Enabled, Profile, Direction, Action"
DisplayName Enabled Profile Direction Action
----------- ------- ------- --------- ------
WSL2 8080 Inbound True Private Inbound Allow
Significado: La regla existe, está habilitada, aplica al perfil Private y permite inbound.
Decisión: Si tu red está en Public (Tarea 11), esta regla no coincidirá. Arregla el perfil o añade Public (con precaución).
Tarea 11: Verifica el perfil de red de Windows (Público vs Privado)
cr0x@server:~$ powershell.exe -NoProfile -Command "Get-NetConnectionProfile | Format-Table -AutoSize"
Name InterfaceAlias NetworkCategory IPv4Connectivity
---- -------------- --------------- ----------------
OfficeLAN Ethernet Public Internet
Significado: Estás en un perfil Público, por lo que las reglas solo para Private no servirán.
Decisión: O cambia el perfil a Private (si procede) o permite el puerto en Public para esta interfaz solamente.
Tarea 12: Confirma que el tráfico llega a Windows (captura de paquetes, rápida y honesta)
cr0x@server:~$ powershell.exe -NoProfile -Command "pktmon filter remove; pktmon filter add -p 8080; pktmon start --etw -m real-time"
PktMon started with Real Time display.
Significado: Ahora estás vigilando paquetes entrantes en el puerto 8080.
Decisión: Si no ves nada durante una prueba desde el cliente, el problema está corriente arriba (IP equivocada, VLAN, ruta del cliente o política de red). Si ves tráfico, céntrate en firewall/portproxy/servicio.
Broma #1: El reenvío de puertos es como la política de oficina—todo funciona hasta que asumes que la otra parte puede “simplemente acceder”.
Tres formas de exponer servicios WSL2 a la LAN (y cuándo usar cada una)
Enfoque A: portproxy de Windows (simple, funciona, solo TCP)
Este es el recurso habitual para “Necesito que mi servicio TCP en WSL2 sea accesible desde mi LAN hoy”. Enlazas un listener en Windows y lo reenvías a la IP de WSL.
Es aburrido. Lo aburrido es bueno.
Úsalo cuando:
- Necesites TCP (HTTP, gRPC, SSH, Prometheus, bases de datos por TCP).
- Puedas tolerar una pequeña configuración en el lado de Windows.
- Quieras accesibilidad desde la LAN sin cambiar el modo de red de WSL2.
Enfoque B: Proxy inverso en Windows (IIS/NGINX/Caddy en el host)
Si quieres terminación TLS, autenticación en el host, registros más limpios o múltiples backends con enrutamiento sensato, ejecuta un proxy inverso en Windows
y apúntalo a WSL. Esto es más limpio que apilar múltiples reglas portproxy, y es más sencillo de razonar cuando tienes más de un servicio.
Úsalo cuando:
- Necesites HTTPS y no quieras que tus certificados de desarrollo vivan solo dentro de WSL.
- Quieras enrutamiento por rutas (
/api,/grafana), o varias apps en el puerto 443. - Necesites registros reales y limitación de tasa.
Enfoque C: Bridging / modos de red espejados (tentador, pero depende del entorno)
Dependiendo de tu versión de Windows y WSL hay modos de red más nuevos que pueden cambiar cómo WSL se conecta (incluyendo comportamiento “espejado”).
Esto puede reducir la necesidad de reenvíos explícitos, pero no es una solución universal—especialmente en entornos corporativos con controles de endpoint,
clientes VPN y políticas de firewall gestionadas.
Úsalo cuando:
- Estás estandarizando una flota de desarrollo y puedes validar el comportamiento en builds idénticos.
- Quieres menos piezas móviles que portproxy + tareas programadas.
- Entiendes que “funciona en mi portátil” no es una estrategia de despliegue.
Método 1 (más común): netsh portproxy en Windows + firewall
Paso 1: Asegúrate de que tu servicio escucha en algo accesible desde eth0 de WSL
Si tu app se enlaza a 127.0.0.1 dentro de WSL, solo aceptará conexiones originadas dentro de esa misma instancia WSL.
Eso está bien para desarrollo local. Es inútil para exposición en la LAN.
Ejemplo: Uvicorn/FastAPI. No hagas esto:
cr0x@server:~$ wsl.exe -e bash -lc "python3 -m uvicorn app:app --host 127.0.0.1 --port 8000"
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
Haz esto:
cr0x@server:~$ wsl.exe -e bash -lc "python3 -m uvicorn app:app --host 0.0.0.0 --port 8000"
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
Decisión: Antes de tocar la red de Windows, consigue que ss -lntp muestre 0.0.0.0:8000 (o la IP de eth0 de WSL).
Ese es el contrato que vas a reenviar.
Paso 2: Añade una regla portproxy (Windows escucha y reenvía a WSL)
Elige un puerto de escucha externo en Windows. A menudo mantendrás el mismo que el puerto interno.
Aquí reenviaremos el puerto 8080 de Windows al puerto 8000 de WSL.
cr0x@server:~$ powershell.exe -NoProfile -Command "netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 connectaddress=172.24.181.166 connectport=8000"
Ok.
Significado: Windows ahora acepta conexiones TCP en todas las interfaces (incluida la LAN) en el puerto 8080 y las reenvía a WSL.
Decisión: Si solo quieres exposición en la LAN en una interfaz/IP concreta, establece listenaddress en tu IP LAN en lugar de 0.0.0.0.
Paso 3: Verifica la regla y el listener
cr0x@server:~$ powershell.exe -NoProfile -Command "netsh interface portproxy show v4tov4"
Listen on ipv4: Connect to ipv4:
Address Port Address Port
--------------- ---------- --------------- ----------
0.0.0.0 8080 172.24.181.166 8000
cr0x@server:~$ powershell.exe -NoProfile -Command "netstat -ano | findstr :8080"
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 4
Significado: El mapeo de portproxy existe y Windows está escuchando.
Decisión: Si netstat no muestra nada, tienes un conflicto (puerto en uso), privilegios insuficientes o una política que lo bloquea.
Paso 4: Prueba desde Windows, luego desde la LAN
cr0x@server:~$ powershell.exe -NoProfile -Command "curl.exe -I http://127.0.0.1:8080"
HTTP/1.1 200 OK
Server: uvicorn
Date: Tue, 06 Feb 2026 11:22:40 GMT
Content-Type: text/html; charset=utf-8
Significado: Windows puede alcanzar su propio listener y reenviarlo a WSL.
Decisión: Si localhost funciona pero la LAN no, tu problema casi siempre es el perfil/reglas del Firewall de Windows o la red upstream.
Reglas de Firewall de Windows que no te harán odiar la vida
El Firewall de Windows no es tu enemigo. Es un portero. Solo necesitas ponerte en la lista.
La parte sutil es el perfil: Domain, Private, Public. Tu “OfficeLAN” podría estar categorizada como Pública, y entonces tu regla cuidadosamente diseñada
para Private no hará nada.
Crea una regla de entrada que permita el puerto de escucha
cr0x@server:~$ powershell.exe -NoProfile -Command "New-NetFirewallRule -DisplayName 'WSL2 8080 Inbound' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8080 -Profile Private"
Name : {2d4e3f2b-41c0-4b84-9c85-1c09f3324c7f}
DisplayName : WSL2 8080 Inbound
Enabled : True
Direction : Inbound
Profiles : Private
Significado: TCP/8080 inbound está permitido cuando tu interfaz está en el perfil Private.
Decisión: Si estás en Public (Tarea 11), o cambia la categoría de la red o añade Public. No abras puertos en Public a ciegas en un portátil que llevas contigo.
Limita el alcance: permite solo tu subred LAN (recomendado)
cr0x@server:~$ powershell.exe -NoProfile -Command "Set-NetFirewallRule -DisplayName 'WSL2 8080 Inbound' -RemoteAddress 192.168.1.0/24"
Significado: Solo clientes en 192.168.1.0/24 pueden conectar.
Decisión: Este es el movimiento maduro para laboratorios domésticos y subredes de oficina. Te lo agradecerás después.
Confirma que la regla se aplica y está habilitada
cr0x@server:~$ powershell.exe -NoProfile -Command "Get-NetFirewallRule -DisplayName 'WSL2 8080 Inbound' | Get-NetFirewallPortFilter | Format-Table -AutoSize"
Protocol LocalPort RemotePort IcmpType LocalAddress RemoteAddress
-------- --------- ---------- -------- ------------ -------------
TCP 8080 Any Any Any 192.168.1.0/24
Significado: El filtro de puerto es correcto y está acotado.
Decisión: Si RemoteAddress muestra “Any” y no lo pretendías, ajústalo. Los incidentes de seguridad suelen empezar con “Es solo mi equipo de desarrollo”.
Hazlo persistente tras reinicios de WSL
La IP de WSL2 cambia. Las reglas portproxy no la siguen mágicamente. Si codificas la IP antigua de WSL, estarás
“misteriosamente caído” tras un reinicio, un apagado de WSL o a veces después de que la máquina se despierte mal.
Hay dos opciones sensatas:
- Automatizar la actualización de portproxy cada vez que WSL arranque (o al iniciar sesión).
- Dejar de usar portproxy para backends dinámicos y poner un reverse proxy en Windows que apunte a
localhostvía el reenvío de localhost de WSL (cuando proceda).
Opción 1: Script para actualizar portproxy al iniciar sesión (simple, efectivo)
Este one-liner de PowerShell obtiene la IP actual de WSL y actualiza un mapeo portproxy.
cr0x@server:~$ powershell.exe -NoProfile -Command "$wslip = (wsl.exe -e bash -lc `"ip -4 addr show eth0 | sed -n 's/.*inet \\([0-9.]*\\).*/\\1/p'`").Trim(); netsh interface portproxy delete v4tov4 listenport=8080 listenaddress=0.0.0.0 2>$null; netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 connectaddress=$wslip connectport=8000; netsh interface portproxy show v4tov4"
Listen on ipv4: Connect to ipv4:
Address Port Address Port
--------------- ---------- --------------- ----------
0.0.0.0 8080 172.24.181.166 8000
Significado: La regla está ahora alineada con la IP actual de WSL.
Decisión: Pon esto en una Tarea Programada “Al iniciar sesión” o “Al iniciar” con los más altos privilegios.
Si no lo ejecutas elevado, los cambios de portproxy pueden fallar silenciosamente o funcionar a medias.
Opción 2: Confirma que WSL no se está apagando inesperadamente
cr0x@server:~$ wsl.exe --status
Default Distribution: Ubuntu
Default Version: 2
WSL version: 2.1.5.0
Kernel version: 5.15.146.1
Significado: WSL está instalado y activo; los detalles de versión ayudan cuando el comportamiento difiere entre máquinas.
Decisión: Si tu organización tiene versiones mixtas, estandariza o espera comportamiento inconsistente de puerto/localhost.
Haz que el servicio escuche correctamente (la parte que todos olvidan)
La mayoría de fallos de “reenvío WSL2” no son fallos de reenvío. Son fallos de binding.
Tu servicio solo escucha en loopback, así que funciona desde dentro de WSL y quizá desde Windows vía el reenvío especial de localhost,
pero no aceptará conexiones que entren por eth0.
Diagnostica el binding: loopback vs todas las interfaces
cr0x@server:~$ wsl.exe -e bash -lc "ss -lnt | awk 'NR==1 || /:8000|:9090/'"
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.1:8000 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:9090 0.0.0.0:*
Significado: 8000 es solo loopback; 9090 es accesible desde la red de la VM WSL.
Decisión: Para exposición en la LAN enlaza a 0.0.0.0 o a la IP de WSL, luego protégete con firewall/proxy si hace falta.
Comprueba qué dirección cree tu app que debe enlazar
cr0x@server:~$ wsl.exe -e bash -lc "grep -R --line-number 'listen\\|bind\\|host' /etc/nginx 2>/dev/null | head"
Significado: No hay configuración de nginx en este ejemplo. En sistemas reales encontrarás sorpresas como listen 127.0.0.1:....
Decisión: Si ves binds en loopback, decide si quieres que portproxy reenvíe a loopback (no típico) o cambia el servicio para que escuche en eth0.
Broma #2: Si te enlazas a 127.0.0.1 y esperas que la LAN llegue, básicamente te estás enviando un paquete a ti mismo y culpas al servicio postal.
Docker/Desktop/controles dentro de WSL2: la capa extra
Los contenedores no eliminan la complejidad de red; la concentran. Si ejecutas Docker dentro de WSL2 (o Docker Desktop usando WSL2),
puedes tener tres capas de red: LAN → Windows → VM WSL2 → contenedor.
La decisión correcta depende de dónde esté publicado el puerto del contenedor.
Tarea: Comprueba la publicación de puertos del contenedor dentro de WSL2
cr0x@server:~$ wsl.exe -e bash -lc "docker ps --format 'table {{.Names}}\t{{.Ports}}' | head"
NAMES PORTS
api-dev 0.0.0.0:8000->8000/tcp
grafana 127.0.0.1:3000->3000/tcp
Significado: api-dev está publicado en todas las interfaces en WSL2; grafana es solo loopback dentro de WSL2.
Decisión: Para exposición en la LAN publica el puerto del contenedor en 0.0.0.0 en WSL2 (o usa un reverse proxy en el lado WSL), luego reenvía desde Windows.
Tarea: Verifica desde Windows a la IP de WSL para un servicio en contenedor
cr0x@server:~$ powershell.exe -NoProfile -Command "Test-NetConnection -ComputerName 172.24.181.166 -Port 8000"
ComputerName : 172.24.181.166
RemoteAddress : 172.24.181.166
RemotePort : 8000
InterfaceAlias : vEthernet (WSL)
SourceAddress : 172.24.176.1
TcpTestSucceeded : True
Significado: El puerto publicado por el contenedor es accesible desde Windows a través de la interfaz vEthernet.
Decisión: Ahora haz portproxy del puerto de Windows al WSL:8000 y gestiona el firewall.
Tres micro-historias del mundo corporativo (para que no las repitas)
1) El incidente causado por una suposición equivocada
Un equipo construyó una cadena de herramientas interna: una pequeña API en WSL2, una UI en la máquina de otro desarrollador y algo de automatización que llamaba a la API desde un runner CI en la LAN.
El desarrollador lo mostró: funciona en su portátil Windows usando http://localhost:5000. Todos asintieron. Hicieron merge.
Cuando el runner CI intentó llamarlo, timeouts. La suposición fue “localhost significa accesible”, que es el tipo de mentira que sobrevive justo el tiempo suficiente para desplegar.
Habían confundido el reenvío localhost del host Windows con la accesibilidad real en la LAN.
La depuración empezó en el lugar equivocado. La gente miraba logs de la aplicación y culpaba a clientes HTTP. Mientras tanto, los paquetes ni siquiera llegaban a Windows.
El perfil de firewall estaba en Public en el portátil porque la red se trataba como no confiable por política. El inbound estaba bloqueado.
La solución fue sencilla: una regla de firewall entrante de Windows acotada al subnet del CI, más un mapeo portproxy que se actualizaba al iniciar sesión.
La parte importante no fueron los comandos. Fue el cambio en el modelo mental: WSL2 es un segmento de red backend, y Windows es el borde.
Después escribieron un runbook de una página: “Si solo funciona en localhost, no es un servicio. Es una demo local.” Eso les salvó de repetir el error.
2) La optimización que salió mal
Otro equipo tenía múltiples servicios en WSL2 y se cansó de gestionar reglas portproxy. Alguien sugirió un enfoque “más limpio”:
enlazar todo dentro de WSL2 a 0.0.0.0, luego abrir una regla amplia de inbound en Windows para un rango de puertos.
Menos administración, onboarding más rápido. Sonaba eficiente.
Entonces un escaneo de seguridad marcó la máquina por exponer servicios inesperados en la red corporativa.
Algunos de esos puertos eran bases de datos de desarrollo sin autenticación (porque “es solo mi portátil”), y uno era un endpoint de depuración que filtraba variables de entorno.
El equipo discutió que era un falso positivo. No lo era. Habían creado una estación objetivo con “defensas ligeras”.
Incluso si nadie la explotaba, la exposición sola bastó para activar respuesta a incidentes y escrutinio de políticas.
El rollback fue doloroso pero educativo: pasaron a un proxy inverso en Windows en 443 con autenticación, y solo reenviaron puertos específicos.
También restringieron reglas de firewall a subnets conocidas. El onboarding quedó un poco más complejo, pero la postura de seguridad dejó de ser embarazosa.
La optimización no es solo velocidad. En redes, “menos reglas” a menudo significa “mayor radio de impacto”.
3) La práctica aburrida pero correcta que salvó el día
Un equipo de plataforma tenía un problema predecible: la IP de WSL2 rompía integraciones locales para varios ingenieros cada semana.
En lugar de sesiones heroicas de depuración, escribieron un script aburrido y lo estandarizaron mediante gestión de endpoints.
El script hacía tres cosas: consultar la IP actual de WSL, reescribir mapeos portproxy para una lista corta de puertos requeridos y validar listeners con netstat.
Si la validación fallaba, registraba un error y paraba. Sin conjeturas, sin estado parcial.
También crearon reglas de firewall con alcances explícitos (solo subredes de oficina) y las fijaron a perfiles Private/Domain.
En redes Públicas (cafeterías), los servicios simplemente no eran alcanzables. Eso era una característica, no un fallo.
Meses después, cuando una actualización de Windows cambió el comportamiento en un subconjunto de máquinas, su paso de validación lo detectó temprano.
No descubrieron la rotura durante una demo. La descubrieron durante la ejecución del script de inicio de sesión, con un punto de fallo claro.
El trabajo SRE más valioso a menudo parece papeleo: estandarización, scripts idempotentes y comprobaciones que fallen ruidosamente.
Errores comunes: síntoma → causa raíz → solución
1) Síntoma: funciona en WSL con curl, falla desde la LAN con timeout
Causa raíz: El Firewall de Windows bloquea inbound en el puerto de escucha (a menudo perfil de red equivocado: Public vs Private).
Solución: Crea/habilita una regla de entrada que permita el puerto y corrige el perfil; acótala a tu subred LAN.
2) Síntoma: funciona desde localhost en Windows, falla desde Windows a WSL_IP
Causa raíz: El servicio en WSL se liga solo a 127.0.0.1, o el firewall de Linux bloquea no‑loopback.
Solución: Liga el servicio a 0.0.0.0 (o a la IP de eth0 de WSL). Revisa con ss -lntp.
3) Síntoma: la LAN ve “connection refused” de inmediato
Causa raíz: Windows es alcanzable, pero nada está escuchando (portproxy ausente, listenport equivocado, o conflicto de puerto que impidió el binding).
Solución: Revisa netstat -ano para LISTENING. Arregla conflictos de puerto o recrea el mapeo portproxy.
4) Síntoma: funcionó ayer; hoy hace timeout
Causa raíz: La IP de WSL2 cambió; portproxy sigue apuntando a la IP antigua.
Solución: Vuelve a consultar la IP de WSL y actualiza portproxy. Automatízalo con una Tarea Programada.
5) Síntoma: solo algunos clientes de la LAN pueden conectar
Causa raíz: Regla de firewall con alcance demasiado estricto, cliente en otra subred/VLAN, o cliente en VPN con enrutamiento distinto.
Solución: Valida la IP/subnet origen del cliente. Amplía RemoteAddress intencionadamente o enruta apropiadamente.
6) Síntoma: errores HTTPS/TLS o comportamiento de Host header equivocado
Causa raíz: Usar portproxy crudo para múltiples apps HTTP sin un proxy inverso; el backend espera Host/SNI específicos.
Solución: Pon un proxy inverso en Windows, termina TLS allí, enruta por host/ruta y reenvía a WSL.
7) Síntoma: servicio UDP nunca funciona a través de portproxy
Causa raíz: Portproxy solo soporta TCP.
Solución: Rediseña (usa TCP), ejecuta otro proxy que soporte UDP, o usa un modo de red que proporcione direccionamiento directo.
8) Síntoma: portproxy existe, firewall abierto, y aún así nada
Causa raíz: Escuchas en 0.0.0.0 pero la NIC de Windows está en perfil Public con restricciones entrantes o reglas corporativas de endpoint que anulan el firewall local.
Solución: Revisa el perfil de red, políticas de seguridad del endpoint y valida con captura de paquetes (pktmon). Si la política bloquea inbound, deja de pelear y usa un proxy/ingreso aprobado.
Listas de verificación / plan paso a paso
Checklist A: Un servicio, un puerto, necesita acceso LAN (TCP)
-
Confirma que el servicio se liga correctamente en WSL2.
Ejecuta
ss -lntp. Quieres0.0.0.0:PORToWSL_IP:PORT, no127.0.0.1:PORT. -
Obtén la IP de WSL.
Usa
wsl.exe -e bash -lc "ip -4 addr show eth0 ...". Escríbela; será tu connectaddress. -
Prueba Windows hacia WSL directamente.
Test-NetConnection -ComputerName WSL_IP -Port PORT. Si esto falla, no toques la LAN todavía. -
Crea el mapeo portproxy.
Enlaza en Windows
listenaddress=0.0.0.0y reenvía a WSL. -
Abrir Firewall de Windows para el puerto de escucha.
Crea una regla inbound allow en Private/Domain; acota RemoteAddress a tu subred LAN.
-
Prueba desde otra máquina de la LAN.
Usa
curlo un navegador. No lo consideres hecho hasta que otra máquina lo confirme. -
Hazlo persistente.
Programa un script para actualizar el mapeo portproxy con la IP actual de WSL al inicio/inicio de sesión.
Checklist B: Múltiples servicios (HTTP) y quieres que quede limpio
- Ejecuta un proxy inverso en Windows en 443 (un único agujero de entrada).
- Reenvía a backends en WSL en sus puertos internos.
- Mantén los puertos de WSL cerrados a la LAN; solo el proxy de Windows queda expuesto.
- Usa alcances de firewall para limitar quién puede acceder al proxy.
- Registra las solicitudes en el lado de Windows; la depuración se vuelve manejable.
Checklist C: Te sigues rompiendo después del reboot
- Asume que la IP de WSL cambió hasta que se demuestre lo contrario.
- Actualiza programáticamente el mapeo portproxy.
- Valida:
netsh ... showynetstat -ano. - Si sigue fallando, ejecuta otra vez el guion de diagnóstico rápido. No “simplemente reinicies”.
Una cita que vale la pena mantener en tu monitor
“Everything fails, all the time.” — Werner Vogels
No es pesimismo. Es una limitación de diseño. Tu reenvío de puertos debería estar construido como si fuera a reiniciarse, renumerarse y tener mal perfil—porque lo hará.
Preguntas frecuentes
1) ¿Por qué puedo alcanzar el servicio desde localhost en Windows pero no desde otras máquinas de la LAN?
Porque el reenvío localhost Windows→WSL no es enrutamiento LAN. Las máquinas de la LAN alcanzan la IP LAN de Windows, y Windows debe aceptar tráfico entrante
(firewall) y reenviarlo (portproxy o proxy) a WSL.
2) ¿Siempre necesito netsh portproxy?
No. Es lo más simple para TCP. Si quieres TLS, enrutamiento y logs, ejecuta un proxy inverso en Windows en su lugar.
Si necesitas UDP, portproxy no te servirá.
3) ¿Por qué portproxy se rompe tras un reboot o wsl --shutdown?
La VM WSL2 recibe una IP nueva. Portproxy sigue apuntando a la antigua. Automatiza la actualización del mapeo con la IP actual de WSL al inicio/inicio de sesión.
4) ¿Puedo reenviar a 127.0.0.1 dentro de WSL?
Portproxy reenvía a una IP que Windows puede enrutar. Típicamente reenvías a la IP eth0 de WSL.
Si tu servicio es solo loopback, cámbialo para que escuche en 0.0.0.0 (y luego controla la exposición con firewall/proxy).
5) ¿Es seguro poner listenaddress=0.0.0.0?
Es seguro solo si tus alcances de firewall son sensatos. Si expones un puerto en todas las interfaces y lo permites desde “Any”, estás publicando un servicio.
Restringe por perfil y RemoteAddress, especialmente en portátiles.
6) ¿Portproxy soporta UDP?
No. Solo TCP. Si necesitas servicios UDP (algunos juegos, DNS, cierta telemetría), usa otro mecanismo proxy o rediseña hacia TCP.
7) ¿Por qué veo LISTENING PID 4 para mi puerto reenviado?
Eso es esperado. El proceso System aloja el listener para reglas portproxy.
Valida el mapeo con netsh interface portproxy show v4tov4 y pruebas end-to-end.
8) ¿Puedo enlazar el reenvío solo a mi IP LAN en lugar de a todas las interfaces?
Sí. Establece listenaddress en tu IP LAN (por ejemplo 192.168.1.40) y mantén la regla de firewall acotada también.
Esto reduce la exposición accidental en adaptadores VPN u otras interfaces.
9) ¿Cuál es la forma más rápida de saber si la petición de la LAN siquiera llega a mi máquina Windows?
Usa pktmon filtrado por el puerto de escucha mientras haces una petición desde un cliente de la LAN. Si no llegan paquetes, deja de culpar a WSL.
Arregla el objetivo IP, el VLAN, o el comportamiento VPN del cliente.
Conclusión: próximos pasos que realmente funcionan
Haz esto aburrido. Lo aburrido escala.
- Arregla el binding en WSL primero: asegúrate de que tu servicio escucha en
0.0.0.0(o en la IP eth0 de WSL), no solo en loopback. - Prueba que Windows puede alcanzar WSL por IP con
Test-NetConnection. Si esto falla, no involucres la LAN. - Usa portproxy para exposición TCP simple, y luego abre el Firewall de Windows de forma estrecha (perfil + alcance de subred).
- Automatiza la actualización de portproxy para que el cambio de IP de WSL no te despierte (o arruine tu demo) tras cada reinicio.
- Si la complejidad crece (TLS, múltiples apps, autenticación), deja de apilar parches y ejecuta un proxy inverso adecuado en Windows.
Si tratas tu portátil como un pequeño servidor de borde—con ingreso explícito, política explícita y configuración repetible—dejarás de “depurar redes”
y empezarás a entregar servicios.