Port TCP invisible dans netstat et inaccessible sous Windows : guide de diagnostic pare‑feu, services et réseau

Un port TCP autorisé dans le Pare‑feu Windows n’apparaît pas dans netstat et refuse les connexions ? Ce guide pas à pas détaille les vérifications système, réseau et applicatives pour diagnostiquer précisément la cause et rétablir l’écoute.

Sommaire

Vue d’ensemble du problème

Ouvrir un port dans le Pare‑feu Windows ne « crée » pas un port en écoute. Le pare‑feu filtre, tandis que l’écoute dépend d’un processus serveur (IIS, Apache, service applicatif, etc.) qui se lie au port sur une ou plusieurs interfaces. Ainsi, deux conditions doivent être réunies :

  • Un processus doit écouter le port demandé sur l’IP souhaitée (0.0.0.0, IPv4 spécifique, ::, IPv6 spécifique, 127.0.0.1/::1, etc.).
  • Les règles de filtrage (Pare‑feu Windows et solutions tierces) doivent autoriser le trafic entrant vers ce port depuis la source qui vous intéresse.

Si l’une de ces conditions manque, netstat -an n’affichera pas l’état LISTENING attendu, et un telnet <IP> <Port> échouera.

Diagnostic rapide

  1. Confirmer l’écoute locale : sur la machine cible, exécutez en élévation : netstat -abno | findstr /R /C:":<Port>" Get-NetTCPConnection -LocalPort <Port> -State Listen | Select-Object LocalAddress,LocalPort,OwningProcess,CreationTime
  2. Associer le port au processus : $conns = Get-NetTCPConnection -LocalPort <Port> -State Listen Get-Process -Id $conns.OwningProcess | Format-List Id,ProcessName,Path
  3. Vérifier la règle de pare‑feu : Get-NetFirewallRule -Enabled True | Where-Object {$_.Direction -eq "Inbound"} | Get-NetFirewallPortFilter | Where-Object {$_.Protocol -eq "TCP" -and $_.LocalPort -match "^(<Port>|\*)$"} | Format-Table -AutoSize
  4. Tester localement puis à distance : Test-NetConnection -ComputerName 127.0.0.1 -Port <Port> -InformationLevel Detailed Test-NetConnection -ComputerName <IP-cible> -Port <Port> -InformationLevel Detailed
  5. Contrôler les solutions de sécurité tierces : EDR/antivirus/IDS pouvant bloquer le trafic même si le pare‑feu Windows autorise.
  6. Vérifier les interfaces et la topologie : VM, NAT/bridge, vSwitch, VLAN, route par défaut (route print), pare‑feu périmétrique.
  7. Examiner les journaux : pfirewall.log, Journaux d’événements (WFP), et pktmon ou Wireshark pour voir si les paquets arrivent.

Vérifier la règle de pare‑feu

Contrôler protocole, port, direction et profils

La règle doit être entrante, TCP, avec le bon port, activée et appliquée au profil réseau effectif (Domaine/Privé/Public).

# Règle par nom (verbeux)
netsh advfirewall firewall show rule name="Nom de la règle" verbose

# Vue PowerShell complète

$rule = Get-NetFirewallRule -DisplayName "Nom de la règle"
$rule | Get-NetFirewallPortFilter | Format-List
$rule | Get-NetFirewallAddressFilter | Format-List
$rule | Get-NetFirewallProfile | Format-List 

Profils actifs :

Get-NetConnectionProfile | Select-Object InterfaceAlias,NetworkCategory

Si votre poste est en profil Public et que la règle ne s’applique qu’à Privé ou Domaine, les connexions seront bloquées.

Étendue des adresses et interfaces

Vérifiez le champ « Adresses distantes » (RemoteAddress) et « Adresses locales » (LocalAddress). Une règle limitée à 127.0.0.1 n’autorisera pas l’accès depuis le réseau.

$rule | Get-NetFirewallAddressFilter | 
  Select-Object LocalAddress,RemoteAddress,InterfaceType,EdgeTraversalPolicy | Format-List

Programmes et services associés

Certaines règles ciblent un programme (-Program) ou un service (-Service). Si le binaire ou le service a changé d’emplacement, la règle ne s’applique plus.

$rule | Format-List DisplayName,Enabled,Action,Direction,Program,Service,PolicyStoreSourceType

Redémarrer le Pare‑feu

Après modification massive, redémarrez le service pour purger l’état :

Restart-Service mpssvc -Force

Contrôler les logiciels de sécurité tiers

Antivirus/EDR/IDS, agents proxy ou contrôleurs d’accès réseau peuvent surclasser les règles Windows. Sans les désinstaller, effectuez un test contrôlé : bascule en mode apprentissage/diagnostic, policy temporaire d’autorisation sur le port et vérification des journaux. Notez l’horodatage des tentatives de connexion pour retrouver rapidement les événements correspondants.

Vérifier la configuration réseau

Interfaces physiques et virtuelles

Get-NetAdapter | Where-Object {$_.Status -eq "Up"} |
  Select-Object Name,InterfaceDescription,Status,MacAddress,LinkSpeed

Get-NetIPAddress | Select-Object InterfaceAlias,AddressFamily,IPAddress,PrefixLength

Sur une VM, vérifiez le mode : NAT (IP privée non joignable depuis l’extérieur sans redirection), Bridge (IP du LAN, directement joignable), Host‑Only, ou vSwitch isolé. Les conteneurs/Docker/WSL2 créent des réseaux NAT avec redirections de ports ; assurez‑vous que la redirection couvre le port attendu.

Routage, NAT et filtrage périmétrique

route print

Une passerelle ou un pare‑feu en amont peut bloquer le flux. La « boucle de NAT » (hairpin) échoue parfois : tester depuis un hôte réellement externe plutôt que depuis le même LAN qui cible l’IP publique.

S’assurer qu’un service écoute réellement

Lister les sockets en écoute

Get-NetTCPConnection -State Listen | 
  Sort-Object LocalPort | 
  Select-Object LocalAddress,LocalPort,OwningProcess

ou :

netstat -abno | more

Astuce : lancez vos vérifications avec élévation, sinon certaines informations peuvent être masquées.

Associer le port au processus puis au binaire

$p = (Get-NetTCPConnection -LocalPort <Port> -State Listen).OwningProcess
Get-Process -Id $p | Select-Object Id,ProcessName,Path,StartTime

Si aucun processus n’écoute, le port ne peut pas s’ouvrir malgré la règle pare‑feu. Démarrez/relancez le service applicatif et surveillez son journal d’erreurs (bind failure, address already in use, etc.).

Conflit de port

Si un autre processus occupe déjà le port, votre application échouera au démarrage. Identifiez le PID occupant et libérez le port ou changez de port.

Cas spécifiques à HTTP.sys (ports 80/443 et au‑delà)

Sur Windows, HTTP.sys peut partager un même port entre plusieurs services via des réservations d’URL (URLACL). Il est possible que netstat montre PID=4 (System) à l’écoute sur 0.0.0.0:80, alors que votre service doit réserver une URL (préfixe) plutôt que le port brut.

netsh http show urlacl
netsh http show servicestate

Corrigez en créant une réservation d’URL si requis (exemple) :

netsh http add urlacl url=http://+:8080/ user=DOMAIN\CompteService

IPv6‑only, loopback‑only et liaisons d’interface

Un binaire peut se lier à ::1 (IPv6 localhost) uniquement, rendant le service invisible en IPv4. De même, une liaison sur 127.0.0.1 n’est pas accessible depuis le réseau. Contrôlez l’adresse locale dans la sortie netstat/Get‑NetTCPConnection. Pour écouter sur toutes les interfaces IPv4 : liez‑vous à 0.0.0.0 (ou :: pour IPv6).

Ports réservés et plages exclues

Windows peut réserver des plages de ports (Hyper‑V, WSL2, services système). Avant de choisir un port, vérifiez les plages exclues et dynamiques :

netsh interface ipv4 show excludedportrange protocol=tcp
netsh interface ipv6 show excludedportrange protocol=tcp
netsh interface ipv4 show dynamicport tcp
netsh interface ipv6 show dynamicport tcp

Évitez de choisir un port inclus dans ces plages ou ajustez la configuration si vous savez exactement ce que vous faites.

Tester correctement la connectivité

Depuis la machine locale

Test-NetConnection -ComputerName 127.0.0.1 -Port <Port> -InformationLevel Detailed
# ou via IPv6 local
Test-NetConnection -ComputerName ::1 -Port <Port>

Si le test local échoue alors que la règle pare‑feu est ouverte, c’est presque toujours un problème d’écoute du service.

Depuis une machine distante

Test-NetConnection -ComputerName <IP-cible> -Port <Port> -InformationLevel Detailed -TraceRoute

Telnet reste utile pour tester un simple handshake TCP :

telnet <AdresseIP> <Port>

Si Client Telnet n’est pas installé : Fonctionnalités Windows → Client Telnet.

Journalisation et capture de paquets

Activer la journalisation du Pare‑feu Windows

Set-NetFirewallProfile -Profile Domain,Public,Private `
  -LogAllowed True -LogBlocked True `
  -LogFileName "C:\Windows\System32\LogFiles\Firewall\pfirewall.log" `
  -LogMaxSizeKilobytes 32767

Reproduisez le test et observez les entrées ALLOW/DROP pour l’IP source et le port destinataire.

Journaux WFP et Observateur d’événements

Les événements WFP indiquent les décisions de filtrage (par ex. 5156 autorisé, 5157/5152 refusé). Filtrez par port et protocole pour gagner du temps.

Packet Monitor (pktmon) intégré

pktmon start --etw -p 0
# reproduire le problème, puis :
pktmon stop
pktmon format PktMon.etl -o trace.txt
# ou convertir en pcapng :
pktmon pcapng PktMon.etl -o trace.pcapng

Ouvrez ensuite le .pcapng dans votre analyseur favori pour confirmer l’arrivée (ou non) des SYN et la réponse (SYN/ACK, RST, ICMP).

Erreurs fréquentes et correctifs immédiats

  • Règle créée pour le mauvais profil : appliquez la règle au profil actif (Private, Domain ou Public).
  • Règle limitée à 127.0.0.1 : étendez l’adresse locale à Any ou à l’IP de l’interface réseau.
  • Service non démarré : démarrez et vérifiez les journaux applicatifs de bind.
  • Conflit avec HTTP.sys/IIS : créez une réservation URLACL ou changez l’URL/port.
  • EDR bloque le port : ajoutez une exception conforme à la politique sécurité.
  • Port dans une plage exclue : sélectionnez un port hors excludedportrange.
  • Service lié à IPv6 uniquement : activez la dual‑stack ou liez explicitement à IPv4.
  • NAT/hairpin casse le test : testez depuis une machine réellement externe.

Tableau de correspondance symptômes ⇄ causes ⇄ commandes

SymptômeCause probableCommande(s) à exécuterPiste de résolution
netstat n’affiche rienService non démarré ou erreur de bindGet-NetTCPConnection -State Listen
Get-EventLog applicatif
Démarrer service, corriger la config d’écoute
Écoute sur 127.0.0.1 uniquementLiaison loopbacknetstat -an | findstr <Port>Lier à 0.0.0.0 ou à l’IP de l’interface
Test local OK, distant KOPare‑feu bloque ou filtrage amontGet-NetFirewallRule
pfirewall.log
Ajuster règle entrante, vérifier ACL périmétriques
Port occupé par un autre PIDConflit de portnetstat -abnoLibérer ou changer de port
Port visible mais HTTP inaccessibleRéservation URL manquantenetsh http show urlaclCréer urlacl pour l’URL de l’app
Pas de paquets entrantsRoutage/NAT/ACL amontpktmon / capture réseauCorriger routage, DNAT, pare‑feu matériel

Runbook reproductible

  1. Arrêter l’application qui devrait écouter.
  2. Valider l’absence d’écoute (attendu) : netstat -an | findstr /R /C:":<Port>"
  3. Créer/contrôler la règle (exemple) : New-NetFirewallRule -DisplayName "App <Port> TCP In" ` -Direction Inbound -Action Allow -Enabled True ` -Profile Any -Protocol TCP -LocalPort <Port>
  4. Démarrer l’application et contrôler l’écoute : Get-NetTCPConnection -LocalPort <Port> -State Listen | Select-Object LocalAddress,LocalPort,OwningProcess
  5. Test local : Test-NetConnection -ComputerName 127.0.0.1 -Port <Port> -InformationLevel Detailed
  6. Test distant : Test-NetConnection -ComputerName <IP/nom-fqdn> -Port <Port> -InformationLevel Detailed -TraceRoute
  7. En cas d’échec : activer la journalisation pare‑feu et lancer une capture avec pktmon. Corriger selon les indices.

Script PowerShell « tout‑en‑un »

Ce script consolide les principaux contrôles pour un port donné.

param(
  [Parameter(Mandatory=$true)][int]$Port,
  [string]$Remote = "127.0.0.1"
)

Write-Host "=== Vérification d'écoute ==="
$listen = Get-NetTCPConnection -State Listen -ErrorAction SilentlyContinue |
Where-Object {$_.LocalPort -eq $Port}
if($listen){
$p = Get-Process -Id $listen.OwningProcess -ErrorAction SilentlyContinue
$listen | Select-Object LocalAddress,LocalPort,State,OwningProcess | Format-Table -AutoSize
if($p){ $p | Format-List Id,ProcessName,Path,StartTime }
}else{
Write-Warning "Aucun processus n'écoute le port $Port"
}

Write-Host "`n=== Règles de pare-feu TCP entrantes ==="
$rules = Get-NetFirewallRule -Enabled True -Direction Inbound |
Get-NetFirewallPortFilter |
Where-Object {$*.Protocol -eq "TCP" -and ($*.LocalPort -match "^(?:$Port|*)$")}
if($rules){
$rules | Format-Table LocalPort,Protocol,RemotePort -AutoSize
}else{
Write-Warning "Aucune règle entrante TCP ne correspond au port $Port"
}

Write-Host "`n=== Étendue adresses (si applicable) ==="
Get-NetFirewallRule -Enabled True -Direction Inbound |
Where-Object {$_.DisplayName -match "$Port"} |
Get-NetFirewallAddressFilter |
Select-Object LocalAddress,RemoteAddress,InterfaceType,EdgeTraversalPolicy | Format-Table -AutoSize

Write-Host "`n=== Test de connectivité ==="
Test-NetConnection -ComputerName $Remote -Port $Port -InformationLevel Detailed

Informations complémentaires utiles

  • Journalisation du Pare‑feu : activez le fichier pfirewall.log pour voir si des paquets sont bloqués ou autorisés.
  • Ports réservés : contrôlez les réservations/ exclusions : netsh interface ipv4 show excludedportrange tcp netsh interface ipv6 show excludedportrange tcp
  • Stratégies de sécurité et QoS : en environnement Active Directory, des GPO peuvent réécrire les règles locales. Vérifiez les stratégies appliquées au poste/serveur.
  • Analyse du trafic : Wireshark ou Packet Monitor pour valider l’arrivée des paquets et la réponse (SYN/ACK ou RST).

FAQ rapide

Pourquoi mon port est‑il autorisé par le pare‑feu mais invisible dans netstat ?
Parce que personne n’écoute ce port. Le pare‑feu ne crée pas une écoute ; il autorise seulement le passage si un processus est lié au port.

Un test local réussit mais l’accès distant échoue, que regarder ?
Les règles de pare‑feu (profil actif, plage d’IP distantes), les ACL en amont (pare‑feu matériel), la NAT, ou un EDR.

Comment savoir si IIS/HTTP.sys occupe mon port ?
Vérifiez netstat -abno (PID 4/System) et netsh http show urlacl. Créez une réservation d’URL si nécessaire.

Mon service écoute sur ::1 mais pas en IPv4.
Activez la liaison dual‑stack ou liez explicitement à 0.0.0.0 / l’IP IPv4. Les adresses mappées IPv4→IPv6 peuvent être désactivées selon la pile réseau.

Quels ports éviter ?
Évitez les plages dynamiques/exclues reportées par netsh interface ... show dynamicport et show excludedportrange. Choisissez un port applicatif stable.

Conclusion

Un port « ouvert » exige à la fois une écoute par un processus et une autorisation par les filtres réseau. En validant la règle de pare‑feu, en confirmant l’écoute effective et en éliminant les blocages externes (EDR, NAT, ACL), vous isolez rapidement la cause. La plupart des incidents proviennent d’un service qui ne se lie pas à l’IP/au port attendu, d’un profil de pare‑feu inadéquat, d’une règle trop restrictive, ou d’une interférence (HTTP.sys, ports exclus, sécurité tierce). Les commandes fournies ci‑dessus constituent un chemin de diagnostic reproductible pour rétablir une connectivité fiable.

Sommaire