Aller au contenu

Listeners DNS

DNS C2 utilise les requêtes et réponses DNS comme canal de données secret. Le trafic DNS est rarement bloqué par les pare-feu et est souvent négligé par la surveillance du réseau, ce qui en fait un transport de sauvegarde idéal pour les environnements restrictifs. Le compromis est une bande passante très faible par rapport à HTTP/HTTPS : le DNS est le mieux adapté à la persistance à long terme, au transfert initial et aux environnements dans lesquels la sortie HTTP est bloquée.


Architecture

DNS C2 encode les données des beacons dans les étiquettes de sous-domaines DNS et décode les réponses du serveur à partir des enregistrements DNS. Le relais exécute un serveur DNS qui traite ces requêtes et s'interface avec le même registre de beacons et la même file d'attente de tâches utilisés par les listeners HTTP.

sequenceDiagram
    participant Implant as Implant (Windows)
    participant DNS as DNS Server (Relay)
    participant C2 as C2 Handler (Relay)
    participant Backend as Backend API Server

    Implant->>DNS: DNS query (beacon.c2.example.com)
    DNS->>C2: Decode query, register beacon
    C2->>Backend: WebSocket event (beacon check-in)
    Backend-->>C2: WebSocket command (task queue)
    C2-->>DNS: Encode response
    DNS-->>Implant: A/AAAA/TXT record response

Le serveur DNS partage le registre des beacons et la file d'attente des tâches avec tous les listeners HTTP/HTTPS sur le même relais, de sorte que les beacons peuvent être gérées via une interface unifiée quel que soit leur transport.


Configuration de l'infrastructure DNS

Avant de créer un listener DNS, vous avez besoin d'un domaine avec des enregistrements DNS pointant vers le relais.

Exigences

  1. Un domaine que vous contrôlez (ou un sous-domaine qui vous est délégué)
  2. Un enregistrement NS pointant le sous-domaine C2 vers l'IP publique du relais
  3. Règles de pare-feu autorisant le port UDP entrant 53 vers le relais

Configuration des zones étape par étape

1. Choisissez un domaine C2

Utilisez un sous-domaine dédié au trafic C2. Évitez d'utiliser le domaine racine puisque la délégation NS s'applique à l'ensemble de la zone.

c2.example.com

2. Créer un enregistrement NS

Chez votre registraire DNS ou éditeur de zone, créez un enregistrement NS qui délègue le sous-domaine C2 à l'IP publique du relais :

c2.example.com.    IN    NS    ns1.example.com.
ns1.example.com.   IN    A     <RELAY_PUBLIC_IP>

3. Vérifier la délégation

dig NS c2.example.com

La section de réponse doit montrer votre enregistrement NS pointant vers l'adresse IP du relais.

Propagation DNS

Les modifications DNS peuvent prendre jusqu'à 48 heures pour se propager à l'échelle mondiale. En pratique, la plupart des changements prennent effet dans un délai de 15 à 30 minutes. Utilisez dig avec un résolveur spécifique pour vérifier la propagation : dig @8.8.8.8 NS c2.example.com.

Environnements de laboratoire

Pour les tests en laboratoire, vous n'avez pas besoin de DNS public. Configurez le résolveur DNS de l'implant pour qu'il pointe directement vers l'adresse IP du relais ou utilisez un serveur DNS local (par exemple, dnsmasq) pour résoudre le domaine C2. Définissez le champ dns_resolver sur le listener pour contourner entièrement le résolveur système.


Création d'un listener DNS

Les listeners DNS utilisent la même API que les listeners HTTP mais nécessitent des champs spécifiques au DNS.

curl -s -X POST https://stentor.app/api/v1/listeners \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "DNS Covert",
    "relay_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "type": "dns",
    "port": 53,
    "dns_domain": "c2.example.com",
    "dns_ttl": 60,
    "dns_idle": "0.0.0.0",
    "dns_max_txt": 252
  }' | jq

Ensuite, démarrez le listener :

curl -s -X POST https://stentor.app/api/v1/listeners/$LISTENER_ID/start \
  -H "Authorization: Bearer $TOKEN" | jq '.status'

Le port 53 nécessite root

Le port UDP 53 est un port privilégié. Le processus de relais doit s'exécuter en tant qu'utilisateur root (ou disposer de CAP_NET_BIND_SERVICE) pour se lier au port 53. Pour les tests non root, utilisez le port 5353 et configurez le résolveur de l'implant en conséquence.


Options de configuration

Le tableau ci-dessous répertorie tous les champs pertinents pour les listeners DNS.

Champ Type Par défaut Description
name chaîne -- Obligatoire. Nom d'affichage du listener.
type chaîne -- Obligatoire. Doit être "dns".
relay_id chaîne -- Obligatoire. UUID du relais hébergeant cet listener.
port int 53 Obligatoire. Port UDP pour le serveur DNS.
dns_domain chaîne -- Obligatoire. Suffixe de domaine C2 (par exemple, "c2.example.com"). Toutes les requêtes doivent être des sous-domaines de ce domaine.
dns_ttl int 60 Durée de vie des réponses DNS en secondes. Des valeurs inférieures signifient une livraison plus rapide des tâches mais plus de trafic DNS.
dns_idle chaîne "0.0.0.0" Adresse IP renvoyée lorsque le beacon n'a aucune tâche en attente. La réponse au repos indique à l'implant « rien à faire ».
dns_max_txt int 252 Longueur maximale des données d'enregistrement TXT par réponse en octets. Des valeurs plus élevées augmentent la bande passante mais peuvent être divisées par les résolveurs.
dns_resolver chaîne null Adresse du résolveur DNS personnalisé (par exemple, "8.8.8.8:53"). Remplace le résolveur système pour les requêtes DNS de beacon. Voir Remplacement du résolveur DNS.
guardrails JSON null Règles de filtrage des beacons. Même schéma que les listeners HTTP -- voir la section HTTP/HTTPS Guardrails.

Modes de canal de données

Stentor DNS C2 prend en charge trois modes de canal de données qui contrôlent le type d'enregistrement DNS utilisé pour la communication serveur-beacon. Chaque mode offre des compromis différents en matière de bande passante et de furtivité.

Comparaison des modes

Mode Type d'enregistrement Bande passante Furtif Compatibilité
dns Un (IPv4) ~4 octets/réponse Élevé Universel
dns6 AAAA (IPv6) ~16 octets/réponse Moyen La plupart des réseaux
dns-txt TXT ~252 octets/réponse Inférieur Peut être connecté

DNS (enregistrements A) - par défaut

Le mode par défaut encode les données de beacon dans les étiquettes de sous-domaines DNS et renvoie les données du serveur dans les enregistrements A (adresses IPv4). Chaque enregistrement A contient 4 octets de données.

  • Bande passante : La plus basse (~ 4 octets par réponse)
  • Furtif : Le plus élevé : les requêtes d'enregistrement A sont le type de requête DNS le plus courant.
  • Compatibilité : Universel – fonctionne sur tous les réseaux autorisant le DNS

dns6 (enregistrements AAAA)

Même encodage que le mode dns mais utilise des enregistrements AAAA (adresses IPv6). Chaque enregistrement AAAA contient 16 octets de données, soit quatre fois la bande passante des enregistrements A.

  • Bande passante : Moyenne (~ 16 octets par réponse)
  • Furtif : Moyen : les requêtes AAAA sont courantes sur les réseaux modernes, mais moins que les requêtes A.
  • Compatibilité : La plupart des réseaux : certains réseaux existants ou proxys restrictifs peuvent filtrer les requêtes AAAA.

dns-txt (enregistrements TXT)

Utilise les enregistrements TXT pour les réponses du serveur, offrant ainsi la bande passante la plus élevée. La configuration dns_max_txt contrôle la longueur maximale de l'enregistrement TXT (252 octets par défaut).

  • Bande passante : La plus élevée (~ 252 octets par réponse)
  • Furtif : Inférieur : les réponses aux enregistrements TXT volumineux sont plus visibles pour la surveillance DNS
  • Compatibilité : Large – mais certains proxys DNS d'entreprise enregistrent ou inspectent les enregistrements TXT.

Changement de mode au moment de l'exécution

Les opérateurs peuvent changer le mode du canal de données pour un beacon en direct via la console de beacon :

mode dns       # Switch to A record mode (default)
mode dns6      # Switch to AAAA record mode
mode dns-txt   # Switch to TXT record mode

Commencez bas, augmentez

Commencez par dns (enregistrements A) pour l'enregistrement et la préparation initiaux. Une fois le beacon établie et que vous avez besoin de plus de bande passante (par exemple pour télécharger des fichiers), passez en mode dns-txt. Revenez à dns lorsque vous êtes inactif pour minimiser le risque de détection.


Pipeline de taches DNS

Cette section documente le flux complet des taches backend -- de l'enregistrement initial du beacon jusqu'a la livraison des taches et la soumission des resultats. Comprendre ce pipeline est essentiel pour depanner les communications DNS C2 et configurer le routage des beacons enfants P2P.

Flux d'enregistrement du beacon

Lorsqu'un implant se connecte (ou se reconnecte) via DNS, il initie un enregistrement en envoyant une requete TXT avec une charge utile JSON encodee en Base32 dans les etiquettes de sous-domaines. Le gestionnaire DNS du relais (handleBeaconCheckin) traite cela comme suit :

  1. Decodage de la requete : Le gestionnaire joint les etiquettes de sous-domaines et les decode en Base32 pour obtenir un JSON CheckinRequest contenant : hostname, username, ip, os, arch, pid et beacon_id
  2. Evaluation des guardrails : Si des guardrails sont configures sur le listener, le gestionnaire evalue l'IP, le hostname et le username du beacon par rapport aux regles. Les beacons non conformes recoivent RCODE_REFUSED et un evenement guardrail_violation est envoye via WebSocket
  3. Premier enregistrement (beacon_id vide) : Le gestionnaire cree un nouveau beacon via le BeaconRegistry partage et declenche un evenement WebSocket beacon_new vers le serveur backend
  4. Enregistrement subsequent (beacon_id existant) : Le gestionnaire met a jour l'enregistrement du beacon existant. Si le beacon a ete supprime lors du nettoyage des beacons inactifs, il est re-enregistre. Un evenement WebSocket beacon_checkin est declenche
  5. Reponse : Le gestionnaire renvoie une reponse JSON encodee en Base32 sous forme d'enregistrement TXT contenant beacon_id, l'intervalle sleep et le pourcentage de jitter
sequenceDiagram
    participant Implant as Implant (Windows)
    participant DNS as DNS Server (Relay)
    participant Registry as BeaconRegistry
    participant Backend as Backend API Server

    Implant->>DNS: TXT query (beacon.{base32_checkin}.c2.example.com)
    DNS->>DNS: Base32-decode + JSON parse CheckinRequest
    DNS->>DNS: Evaluate guardrails (if configured)
    DNS->>Registry: Register or update beacon
    DNS->>Backend: WebSocket event (beacon_new / beacon_checkin)
    DNS->>Implant: TXT response (Base32 JSON: {beacon_id, sleep, jitter})

Registre partage

Le BeaconRegistry est partage entre les listeners DNS et HTTP/HTTPS sur le meme relais. Un beacon qui s'enregistre via DNS est visible par tous les listeners, et les taches mises en file d'attente par n'importe quel listener peuvent etre livrees via n'importe quel transport.

Flux de livraison des taches

Apres l'enregistrement, le beacon interroge periodiquement pour obtenir des taches. Le gestionnaire DNS prend en charge trois modes d'interrogation selon le type d'enregistrement DNS utilise :

Mode TXT (handleTaskPoll) : Le beacon envoie une requete TXT avec son identifiant de beacon encode en Base32. Le gestionnaire traite cela via un depilement a deux niveaux :

  1. Decodage de l'identifiant du beacon : Decodage Base32 des etiquettes de sous-domaines et analyse de l'UUID
  2. Validation du beacon : Confirmation de l'existence du beacon dans le registre et mise a jour de son horodatage de battement de coeur
  3. Verification de la file d'attente locale : Depilement de la prochaine tache depuis la TaskQueue locale (partagee avec les listeners HTTP)
  4. Basculement vers le proxy backend : Si la file d'attente locale est vide ET qu'un proxy backend est configure, le gestionnaire appelle GET /api/v1/c2/task?beacon_id={id} sur le serveur backend pour depiler les taches mises en file d'attente cote serveur
  5. Reponse : Tache complete en JSON encode en Base32 contenant task_id, type, data encode en base64 et le champ optionnel relay_for
  6. Statut de la tache : La tache depilee est marquee comme dispatched

Mode A (handleTaskPollA) : Renvoie 4 octets de donnees de tache encodes sous forme d'adresse IPv4. Lorsqu'aucune tache n'est en attente, le gestionnaire renvoie l'IP dns_idle (par defaut 0.0.0.0).

Mode AAAA (handleTaskPollAAAA) : Renvoie 16 octets de donnees de tache encodes sous forme d'adresse IPv6. Lorsqu'aucune tache n'est en attente, le gestionnaire renvoie :: (IPv6 tout-zeros).

sequenceDiagram
    participant Beacon as Beacon
    participant DNS as DNS Handler
    participant Queue as TaskQueue (Local)
    participant Backend as Backend API

    Beacon->>DNS: TXT/A/AAAA query ({base32_beacon_id}.c2.example.com)
    DNS->>Queue: Dequeue(beacon_id)
    alt Task in local queue
        Queue-->>DNS: Task
    else Local queue empty
        DNS->>Backend: GET /api/v1/c2/task?beacon_id={id}
        Backend-->>DNS: Task (with optional relay_for)
    end
    DNS->>Beacon: Response (task data or idle)

Configuration du proxy backend

Le proxy backend est active en appelant SetBackendProxy(backendURL, relaySecret) sur le gestionnaire DNS. Ceci est necessaire pour que les taches mises en file d'attente cote serveur atteignent les beacons DNS -- sans cela, seules les taches mises en file d'attente directement dans la file locale du relais sont livrees.

Agregation P2P via le beacon DNS parent

Lorsqu'un beacon enfant P2P (par exemple, un beacon SMB ou TCP bind) n'a pas de canal C2 direct, il s'appuie sur son beacon parent pour relayer les taches. Le mecanisme de proxy backend du gestionnaire DNS permet cela via le champ relay_for :

  1. Un operateur met en file d'attente une tache pour un beacon enfant P2P sur le serveur
  2. Le beacon DNS parent interroge le backend via proxyTaskPollToBackend()
  3. Le backend renvoie la tache avec le champ relay_for defini sur l'identifiant du beacon enfant
  4. Le gestionnaire DNS inclut relay_for dans la reponse TXT de tache au beacon parent
  5. Le beacon parent reconnait le champ relay_for et relaie la tache vers l'enfant via son lien P2P (pipe nomme SMB, socket TCP bind)
  6. Le beacon enfant execute la tache et renvoie le resultat via le parent
  7. Le parent transmet le resultat au serveur
sequenceDiagram
    participant Server as Backend Server
    participant DNS as DNS Parent Beacon
    participant SMB as SMB Child Beacon

    Server->>DNS: Task poll response (relay_for=child_id)
    DNS->>SMB: Relay task over P2P link (named pipe / TCP)
    SMB->>SMB: Execute task
    SMB->>DNS: Return task result over P2P link
    DNS->>Server: Forward result (task_complete event)

Le beacon parent doit etre actif

Les taches des beacons enfants P2P ne sont livrees que lorsque le beacon parent interroge activement. Si le beacon DNS parent se deconnecte ou si son intervalle de veille est trop long, les taches enfants s'accumulent sur le serveur jusqu'a ce que le parent reprenne l'interrogation.

Fragmentation des resultats volumineux

Les resultats de taches qui depassent les limites de taille des etiquettes DNS sont divises en fragments et soumis via plusieurs requetes DNS. Les fonctions handleResultSubmission() et processCompleteResult() du gestionnaire gerent ce processus :

  1. L'implant divise le resultat de la tache en fragments qui tiennent dans les etiquettes de sous-domaines DNS
  2. Chaque fragment est envoye sous forme de requete d'enregistrement A avec le format d'etiquette suivant :
{base32_chunk_data}.{chunk_index}.{total_chunks}.{task_id}.result.c2.example.com
  1. Le gestionnaire stocke chaque fragment dans une map resultChunks indexee par task_id
  2. Chaque fragment est acquitte avec une reponse d'enregistrement A : 1.0.0.{chunk_index} (succes) ou 1.0.0.255 (erreur)
  3. Lorsque tous les fragments sont recus (len(chunks) == total_chunks), processCompleteResult() les reassemble dans l'ordre en iterant les indices de fragments de 0 a N-1
  4. Les donnees reassemblees sont analysees en tant que JSON contenant les champs beacon_id, success, output et error
  5. Le resultat complet est transmis au backend via un evenement WebSocket task_complete

Acquittement des fragments

L'acquittement par fragment (1.0.0.{chunk_index}) permet a l'implant de detecter les fragments perdus et de les retransmettre. La reponse d'erreur (1.0.0.255) indique un echec de decodage ou d'analyse sur ce fragment specifique.

Commutation du mode de transport DNS

Le point d'entree ServeDNS route les requetes entrantes en fonction du type d'enregistrement DNS demande. Cela determine quel gestionnaire traite la requete :

Type d'enregistrement Gestionnaire Route vers Capacite de donnees
TXT handleTXTQuery() Enregistrement du beacon (QueryTypeBeacon) ou interrogation de tache (QueryTypeTask) JSON complet (jusqu'a dns_max_txt octets)
A handleAQuery() Interrogation de tache (QueryTypeTask), soumission de resultat (QueryTypeResult), ou exfiltration (QueryTypeExfil) 4 octets par reponse
AAAA handleAAAAQuery() Interrogation de tache (QueryTypeTask) 16 octets par reponse

Le type de requete (QueryTypeBeacon, QueryTypeTask, QueryTypeResult, QueryTypeExfil) est determine par le prefixe de sous-domaine analyse a partir du nom de la requete. Ces prefixes sont configurables via le bloc dns-beacon du profil malleable (voir Configuration DNS malleable).

Pour le changement de mode au moment de l'execution depuis la console operateur, voir Changement de mode au moment de l'execution ci-dessus.


Remplacement du résolveur DNS

Le champ dns_resolver configure le beacon pour envoyer des requêtes DNS à un résolveur spécifique au lieu du serveur DNS par défaut du système. Ceci est utile dans les environnements où les serveurs DNS d'entreprise inspectent ou bloquent les domaines C2.

Exemple :

curl -s -X POST https://stentor.app/api/v1/listeners \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "DNS Bypass",
    "relay_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "type": "dns",
    "port": 53,
    "dns_domain": "c2.example.com",
    "dns_resolver": "8.8.8.8:53"
  }' | jq

Cela indique au beacon d'envoyer toutes les requêtes DNS C2 au DNS public de Google (8.8.8.8) au lieu du serveur DNS d'entreprise de la cible.

Détection du trafic DNS non standard

De nombreux environnements d'entreprise surveillent le trafic DNS vers les résolveurs externes (en particulier 8.8.8.8 et 1.1.1.1). Un hôte envoyant des requêtes DNS à un résolveur externe au lieu du serveur DNS interne est un indicateur fort de compromission. Pensez à utiliser le résolveur système lorsque cela est possible ou utilisez DNS-over-HTTPS (DoH) pour encapsuler les requêtes dans le trafic HTTPS.


Limitation de débit et anti-détection

Le serveur DNS prend en charge la limitation de débit et la gigue de réponse pour empêcher la détection par les systèmes IDS/IPS qui surveillent les modèles d'inondation DNS.

Paramètre Type Par défaut Description
RateLimitQPS float 0 (désactivé) Nombre maximal de requêtes par seconde par adresse IP source. Les requêtes excédentaires reçoivent SERVFAIL.
RateLimitBurst int 20 Allocation de rafale supérieure à la limite QPS. Permet de courtes rafales sans limitation.
JitterMs int 0 (désactivé) Délai de réponse aléatoire en millisecondes. Ajoute du bruit au timing de réponse.

Paramètres recommandés pour la furtivité

Pour les opérations secrètes, définissez RateLimitQPS sur 2-5 et JitterMs sur 100-500. Cela empêche le beacon de générer une rafale détectable de requêtes DNS tout en ajoutant un bruit de synchronisation qui annule l'analyse statistique.

Réponse au repos

Le champ dns_idle contrôle l'adresse IP renvoyée par le serveur DNS lorsqu'un beacon s'enregistre mais n'a aucune tâche en attente.

  • Par défaut : "0.0.0.0" pour les enregistrements A, "::" pour les enregistrements AAAA
  • L'implant interprète la réponse d'inactivité comme « aucune tâche disponible » et se rendort

Définir dns_idle sur une adresse IP plausible (par exemple, une adresse IP de serveur légitime) peut rendre les réponses inactives plus naturelles dans les journaux DNS.


Configuration DNS malléable

Les profils C2 malléables incluent un bloc dns-beacon qui personnalise le comportement DNS C2. Ces paramètres remplacent les valeurs par défaut du listener lorsqu'un profil est attaché.

Paramètres clés

Paramètre Description
dns_idle IP renvoyée pour les beacons inactifs (remplace le listener dns_idle)
dns_max_txt Longueur maximale de l'enregistrement TXT (remplace le listener dns_max_txt)
dns_sleep Intervalle de veille entre les requêtes DNS en millisecondes
dns_ttl TTL pour les réponses DNS (remplace le listener dns_ttl)
dns_stager_prepend Données ajoutées aux réponses du module de préparation DNS
dns_stager_subhost Préfixe de sous-domaine pour les requêtes intermédiaires

Préfixes de sous-domaines personnalisés

Le profil malléable contrôle les préfixes de sous-domaines utilisés pour différentes opérations C2 :

Préfixe Par défaut Objectif
beacon beacon Requêtes d'enregistrement Beacon
get_A cdn Une récupération de données d'enregistrement
get_AAAA www6 Récupération de données d'enregistrement AAAA
get_TXT api Récupération de données d'enregistrement TXT
put_output post Soumission des résultats de la tâche
put_metadata www Soumission de métadonnées (enregistrement via un gestionnaire profilé)

DNS sur HTTPS (DoH)

Le bloc imbriqué dns-over-https permet le transport DoH comme alternative au DNS brut. Une fois configurée, le beacon encapsule les requêtes DNS dans les requêtes HTTPS adressées à un serveur DoH, les rendant impossibles à distinguer du trafic HTTPS normal.

Paramètre Description
doh_server URL du serveur DoH (par exemple, "https://dns.google/dns-query")
doh_verb Méthode HTTP : "GET" ou "POST"
doh_useragent Agent utilisateur personnalisé pour les requêtes DoH

Pour obtenir la syntaxe complète des profils malléables et des exemples de configuration, consultez la page Profils malléables.


Dépannage

Les requêtes DNS n'atteignent pas le relais

  1. Vérifiez les enregistrements NS : Vérifiez la délégation avec dig NS c2.example.com -- la réponse doit pointer vers l'adresse IP du relais.
  2. Vérifiez le pare-feu : Assurez-vous que le port UDP 53 est ouvert en entrée vers le relais
  3. Vérifiez l'état du listener : Confirmez que le listener est running via GET /api/v1/listeners/$LISTENER_ID.
  4. Vérifiez le suffixe du domaine : Le serveur DNS traite uniquement les requêtes qui sont des sous-domaines du dns_domain configuré.

Rappel de beacon lente

  1. Mise en cache DNS : Les résolveurs intermédiaires mettent en cache les réponses basées sur la durée de vie. Réduisez dns_ttl pour une livraison plus rapide des tâches (au prix d'un trafic DNS plus important)
  2. Limitation du débit : Si RateLimitQPS est défini trop bas, les requêtes peuvent être limitées. Vérifier les journaux de relais pour les réponses SERVFAIL
  3. Chaîne de résolution : Plusieurs sauts de résolution ajoutent de la latence. Pensez à utiliser dns_resolver pour pointer directement vers le relais

Problèmes de canal de données

  1. Requêtes AAAA bloquées : Certains réseaux filtrent les requêtes AAAA. Revenir au mode dns (enregistrement A)
  2. Réponses TXT tronquées : Certains proxys DNS tronquent les enregistrements TXT volumineux. Réduisez dns_max_txt à 180 ou passez en mode A/AAAA
  3. Erreurs d'encodage : Vérifiez que dns_domain correspond exactement entre le listener et la configuration de l'implant.

Le remplacement du résolveur ne fonctionne pas

  1. DNS sortant bloqué : Le pare-feu de l'entreprise peut bloquer le DNS vers les résolveurs externes sur le port 53. Essayez plutôt DNS sur HTTPS (DoH).
  2. Incompatibilité IP : Vérifiez que la valeur dns_resolver inclut le port (par exemple, "8.8.8.8:53", pas seulement "8.8.8.8")
  3. Règles de sortie du pare-feu : Certains environnements autorisent uniquement le DNS vers des résolveurs spécifiques sur liste blanche.