Deux problèmes récurrents sur Windows Server 2022 : un serveur qui obtient des IPv6 mais ne répond pas au ping, et un démarrage HTTP/PXE en IPv6 qui refuse l’autodécouverte. Voici un guide opérationnel, précis et reproductible pour diagnostiquer et corriger ces deux situations.
Serveur Windows 2022 : pourquoi le ping IPv6 ne répond‑il pas ?
Diagnostic rapide
- Le serveur reçoit bien des adresses IPv6 et les distribue via DHCPv6/SLAAC, mais ne répond pas aux requêtes ICMPv6 (ping).
- Inspection côté serveur : pile IPv6 correcte, adresses présentes, passerelle/RA visibles, pare‑feu parfois même désactivé.
- Constat clé : la panne vient souvent du client (pare‑feu local, profil réseau « Public », ou pile IPv6 bridée) qui bloque ou n’émet pas les paquets ICMPv6.
Comprendre ce qui se passe (en 60 secondes)
En IPv6, un ping utilise ICMPv6 : Echo Request (type 128) et Echo Reply (type 129). Les échanges reposent aussi sur la découverte de voisins (NDP/Neighbor Discovery) et sur les annonces de routeurs (RA). Si NDP est filtré, si le client ne résout pas l’adresse MAC du serveur, ou si son pare‑feu bloque ICMPv6, la réponse ne revient jamais au client, même si le serveur lui-même est correctement configuré.
Résolution pas‑à‑pas
- Vérifier la pile IPv6 côté serveur et client
ipconfig /all Get-NetIPConfiguration Get-NetIPInterface -AddressFamily IPv6
Contrôlez : présence d’une adresse global unicast (2000::/3), d’une link‑local (fe80::/64), passerelle par défaut, DNS, et l’InterfaceIndex (ifIndex) utile pour pinger une link‑local. - Autoriser explicitement ICMPv6 (même si vous pensez que « tout est ouvert »)
PowerShell New‑NetFirewallRule -DisplayName "Allow ICMPv6‑Echo‑In" ` -Direction Inbound -Protocol ICMPv6 ` -IcmpType 128 -Action Allow # (optionnel) S'assurer que la réponse sort bien New‑NetFirewallRule -DisplayName "Allow ICMPv6‑Echo‑Out" ` -Direction Outbound -Protocol ICMPv6` -IcmpType 129 -Action Allow
Remarque : désactiver le pare‑feu n’est pas une bonne pratique et peut être trompeur (profils de réseau, règles par défaut, filtrage par service). Créez des règles explicites, auditez et journalisez. - Tester l’adresse link‑local du serveur (nécessite l’index d’interface)
Get-NetIPInterface -AddressFamily IPv6 | ft ifIndex, InterfaceAlias # Depuis le client (Windows) ping -6 fe80::% # Depuis Linux/macOS ping -6 -I fe80::
Si la link‑local répond, la connectivité L2/NDP est bonne. En cas d’échec : pensez VLAN, filtres RA/NDP au niveau du switch, ND‑snooping mal paramétré, ou une VM bridée. - Contrôler la découverte de voisins (NDP)
netsh interface ipv6 show neighbors Get‑NetNeighbor -AddressFamily IPv6 | sort InterfaceIndex, State | ft
L’état attendu d’un voisin actif est Reachable ou Stale. En Incomplete ou Delay qui persistent : suspectez un filtrage NDP/ICMPv6. - Corriger la configuration réseau du client
- Sur Windows 10/11 : passez le profil réseau en Privé, activez « Autoriser les requêtes d’écho ICMPv6 » dans le pare‑feu (inbound), supprimez les règles contradictoires.
- Sur Linux : regardez
firewalld
/nftables
(icmpv6 type echo-request/reply
), NetworkManager (ipv6.ip6-privacy
), RA (rdisc6
). - Sur macOS : vérifiez qu’aucun outil tiers ne bloque ICMPv6, et testez avec
nc -6
pour confirmer la pile.
Une fois le filtrage client levé, le ping IPv6 fonctionne comme prévu.
Tableau de dépannage côté client
OS | Commande | Ce qu’on vérifie |
---|---|---|
Windows | ping -6 <IPv6> , Get-NetFirewallRule | Émission/réception ICMPv6, règles bloquantes, profil réseau. |
Windows | Get-NetNeighbor -AddressFamily IPv6 | Résolution MAC via NDP ; états Reachable/Stale. |
Linux | ping -6 -I eth0 ::1 , ip -6 neigh | ICMPv6 actif, cache voisin, éventuels FAILED. |
macOS | ping6 <IPv6> , ndp -a | Echo Reply reçu ; découverte de voisins. |
Vérifications avec Wireshark (fortement recommandé)
- Filtre :
icmpv6 && (icmpv6.type == 128 || icmpv6.type == 129)
pour voir requêtes/réponses. - Filtre NDP :
icmpv6.type in {135 136}
(Neighbor Solicitation/Advertisement). - Si vous voyez la requête 128 partir du client sans réponse 129 : regardez le pare‑feu du serveur et la table NDP côté client.
Pièges fréquents
- Profils réseau : en « Public », Windows bloque par défaut plusieurs ICMPv6 entrant.
- Outils de sécurité : certaines EDR/NGFW endpoint filtrent ICMPv6 à l’insu de l’OS.
- Switchs L2 : ND‑snooping/RA‑guard trop stricts, filtrage MLD qui casse la découverte.
- VM et vSwitch : modes « promiscuous »/port security, tag VLAN manquant, offloads désactivés.
Démarrage HTTP/PXE en IPv4 & IPv6 : faire parler DHCPv6
Contexte
En IPv4, le boot HTTP via firmware/UEFI fonctionne classiquement avec l’option 60 (Vendor Class Identifier, ex. HTTPClient
) et l’option 67 (fichier de boot, souvent en URL complète) configurées dans la portée DHCP.
En IPv6, le même firmware peut démarrer si l’on saisit l’URL manuellement dans l’UEFI, mais l’autodécouverte DHCPv6 échoue si le serveur n’envoie pas les options attendues par la norme de démarrage réseau.
Ce qu’attend le micrologiciel UEFI (DHCPv6)
Option DHCPv6 | Rôle | Valeur / Exemple | Commentaires |
---|---|---|---|
59 — Bootfile URL | Chemin complet du programme ou chargeur à démarrer | http://[2001:db8::1]/EFI/Bootx64.efi | Définie par la norme de boot réseau sur DHCPv6 (RFC 5970). HTTPS est souvent supporté : https://[...]/ . |
60 — Bootfile Parameters | Paramètres supplémentaires (kernel initrd, arguments) | img=initrd.img kernel=linux ... | Optionnelle ; utile pour iPXE, LinuxBoot, etc. |
61 — Client System Architecture Type | Identifie l’architecture (x64, ARM64…) | Liste d’entiers codés ; ex. 7 (EFI x86‑64) | Permet de servir des URL différentes selon l’archi. |
62 — Network Interface Identifier | Identifie l’interface/contrôleur réseau | Bytes spécifiques au constructeur | Peut être ignoré sauf besoin d’appariement fin. |
15 — User Class (ou 16 — Vendor Class) | Indique la « classe » du client | HTTPClient ou PXEClient | Certains firmwares vérifient User Class (15), d’autres Vendor Class (16). Fournir au moins l’un des deux augmente la compatibilité. |
Sans un Bootfile URL (59) cohérent et, selon le firmware, une classe HTTPClient/PXEClient (15/16), le client n’interprète pas la réponse DHCPv6 comme une offre de démarrage HTTP/PXE.
Limites du service DHCP Windows (2019/2022 constatées sur le terrain)
- L’interface graphique refuse souvent d’ajouter les options réservées (59/60/61/62) en DHCPv6, ou les masque une fois créées.
- Selon les builds, le service peut n’émettre ni 59 ni 60 malgré une définition locale ; le comportement varie.
- Le Vendor‑specific (option 17) est accepté, mais tous les firmwares ne savent pas y retrouver une URL de boot encapsulée.
Solutions de contournement (comparatif)
Approche | Mise en œuvre | Avantages | Inconvénients |
---|---|---|---|
PowerShell/Netsh (DHCP Windows) | Définir les options 59/60 (+ 15/16) et les valeurs au niveau serveur/portée. | Pas de logiciel tiers, scriptable, traçable. | La GUI ne reflète pas toujours l’état ; fiabilité variable selon build. |
Option 17 (Vendor‑specific) | Encapsuler des données attendues par un firmware d’un constructeur donné. | Reste compatible avec DHCP Windows. | Non universel ; dépend fortement du microcode client. |
Serveur DHCP tiers (ISC dhcpd, Kea, dnsmasq) | Remplacer/compléter le rôle DHCPv6. | Prise en charge native des 59/60/61/62, logs détaillés. | Un service de plus à maintenir/superviser. |
WDS/MDT | Activer Windows Deployment Services en mode IPv6. | Intégré à l’écosystème Microsoft, PXE complet. | Ajoute un rôle serveur complet, au‑delà du DHCP pur. |
Mise à jour UEFI | Installer le dernier firmware sur les postes. | Peut corriger la logique DHCPv6 côté client. | Dépend du constructeur, cycles de validation nécessaires. |
Configuration détaillée avec PowerShell (exemples reproductibles)
Adaptez les noms, adresses et préfixes à votre environnement. Les commandes ci-dessous créent d’abord les définitions d’options si elles n’existent pas, puis posent les valeurs au niveau de la portée DHCPv6.
PowerShell
# 1) Définir les options DHCPv6 pour le boot réseau (si besoin)
Try { Add-DhcpServerv6OptionDefinition -OptionId 59 -Name "Bootfile URL" -Type String -Description "RFC5970" } Catch {}
Try { Add-DhcpServerv6OptionDefinition -OptionId 60 -Name "Bootfile Params" -Type String -Description "RFC5970" } Catch {}
Try { Add-DhcpServerv6OptionDefinition -OptionId 61 -Name "Client Arch Type" -Type Byte -Array $true -Description "RFC5970" } Catch {}
Try { Add-DhcpServerv6OptionDefinition -OptionId 62 -Name "Network Interface ID" -Type Byte -Array $true -Description "RFC5970" } Catch {}
Try { Add-DhcpServerv6OptionDefinition -OptionId 15 -Name "User Class" -Type String -Description "HTTPClient/PXEClient" } Catch {}
Try { Add-DhcpServerv6OptionDefinition -OptionId 16 -Name "Vendor Class" -Type String -Description "HTTPClient/PXEClient" } Catch {}
# 2) Renseigner les valeurs au niveau d’une portée
$Scope = "2001:db8:100::/64"
Set-DhcpServerv6OptionValue -ScopeId $Scope -OptionId 59 -Value "http://[2001:db8::1]/EFI/Bootx64.efi"
# Fournir au moins une classe reconnue par votre firmware
Set-DhcpServerv6OptionValue -ScopeId $Scope -OptionId 15 -Value "HTTPClient"
# En complément ou si votre firmware attend Vendor Class :
Set-DhcpServerv6OptionValue -ScopeId $Scope -OptionId 16 -Value "HTTPClient"
# (facultatif) Paramètres additionnels
# Set-DhcpServerv6OptionValue -ScopeId $Scope -OptionId 60 -Value "img=initrd.img kernel=vmlinuz console=ttyS0"
Contrôlez ensuite ce que le service émet réellement :
Get-DhcpServerv6OptionValue -ScopeId $Scope | Sort-Object OptionId | ft OptionId, Name, Value
Équivalents Netsh (utile en dépannage rapide)
netsh dhcp server v6 add optiondef 59 "Bootfile URL" STRING 0 comment="RFC5970"
netsh dhcp server v6 add optiondef 60 "Bootfile Params" STRING 0
netsh dhcp server v6 add optiondef 15 "User Class" STRING 0
netsh dhcp server v6 add optiondef 16 "Vendor Class" STRING 0
netsh dhcp server v6 set optionvalue 59 STRING "http://[2001:db8::1]/EFI/Bootx64.efi" scope=2001:db8:100::/64
netsh dhcp server v6 set optionvalue 15 STRING "HTTPClient" scope=2001:db8:100::/64
Validation côté réseau (Wireshark)
- Filtre DHCPv6 :
dhcpv6
. Regardez les échanges SOLICIT → ADVERTISE → REQUEST → REPLY. - Vérifiez que l’ADVERTISE ou le REPLY contiennent les options 59 (Bootfile URL) et, selon le besoin, 15/16 (User/Vendor Class).
- Le client doit ensuite initier une connexion HTTP/HTTPS vers l’URL fournie (
GET /EFI/Bootx64.efi
). Vous devez voir les paquets TCP/80 ou TCP/443 vers l’adresse de votre serveur.
Modèles d’UEFI connus et subtilités
- HTTP Boot vs PXE : certains firmwares parlent « HTTP Boot » (UEFI) sans « PXE » au sens strict ; d’autres exigent la chaîne
PXEClient
en User/Vendor Class. Fournir HTTPClient est le plus universel, mais PXEClient peut rester nécessaire dans des parcs mixtes. - HTTPS Boot : impose souvent des autorités racines à jour dans l’UEFI. En cas d’échec, testez en HTTP simple pour isoler un problème TLS.
- Arch Type (61) : utile pour rediriger ARM64 et x86‑64 vers des chargeurs différents (par ex.
BootAA64.efi
vsBootx64.efi
).
Bonnes pratiques de déploiement
- Conservez les crochets
[ ]
autour de l’adresse IPv6 dans les URL (http://[2001:db8::1]/...
), sinon l’UEFI interprète mal l’hôte et le port. - Ne dupliquez pas les options IPv4 (60/66/67) en IPv6 : elles n’existent pas côté DHCPv6 et ne seront pas honorées.
- Journalisez le service HTTP (logs d’accès) et synchronisez l’heure (NTP) : des erreurs de temps brisent parfois HTTPS Boot.
- En prod, servez les binaires depuis un chemin stable (
/EFI/
) et versionnez vos chargeurs iPXE/shim pour simplifier le rollback.
Procédure de test en laboratoire (checklist)
- DHCPv6 seul : activer 59 (URL) + 15/16 (classe). Capturer les trames et vérifier la présence effective des options.
- Accès HTTP : depuis une machine jointe au même VLAN,
curl -6 -I http://[2001:db8::1]/EFI/Bootx64.efi
et vérifier200 OK
. - Client UEFI : booter en IPv6 sans URL manuelle. Le client doit demander en DHCPv6, recevoir 59 et poursuivre en HTTP.
- Cas HTTPS : basculer l’URL en
https://
, vérifier les certificats (empreintes, chaîne complète), et réessayer.
Questions/Réponses rapides
Q : Pourquoi l’interface DHCP Windows ne montre pas les options 59/60 que j’ai ajoutées ?
R : Elles sont traitées comme « réservées » et la console MMC peut les masquer. Utilisez PowerShell pour créer/voir/modifier et Wireshark pour valider l’émission réelle.
Q : Je n’ai que la link‑local fe80::
sur le client. Le boot HTTP sur IPv6 peut‑il marcher ?
R : Le client doit atteindre votre serveur HTTP en global unicast. Assurez‑vous que le VLAN reçoit des RA valides et qu’une global est attribuée (DHCPv6 stateful ou SLAAC).
Q : Faut‑il absolument l’option User/Vendor Class ?
R : Pas toujours, mais c’est souvent attendu (HTTPClient
ou PXEClient
). Elle aide le firmware à reconnaître qu’une offre DHCPv6 contient un service de boot réseau.
Checklist finale (à coller dans votre runbook)
- ICMPv6 : règles pare‑feu explicites (128/129), test link‑local avec ifIndex, NDP en Reachable.
- DHCPv6 : options 59 (+ 60/61/62 si besoin) présentes dans ADVERTISE/REPLY ; 15/16 avec
HTTPClient
/PXEClient
. - HTTP/HTTPS : URL avec crochets, serveur joignable en IPv6, logs 200/3xx/4xx utiles.
- Firmware : version UEFI récente, Secure Boot/TLS testés, architectures servies correctement.
Conclusion
En IPv6, la réussite d’un ping comme d’un boot HTTP/PXE dépend d’ICMPv6/NDP côté hôte et des options DHCPv6 réellement émises. Pour le ping : ne vous fiez pas au statut du pare‑feu ; créez des règles ICMPv6 claires et vérifiez NDP/Wireshark. Pour le boot : Windows Server 2022 peut envoyer les options nécessaires via PowerShell, mais l’expérience montre que (1) la console GUI n’est pas fiable pour ces options et (2) certains builds nécessitent une validation attentive en capture. En cas d’instabilité, un DHCPv6 tiers (Kea/dnsmasq) ou l’activation de WDS peuvent offrir une voie plus robuste.
Dernier rappel : en IPv6 les options IPv4 60/66/67 n’existent pas ; utilisez 59 (Bootfile URL) et, selon le firmware, 15/16 (classe). Contrôlez toujours par capture que votre serveur envoie bien ce que vous croyez avoir configuré.
Annexe : scripts prêts à l’emploi
Autoriser ICMPv6 sur un serveur Windows
PowerShell
# Écho entrant (type 128) et sortant (type 129)
New‑NetFirewallRule -DisplayName "Allow ICMPv6 Echo In" `
-Direction Inbound -Protocol ICMPv6 `
-IcmpType 128 -Action Allow
New‑NetFirewallRule -DisplayName "Allow ICMPv6 Echo Out" `
-Direction Outbound -Protocol ICMPv6 `
-IcmpType 129 -Action Allow
# Vérifier
Get‑NetFirewallRule | ? DisplayName -like "*ICMPv6 Echo*" | ft DisplayName, Enabled, Direction, Action
Vérifier la connectivité IPv6 et NDP
PowerShell
# InterfaceIndex pour pinger une link‑local
Get‑NetIPInterface -AddressFamily IPv6 | ft ifIndex, InterfaceAlias, AddressFamily, ConnectionState
# Table NDP
Get‑NetNeighbor -AddressFamily IPv6 | sort InterfaceIndex, State | ft InterfaceIndex, IPAddress, LinkLayerAddress, State
Configurer DHCPv6 pour HTTP Boot (exemple minimal)
PowerShell
$Scope = "2001:db8:100::/64"
# Définir les options si absentes
Try { Add-DhcpServerv6OptionDefinition -OptionId 59 -Name "Bootfile URL" -Type String } Catch {}
Try { Add-DhcpServerv6OptionDefinition -OptionId 15 -Name "User Class" -Type String } Catch {}
# Renseigner les valeurs
Set-DhcpServerv6OptionValue -ScopeId $Scope -OptionId 59 -Value "http://[2001:db8::1]/EFI/Bootx64.efi"
Set-DhcpServerv6OptionValue -ScopeId $Scope -OptionId 15 -Value "HTTPClient"
# Vérification
Get-DhcpServerv6OptionValue -ScopeId $Scope | ft OptionId, Name, Value
Filtres Wireshark utiles
# ICMPv6 écho
icmpv6 && (icmpv6.type == 128 || icmpv6.type == 129)
# NDP (Neighbor Solicitation / Advertisement)
icmpv6.type in {135 136}
# DHCPv6 (boot)
dhcpv6
# HTTP vers le serveur de boot
ipv6 && tcp.port in {80,443} && ipv6.dst == 2001:db8::1
FAQ opérationnelle
Le client IPv6 répond en link‑local mais pas en global : vérifiez la route par défaut, la MTU (risque de PMTUD cassé), et les RA (drapeaux M/O). Un pare‑feu intermédiaire peut bloquer ICMPv6 « Packet Too Big », ce qui casse les gros paquets.
Les options 59/60 ne partent pas alors qu’elles sont configurées : redémarrez le service DHCP, exportez/importez la config pour réinitialiser les définitions, et confirmez par capture. Si le firmware exige Vendor Class
(16), renseignez‑la en plus de User Class
(15).
Le client affiche « No suitable boot device » : soit l’URL n’est pas fournie (option 59 absente), soit le serveur HTTP n’est pas joignable en IPv6, soit le binaire EFI renvoyé n’est pas compatible avec l’architecture (pensez option 61 ou à segmenter par portées).
Comment tracer proprement ? Centralisez les journaux DHCP et HTTP, annotez vos captures par ticket, et automatisez vos tests (Test‑NetConnection -ComputerName [2001:db8::1] -Port 80 -InformationLevel Detailed -TraceRoute
).
Résumé stratégique
- Ping IPv6 : n’est pas « juste un ping » ; c’est ICMPv6 + NDP. Autorisez explicitement Echo In/Out, vérifiez la table de voisins, et commencez toujours par la link‑local.
- Boot HTTP/PXE IPv6 : oubliez 60/66/67 côté IPv6. Servez une URL en option 59 et facilitez la détection avec 15/16 = HTTPClient/PXEClient. Validez en capture.
- Windows Server 2022 : PowerShell permet de tout configurer, mais la GUI peut être trompeuse. En cas de doute, privilégiez la capture réseau et, si nécessaire, un DHCPv6 plus souple ou WDS.
Avec ces procédures, vous disposez d’une méthode reproductible pour restaurer le ping IPv6 et rendre le boot HTTP/PXE fiable en environnement Windows Server 2022.