Réponses DNS REFUSED : ACL et politiques qui vous bloquent (et comment les corriger)

Cet article vous a aidé ?

REFUSED est l’équivalent DNS d’être prié de s’éloigner à la porte par quelqu’un qui tient un registre. Le paquet est arrivé. Le serveur a compris votre requête.
Il a simplement décidé que vous n’étiez pas invité.

Cela rend REFUSED à la fois plus simple et plus agaçant qu’un timeout : votre réseau fonctionne probablement, votre client aussi, et votre serveur refuse très volontairement
d’aider. L’astuce consiste à identifier quelle politique effectue le refus, et si elle est correcte.

Ce que REFUSED signifie vraiment (et ce que ce n’est pas)

En termes DNS, REFUSED est un RCODE (code de réponse) qui dit : « Je ne réponds pas à cette requête à cause d’une politique locale. »
Pas « je ne sais pas », pas « le nom n’existe pas », pas « je suis cassé ». Politique.

Les deux malentendus les plus fréquents :

  • REFUSED n’est pas NXDOMAIN. NXDOMAIN signifie que le serveur a fait le travail et a conclu que le nom n’existe pas.
    REFUSED signifie que le serveur n’essaie même pas (ou ne divulgue pas le résultat) pour vous.
  • REFUSED n’est pas SERVFAIL. SERVFAIL signifie « j’ai essayé, quelque chose a échoué. » REFUSED signifie « non, intentionnellement. »

Un bon modèle mental : REFUSED est le videur du serveur DNS qui fait respecter la liste des invités. Votre requête peut être parfaitement valide.
Vous pourriez même obtenir une réponse du même serveur si vous interrogez depuis une autre IP, sur une autre interface, en utilisant la bonne clé TSIG,
ou avec la récursion activée pour votre réseau.

Où vous le voyez

Vous verrez REFUSED dans des outils comme dig comme status: REFUSED, souvent avec une petite réponse et sans section answer.
Certains clients cachent cela derrière des messages vagues comme « server refused » ou « DNS name does not exist » (ce qui est erroné, merci).

Pourquoi vous devriez vous en préoccuper

REFUSED est généralement la sécurité qui fonctionne comme prévu : pas de résolveurs ouverts, pas de transferts de zone vers le monde, pas de récursion pour des réseaux aléatoires,
pas de fuite de données entre vues split-horizon. L’incident se produit quand cette politique bloque les mauvaises personnes, ou quand votre architecture dépend
d’un comportement (récursion, forward, transfert, update) qui n’a jamais été autorisé.

Une idée paraphrasée de Gene Kim (auteur opérations/fiabilité) : rendre le travail visible et réduire l’incertitude, car les files cachées et les surprises provoquent des pannes.
REFUSED est souvent une « politique cachée » devenue visible.

Faits intéressants et contexte historique

  • Les RCODEs sont anciens : les codes de réponse DNS datent des premiers travaux de conception DNS dans les années 1980, où le concept de « refus par politique » existait déjà.
  • Les résolveurs ouverts sont devenus un problème mondial : l’abus généralisé des résolveurs récursifs ouverts pour des attaques par réflexion/amplification a poussé les opérateurs
    à refuser la récursion par défaut pour les clients non fiables.
  • Les valeurs par défaut de BIND ont évolué : des configurations anciennes et des snippets copiés-collés peuvent laisser la récursion ouverte ou fermée de façon inattendue,
    selon la version et le packaging de la distribution.
  • Le split-horizon DNS précède le branding « zero trust » : servir des réponses différentes selon le client est une vieille astuce d’entreprise pour cacher des noms internes et diriger le trafic.
  • EDNS(0) a changé la donne : l’extension DNS pour supporter des réponses UDP plus grandes a exposé de nouveaux points de politique : tailles de buffer, basculement TCP, et filtrage
    des clients EDNS « bizarres ».
  • DNSSEC a complexifié les résolveurs : les échecs de validation DNSSEC apparaissent typiquement comme SERVFAIL, mais de nombreux environnements ajoutent des couches de politique (pare-feu, RPZ)
    qui transforment certaines requêtes en REFUSED volontairement.
  • RPZ a popularisé les réponses pilotées par politique : les Response Policy Zones permettent aux résolveurs de réécrire ou bloquer des réponses (NXDOMAIN, CNAME vers un jardin fermé, ou comportement similaire à REFUSED).
  • Anycast a rendu « même IP, politique différente » réel : avec anycast DNS, deux utilisateurs peuvent toucher des instances différentes avec des ACL différentes, rendant REFUSED intermittent.

Mode d’emploi pour un diagnostic rapide

Si vous ne retenez rien d’autre, retenez cet ordre. Il est optimisé pour les incidents réels : boucles courtes, signal élevé, devinettes minimales.

1) Confirmez ce qui refuse : quel serveur, quel chemin, quel protocole

  • Recevez-vous REFUSED du stub local (systemd-resolved), d’un résolveur d’entreprise, ou d’un serveur autoritaire ?
  • Est-ce UDP uniquement ? TCP uniquement ? Seulement via VPN ? Seulement sur un sous-réseau ?
  • Est-ce pour un nom, une zone ou tout ?

2) Comparez le comportement depuis deux IP sources

Même requête, réseaux clients différents. Si l’un fonctionne et l’autre reçoit REFUSED, il s’agit presque toujours d’une ACL, d’une vue, ou de « récursion autorisée pour A mais pas pour B ».

3) Déterminez si la récursion est impliquée

Interrogez un nom externe (comme quelque chose qui n’est pas dans vos zones) directement contre le serveur suspecté. S’il refuse cela mais répond aux noms internes,
vous regardez les contrôles de récursion ou des restrictions de forwarding.

4) Cherchez des moteurs de politique (RPZ, pare-feu DNS, vues, règles géo)

Si le refus est spécifique à un nom (certains domaines seulement), supposez une politique. S’il est spécifique au client (certains sous-réseaux seulement), supposez une ACL/vue/liaison d’interface.

5) Vérifiez les logs en dernier — mais vérifiez-les correctement

Les logs peuvent confirmer le chemin de décision, mais dans beaucoup d’environnements ils sont limités en débit, échantillonnés, ou présents seulement sur le nœud qui refuse dans une flotte anycast.
Utilisez les logs pour valider une hypothèse, pas pour en générer une.

Blague #1 : la politique DNS, c’est comme le café de bureau — tout le monde en dépend, personne n’en est propriétaire, et quand il est mauvais, la productivité s’effondre.

Où REFUSED est généré : résolveur vs autoritaire vs middleboxes

Résolveurs récursifs

Les résolveurs récursifs refusent les requêtes quand ils sont configurés pour le faire selon l’IP du client, l’interface ou le type de requête. Cas courants :

  • Récursion désactivée ou restreinte : le serveur répondra de façon autoritaire pour ses propres zones, mais refusera la récursion pour les externes.
  • ACL refuse le client : « access-control » (Unbound) ou « allow-query/allow-recursion » (BIND) bloque la source.
  • Zone de politique / pare-feu DNS : RPZ ou équivalent refuse (ou réécrit) selon le domaine.
  • Limitation de débit / contrôles d’abus : certaines piles refusent quand vous déclenchez des seuils.

Serveurs autoritaires

Les serveurs autoritaires refusent lorsque la requête est hors de leur périmètre, quand les vues restreignent qui peut interroger, ou lorsqu’une opération spéciale est tentée :

  • AXFR/IXFR refusés : les transferts de zone sont couramment refusés sans allow-transfer explicite et parfois sans TSIG.
  • Mise à jour dynamique refusée : les updates RFC2136 requièrent allow-update et généralement TSIG. Sinon : refus.
  • ACL de requête : certaines déploiements autoritaires restreignent qui peut interroger des zones internes.

Forwarders et « DNS au milieu »

REFUSED peut aussi provenir d’un forwarder (comme CoreDNS, dnsmasq, systemd-resolved, ou un proxy DNS cloud) qui applique des règles avant de forwarder,
ou renvoie un REFUSED reçu en amont.

Ensuite il y a les middleboxes : pare-feu qui inspectent le DNS, « passerelles de sécurité » qui répondent au nom du DNS, ou load balancers avec une logique de health-check.
Ils peuvent générer un comportement ressemblant à REFUSED qui semble être une décision DNS mais relève en réalité d’un équipement réseau.

Politiques qui vous bloquent : ACL, contrôles de récursion, RPZ, vues, TSIG, et compagnons

1) ACL client : « allow-query » et « allow-recursion » (BIND)

Dans BIND, les deux réglages que les gens confondent sont allow-query et allow-recursion. Ils ne sont pas interchangeables.

  • allow-query : qui peut poser des questions du tout (pour les zones servies, et parfois globalement).
  • allow-recursion : qui peut utiliser la récursion (récupérer des réponses ailleurs).

Un serveur peut être prêt à répondre de façon autoritaire pour corp.example mais refuser la récursion pour les noms internet. C’est normal et souhaitable.
Le problème survient quand on déploie « un résolveur pour tous » et qu’on oublie que la moitié des clients ne sont pas dans la liste de sous-réseaux autorisés.

2) Unbound access-control : trompeusement simple

Unbound tend à être plus clair : vous définissez des règles access-control par sous-réseau et action (allow/refuse/deny).
Mais « plus clair » ne veut pas dire « difficile à foirer ».

Si vous ajoutez une règle refuse large avant une allow plus spécifique (ou que vous comprenez mal la priorité des correspondances), vous pouvez verrouiller une région.
Et dans une flotte anycast, vous pouvez ne bloquer que les nœuds qui ont pris ce changement.

3) Vues et split-horizon : bonne idée, effets de bord nets

Les vues (BIND) ou constructions similaires permettent des réponses différentes selon l’adresse source. Elles sont parfaites pour :

  • enregistrements internes vs externes
  • zones privées accessibles uniquement via VPN
  • migrations cloud où vous orientez certains réseaux vers de nouveaux endpoints

Elles créent aussi un motif classique REFUSED : les clients tombent dans la « mauvaise vue » et reçoivent REFUSED parce que cette vue n’a pas de récursion,
pas d’accès à la zone, ou des ACL plus strictes.

4) RPZ / pare-feu DNS : quand le serveur refuse parce que le nom est « mauvais »

Beaucoup d’entreprises exécutent des Response Policy Zones ou des fonctionnalités de type pare-feu DNS. Selon la politique, un domaine bloqué peut donner :
NXDOMAIN, une IP de walled-garden, ou occasionnellement un comportement de type refus (ou un refus provenant d’un moteur de politique en amont).

Si REFUSED est spécifique à un domaine et cohérent entre clients, suspectez RPZ ou un résolveur de sécurité en amont. S’il est spécifique au domaine et incohérent,
suspectez plusieurs résolveurs avec des versions de politique différentes.

5) Transferts de zone (AXFR/IXFR) : le refus est la valeur par défaut

Si vous tentez un AXFR depuis une station de travail aléatoire et obtenez REFUSED : félicitations, quelqu’un a fait au moins une chose correctement.
Les transferts doivent être explicitement permis aux secondaires, souvent avec TSIG.

6) Mises à jour dynamiques : TSIG ou ça n’a pas eu lieu

Les mises à jour RFC2136 sont puissantes et dangereuses. Un refus ici est normalement dû à une clé manquante, une mauvaise clé, un mauvais algorithme, ou une mauvaise « update-policy ».

7) Liaison d’interface et surprises d’adresse source

Les ACL DNS sont évaluées par rapport à l’IP source. Dans NAT, VPN, Kubernetes et load balancers cloud, « l’IP source que vous pensez avoir »
n’est souvent pas l’IP source que le serveur DNS voit.

REFUSED apparaît après un changement réseau parce que l’ACL n’a pas suivi le changement.

8) DNS over TCP / EDNS / fragmentation : politique par accident

Certains environnements restreignent TCP/53, ou bloquent les grosses réponses UDP DNS. Quand un résolveur tente UDP, reçoit une troncature, retente en TCP, et que TCP est bloqué,
vous voyez habituellement des timeouts. Mais certains middleboxes et proxies répondent avec REFUSED ou un échec immédiat.

N’assumez pas que REFUSED est purement un « problème de config DNS ». Cela peut être « la sécurité réseau pense que DNS doit rester à 512 octets pour toujours ».

Tâches pratiques : commandes, sorties et décisions (12+)

Ce sont les tâches que j’exécute réellement pendant les incidents. Chacune inclut la commande, un extrait de sortie réaliste, ce que cela signifie, et la décision à prendre.
Utilisez-les comme script d’investigation répétable, pas comme rituel unique.

Tâche 1 : Reproduire avec dig et capturer clairement le RCODE

cr0x@server:~$ dig @10.20.30.40 www.example.com A +norecurse

; <<>> DiG 9.18.24 <<>> @10.20.30.40 www.example.com A +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 59821
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;www.example.com.                IN      A

;; Query time: 2 msec
;; SERVER: 10.20.30.40#53(10.20.30.40) (UDP)
;; WHEN: Tue Dec 31 11:02:18 UTC 2025
;; MSG SIZE  rcvd: 56

Ce que cela signifie : Le serveur DNS a répondu rapidement avec REFUSED. Le chemin réseau est correct.

Décision : Arrêtez de déboguer routage et pare-feu en premier. Commencez à examiner les ACLs/politiques sur ce serveur ou la couche devant lui.

Tâche 2 : Vérifier si la récursion est en cause (même requête avec récursion souhaitée)

cr0x@server:~$ dig @10.20.30.40 www.example.com A +recurse

;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 3452
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

Ce que cela signifie : Le refus intervient indépendamment du bit RD. Il s’agit probablement d’un « client non autorisé » plutôt que d’une « récursion non disponible ».

Décision : Validez les ACLs clients et les vues. Si vous attendiez des réponses autoritaires, confirmez que vous interrogez le bon serveur.

Tâche 3 : Vérifier que le serveur répond à d’autres (comparaison depuis un sous-réseau connu sain)

cr0x@server:~$ dig @10.20.30.40 www.example.com A +short
93.184.216.34

Ce que cela signifie : Depuis cet hôte, ça marche. Donc le serveur peut répondre ; le refus est spécifique au client ou au chemin.

Décision : Comparez les IP sources et le NAT. Identifiez quelle IP le serveur DNS voit pour le client en échec.

Tâche 4 : Confirmer quel résolveur votre client utilise réellement

cr0x@server:~$ resolvectl status
Global
         Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub
Current DNS Server: 127.0.0.53
       DNS Servers: 127.0.0.53

Ce que cela signifie : systemd-resolved est en jeu ; votre « serveur DNS » peut être un stub qui redirige ailleurs.

Décision : Interrogez le résolveur amont directement, pas seulement 127.0.0.53, ou inspectez les upstreams de resolved avec resolvectl dns.

Tâche 5 : Identifier les serveurs DNS amont configurés sur l’hôte (et surprises)

cr0x@server:~$ resolvectl dns
Global:
Link 2 (ens192): 10.20.30.40 10.20.30.41
Link 3 (tun0): 172.16.0.53

Ce que cela signifie : L’interface VPN fournit son propre résolveur. REFUSED peut n’arriver que lorsque le VPN est actif et que les priorités de route changent.

Décision : Retestez en ciblant chaque IP de résolveur directement. Décidez si les règles split-DNS sont mal appliquées.

Tâche 6 : Déterminer si vous touchez un serveur uniquement autoritaire

cr0x@server:~$ dig @10.20.30.40 corp.example SOA +norecurse

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11906
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; ANSWER SECTION:
corp.example.     3600    IN      SOA     ns1.corp.example. hostmaster.corp.example. 2025123101 7200 3600 1209600 3600

Ce que cela signifie : Le serveur est autoritatif pour corp.example (flag AA). Il peut refuser la récursion pour tout le reste par conception.

Décision : Si des clients utilisent cela comme résolveur général, corrigez l’architecture : pointez les clients vers des résolveurs récursifs, pas vers des serveurs auth-only.

Tâche 7 : Tester explicitement la disponibilité de la récursion avec une requête type root hint

cr0x@server:~$ dig @10.20.30.40 . NS +recurse

;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 41223
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

Ce que cela signifie : Ce serveur refuse la récursion (ou vous refuse). Interroger la racine devrait être possible depuis un résolveur récursif.

Décision : Vérifiez les paramètres recursion et les ACLs clients. Confirmez si ce serveur est censé effectuer la récursion pour votre IP source.

Tâche 8 : Vérifier la correspondance des vues BIND et les ACLs (côté serveur)

cr0x@server:~$ sudo named-checkconf -p | sed -n '1,120p'
options {
        directory "/var/cache/bind";
        recursion yes;
        allow-recursion { 10.20.0.0/16; 127.0.0.1; };
        allow-query-cache { 10.20.0.0/16; 127.0.0.1; };
};

view "internal" {
        match-clients { 10.20.0.0/16; };
        recursion yes;
};

view "external" {
        match-clients { any; };
        recursion no;
};

Ce que cela signifie : Les clients hors 10.20.0.0/16 tombent dans la vue « external » avec récursion désactivée ; ils peuvent voir REFUSED pour des recherches récursives.

Décision : Soit étendez match-clients pour inclure les réseaux voulus (VPN, plages NAT), soit assurez-vous que ces clients utilisent le résolveur approprié.

Tâche 9 : Vérifier les zones locales Unbound

cr0x@server:~$ sudo unbound-control list_local_zones
name type
. transparent
corp.example. transparent
blocked.example. static

Ce que cela signifie : Des zones locales et des politiques peuvent exister. Tous les refus ne sont pas des « ACL » ; certains sont de la « politique locale ».

Décision : Inspectez unbound.conf pour access-control: et les zones de politique ; confirmez le comportement attendu pour les domaines bloqués.

Tâche 10 : Inspecter rapidement les lignes access-control d’Unbound

cr0x@server:~$ sudo grep -nE '^(access-control|interface|do-tcp|do-udp)' /etc/unbound/unbound.conf
12:interface: 10.20.30.40
23:do-udp: yes
24:do-tcp: yes
41:access-control: 10.20.0.0/16 allow
42:access-control: 0.0.0.0/0 refuse

Ce que cela signifie : Le défaut est refuse pour tout le monde sauf 10.20.0.0/16. Si vos clients sont maintenant dans 10.21.0.0/16, ils sont bloqués.

Décision : Ajoutez le(s) nouveau(x) sous-réseau(x) en allow, ou corrigez le NAT pour que les clients apparaissent depuis une IP autorisée.

Tâche 11 : Vérifier si REFUSED est en fait « AXFR denied »

cr0x@server:~$ dig @10.20.30.53 corp.example AXFR

; Transfer failed.

Ce que cela signifie : Les transferts sont bloqués (comme ils devraient l’être par défaut). Certains serveurs renvoient REFUSED ; dig signale juste un échec.

Décision : Si vous configurez un secondaire : implémentez allow-transfer sur le primaire et TSIG entre eux. N’ouvrez pas « temporairement » vers n’importe qui.

Tâche 12 : Valider les permissions de transfert BIND (côté serveur)

cr0x@server:~$ sudo named-checkconf -p | grep -n 'allow-transfer' -n
248:        allow-transfer { key "xfr-tsig"; 10.20.30.54; };

Ce que cela signifie : Les transferts sont autorisés seulement pour 10.20.30.54 et seulement avec une clé TSIG. Si l’IP du secondaire a changé, il se verra refuser.

Décision : Mettez à jour la liste d’adresses autorisées et déployez correctement la clé TSIG. Traitez cela comme un changement contrôlé, pas comme un bricolage d’urgence.

Tâche 13 : Vérifier le refus de mise à jour dynamique dû à l’absence de TSIG

cr0x@server:~$ nsupdate -v <<'EOF'
server 10.20.30.53
zone corp.example
update add test01.corp.example 60 A 10.20.40.10
send
EOF
update failed: REFUSED

Ce que cela signifie : Le serveur refuse les mises à jour sans authentification appropriée. Bien.

Décision : Utilisez TSIG et update-policy. Si cela devait fonctionner, le client n’utilise pas la bonne clé ou vous touchez la mauvaise vue.

Tâche 14 : Consulter les logs du serveur pour une raison explicite « denied » (exemple BIND)

cr0x@server:~$ sudo journalctl -u bind9 -n 20 --no-pager
Dec 31 11:02:18 ns1 named[1442]: client @0x7f9a64012a00 10.21.5.18#43812 (www.example.com): query (cache) 'www.example.com/A/IN' denied
Dec 31 11:02:18 ns1 named[1442]: client @0x7f9a64012a00 10.21.5.18#43812 (www.example.com): query failed (REFUSED) for www.example.com/IN/A at query.c:7750

Ce que cela signifie : Le serveur a explicitement refusé une requête cache (récursive) depuis 10.21.5.18.

Décision : Ajoutez 10.21.0.0/16 à allow-recursion / allow-query-cache (ou orientez ces clients vers le résolveur correct).

Tâche 15 : Prouver la discordance NAT/IP source (capture au serveur)

cr0x@server:~$ sudo tcpdump -ni any port 53 and host 10.21.5.18 -c 3
tcpdump: data link type LINUX_SLL2
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
11:02:18.412345 ens192 In  IP 192.0.2.45.53512 > 10.20.30.40.53: 59821+ A? www.example.com. (32)
11:02:18.412912 ens192 Out IP 10.20.30.40.53 > 192.0.2.45.53512: 59821 Refused 0/0/1 (56)

Ce que cela signifie : Le « client » 10.21.5.18 est en réalité NATé en 192.0.2.45 du point de vue du serveur DNS.

Décision : Corrigez les ACLs pour inclure la plage de sortie NAT, ou ajustez le routage pour préserver l’IP client d’origine (si possible).

Tâche 16 : Vérifier si un forwarder renvoie REFUSED depuis l’amont

cr0x@server:~$ dig @10.20.30.10 www.example.com A +comments

;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 51001
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

Ce que cela signifie : Le forwarder indique que la récursion est disponible (RA), mais refuse quand même. Cela pointe souvent vers une politique (RPZ/sécurité) ou un refus en amont.

Décision : Interrogez l’amont du forwarder (si connu) ou vérifiez la configuration du forwarder pour des blocages de domaine et des ACLs.

Trois mini-récits d’entreprise tirés du terrain

Mini-récit 1 : La panne causée par une fausse supposition

Une entreprise de taille moyenne exploitait deux serveurs BIND par datacenter. Ils étaient étiquetés « DNS1/DNS2 » dans l’inventaire et tout le monde les traitait comme interchangeables.
Une paire était autoritaire pour des zones internes et faisait aussi de la récursion pour les clients. L’autre paire était uniquement autoritaire pour plusieurs zones déléguées utilisées
par une plateforme legacy.

Lors d’un rafraîchissement réseau, une équipe a mis à jour les scopes DHCP et a accidentellement pointé un grand sous-réseau de bureau vers la paire auth-only.
Les symptômes étaient étrangement sélectifs : les noms internes dans corp.example résolvaient correctement, car les serveurs auth étaient autoritatifs.
Tout le reste — connexions SaaS, dépôts de paquets, APIs externes — a commencé à retourner REFUSED.

Les premiers intervenants ont poursuivi pare-feu et liens ISP. Ils ont vu « REFUSED » et l’ont interprété comme « le DNS distant nous bloque ».
Pendant ce temps, les serveurs DNS faisaient exactement ce pour quoi ils avaient été conçus : « Je suis autoritatif pour ces zones ; je ne suis pas votre résolveur récursif. »

La correction fut ennuyeuse : corriger les options DHCP et ajouter une surveillance qui vérifie la récursion sur le VIP du résolveur, pas seulement « le port 53 est ouvert ».
La leçon fut plus nette : ne nommez pas des serveurs par ambiguïté de rôle. « DNS1 » n’est pas un rôle ; c’est une confession.

Mini-récit 2 : L’optimisation qui s’est retournée contre eux

Une autre organisation voulait réduire la charge des résolveurs. Quelqu’un a proposé une approche « intelligente » : router des bureaux distants vers un forwarder régional,
puis vers des résolveurs centraux. Ça avait l’air propre sur les diagrammes : moins d’aller-retour, plus de cache à la périphérie.

Ils ont déployé un forwarder dnsmasq sur les routeurs de succursale avec un cache local agressif et une ACL minimale : autoriser seulement le sous-réseau de la succursale.
Puis un déploiement VPN a eu lieu. Les portables distants entraient dans le réseau de la succursale via un tunnel, mais leurs IP sources provenaient d’un pool différent.
Le dnsmasq du routeur voyait une « source inconnue » et renvoyait REFUSED immédiatement.

L’incident fut pénible car il était intermittent : certains utilisateurs étaient sur Wi‑Fi (NATés dans l’espace autorisé), d’autres sur filaire (non NATés),
d’autres encore distants (tunnelés). Même portable, résultat différent selon l’heure.

Ils ont corrigé en retirant le cache et la politique du routeur : les clients de succursale utilisaient les résolveurs centraux directement via le VPN,
et le routeur ne fournissait plus que le DHCP. L’optimisation n’était pas mauvaise en soi ; elle avait juste déplacé l’application de la politique vers l’endroit le plus fragile du système.

Mini-récit 3 : La pratique ennuyeuse et correcte qui a sauvé la mise

Une entreprise globale exploitait des résolveurs récursifs anycast avec des ACL strictes et RPZ. Ils avaient aussi une habitude qui semblait bureaucratique :
chaque changement de politique de résolveur exigeait une sortie « policy diff » jointe à la demande de changement, plus un déploiement canari sur un site.

Un jour, un ingénieur a mis à jour les plages clients autorisées pour inclure un nouveau VPC cloud. Le changement était correct en intention mais erroné sur un détail :
ils ont ajouté le CIDR du VPC dans un fichier d’environnement mais pas dans la ACL générée pour la production.

Le site canari a immédiatement montré REFUSED pour des clients dans ce VPC. Le runbook incluait une vérification spécifique : lancer une requête depuis une instance dans le VPC,
confirmer qu’elle atteint le nœud canari, et confirmer status: NOERROR pour la récursion.
L’ingénieur a détecté la discordance avant le déploiement en flotte.

Pas de drame. Aucun appel d’escalade exécutif. Juste un changement reverti et re-fait avec la génération correcte. L’ennuyeux a encore gagné.

Erreurs fréquentes : symptôme → cause racine → correction

Cette section est volontairement spécifique. Les conseils génériques provoquent des pannes génériques.

1) Symptom : REFUSED pour des noms externes, les noms internes fonctionnent

  • Cause racine : le client utilise un serveur auth-only ; récursion désactivée ; ou le client tombe dans une vue sans récursion.
  • Correction : pointez les clients vers des résolveurs récursifs ; ou activez la récursion pour la vue appropriée et définissez allow-recursion correctement.

2) Symptom : REFUSED uniquement pour les utilisateurs VPN

  • Cause racine : les ACLs n’incluent pas le pool VPN ; split-DNS mal configuré ; le VPN pousse un résolveur différent avec une politique plus stricte.
  • Correction : incluez le CIDR VPN dans allow-recursion/access-control ; assurez-vous que les clients VPN utilisent le résolveur prévu ; validez le comportement NAT.

3) Symptom : REFUSED seulement pour un domaine (ou une catégorie de domaines)

  • Cause racine : politique RPZ/pare-feu DNS ; résolveur de sécurité en amont ; domaine placé en blocage local-zone static.
  • Correction : confirmez l’intention de la politique ; ajoutez une exception ; déployez la politique de façon cohérente sur les résolveurs ; documentez qui possède la décision.

4) Symptom : REFUSED après avoir placé les résolveurs derrière un load balancer

  • Cause racine : changement d’IP source (SNAT), donc les ACLs ne correspondent plus ; les health-checks viennent d’une plage non fiable et se voient refuser.
  • Correction : préservez l’IP source si possible ; sinon ajoutez les plages egress du LB aux ACLs ; définissez un allow explicite pour les sources de health-check.

5) Symptom : AXFR/IXFR échoue avec « Transfer failed » ou REFUSED

  • Cause racine : manque d’allow-transfer ; IP du secondaire modifiée ; TSIG mismatch ; mismatch de vue (le secondaire touche la mauvaise vue).
  • Correction : ajoutez allow-transfer pour les IP correctes ; utilisez TSIG ; vérifiez que les deux côtés s’accordent sur le nom/algorithme de clé ; assurez-vous que match-clients inclut le secondaire.

6) Symptom : Mises à jour dynamiques retournent REFUSED

  • Cause racine : nsupdate sans TSIG ; update-policy n’autorise pas le nom ; le serveur n’est pas le primaire pour la zone ; mauvaise vue.
  • Correction : configurez TSIG côté client ; ajustez update-policy avec le principe du moindre privilège ; envoyez les updates au primaire ; validez la sélection de vue.

7) Symptom : Certains sites anycast refusent ; d’autres répondent

  • Cause racine : configuration/politique incohérente ; ACLs locales au site ; forwarders amont différents ; réplication RPZ incomplète.
  • Correction : imposez la convergence de config ; ajoutez des tests smoke par site ; identifiez quel nœud a servi la requête via CHAOS TXT ou tagging d’instance.

8) Symptom : Pics de REFUSED seulement sous charge

  • Cause racine : limitation de débit configurée pour refuser ; détection d’abus ; l’amont vous refuse à cause du comportement de votre résolveur (trop de clients derrière un NAT).
  • Correction : ajustez le rate limiting ; corrigez le fan-in NAT ; ajoutez plus d’IP d’egress ; vérifiez que vous ne ressemblez pas accidentellement à un botnet.

Blague #2 : Si vous « autorisez temporairement » la récursion pour any, Internet enverra immédiatement sa confirmation.

Listes de contrôle / plan étape par étape

Étape par étape : isoler la couche qui refuse

  1. Interrogez avec dig contre le résolveur configuré. Notez l’IP du serveur, le status, les flags, UDP/TCP.
  2. Contournez le stub. Si systemd-resolved est utilisé, interrogez les résolveurs amont réels directement.
  3. Interrogez le même nom depuis deux réseaux. LAN de bureau vs VPN, ou un pod vs une VM. Notez les différences.
  4. Interrogez une zone autoritaire attendue. Confirmez l’apparition du flag AA là où prévu ; confirmez le rôle correct du serveur.
  5. Vérifiez explicitement la récursion. Interrogez la racine ou un domaine clairement externe avec +recurse.
  6. Consultez les logs serveur pour « denied/refused ». Confirmez l’IP source que le serveur voit.
  7. Validez NAT et routage. Capture de paquets sur le serveur si nécessaire pour révéler la vraie adresse client.
  8. Identifiez les couches de politique. RPZ, vues, pare-feu DNS en amont, chaînes de forwarding.
  9. Corrigez avec le principe du moindre privilège. Étendez précisément les ACLs ; évitez d’ouvrir la récursion à des plages larges.
  10. Test de régression. Testez depuis un ensemble représentatif de clients. Ensuite surveillez l’exposition aux résolveurs ouverts.

Checklist : changements sûrs qui réduisent les incidents REFUSED sans affaiblir la sécurité

  • Définissez des rôles de résolveur explicites : recursive-only, authoritative-only, ou mixte (et documentez-les).
  • Maintenez un inventaire des CIDR clients autorisés à la récursion ; mettez-le à jour lors des changements réseau.
  • Pour VPN et cloud : décidez si l’IP source est préservée ou NATée ; écrivez les ACLs en fonction de la réalité.
  • Pour anycast : imposez la convergence de config et incluez un indicateur de « version de politique » par nœud.
  • Pour RPZ : établissez un processus d’exception et un propriétaire clair pour les règles de politique.
  • Surveillez les augmentations de taux de REFUSED, et segmentez par sous-réseau client et type de requête.
  • Testez AXFR/IXFR et les updates depuis les secondaires/automations après chaque changement DNS.

Checklist : ce qu’il ne faut pas faire (à moins d’aimer les pagers)

  • N’activez pas la récursion pour any pour « faire marcher les choses ». C’est ainsi qu’on devient un résolveur ouvert victime d’incidents.
  • N’appliquez pas de politique sur les routeurs de succursale à moins de pouvoir les mettre à jour et auditer comme la production.
  • N’assumez pas que « l’IP client » est celle que le serveur voit ; vérifiez avec les logs ou tcpdump.
  • Ne mélangez pas autoritatif et récursif sans précautions ; si vous le faites, documentez l’intention et appliquez des vues.

FAQ

1) Quelle est la différence entre REFUSED et NXDOMAIN ?

NXDOMAIN signifie que le serveur a répondu et que le nom n’existe pas dans l’espace de noms qu’il a vérifié. REFUSED signifie que le serveur a décliné la réponse en raison d’une politique.

2) Un serveur autoritaire peut-il renvoyer REFUSED pour des requêtes normales ?

Oui. Les serveurs autoritaires peuvent restreindre qui peut interroger certaines zones (internes seulement), et refusent couramment les AXFR/IXFR et les mises à jour dynamiques sans autorisation.

3) Pourquoi je reçois REFUSED seulement depuis certains sous-réseaux ?

C’est presque toujours un problème d’ACL ou de correspondance de vue. Soit ces sous-réseaux ne sont pas inclus dans allow-recursion/access-control, soit ils tombent dans une vue avec récursion désactivée.
Le NAT peut rendre cela aléatoire si l’IP source apparente change selon le chemin.

4) Pourquoi dig affiche « ra » (recursion available) mais le statut est REFUSED ?

« RA » est un flag de capacité ; il ne signifie pas que la récursion vous est permise. Beaucoup de résolveurs sont capables de récursion mais la refusent aux clients non autorisés.
Certains forwarders transmettent RA tout en appliquant leur propre politique.

5) REFUSED est-il toujours une mauvaise configuration ?

Non. REFUSED est fréquemment une posture de sécurité correcte : refuser la récursion vers Internet, refuser des transferts de zone largement, refuser des updates non signées.
Cela devient un problème quand la politique et les utilisateurs prévus divergent.

6) Comment RPZ et les pare-feu DNS se rapportent à REFUSED ?

RPZ est un mécanisme de politique qui peut bloquer ou réécrire les réponses DNS en fonction du nom ou de la réponse. Selon l’implémentation et le choix de politique,
les clients peuvent voir NXDOMAIN, un enregistrement de walled-garden, ou un refus propagé depuis un résolveur de politique en amont.

7) Pourquoi les pods Kubernetes voient parfois REFUSED alors que les nœuds ne le voient pas ?

Les pods interrogent souvent CoreDNS, qui forwarde vers des résolveurs amont. L’amont peut voir l’IP du nœud, une IP NAT, ou une IP de gateway NAT cloud.
Si les ACLs de récursion n’incluent pas cette IP apparente, vous obtenez REFUSED. Une autre cause : les plugins de politique de CoreDNS ou les configurations stub-domain.

8) Quelle est la façon la plus sûre de « corriger » REFUSED pour des clients légitimes ?

Identifiez la plage d’IP source exacte telle que le serveur qui refuse la voit, puis ajoutez la règle allow la plus restrictive nécessaire (allow-recursion/access-control),
idéalement dans la vue correcte. Validez que vous n’avez pas créé un résolveur ouvert. Testez depuis plusieurs réseaux.

9) DNSSEC peut-il provoquer REFUSED ?

Les échecs de validation DNSSEC mènent typiquement à SERVFAIL, pas REFUSED. Mais des couches de politique autour de DNSSEC (résolveurs de sécurité, pare-feu DNS) peuvent décider de refuser
certains comportements ou clients. Traitez DNSSEC comme un facteur complicateur, pas comme le coupable par défaut pour REFUSED.

10) Faut-il renvoyer REFUSED ou laisser tomber les paquets pour des clients bloqués ?

Renvoyer REFUSED est plus opérationnellement sympathique : les clients échouent vite et vous pouvez le diagnostiquer. Laisser tomber les paquets peut ressembler à une panne réseau.
Si vous bloquez du trafic abusif à grande échelle, les drops peuvent être appropriés, mais pour l’application de politique interne, REFUSED réduit habituellement le temps d’incident.

Conclusion : prochaines étapes pour réduire réellement les incidents

REFUSED n’est pas un code mystérieux. C’est une décision de politique, et le DNS est plein de politiques : qui peut récursiver, qui peut transférer, qui peut mettre à jour,
quels noms sont bloqués, quels clients reçoivent quelle vue. Quand REFUSED vous mord, c’est généralement parce que la réalité réseau a évolué plus vite que votre politique DNS.

Faites ces prochaines étapes :

  1. Cartographiez les rôles des résolveurs (récursif vs autoritatif) et cessez de pointer les clients sur le mauvais serveur.
  2. Inventoriez les plages sources clients autorisées telles que vues par le résolveur (incluant NAT et pools VPN).
  3. Ajoutez un test de régression qui exécute dig depuis chaque environnement client majeur et alerte sur les pics de REFUSED.
  4. Traitez la politique comme du code : configs diffables, déploiement canari, et propriétaire clair des règles RPZ/pare-feu DNS.

L’objectif n’est pas d’éliminer REFUSED. L’objectif est de rendre les refus intentionnels, documentés et prévisibles — afin que la seule chose bloquée soit le trafic malveillant,
et non votre activité.

← Précédent
systemd « Dépendance échouée » : Trouver le service qui bloque le démarrage
Suivant →
Courriel : Brute force sur IMAP/SMTP — sécurisez sans vous verrouiller

Laisser un commentaire