Inicio » Windows » Cómo hacer permanente un portproxy de WSL2 en Windows 11 (ejemplo con rsync)

Cómo hacer permanente un portproxy de WSL2 en Windows 11 (ejemplo con rsync)

Loading

Si ejecutas un servicio dentro de WSL2 (un demonio rsync, un servidor web, una base de datos...) y quieres que sea accesible desde otros equipos de tu red, tarde o temprano acabas usando netsh interface portproxy. El problema es que la solución "funciona" hasta que reinicias, y entonces deja de responder sin ningún error aparente. En este artículo vemos por qué ocurre, cómo automatizarlo con una tarea programada (por PowerShell y por interfaz gráfica) y una alternativa mucho más limpia: el modo de red mirrored.

El problema: WSL2 y su IP dinámica

WSL2 se ejecuta en una máquina virtual ligera con su propia red NAT. Eso significa que:

  • La IP de la distro es distinta de la de Windows (normalmente en un rango 172.x.x.x).
  • Esa IP cambia con cada arranque de WSL, y también cuando WSL se apaga por inactividad y se vuelve a iniciar.
  • Desde fuera de tu equipo no puedes llegar directamente a ella.

La solución habitual es crear un reenvío de puertos en Windows: lo que llegue al puerto 873 del host se redirige al puerto 873 de la IP de WSL. Para el demonio rsync sería así:

$wslIP = (wsl -d Debian hostname -I).Trim()
netsh interface portproxy add v4tov4 listenport=873 listenaddress=0.0.0.0 connectport=873 connectaddress=$wslIP

La primera línea obtiene la IP de la distro Debian y la segunda crea la regla de reenvío.

Primera confusión: la regla ya es persistente

Una duda muy común es cómo "hacer permanente" esta regla. La realidad es que ya lo es: netsh interface portproxy guarda la configuración en el registro de Windows y la regla sobrevive a los reinicios (siempre que el servicio Auxiliar de IP, iphlpsvc, esté en marcha, que lo está por defecto).

Lo que no es permanente es la IP a la que apunta. Tras un reinicio, la regla sigue existiendo pero reenvía el tráfico a una dirección que WSL ya no tiene. Por tanto, lo que necesitamos no es persistir la regla, sino regenerarla con la IP actual en cada inicio de sesión.

Puedes comprobar el estado actual con:

netsh interface portproxy show all

Opción 1: script de PowerShell + tarea programada

Paso 1: el script

Crea el archivo C:\Scripts\wsl-portproxy.ps1 con este contenido:

$wslIP = ((wsl -d Debian hostname -I).Trim() -split ' ')[0]
netsh interface portproxy delete v4tov4 listenport=873 listenaddress=0.0.0.0
netsh interface portproxy add v4tov4 listenport=873 listenaddress=0.0.0.0 connectport=873 connectaddress=$wslIP

Tres detalles importantes:

  • hostname -I puede devolver varias IPs separadas por espacios, por eso usamos -split ' ' y nos quedamos con la primera.
  • Borramos la regla anterior antes de crear la nueva para no acumular reglas obsoletas.
  • Al ejecutar wsl -d Debian ... se arranca la distro si no estaba iniciada, así que el script funciona aunque WSL esté apagado.

Paso 2: registrar la tarea desde PowerShell

Abre PowerShell como administrador y ejecuta:

$action    = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\wsl-portproxy.ps1"
$trigger   = New-ScheduledTaskTrigger -AtLogOn
$principal = New-ScheduledTaskPrincipal -UserId "$env:USERDOMAIN\$env:USERNAME" -RunLevel Highest
Register-ScheduledTask -TaskName "WSL Portproxy 873" -Action $action -Trigger $trigger -Principal $principal

Por qué esta configuración:

  • -AtLogOn: la tarea se lanza cada vez que inicias sesión.
  • -RunLevel Highest: netsh interface portproxy requiere privilegios de administrador.
  • Tu usuario y no SYSTEM: las distros de WSL se registran por usuario. La cuenta SYSTEM no vería tu Debian y el comando wsl -d Debian fallaría.

Paso 3: abrir el puerto en el firewall

El reenvío no sirve de nada si el firewall de Windows bloquea las conexiones entrantes al puerto 873:

New-NetFirewallRule -DisplayName "WSL rsync 873" -Direction Inbound -Protocol TCP -LocalPort 873 -Action Allow

Se hace una sola vez. Si solo quieres exponer el servicio a tu red local, añade -Profile Private y, mejor aún, -RemoteAddress con tu subred (por ejemplo 192.168.1.0/24). Ten en cuenta que el demonio rsync sin autenticación expuesto a toda la red es una mala idea.

Opción 1 en entorno gráfico

Si prefieres no usar PowerShell, puedes hacer lo mismo con el Programador de tareas.

Crear la tarea

  1. Pulsa Win + R, escribe taskschd.msc y pulsa Enter.
  2. En el panel derecho, haz clic en Crear tarea... (no en "Crear tarea básica", porque necesitas las opciones avanzadas).

Pestaña General

  • Nombre: WSL Portproxy 873.
  • Marca Ejecutar con los privilegios más altos.
  • Deja seleccionado Ejecutar solo cuando el usuario haya iniciado sesión, para que la tarea corra con tu usuario y pueda ver la distro.
  • En Configurar para, elige Windows 10 / Windows 11.

Pestaña Desencadenadores

  1. Clic en Nuevo...
  2. En Iniciar la tarea, selecciona Al iniciar sesión.
  3. Deja marcado Habilitado y acepta.

Pestaña Acciones

  1. Clic en Nueva...
  2. Acción: Iniciar un programa.
  3. Programa o script: powershell.exe
  4. Agregar argumentos:
-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\wsl-portproxy.ps1

Pestaña Condiciones

Si es un portátil, desmarca Iniciar la tarea solo si el equipo está conectado a la corriente alterna para que también se ejecute con batería.

Pestaña Configuración

  • Marca Permitir ejecutar la tarea a petición.
  • Opcional: en Si la tarea ya se está ejecutando, elige No iniciar una nueva instancia.

Pulsa Aceptar e introduce la contraseña de tu usuario si Windows la solicita.

Regla de firewall en gráfico

  1. Win + R → wf.msc.
  2. Reglas de entrada → Nueva regla...
  3. Tipo Puerto → TCP → puertos locales específicos: 873.
  4. Permitir la conexión → marca los perfiles que uses (Dominio, Privado, Público).
  5. Ponle un nombre, por ejemplo WSL rsync 873.

Probar que funciona

En el Programador de tareas, selecciona la tarea, clic derecho y Ejecutar. Después, en una consola de administrador:

netsh interface portproxy show all

Deberías ver la regla del puerto 873 apuntando a la IP actual de WSL. Para confirmar la IP real de la distro:

wsl -d Debian hostname -I

Limitación de esta solución

La tarea solo se ejecuta al iniciar sesión. Si WSL se apaga por inactividad y vuelve a arrancar durante la sesión, la IP puede cambiar y la regla quedará apuntando a una dirección antigua. En ese caso tienes dos opciones: mantener la distro viva (por ejemplo, con un proceso en segundo plano) o relanzar la tarea manualmente con clic derecho → Ejecutar.

Opción 2: modo de red mirrored (la solución de raíz)

Desde Windows 11 22H2 y WSL 2.0.0 existe el modo de red mirrored, en el que WSL comparte la pila de red del host. Con él:

  • WSL usa la misma IP que Windows.
  • Un servicio que escuche en el puerto 873 dentro de la distro es accesible directamente desde la red.
  • No necesitas portproxy ni tarea programada.

Para activarlo, crea o edita el archivo %UserProfile%\.wslconfig:

[wsl2]
networkingMode=mirrored

Después, apaga WSL por completo para que se apliquen los cambios:

wsl --shutdown

Y vuelve a abrir la distro. Si el servicio no responde desde otros equipos, puede que el firewall de Hyper-V esté bloqueando el tráfico entrante hacia WSL. Se puede permitir con:

Set-NetFirewallHyperVVMSetting -Name '{40E0AC32-46A5-438A-A0B2-57B2C3F6F5F0}' -DefaultInboundAction Allow

Ese identificador corresponde al VM Creator de WSL. Si prefieres algo más restrictivo, puedes crear una regla de Hyper-V concreta para el puerto 873 en lugar de permitir todo el tráfico entrante.

Antes de pasarte al modo mirrored, elimina las reglas de portproxy que ya no uses para evitar conflictos con el puerto:

netsh interface portproxy delete v4tov4 listenport=873 listenaddress=0.0.0.0

Qué opción elegir

SituaciónRecomendación
Windows 11 22H2 o superior con WSL actualizadoModo mirrored
Windows 10 o versión antigua de WSLScript + tarea programada
Necesitas exponer solo algunos puertos de forma controladaPortproxy con firewall restringido

Resumen

  • La regla de netsh portproxy ya es persistente; lo que cambia es la IP de WSL2 en cada arranque.
  • Para mantenerla actualizada, regenera la regla en cada inicio de sesión con un script de PowerShell lanzado desde una tarea programada, ejecutada con tu usuario y privilegios elevados.
  • No olvides la regla de firewall para el puerto 873.
  • Si tu sistema lo soporta, el modo networkingMode=mirrored elimina el problema de raíz y simplifica toda la configuración.

Una última nota de seguridad: antes de exponer un demonio rsync fuera de tu equipo, configura autenticación (auth users y secrets file en rsyncd.conf) y limita las direcciones permitidas con hosts allow.