Cloud

Azure UDR et NAT Gateway : diagnostiquer l'egress avant d'ouvrir le firewall

Un runbook de production pour qualifier une panne d'egress Azure avec UDR, NAT Gateway, NSG, firewall, DNS, KQL, validation et rollback avant d'ajouter une règle trop large.

23 juin 2026 azureudrnat-gatewayfirewallroutingnsgdnskqlobservabilityautomationrunbookrollback

Une panne d’egress Azure finit souvent dans une demande simple : “ouvrez le firewall”. Le symptôme paraît clair, l’application ne joint plus une API externe, un registre, un service SaaS ou un endpoint Azure. Pourtant, ouvrir une règle sans diagnostic peut masquer une route UDR erronée, un NAT Gateway saturé, un NSG trop restrictif, une résolution DNS inattendue ou un changement de source IP. Le risque est de rendre le flux plus permissif sans corriger la cause.

Le cas d’usage est une workload Azure intégrée à un VNet. Elle sort vers Internet ou vers un partenaire via une route table, un firewall central, un NAT Gateway et parfois un proxy. Après un déploiement réseau, des appels sortants échouent. Le runbook doit produire une décision : corriger la route, ajuster le firewall, stabiliser la sortie NAT, rollbacker le changement réseau ou refuser une ouverture trop large faute de preuve.

Figer le flux avant de toucher les règles

Avant de modifier le firewall, il faut nommer le flux exact. Une demande comme “l’application n’a plus Internet” est trop large. Le diagnostic doit isoler l’origine, la destination, le port, le protocole, le FQDN et le chemin réseau attendu.

text egress-flow-record.txt
Flux a qualifier
Workload et subnet source
FQDN ou IP destination
Port et protocole
Identite applicative ou job concerne
Heure du premier echec
Changement recent: route table, NSG, NAT, firewall, DNS, proxy

Chemin attendu
Subnet source
NSG applique
Route table et next hop
Firewall ou NVA central
NAT Gateway ou IP publique de sortie
Regle partenaire ou allowlist externe
Logs disponibles pour chaque saut

Ce cadrage évite de corriger au mauvais endroit. Si la destination est un service Azure public, un endpoint partenaire ou un service privé exposé ailleurs, les preuves attendues ne sont pas les mêmes.

Séparer DNS, routage et filtrage

Un échec HTTP ou TLS ne dit pas directement si le firewall bloque. Commencez par prouver la résolution, puis le next hop, puis le filtrage. Les trois couches peuvent produire le même symptôme applicatif.

bash 01-egress-basic-probe.sh
TARGET_FQDN=api.partner.example.com
TARGET_PORT=443

echo "dns"
getent hosts "$TARGET_FQDN" || nslookup "$TARGET_FQDN"

echo "tcp"
timeout 5 bash -lc "cat </dev/null >/dev/tcp/$TARGET_FQDN/$TARGET_PORT" && echo "tcp_connect_ok=true" || echo "tcp_connect_ok=false"

echo "tls"
openssl s_client -connect "$TARGET_FQDN:$TARGET_PORT" -servername "$TARGET_FQDN" </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates

echo "observed egress ip"
curl -sS --connect-timeout 5 https://ifconfig.me || true

La sortie observée doit correspondre au design. Si l’IP de sortie change, une allowlist partenaire peut refuser le flux même si Azure route correctement. Si DNS renvoie une cible différente de l’attendu, une règle firewall peut sembler absente alors que le flux ne va pas vers la bonne destination.

Lire les routes effectives depuis le subnet

Une UDR peut détourner tout le trafic vers un firewall, laisser certaines destinations sortir directement, ou créer une asymétrie entre environnements. Le contrôle doit partir de l’interface réseau ou du subnet représentatif, pas seulement du diagramme.

bash 02-effective-routes.sh
NIC_ID="/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-prod/providers/Microsoft.Network/networkInterfaces/app-nic01"

az network nic show-effective-route-table --ids "$NIC_ID" --output table

az network nic list-effective-nsg --ids "$NIC_ID" --output table

La question n’est pas seulement “existe-t-il une route par défaut ?”. Il faut vérifier le préfixe le plus spécifique, le next hop réel, la priorité entre routes système et routes utilisateur, puis la cohérence avec le NSG appliqué.

Vérifier NAT Gateway sans réduire le sujet à SNAT

NAT Gateway stabilise l’IP sortante et augmente la capacité SNAT, mais il ne corrige pas une mauvaise UDR ni un firewall qui refuse le flux. Dans le diagnostic, NAT doit répondre à deux questions : quelle IP sortante est attendue, et observe-t-on des signes de saturation ou de dérive ?

text nat-gateway-checklist.txt
A verifier
NAT Gateway attache au bon subnet
Public IP ou prefix attendu
Aucun chemin alternatif vers une autre IP de sortie
Allowlist externe alignee avec l'IP observee
Connexions longues ou bursts compatibles avec la capacite SNAT
Changement recent de subnet, route table ou public IP prefix

Decision possible
IP de sortie mauvaise: corriger association ou route avant firewall
Saturation probable: reduire reutilisation, scaler, ajouter capacite ou corriger client
NAT correct: poursuivre vers firewall, DNS, proxy ou application

Un changement de source IP est souvent traité comme une panne firewall côté partenaire. C’est parfois vrai, mais la correction durable consiste à rendre la sortie explicite et vérifiable, pas à ajouter toutes les IP possibles dans une allowlist.

Corréler les refus dans les logs

Si le chemin attendu passe par Azure Firewall ou une NVA journalisée, les logs doivent confirmer le refus, l’absence de flux ou une destination différente. KQL doit rester ciblé : source, destination, port, fenêtre, action.

kusto 03-firewall-egress-correlation.kql
let Window = 2h;
let SourcePrefix = "10.42.";
let TargetFqdn = "api.partner.example.com";
AzureDiagnostics
| where TimeGenerated > ago(Window)
| where Category has_any ("AzureFirewallNetworkRule", "AzureFirewallApplicationRule", "AzureFirewallDnsProxy")
| extend msg = tostring(msg_s)
| where msg has TargetFqdn or msg has SourcePrefix
| project TimeGenerated,
        Category,
        OperationName,
        msg,
        Resource,
        ResourceGroup
| order by TimeGenerated desc

Un résultat vide n’autorise pas automatiquement l’ouverture. Il peut signifier que la route ne passe pas par le firewall, que les logs ne couvrent pas la bonne catégorie, que DNS ne résout pas la destination attendue ou que le flux échoue avant le filtrage.

Décider ouvrir, corriger ou rollbacker

La décision doit distinguer quatre cas. Ouvrir le firewall n’est acceptable que si le chemin, la destination et le refus sont prouvés.

text egress-decision-matrix.txt
Ouvrir ou ajuster le firewall
Destination et port confirmes
Route effective vers le firewall confirmee
Refus observe dans les logs
Scope de regle limite a l'application et au FQDN cible
Expiration ou revue prevue si exception temporaire

Corriger le routage
Next hop inattendu
Route plus specifique mal appliquee
Environnement de test et production divergent
Firewall non traverse alors qu'il devrait l'etre

Corriger NAT ou allowlist
IP de sortie observee differente du design
NAT Gateway absent du subnet attendu
Allowlist partenaire non alignee
Signaux de saturation ou changement de public IP prefix

Rollbacker le changement reseau
Plusieurs flux critiques regressent apres la meme route table
Le changement a elargi ou detourne le trafic
La correction locale serait plus risquee que le retour arriere
Le chemin precedent est connu et validable

Cette matrice protège contre l’exception de facilité. Une règle firewall large peut faire repasser le test immédiat tout en laissant une UDR incorrecte ou une sortie non maîtrisée.

Automatiser le pack de preuve

Le diagnostic peut être préparé par un job AWX, une étape de pipeline ou un outil interne. L’automatisation doit collecter les preuves, pas décider seule d’une ouverture réseau.

yaml egress-evidence-pack.yml
evidence_pack:
flow:
  source_subnet: snet-app-prod
  target_fqdn: api.partner.example.com
  port: 443
required:
  - dns_result_from_workload_network
  - effective_route_table
  - effective_nsg
  - observed_egress_ip
  - firewall_or_proxy_logs
  - rollback_path
block_firewall_change_when:
  - destination_not_confirmed
  - route_does_not_cross_firewall
  - observed_egress_ip_unknown
  - no_owner_for_broad_exception
allow_human_review_when:
  - refused_flow_is_proven
  - scope_is_limited
  - validation_probe_exists
  - rollback_is_documented

Le bon livrable n’est pas un simple statut rouge ou vert. C’est un dossier relisible qui explique pourquoi une règle est nécessaire, ou pourquoi elle ne l’est pas.

Valider et garder le rollback proche

Après correction, rejouez le test depuis le même point réseau. Vérifiez aussi que les flux voisins ne sortent pas par un chemin inattendu et que les logs restent exploitables.

text egress-validation-rollback.txt
Validation apres action
DNS identique a l'attendu
Connexion TCP et TLS OK depuis le workload network
IP de sortie conforme au design
Logs firewall ou proxy visibles
Appel applicatif reussi avec correlation id
Aucun bypass large ajoute sans expiration

Rollback
Revenir a la route table precedente
Retirer la regle firewall temporaire
Restaurer l'association NAT attendue
Rejouer la sonde et comparer avant/apres
Garder les preuves dans le ticket incident ou changement

Si le test ne revient pas après l’ouverture firewall, il faut arrêter d’ajouter des règles et revenir au chemin : DNS, UDR, NSG, NAT, proxy, puis application.

Conclusion

Un incident d’egress Azure ne se résout pas proprement avec une ouverture firewall réflexe. Le flux doit être qualifié de bout en bout : nom, destination, DNS, route effective, NSG, NAT Gateway, firewall, logs et validation applicative.

La bonne décision est parfois d’ajouter une règle ciblée. Mais elle est souvent ailleurs : corriger une UDR, stabiliser l’IP sortante, rollbacker une route table ou refuser une exception trop large. C’est cette discipline qui transforme l’egress Azure en chemin exploitable plutôt qu’en pile d’exceptions difficiles à expliquer.