Networking
Azure Firewall : diagnostiquer une règle masquée avant d’ouvrir le trafic
Un runbook de production pour prouver quelle règle Azure Firewall traite un flux, séparer routage et ordre des policies, puis appliquer une correction ciblée avec validation et rollback.
Une policy Azure Firewall peut contenir la règle qui semble autoriser un flux tout en le refusant, en le contournant ou en le traitant avec une autre règle. Le réflexe courant consiste à ajouter un allow plus large, réduire un numéro de priorité ou ouvrir un NSG. Le service peut repartir, mais la cause reste masquée : le paquet n’atteint pas le firewall, une règle héritée matche en premier, une règle réseau termine le traitement avant la règle applicative, ou un DNAT modifie le chemin réellement observé.
Le cas d’usage est un workload de production dans un spoke Azure qui appelle une API interne ou externe via le firewall du hub. L’appel fonctionnait avant un déploiement de policy ; il expire désormais ou renvoie une erreur proche d’un refus d’autorisation. Le DNS résout toujours et la règle applicative attendue existe. Ce runbook doit aboutir à une décision : corriger la route, corriger la règle exacte, conserver la policy ou revenir à sa version précédente.
Figer un flux avant de lire la policy
Ne commencez pas par parcourir des centaines de règles. Capturez une seule tentative en échec sous forme de quintuplet et joignez le chemin attendu. Utilisez l’adresse IP réellement obtenue après résolution DNS, pas uniquement le FQDN de la configuration applicative.
flow:
timestamp_utc: 2026-08-06T15:42:00Z
source_ip: 10.42.3.17
source_subnet: snet-app-prod
destination_fqdn: api.partner.example
resolved_ip: 203.0.113.24
destination_port: 443
protocol: TCP
expected_path:
next_hop: 10.0.1.4
firewall_policy: fwpolicy-hub-prod
rule_type: application
rule_collection: rc-app-approved-apis
rule: allow-partner-api
validation:
probe: GET /health
expected_status: 200
rollback_policy_version: fwpolicy-hub-prod-v41 Rejouez le test avec un identifiant de corrélation si la destination le permet. Gardez une fenêtre temporelle assez étroite pour retrouver la même connexion dans les journaux du firewall et de l’application.
Prouver que le paquet atteint le firewall
L’absence de log firewall est une information. Avant de modifier la policy, vérifiez les routes effectives de la NIC source et le next hop sélectionné pour la destination. Une route apprise par BGP, une UDR plus spécifique ou un subnet associé à une autre table peut détourner le paquet de l’appliance attendue.
SOURCE_RG="rg-app-prod"
SOURCE_NIC="nic-app-01"
SOURCE_VM="vm-app-01"
SOURCE_IP="10.42.3.17"
DESTINATION_IP="203.0.113.24"
az network nic show-effective-route-table --resource-group "$SOURCE_RG" --name "$SOURCE_NIC" --output table
az network watcher show-next-hop --resource-group "$SOURCE_RG" --vm "$SOURCE_VM" --nic "$SOURCE_NIC" --source-ip "$SOURCE_IP" --dest-ip "$DESTINATION_IP" --output json Contrôlez aussi IP Flow Verify ou les règles NSG effectives quand la source est une VM compatible. Un refus NSG et une policy firewall sans match sont deux incidents différents. Ne compensez pas l’un en affaiblissant l’autre.
Reconstruire l’ordre de traitement Azure Firewall
La priorité de policy n’est pas une liste plate. Azure Firewall évalue les types de règles dans un ordre défini : DNAT, règles réseau, puis règles applicatives. Les règles sont terminales : dès qu’une règle prend en charge la connexion, les suivantes ne sont plus évaluées. Avec une policy héritée, les collections parentes sont évaluées avant les collections filles du même type.
Ce mécanisme produit un incident classique. Une règle réseau large peut matcher TCP 443 sur l’IP de destination avant qu’une règle applicative plus lisible n’évalue le FQDN. Donner une priorité numérique plus faible à la collection applicative ne la fera pas passer avant la règle réseau qui matche.
Lire la policy dans cet ordre
1. Le trafic entrant matche-t-il une règle DNAT ?
2. Une règle réseau héritée matche-t-elle le quintuplet ?
3. Une règle réseau locale le matche-t-elle ?
4. Alors seulement, une règle applicative éligible peut-elle évaluer le FQDN ?
5. Sans match, attendre un refus par défaut.
Ne pas déduire la préséance depuis
Le seul ordre d’affichage du portail
Des noms de règles comme emergency ou default
La priorité d’une collection applicative comparée à une collection réseau
La présence d’un allow qui n’a jamais reçu le flux Exporter la policy effective avant le changement
Relevez la policy attachée au firewall, sa relation avec une éventuelle policy parente, les rule collection groups et leurs priorités. Conservez ce JSON comme état initial pour la revue et le rollback.
FIREWALL_RG="rg-hub-prod"
FIREWALL_NAME="afw-hub-prod"
POLICY_NAME="fwpolicy-hub-prod"
az network firewall show --resource-group "$FIREWALL_RG" --name "$FIREWALL_NAME" --query "{name:name,policy:firewallPolicy.id,provisioningState:provisioningState}" --output json
az network firewall policy show --resource-group "$FIREWALL_RG" --name "$POLICY_NAME" --query "{name:name,parent:basePolicy.id,threatIntelMode:threatIntelMode,provisioningState:provisioningState}" --output json
az network firewall policy rule-collection-group list --resource-group "$FIREWALL_RG" --policy-name "$POLICY_NAME" --output json > firewall-policy-before.json Si une policy parente existe, exportez-la également. Un allow local ne peut pas neutraliser un deny hérité qui a déjà terminé le traitement du même type de règle.
Identifier la règle gagnante dans les logs structurés
Les tables Azure Firewall spécifiques à la ressource exposent l’action, la policy, le rule collection group, la collection et la règle. Interrogez d’abord la fenêtre et le flux exacts. La disponibilité des tables dépend des diagnostic settings : une requête vide ne prouve donc pas une autorisation.
let Start = datetime(2026-08-06T15:40:00Z);
let End = datetime(2026-08-06T15:45:00Z);
let Source = "10.42.3.17";
let Destination = "203.0.113.24";
union isfuzzy=true AZFWNetworkRule, AZFWApplicationRule, AZFWNatRule
| where TimeGenerated between (Start .. End)
| extend Src = tostring(column_ifexists("SourceIp", "")),
Dst = tostring(column_ifexists("DestinationIp", "")),
DstPort = tostring(column_ifexists("DestinationPort", "")),
Fqdn = tostring(column_ifexists("Fqdn", ""))
| where Src == Source
| where Dst == Destination or Fqdn has "api.partner.example"
| project TimeGenerated,
Type,
Action,
ActionReason,
Src,
Dst,
DstPort,
Fqdn,
Policy,
RuleCollectionGroup,
RuleCollection,
Rule
| order by TimeGenerated asc Interprétez le résultat directement. Un deny nommé mène à une correction de policy. Default Action signifie qu’aucune règle n’a matché. Un hit sur un allow inattendu explique pourquoi la règle applicative reste sans compteur. L’absence totale de ligne renvoie vers le routage, la collecte ou la fenêtre du test.
Classer l’échec avant de proposer un changement
Aucun événement firewall
Prouver route effective, next hop et diagnostic settings
Ne pas ajouter de règle allow au firewall
Refus par défaut
Comparer quintuplet et FQDN avec la règle attendue
Contrôler protocole, port, plage source et résolution DNS
Règle réseau inattendue
Examiner les collections réseau héritées et locales
Réduire le scope ou réordonner dans le type réseau
Ne pas tenter de la dépasser avec une règle applicative
Règle DNAT inattendue
Reconstruire la destination traduite et le chemin retour
Valider l’adresse publiée et la restriction des sources
Règle attendue mais appel toujours en échec
Continuer avec TLS, autorisation de destination ou santé applicative
Conserver la policy firewall Cette classification protège la fenêtre de changement. Elle évite de fusionner un incident de route, un incident TLS et un incident de policy dans une exception trop large.
Appliquer la plus petite correction réversible
Une correction de production doit nommer la règle qui masque le flux et le trafic qui doit rester bloqué. Préférez réduire une source, une destination, un port ou un FQDN plutôt que créer un allow global de haute priorité. Si la policy est gérée comme du code, corrigez la définition source et relisez le plan au lieu de patcher le portail sans trace durable.
change:
observed_rule: deny-unclassified-egress
intended_rule: allow-partner-api
correction: exclude approved destination from broad network deny
scope:
source: 10.42.3.0/24
destination: 203.0.113.24/32
port: 443
must_remain_blocked:
- other destinations on tcp/443
- non-production source subnets
evidence:
- before-policy export
- effective route and next hop
- matched firewall log row
- application probe result
rollback:
- restore policy version fwpolicy-hub-prod-v41
- replay blocked and allowed control probes Utilisez une policy de test ou d’observation lorsque l’architecture le permet. Sinon, gardez un périmètre étroit, déployez dans une fenêtre observée et préparez la définition précédente avant le début du changement.
Valider l’autorisation et le garde-fou
La validation demande deux sondes. La sonde positive prouve le flux applicatif attendu. Le contrôle négatif prouve que la correction n’a pas ouvert une destination ou une source voisine. Confirmez ensuite la règle gagnante dans les logs Azure Firewall.
Valider
La source attendue atteint la destination et le port approuvés
Le log firewall nomme la règle allow prévue
Une destination voisine reste refusée par la règle attendue
La route et le next hop n’ont pas changé
La réponse applicative et TLS sont sains
Rollback si
Le deny large ne protège plus les destinations non concernées
Une autre règle héritée ou locale matche de manière inattendue
Le flux attendu échoue encore après la modification
Le déploiement de policy ou les logs deviennent incohérents
Après rollback
Restaurer la définition précédente de la policy
Rejouer les sondes positive et négative
Confirmer les règles gagnantes précédentes dans les logs
Conserver le pack de preuves dans l’incident Conclusion
Une règle Azure Firewall n’est pas effective parce qu’elle existe. Elle l’est seulement si le paquet atteint le firewall et si l’ordre de traitement lui permet de prendre en charge le flux. Les preuves utiles sont donc un quintuplet, une route effective, un next hop, la policy exportée et une ligne de log qui nomme la règle gagnante.
La décision devient alors bornée : corriger le routage si le firewall n’a jamais vu le paquet, corriger la règle exacte si une autre collection a terminé le traitement, laisser la policy intacte si le allow attendu a déjà matché, ou restaurer la version précédente si le test de garde-fou échoue. C’est plus sûr que d’ouvrir le trafic jusqu’à disparition du symptôme.