Ferme ton Bind !

Il est important de fermer complètement son Bind, à savoir mettre dans son named.conf :

allow-query { localhost;};
allow-recursion { localhost; };
allow-transfer { none; };

Cela provoque un statut REFUSED pour toutes les requêtes non autorisées. Si refuser les transferts (requêtes AXFR dévoilant toute votre zone) est sage et refuser les requêtes récursives est logique (vous ne voulez pas être serveur DNS pour le monde entier), il faut également refuser toutes les requêtes par défaut afin d’éviter de potentiels dénis de service.

Vous noterez que les directives ci-dessus autorisent les requêtes classiques de la part de localhost dans la mesure où il est fréquent que votre machine se serve de son propre Bind. Si ce n’est pas le cas, mettre toutes les directives à none.

Un moyen simple de vérifier qu’un serveur DNS refuse bien toutes les requêtes :

dig google.fr @<serveur DNS>

Vous ne devez pas obtenir la(les) réponse(s), ni même obtenir la liste des ROOT SERVERS. Vous devez obtenir status: REFUSED (ou alors un timeout…).

J’ai souvent eu du mal à expliquer pourquoi il fallait fermer complètement son Bind, car la menace des attaques DOS restait un peu vague. Ce n’est désormais plus le cas depuis quelques semaines où chaque administrateur d’un Bind assiste (dans ses logs ;-) aux multiples requêtes “. NS IN” générées par des robots/virus :

client 76.9.16.171#39068: query (cache) './NS/IN' denied
client 69.64.87.156#42646: query (cache) './NS/IN' denied

On déplore même des victimes de ces attaques DDOS de grande ampleur, notamment NetworkSolutions qui l’explique sur son blog. Pour contrer cela, on peut refuser les paquets en amont : voici un fameux paquet (format PCAP). On voit donc que l’on peut interdire les paquets comportant une requête DNS récursive (flags = 0x0100). Sur une machine Linux, on peut le faire avec iptables et le module u32 (attention, il semble y avoir des bugs avec certaines versions) :

iptables -A INPUT -p udp --dport domain -m u32 --u32 "0>>22&0x3C@10=0x01000001" -j DROP

SI vous ne voulez pas interdire toutes les requêtes récursives, j’ai trouvé sur Internet une règle plus précise qui matche sur le “. NS IN” (voir commentaires de ce post) :

iptables -A INPUT -j DROP -p udp --dport domain -m u32 --u32 \
"0>>22&0x3C@12>>16=1&&0>>22&0x3C@20>>24=0&&0>>22&0x3C@21=0x00020001"

Enfin, sur l’excellent blog de Stéphane Bortzmeyer, vous trouverez plus de détails et des outils pour mesurer le nombre d’attaques sur votre serveur.

Tags: , ,

9 Responses to “Ferme ton Bind !”

  1. Olivier B. says:

    Bonsoir,

    merci pour ce petit filtre iptables ; je cherchais justement une solution de la sorte, mais y était sûrement mal pris ;)

  2. Hello reg,

    Merci pour le conseil, j’avais une machine qui me répondait la liste des serveurs Root. J’ai donc ajouté la directive pour “allow-query”.

    Par contre, au niveau du transfert, ne faut-il pas autoriser le serveur DNS secondaire pour qu’il puisse se synchroniser ? Je dis peut-être une connerie sachant mes connaissances limitées au niveau des serveurs de noms.

    Un petit détail change aussi pour moi, au lieu du simple “localhost”, j’ai aussi “127.0.0.1” et mes 2 IP publiques dans les blocs autorisés. Je ne sais plus pourquoi c’est comme ça. Est-ce mal ?

  3. loloemr says:

    Petite question : à quoi sert un serveur dns si on ne peut faire aucune requète dessus ?

  4. Hello Jérémy,

    Pour le allow-transfert{}, il est recommandé de le désactiver globalement et de l’activer spécifiquement pour les domaines concernés dans la configuration de zone. Exemple :
    allow-transfert{none;};
    zone "example.com" {
    allow transfer { "acl1"; };
    zone "anotherexample.com" {
    allow transfer { "acl2"; };
    }

    Bien sûr, si tu n’as qu’un seul serveur secondaire, ça se discute (pense néanmoins aux évolutions possibles). Enfin, tu as compris : le principal est de ne pas répondre à tout le monde !

  5. Hello loloemr,

    On autorise évidemment les réponses pour certains domaines en définissant une zone. Par exemple :
    zone "example.com" {
    type master;
    file "/etc/bind/db.example.com";
    allow-query { any; };
    allow-transfer { "myacl1"; };
    };

  6. sov says:

    Mmm salut et merci pour ce billet,
    par contre depuis que j’ai bloqué au niveau du pare-feu grâce à l’astuce glissé ici (thx :p), je reçois le même genre de flood sur mon reverse (sur lequel je n’ai pas la main donc y a de toute manière peu de chances que cela soit des requêtes légitimes).
    Et pareil les IP doivent être falsifié parce que leurs reverses renvoient sur des machines de gros groupes (genre nintendo).
    Vous avez observé quelque chose de similaire chez vous ?

  7. Merci pour les précisions.

    Un tuc était pas clair (pour moi) c’est que si on ferme le bind globalement au niveau des requêtes externes, il faut les ouvrir à nouveau pour les domaines qui sont déclarés sur le serveur en question, sinon, ils ne seront plus accessibles. Evidemment en y repensant maintenant, c’est ultra logique.

    C’est ce qui m’est bêtement arrivé aujourd’hui. J’ai suivi le conseil sans trop chercher et j’avais mes domaines qui ne répondaient plus. Ça n’a pas l’air de m’avoir causé de tort entre les caches, le DNS secondaire, … mais bon, j’aurai dû réfléchir.

    Là avec le “allow-query { any; };” dans chacunes de mes zones master, ça marche bien mieux ;-)

  8. AU fait, reg, tu pourrais te faire un gravatar, ça egayerait tes commentaires. http://gravatar.com/. Ça s’ajoute automatiquement en fonction de ton adresse e-mail sur les commentaires de blogs, …

  9. J’avais un compte en fait, mais pas d’image en place. J’ai essayé d’en mettre une…