Networking

Azure : diagnostiquer un routage asymétrique avant de changer une UDR

Un runbook de production pour qualifier un routage asymétrique Azure avec routes effectives, UDR, Azure Firewall, NAT Gateway, flow logs, validation et rollback avant de modifier les tables de routes.

04 juil. 2026 azurenetworkingudrroute-tableazure-firewallnat-gatewayeffective-routesobservabilitykqlrunbookrollbackproduction

Un routage asymétrique rend très vite un incident réseau Azure difficile à lire. La requête sort bien du subnet workload par le next hop attendu, mais la réponse revient par un autre chemin, contourne le firewall, passe par une autre appliance, ressort via un NAT Gateway ou disparaît derrière une route qui n’existe que d’un côté. Le symptôme ressemble alors à un timeout, un 502 intermittent, un deny firewall, une absence de log ou une rafale de retries applicatifs.

Le réflexe risqué consiste à modifier immédiatement l’UDR : ajouter un préfixe plus large, tout pointer vers le firewall, supprimer une route, ou ouvrir une règle NSG pour faire passer le test. Cela peut masquer la vraie panne et créer un deuxième incident. Le cas d’usage est un environnement Azure hub-and-spoke où un workload appelle une API interne, un service privé ou une dépendance on-premises via un routage contrôlé. Le but du runbook est de prouver le chemin aller et le chemin retour avant de toucher aux tables de routes.

Figer le flux et le chemin attendu

Commencez par nommer un seul flux. Ne diagnostiquez pas tout le VNet d’un coup. Un changement de table de routes n’est défendable que si la source, la destination, le protocole, le port et les next hops attendus sont clairs.

text route-asymmetry-contract.txt
Flux a qualifier
Workload source: app-prod-api
Subnet source: snet-app-prod / 10.42.12.0/24
IP source: 10.42.12.18
Destination: orders.internal.contoso.net / 10.55.4.20
Protocole et port: TCP 443
Chemin aller attendu: subnet spoke -> Azure Firewall -> peering hub -> subnet service
Chemin retour attendu: subnet service -> Azure Firewall -> subnet spoke
Changement recent: mise a jour de route table sur snet-app-prod ou subnet service

Preuves requises avant modification UDR
Resolution DNS depuis la source
Route effective sur la NIC source
Route effective sur la NIC ou le subnet destination
Logs firewall ou appliance dans les deux sens
Preuves NSG flow quand disponibles
Rejeu applicatif avec identifiant de correlation
Route table precedente ou rollback d'association

Si l’équipe ne sait pas décrire le chemin retour, elle ne doit pas encore modifier la route aller. Beaucoup d’incidents asymétriques viennent de l’hypothèse fausse que les tables de routes sont symétriques.

Prouver que le DNS ne change pas la cible

Avant de comparer les routes, vérifiez que l’appelant résout bien l’adresse attendue. L’analyse de routage ne vaut plus grand-chose si un côté appelle un endpoint public, une ancienne IP privée ou un hostname régional différent.

text dns-target-checks.txt
Controles DNS depuis le chemin workload
Resoudre le FQDN depuis le subnet source ou le runner
Comparer l'IP resolue avec l'IP attendue de la dependance
Verifier les liens de private zone et les regles de forwarding si DNS prive
Confirmer qu'aucun override local ou cache ancien ne pointe vers un ancien endpoint
Repeter depuis le cote destination si le retour utilise un callback nomme

Bloquer les changements UDR quand
La source resout une adresse publique inattendue
Des appelants differents resolvent des IP privees differentes sans proprietaire
Le test en echec utilise une IP alors que la production utilise un FQDN
Le DNS a change pendant la fenetre d'incident

Private Endpoint peut apparaître dans cette vérification quand la dépendance utilise une adresse privée, mais ce n’est pas le centre du diagnostic. La question est de savoir si les deux côtés parlent bien de l’adresse qui doit être routée.

Comparer les routes effectives des deux côtés

Une table de routes montre l’intention. Les routes effectives montrent ce que la NIC utilise réellement après combinaison des routes système, peering, BGP, UDR et routes propagées. Capturez les routes effectives côté source et côté destination avant de changer une table.

bash 01-effective-routes.sh
SOURCE_NIC="nic-app-prod-api-01"
SOURCE_RG="rg-prod-app"
DEST_NIC="nic-orders-prod-01"
DEST_RG="rg-prod-orders"
DEST_IP="10.55.4.20"
SOURCE_IP="10.42.12.18"

az network nic show-effective-route-table --resource-group "$SOURCE_RG" --name "$SOURCE_NIC" --output table

az network nic show-effective-route-table --resource-group "$DEST_RG" --name "$DEST_NIC" --output table

# Inspecter ensuite la route qui couvre DEST_IP cote source
# et la route qui couvre SOURCE_IP cote destination.

Cherchez les différences de next-hop type : VirtualAppliance, VnetLocal, VNetPeering, Internet, VirtualNetworkGateway ou None. Le problème n’est pas seulement une route manquante. Il peut venir d’un préfixe plus spécifique qui gagne d’un côté, d’une route propagée qui contredit l’attendu, ou d’un subnet associé à la mauvaise route table.

Inspecter associations et dérive des route tables

Une UDR correcte dans la mauvaise table ne sert à rien. Une route table attachée à un seul subnet peut créer exactement l’asymétrie que l’équipe essaie de corriger.

bash 02-route-table-drift.sh
VNET_RG="rg-network-prod"
VNET="vnet-spoke-prod"

az network vnet subnet list --resource-group "$VNET_RG" --vnet-name "$VNET" --query "[].{subnet:name,addressPrefix:addressPrefix,routeTable:routeTable.id,nsg:networkSecurityGroup.id,natGateway:natGateway.id}" --output table

az network route-table list --resource-group "$VNET_RG" --query "[].{name:name,routes:routes[].{name:name,prefix:addressPrefix,nextHop:nextHopType,nextHopIp:nextHopIpAddress}}" --output json

Regardez aussi les écritures récentes sur les route tables, peerings, policies firewall, associations NAT Gateway et configurations de subnet. Une route peut avoir changé parce qu’un déploiement IaC a réassocié un subnet, pas parce qu’une route a été éditée directement.

Corréler firewall et preuves de flux

Un routage asymétrique se voit souvent par une absence de preuve. Le firewall voit la requête mais pas la réponse, ou la réponse mais pas la requête. Les NSG flow logs peuvent montrer des refus d’un côté alors que le firewall semble propre.

kusto 03-route-asymmetry-evidence.kql
let StartTime = datetime(2026-07-04T10:00:00Z);
let EndTime = datetime(2026-07-04T10:30:00Z);
let SourceIp = "10.42.12.18";
let DestinationIp = "10.55.4.20";
AzureDiagnostics
| where TimeGenerated between (StartTime .. EndTime)
| where Category has_any ("AzureFirewallNetworkRule", "AzureFirewallApplicationRule")
| where msg_s has_any (SourceIp, DestinationIp)
| project TimeGenerated, Category, msg_s, action_s, protocol_s, source_s, destination_s, destinationPort_s
| order by TimeGenerated asc

Une seule entrée autorisée ne suffit pas. Pour une inspection stateful, confirmez que l’équipement attendu voit toute la conversation. Si un firewall central doit inspecter le chemin mais ne voit jamais le retour, ajouter une règle applicative ne corrigera pas la route.

Vérifier NAT Gateway et identité sortante

NAT Gateway peut faire ressembler le problème à une dérive firewall ou allowlist. Un workload peut sortir via NAT sur un chemin et via Azure Firewall ou une appliance sur un autre. La destination voit alors une IP source différente de celle attendue.

text nat-gateway-checks.txt
Verifier l'impact NAT
NAT Gateway est-il associe au subnet source ?
La destination allowlist-elle l'IP publique firewall, l'IP publique NAT ou l'IP privee source ?
Un changement de route a-t-il deplace le trafic hors du chemin NAT ?
Les metriques SNAT ou le nombre de connexions sont-ils anormaux ?
Le chemin retour attend-il la source privee originale ou l'adresse traduite ?

Bloquer les edits de route quand
L'IP source observee cote destination est inconnue
NAT Gateway et Azure Firewall apparaissent tous les deux comme chemins possibles
L'equipe ne sait pas quelle IP publique doit etre allowlistee
Un rollback changerait l'identite sortante sans preavis

Routage et identité se rejoignent à la sortie. La route peut être techniquement valide alors que la dépendance refuse la nouvelle identité réseau.

Valider avec un rejeu contrôlé

Ne validez pas un changement de route avec un retry applicatif flou. Rejouez un flux avec timestamp, hôte source, destination, port et identifiant de corrélation. Capturez les logs de la source, du firewall ou de l’appliance, de la destination et du workspace de monitoring.

yaml route-replay-plan.yml
replay:
flow_id: route-asymmetry-20260704-01
source: app-prod-api / 10.42.12.18
destination: orders.internal.contoso.net / 10.55.4.20
protocol: tcp
port: 443
method:
  - resoudre la destination depuis la source
  - ouvrir une requete TCP ou HTTPS controlee
  - inclure un header de correlation si HTTP est disponible
  - capturer les routes effectives avant et apres changement
  - interroger logs firewall et flow logs pour les deux IP
success:
  - la route source pointe vers le next hop attendu
  - la route destination vers la source pointe vers le next hop attendu
  - le firewall ou l'appliance observe le sens attendu
  - l'application recoit une reponse valide
cleanup:
  - retirer regle ou host route temporaire de diagnostic
  - restaurer la route table precedente si la validation echoue

Un rejeu utile rend la décision de routage auditable. Il évite aussi de déclarer un succès parce qu’un retry est passé par une autre instance.

Décider changement, rollback ou blocage

Une modification d’UDR doit être le résultat du diagnostic, pas sa méthode. Gardez la décision explicite.

text route-decision.txt
Changer l'UDR
La route effective prouve le mauvais next hop pour le prefixe exact
Le chemin retour est compris et reste symetrique
La policy firewall ou appliance autorise deja le flux vise
L'impact NAT ou identite sortante est documente
Le rollback de route table est pret

Rollbacker la route table
L'incident demarre apres une association ou mise a jour de route table
La route precedente restaure le chemin aller et retour attendu en test
La nouvelle route envoie un seul cote dans le chemin inspecte
La recuperation applicative est prouvee apres rollback

Corriger plutot firewall, NSG ou DNS
Les routes sont correctes des deux cotes
Le firewall refuse le flux attendu
Les NSG flow logs montrent un deny subnet ou NIC
Le DNS resout la mauvaise cible

Bloquer le changement
Seul le chemin aller est connu
La route effective cote destination manque
Aucun log ne prouve ou passe le retour
La route proposee utilise un prefixe large pour masquer l'incertitude
Le rollback impacterait des workloads non lies

La correction la plus sûre est souvent un préfixe plus étroit, une correction d’association de route table, un réglage de propagation de peering, ou un rollback vers la dernière table connue. Les préfixes larges et bypass d’urgence doivent expirer vite et rester attachés à des preuves.

Garder le rollback observable

Un rollback de routage n’est pas terminé quand la commande réussit. Il est terminé quand le chemin initial est visible à nouveau et qu’aucun workload adjacent n’a été déplacé.

text route-rollback-validation.txt
Validation du rollback
Route table ou entree de route precedente restauree
Routes effectives controlees sur les NIC source et destination
Logs firewall ou appliance montrant la conversation attendue
NAT ou identite source sortante conforme au chemin documente
Probe applicative OK avec le meme FQDN et port
Monitoring sans nouveaux denies pour les workloads voisins
Dossier incident avec diff de route, decision et proprietaire du cleanup

Rollback incomplet quand
Seule la route source a ete controlee
Une route large temporaire reste sans expiration
La destination voit une identite source differente
Les logs firewall manquent encore un sens
La route table est corrigee manuellement mais l'IaC va recreer la derive

Si la table de routes est gérée par infrastructure as code, le rollback doit inclure l’état IaC ou la pull request. Sinon, le prochain déploiement peut réintroduire l’asymétrie.

Conclusion

Un routage asymétrique ne se corrige pas avec une UDR plus large. Il se qualifie en comparant le chemin dans les deux sens : cible DNS, routes effectives, association de route table, preuves firewall ou appliance, identité NAT et rejeu contrôlé.

La décision de production devient simple seulement quand ces preuves existent : changer une route étroite, corriger une autre couche, rollbacker la table de routes, ou bloquer le changement tant que le chemin retour n’est pas connu. C’est cette discipline qui garde les chemins privés Azure explicables au lieu de transformer le routage en essai-erreur.