Il guasto tipico non è “WSL2 non parte”. È più subdolo. Dopo un riavvio di LxssManager o dopo un update di Windows, la VM di WSL2 torna su, ma la rete cambia faccia.
Succede su Windows 11 e su Windows Server con ruolo da workstation o jump host. I sintomi arrivano insieme: un servizio locale non ascolta più, il firewall registra blocchi strani, Docker Desktop perde il bind, una porta risulta aperta dentro WSL ma chiusa da host.
In mezzo ci sono tre piani diversi. Il servizio Windows. La rete virtuale di WSL2. Le regole del firewall, spesso scritte per un IP che non è più quello giusto.
Qui vediamo cosa fare quando va storto. Non una teoria su WSL2. Una sequenza da sysadmin per diagnosticare, fare rollback e ripristinare senza spegnere mezzo server.
Prerequisiti
Serve accesso amministrativo alla macchina. Serve anche sapere quale servizio stai esponendo, perché il controllo cambia se parliamo di SSH, reverse proxy, agent di monitoring o web app locale.
- Windows 11 22H2 o successivo, oppure Windows Server con WSL2 abilitato.
- PowerShell avviato come amministratore.
- Accesso a WSL, con almeno una distribuzione installata.
- Capacità di modificare regole del Windows Defender Firewall.
- Un servizio test da ripristinare, ad esempio su porta 3000, 8080 o 8443.
Note: se la macchina è usata in produzione, pianifica una finestra breve. Alcuni comandi riavviano il servizio WSL e chiudono le sessioni attive nella distro.
Step 1: capire se il problema è nel servizio, nella rete o nel firewall
La prima mossa è separare i tre strati. Se il servizio ascolta dentro WSL, il problema non è l’app. Se la porta è raggiungibile in locale ma non da host, il sospetto va al firewall o al forwarding.
Parti da PowerShell e controlla lo stato dei servizi principali.
Get-Service LxssManager, hns, vmcompute | Format-Table Name, Status, StartType# Output: tutti i servizi risultano Running o almeno LxssManager è attivo.
Poi entra nella distro e verifica il listener. Usa il comando che corrisponde al tuo servizio.
wsl -d Ubuntu -- bash -lc 'ss -lntp | grep -E ":3000|:8080|:8443"'# Output: una riga con LISTEN e il processo atteso.
Warning: se il servizio ascolta solo su 127.0.0.1 dentro WSL, dall’host potresti non vederlo come ti aspetti. In quel caso il fix non è nel firewall.
Step 2: verificare l’IP effettivo di WSL2 dopo il riavvio
WSL2 usa una rete NAT con IP dinamico. Dopo un restart del servizio o dopo sleep/hibernate, l’IP della distro può cambiare. Le regole create ieri puntano a un indirizzo vecchio.
Controlla l’IP corrente della distro e quello visto dall’host. Questa differenza spiega molti falsi allarmi.
wsl -d Ubuntu -- bash -lc "ip -4 addr show eth0 | awk '/inet / {print $2}'"
Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.InterfaceAlias -match 'vEthernet|WSL'} | Format-Table InterfaceAlias, IPAddress# Output: un indirizzo tipo 172.29.x.x/20 sulla distro e un alias vEthernet (WSL) lato host.
Se l’IP cambia spesso, non inseguirlo con regole manuali fragili. Serve una regola basata sull’interfaccia o un meccanismo di refresh.
Mini-scenario
Hai un agente Prometheus che ascolta su 9090 dentro WSL2. Ieri era raggiungibile da localhost:9090. Oggi no. Il comando mostra un nuovo IP NAT. Il firewall non è rotto: sta filtrando un forward vecchio o una porta legata a un IP non più valido.
Step 3: creare un rollback veloce delle regole firewall problematiche
Quando il comportamento cambia all’improvviso, il rollback deve essere immediato. Non cancellare tutto a mano. Disabilita prima la regola sospetta, poi verifica.
Se hai già una regola dedicata per la porta, usa il nome preciso. È il modo più pulito per tornare indietro.
Get-NetFirewallRule -DisplayName "WSL2 3000 inbound" | Disable-NetFirewallRule
Get-NetFirewallRule -DisplayName "WSL2 3000 inbound" | Format-Table DisplayName, Enabled, Direction, Action# Output: Enabled passa da True a False.
Se la regola è stata creata in modo sporco, conviene esportare prima la configurazione corrente. Così puoi ripristinare in modo chirurgico.
netsh advfirewall export C:\Temp\firewall-before-wsl2-fix.wfw# Output: file .wfw creato senza errori.
Note: una regola duplicata può mascherare il problema. Se esistono più regole sulla stessa porta, disabilitarne una sola non basta.
Step 4: ricreare una regola stabile per l’accesso dall’host
La soluzione più robusta è una regola inbound limitata all’interfaccia giusta o al profilo corretto. Evita aperture generiche su tutte le reti.
Per un servizio in ascolto su una porta specifica, crea una regola minima e leggibile.
New-NetFirewallRule `
-DisplayName "WSL2 app 3000 inbound" `
-Direction Inbound `
-Action Allow `
-Protocol TCP `
-LocalPort 3000 `
-Profile Private `
-Program "C:\Windows\System32\wsl.exe"# Output: la regola viene creata e appare in Get-NetFirewallRule.
Se devi aprire verso una subnet interna, restringi anche il remote address.
Set-NetFirewallRule -DisplayName "WSL2 app 3000 inbound" -RemoteAddress 127.0.0.1,192.168.0.0/24# Output: la regola accetta solo gli indirizzi indicati.
Warning: non usare Any come default solo per far funzionare il test. È il modo più rapido per trasformare un problema di rete in un problema di sicurezza.
Step 5: ripristinare il layer WSL2 senza reboot completo
Quando il servizio resta incastrato, non serve sempre riavviare la macchina. Spesso basta ripartire dal motore WSL.
Questo interrompe le distro, ma evita un downtime più lungo.
wsl --shutdown
Restart-Service LxssManager
wsl -l -v# Output: le distribuzioni tornano visibili e lo stato passa a Running dopo il riavvio.
Se usi WSL per un servizio in background, riavvialo esplicitamente dopo lo shutdown.
wsl -d Ubuntu -- bash -lc 'sudo systemctl restart myapp.service && sudo systemctl --no-pager --full status myapp.service'# Output: Active: active (running) e nessun errore di bind.
Se il servizio è gestito da systemd dentro WSL, il problema può essere una dipendenza non ripartita. In quel caso controlla anche le unità collegate.
Step 6: testare il percorso completo dall’host al servizio
La verifica finale deve attraversare lo stesso percorso che userà l’utente o il sistema esterno. Non basta fare curl da dentro la distro.
Dal lato host, prova la connessione diretta alla porta esposta. Poi verifica che l’app risponda davvero.
Test-NetConnection 127.0.0.1 -Port 3000
curl.exe -I http://127.0.0.1:3000# Output: TcpTestSucceeded : True e una risposta HTTP valida, ad esempio 200 OK o 302 Found.
Se il servizio deve essere raggiunto da un’altra macchina della LAN, prova anche dall’esterno con l’IP dell’host Windows. Se fallisce qui ma non in locale, il problema è quasi sempre nel firewall o nel profilo di rete.
Step 7: mettere un controllo di drift per evitare il prossimo incidente
Il guasto ritorna quando nessuno controlla il drift. L’IP di WSL2 cambia. Le regole restano vecchie. Il servizio riparte, ma la porta non torna raggiungibile.
Per questo conviene un controllo periodico che confronti la porta attesa con la regola firewall esistente. Una soluzione semplice usa un task schedulato e uno script PowerShell.
$wslIp = (wsl -d Ubuntu -- bash -lc "ip -4 addr show eth0 | awk '/inet / {print $2}' | cut -d/ -f1").Trim()
$rule = Get-NetFirewallRule -DisplayName "WSL2 app 3000 inbound" -ErrorAction SilentlyContinue
if (-not $rule) { Write-Host "missing rule" }# Output: o la regola esiste, oppure compare missing rule.
Se vuoi qualcosa di più solido, salva anche l’IP rilevato in un file di stato. Al cambio IP, lo script può aggiornare la regola o avvisare via log.
Note: su macchine condivise, è meglio notificare un cambio IP che modificare automaticamente il firewall senza controllo.
Verifica finale
La verifica finale deve dirti tre cose. Il servizio è vivo. La rete WSL è coerente. Il firewall non blocca la porta giusta.
- LxssManager è attivo.
- La distro WSL risponde con il listener corretto.
Test-NetConnectiondall’host dà esito positivo.- La regola firewall è limitata alla porta e al profilo previsti.
- Un riavvio di
wsl --shutdownnon rompe di nuovo l’accesso.
Se uno di questi punti fallisce, non cercare subito l’errore nell’app. Prima verifica il layer che è cambiato per ultimo.
Troubleshooting
Errore 1: WSL service failed to start.
La distro non riesce a riagganciare il motore WSL dopo un restart del servizio o dopo un update.
Cause: stato interno della VM WSL corrotto o servizio LxssManager rimasto bloccato.
Fix:
wsl --shutdown
Restart-Service LxssManager
wsl -l -v# Output: la distro torna in elenco con stato coerente.
Errore 2: Test-NetConnection : TcpTestSucceeded : False
La porta è aperta dentro WSL, ma l’host non la raggiunge.
Cause: regola firewall assente, disabilitata o legata a un IP WSL vecchio.
Fix:
New-NetFirewallRule -DisplayName "WSL2 app 3000 inbound" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 3000 -Profile Private# Output: la porta passa a essere raggiungibile dall’host.
Errore 3: bind: Address already in use
Il servizio dentro WSL prova ad ascoltare su una porta già occupata da un processo rimasto attivo.
Cause: restart incompleto dell’app o vecchio processo non terminato dopo wsl --shutdown.
Fix:
wsl -d Ubuntu -- bash -lc 'sudo fuser -k 3000/tcp; sudo systemctl restart myapp.service'# Output: il vecchio processo viene chiuso e il servizio riparte.
Conclusione
Con WSL2 il problema raramente è solo “la porta non va”. Di solito si rompe la catena tra servizio, IP dinamico e firewall. Se la diagnosi separa bene questi livelli, il ripristino diventa rapido.
Il prossimo passo concreto è automatizzare il controllo del drift con un task schedulato. Bastano pochi minuti per evitare il classico fermo da restart che sembra casuale ma non lo è.
Se il servizio torna su ma la porta sparisce, pensa prima al cambio IP di WSL2 e poi al firewall. È quasi sempre lì che si rompe la fiducia tra host e guest.
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.