Je viens de résoudre un vieux problème que j'avais ici.

  1. Problème à résoudre
  2. La solution: les "views" de BIND
    1. Déclarer plusieurs fois la même zone selon l'origine
    2. Maintenire plusieurs zones pour le même domaine
    3. Attention à...
  3. Config dnsmasq

Problème à résoudre

Le problème était que les machines qui se connectaient au mesh tombaient sur mon resolveur DNS externe, qui resolvait tous les hosts (y compris ceux du mesh) par l'internet normal.

Ceci faisait que tout tombait sur l'adresse IP externe, donc mon firewall, au lieu des IPs internes (192.168.0.x ici) ou des IPs du mesh (172.16.0.x). En fait, pour le mesh, ça ne resolvait tout simplement pas.

La solution: les "views" de BIND

Pour régler le problème, j'ai utilisé une fonctionalité de BIND que je n'avais jamais utilisé: les view de bind.

C'est en fait pas si compliqué: l'idée est que BIND regarde l'IP d'origine et sert un zonefile différent dépendamment d'où tu viens.

Déclarer plusieurs fois la même zone selon l'origine

Le gros de la job se fait dans mon fichier de conf de bind, comme suit:

view "rfc1918" {
  match-clients { 192.168/16; 172.16/12; 127.0.0.1; };

  zone "orangeseeds.org" {
    type master;
    file "/etc/bind/master/rfc1918.orangeseeds.org.db";
  };

  zone "anarcat.ath.cx" {
    type master;
    file "/etc/bind/master/anarcat.ath.cx.db";
  };
};

view "ipv4" {
  match-clients { any; };

  zone "orangeseeds.org" {
    type master;
    file "/etc/bind/master/ipv4.orangeseeds.org.db";
    allow-transfer { 217.70.177.40; };
  };

  zone "anarcat.ath.cx" {
    // managed by dyndns.org
    type master;
    file "/etc/bind/db.empty";
    allow-query { none; };
  };
};

Un peu difficile à digérer? Prenez le temps! :) La clef est dans la ligne match-clients: on voit que le view (et donc le zonefile) rfc1918 s'appliquent seulement quand on vient de 192.168 (mon réseau interne) ou 172.16 (le mesh).

Le second view s'applique seulement si le premier ne matche pas (j'ai deviné: on dirait que ça marche comme ça mais c'est pas documenté clairement).

Maintenire plusieurs zones pour le même domaine

Après, vous allez vous demander si c'est bien du gossage de maintenir deux zonefiles: eh bien non! grâce à un autre bidule que je ne connaissais pas de BIND: la directive $INCLUDE. Le zonefile ipv4.orangeseeds.org a l'air de ça:

$TTL 3h

; don't forget to change the TTL in orangeseeds.org.db when you change this file!
$INCLUDE /etc/bind/master/orangeseeds.org.db ; absolute path needed

; specific to the internetz (not for internal)
@   NS  ns6.gandi.net.

ns0     a       72.0.72.144

; can't be a CNAME because a CNAME is alone, and we have a NS record above
@       A       72.0.72.144
marcos  A       72.0.72.144
roadkiller      A       72.0.72.144

Donc la plupart des définitions sont dans le zonefile commun, orangeseeds.org.db, qui est inclus aussi dans le zone rfc1918, que voici:

$TTL 3h

; don't forget to change the TTL in orangeseeds.org.db when you change this file!
$INCLUDE /etc/bind/master/orangeseeds.org.db ; absolute path needed

ns0 A       192.168.0.3

; from the inside, this is an actual secondary
; it's not necessary in the ipv4 view because the internet should never reach this secondary
@   NS  ns1
ns1 A   192.168.0.1

; can't be a CNAME because a CNAME is alone, and we have a NS record above
@       A       192.168.0.3
; local machines
marcos  A       192.168.0.3
roadkiller      A       192.168.0.1
ata     A       192.168.0.16
lenny   A       192.168.0.4
; RL machines I manage
boulette        A       172.16.0.2
plastik A       172.16.1.20
easternblock    A       172.16.0.6
atlas   A       172.16.0.7
grace   A       172.16.0.16
lacou   A       172.16.0.19

La beauté de la chose est qu'on a pas besoin de spécifier les adresses IPv6 partout, elles sont communes à toutes les views, et donc dans le zonefile commun, que voici:

; this zone file defines non-IP specific names
; 
; this is because of the stupid NAT: we need to have a split-view setup where multiple zonefiles are used
;
; see http://www.zytrax.com/books/dns/ch6/#split-view for more information
;
; in itself, this zonefile is incomplete for IPv4, another zonefile needs to include it and define various A records for it to work on IPv4.
;
; IPv6 should be functional regardless, however.

@       SOA ns0 postmaster 2013090805 1d 12h 1w 3h
        ; Serial, Refresh, Retry, Expire, Neg. cache TTL

@       NS      ns0
; not for internal network
;@       NS      ns6.gandi.net.

ns0     AAAA    2001:1928:1:9::1

@       MX      5 marcos

; can't be a CNAME because a CNAME is alone, and we have a NS record above
;@      AAAA    2001:1928:1:9:beae:c5ff:fe89:e238
@       AAAA    2001:1928:1:9::1
;marcos AAAA    2001:1928:1:9:beae:c5ff:fe89:e238
marcos  AAAA    2001:1928:1:9::1
roadkiller      AAAA    2001:1928:1:9::

sh      CNAME   marcos
shell   CNAME   marcos
imap    CNAME   marcos
voice   CNAME   roadkiller
voip    CNAME   roadkiller
vpn     CNAME   roadkiller
git     CNAME   marcos
src CNAME   git
radio   CNAME   marcos
aegir   CNAME   marcos
bm      CNAME   marcos
st      CNAME   status
status  CNAME   marcos
roadkill        CNAME roadkiller
mail    CNAME   marcos
photos  CNAME   marcos
ph      CNAME   photos
; PhotoFloat
pf      CNAME   marcos
sd      CNAME   sondage
sondage CNAME   marcos
dhal    CNAME   marcos
munin   CNAME   marcos
wiki    CNAME   marcos
rococo  CNAME   wiki
source.rococo   CNAME   wiki
foufem  CNAME   wiki
cats    CNAME   wiki

Attention à...

Quelques enjeux à faire attention:

  1. une fois qu'on utilise les views, faut que tous les zones soient dans un views. c'est chiant, mais ça semble inévitable. pour moi, cela s'est résumé à désactiver l'include named.conf.default-zones de Debian, qui est inutile vu que le serveur n'est pas "récursif" anyways.

  2. quand on modifie un des fichiers, il faut quand même mettre à jour le serial dans le zonefile commun! ceci peut être un peu gossant parce que ça veut dire qu'un changement sur le zonefile local fait changer le serial du zonefile public...

  3. mon routeur roule un autre serveur DNS, récursif celui-là, pour lequel j'ai configuré un peu de colle spéciale pour qu'il consulte le serveur normal pour les zones spécifiées (sinon ça marche juste pas, en fait):

    zone "orangeseeds.org" {
            type slave;
            file "/etc/namedb/slave/orangeseeds.org.slave";
            masters {
                    192.168.0.3; // marcos
            };
            notify no;
    };
    

    ceci pourrait rendre un tel déploiement difficile sinon impossible avec un routeur qui ne roule pas bind... :/

  4. pour que les notify fonctionnent correctement, il faut s'assurer que les enregistrements NS de chaque vue soient bien configurés. notez comment les views ont chacun des enregistrement A mais aussi NS spécifiques.

Je pense que c'est pas mal ça!

Config dnsmasq

dnsmasq, il est con: par défaut il ne va pas résoudre ces noms de domaines internes sous OpenWRT.

Pour que dnsmasq resolve correctement mes hostnames locaux, j'ai du mettre ceci dans mon /etc/config/dhcp:

config dnsmasq
    option rebind_protection '0'

On peut aussi mettre des exceptions spécifiques par domaine:

config 'dnsmasq'
    list 'rebind_domain' '/orangeseeds.org/'

Après, faut repartir dnsmasq:

/etc/init.d/dnsmasq restart

Source

Created . Edited .