Networking

Azure Firewall DNS proxy : diagnostiquer l'egress avant d'ouvrir des règles

Un runbook de production pour qualifier un échec d'egress Azure avec DNS proxy Firewall, résolution FQDN, UDR, règles applicatives, logs, validation et rollback avant d'élargir les flux.

30 juin 2026 azureazure-firewalldnsdns-proxyegressudrnetworkingobservabilitykqlrunbookrollback

Un incident d’egress Azure commence souvent par une demande simple : “ouvrez la sortie vers cette API”. Le workload ne joint plus une dépendance externe ou privée, la règle applicative Azure Firewall semble pourtant exister, et les logs ne montrent pas toujours le même FQDN que celui testé depuis un poste d’administration. Le réflexe dangereux consiste à ajouter une règle plus large, une exception IP ou un contournement de routage.

Le cas d’usage est un spoke Azure dont les subnets sortent par UDR vers Azure Firewall. Les règles applicatives autorisent certains FQDN, le DNS proxy du Firewall est censé garder la résolution cohérente avec les logs et les décisions de filtrage, et plusieurs workloads utilisent App Service VNet Integration, machines virtuelles, jobs CI privés ou conteneurs. L’objectif du runbook est de décider si l’incident vient vraiment d’une règle manquante, d’une résolution DNS qui contourne le Firewall, d’une route, d’un SNAT ou d’un changement côté dépendance.

Décrire le chemin egress complet

Avant de toucher aux règles, écris le chemin attendu. Une règle applicative basée sur FQDN n’est fiable que si le workload résout le nom dans un chemin compatible avec Azure Firewall. Si une VM utilise un resolver interne, si App Service hérite d’une configuration DNS différente, ou si un forwarder renvoie une adresse qui ne correspond plus au FQDN observé par le Firewall, l’ouverture de règle ne corrige pas la cause.

text egress-path-scope.txt
Incident
Workload: api-orders-prod
Subnet: spoke-prod/app-integration
Dependency: api.partner.example
Expected path: subnet -> UDR -> Azure Firewall -> Internet or private dependency
Expected DNS path: workload -> Azure Firewall DNS proxy or approved resolver -> upstream DNS
Expected rule: application rule on api.partner.example over HTTPS

Questions before change
Which resolver is used by the workload at runtime?
Is Azure Firewall DNS proxy enabled and advertised to this subnet?
Does the UDR force traffic to the Firewall for the dependency IP?
Do Firewall logs show the expected FQDN or only an IP flow?
Which validation proves the dependency works without broadening egress?

Cette description évite de mélanger trois sujets : résolution de nom, routage vers le Firewall, et décision de filtrage. Les trois doivent être vrais pour accepter le changement.

Capturer l’état du Firewall et du DNS proxy

Le premier contrôle est la configuration réelle du Firewall. Vérifie le DNS proxy, les serveurs DNS configurés, la politique associée et les collections de règles qui portent l’egress du workload.

bash 01-capture-firewall-dns-proxy.sh
FIREWALL_NAME="azfw-prod"
FIREWALL_RG="rg-network-prod"
POLICY_NAME="azfw-policy-prod"
POLICY_RG="rg-network-prod"

az network firewall show --name "$FIREWALL_NAME" --resource-group "$FIREWALL_RG" --query "{name:name,privateIp:ipConfigurations[0].privateIPAddress,dnsSettings:dnsSettings,firewallPolicy:firewallPolicy.id}" --output json

az network firewall policy show --name "$POLICY_NAME" --resource-group "$POLICY_RG" --query "{name:name,dnsSettings:dnsSettings,threatIntelMode:threatIntelMode}" --output json

az network firewall policy rule-collection-group list --policy-name "$POLICY_NAME" --resource-group "$POLICY_RG" --query "[].{name:name,priority:priority,provisioningState:provisioningState}" --output table

Archive cette capture avec l’incident. Si le DNS proxy est désactivé, ou si les workloads ne l’utilisent pas, les règles FQDN peuvent devenir difficiles à expliquer. Elles peuvent encore fonctionner dans certains cas, mais l’équipe perd l’alignement entre résolution, logs et politique.

Prouver le resolver utilisé par le workload

Le test utile ne part pas du poste d’administration. Il part du subnet, du runtime ou du runner qui échoue. L’objectif est de savoir quel resolver répond, quelle adresse est obtenue, et si cette adresse passe ensuite par l’UDR vers le Firewall.

bash 02-workload-dns-and-route-check.sh
TARGET_FQDN="api.partner.example"
EXPECTED_FIREWALL_IP="10.40.0.4"

printf "Resolver configuration
"
cat /etc/resolv.conf || true

printf "Resolved addresses
"
getent hosts "$TARGET_FQDN" || nslookup "$TARGET_FQDN"

printf "Route selected toward resolved IP
"
TARGET_IP="$(getent hosts "$TARGET_FQDN" | awk '{print $1}' | head -1)"
ip route get "$TARGET_IP"

printf "TCP probe
"
timeout 5 bash -c "cat < /dev/null > /dev/tcp/$TARGET_FQDN/443"

Pour App Service ou Functions avec VNet Integration, le test doit utiliser un contexte proche du runtime : console Kudu si elle est pertinente, job de diagnostic, conteneur temporaire ou probe synthétique dans le même spoke. Pour un runner CI privé, le preflight doit tourner avant le déploiement.

Lire les logs Firewall comme preuve de chemin

Une règle applicative Azure Firewall doit laisser une trace avec le FQDN, l’action, la collection et la règle. Si les logs ne montrent qu’un flux réseau vers une IP, ou ne montrent rien, l’incident n’est peut-être pas une règle applicative manquante.

kusto 03-firewall-egress-evidence.kql
let TargetFqdn = "api.partner.example";
let WindowStart = ago(2h);
AZFWApplicationRule
| where TimeGenerated > WindowStart
| where Fqdn has TargetFqdn or TargetUrl has TargetFqdn
| project TimeGenerated, SourceIp, Fqdn, TargetUrl, Action, RuleCollection, Rule, Protocol, DestinationPort, Policy
| order by TimeGenerated desc

Complète avec les logs réseau lorsque l’application ne remonte pas dans les règles applicatives.

kusto 04-firewall-network-flow-check.kql
let WorkloadPrefix = "10.42.";
let WindowStart = ago(2h);
AZFWNetworkRule
| where TimeGenerated > WindowStart
| where SourceIp startswith WorkloadPrefix
| project TimeGenerated, SourceIp, DestinationIp, DestinationPort, Action, RuleCollection, Rule, Protocol
| order by TimeGenerated desc

Si le flux apparaît en règle réseau vers une IP alors que la politique attend une règle applicative FQDN, la question devient DNS et classification du trafic, pas seulement ouverture de port.

Séparer les causes fréquentes

Le diagnostic doit converger vers une cause testable. Les symptômes se ressemblent, mais les corrections ne sont pas les mêmes.

text egress-diagnosis-matrix.txt
DNS proxy ou resolver
Le workload ne pointe pas vers le DNS proxy attendu
Le resolver interne ne forwarde pas comme prévu
Le FQDN résout vers une IP différente selon les subnets
Les logs Firewall ne contiennent pas le FQDN attendu

Routage
L'UDR ne couvre pas le préfixe résolu
Une route plus spécifique contourne le Firewall
Le retour passe par un chemin asymétrique
Le test depuis un autre subnet réussit mais pas depuis le runtime

Politique Firewall
La règle FQDN existe mais dans une collection moins prioritaire
Le port ou protocole ne correspond pas au flux réel
Une règle deny plus prioritaire intercepte la demande
Le FQDN effectif est un alias, un CDN ou un sous-domaine différent

Dépendance ou identité
La connexion arrive mais l'API retourne 401, 403 ou 429
Le certificat, SNI ou hostname attendu ne correspond pas
Le partenaire a changé d'IP, de domaine ou de politique de rate limit

Cette matrice évite l’exception large. Une IP ajoutée en urgence peut masquer un problème DNS, contourner l’intention FQDN et rendre le prochain incident plus difficile.

Valider une correction minimale

La correction doit être ciblée. Selon la cause, elle peut consister à activer ou rétablir le DNS proxy, corriger le resolver du subnet, ajouter un forwarder explicite, ajuster une UDR, corriger le FQDN exact ou repositionner une règle applicative.

yaml egress-change-guardrails.yml
before_change:
- capture_firewall_policy_and_dns_settings
- prove_runtime_resolver
- prove_effective_route_to_resolved_ip
- collect_application_and_firewall_logs

allowed_corrections:
- restore_dns_proxy_usage_for_subnet
- fix_forwarder_for_expected_domain
- add_exact_fqdn_application_rule
- adjust_rule_priority_with_evidence
- correct_udr_to_firewall_for_dependency_prefix

block_change_when:
- requested_rule_uses_wildcard_without_examples
- only_admin_workstation_test_passes
- rollback_state_is_missing
- firewall_logs_do_not_show_attempts_from_workload
- dependency_error_is_authentication_not_network

Après correction, rejoue le test depuis le workload et relis les logs. La validation doit montrer le FQDN attendu, la règle attendue, l’action Allow, puis un succès applicatif.

Décider : corriger, ouvrir, ou rollbacker

La décision doit rester simple. Ouvre une règle seulement si la résolution et le routage sont prouvés, et si le FQDN réellement appelé est connu. Corrige le chemin DNS ou UDR si les logs ne correspondent pas au modèle attendu. Rollbacke si le changement rend le chemin moins explicable.

text egress-decision.txt
Accept change
Workload uses the approved resolver or Firewall DNS proxy
Resolved IP uses the expected UDR toward Azure Firewall
Firewall logs show the target FQDN and the intended rule
Application probe succeeds without wildcard or broad IP exception
Monitoring shows no new deny or timeout burst

Fix before opening more
Resolver differs between runtime and diagnostic host
FQDN is absent from application rule logs
Network rule logs show raw IP flows instead of expected FQDN traffic
Rule priority or protocol does not match the real request

Rollback
DNS proxy change breaks another spoke
UDR change redirects unrelated traffic
Wildcard or IP exception was added without evidence
Application still fails after the targeted correction
Previous resolver, route or rule state is known and restorable

Le rollback n’est pas terminé quand la règle est supprimée. Il est terminé quand le resolver, la route effective, les logs Firewall et le test applicatif retrouvent l’état attendu.

Conclusion

Azure Firewall ne doit pas devenir une liste d’exceptions ajoutées sous pression. Quand l’egress échoue sur un FQDN, le runbook doit d’abord prouver le resolver utilisé, le chemin UDR, la visibilité du FQDN dans les logs et la règle réellement appliquée.

La bonne décision est rarement “ouvrir plus large”. Elle consiste à restaurer un chemin DNS cohérent avec le Firewall, autoriser le FQDN exact si nécessaire, valider depuis le runtime, puis garder un rollback clair. C’est ce qui permet d’exploiter l’egress Azure sans perdre l’explicabilité du réseau.