Instalação e configuração do Bind Trabalhando com Views Master/Slave no FreeBSD 9.2

Configurando o DNS no FreeBSD 9.2 com MultiView do mesmo domínio e fazendo replicação.

Problema: Quando era efetuado replicação e as zonas tinham o mesmo nome ele sempre replicava a zona da view interna ou o primeiro arquivo de referência dentro do named.conf.

Solução dentro de cada View vamos forçar para quem tem que ser a replica e no slave receber a replica que foi forçada por View. Precisamos de 2 endereços ip para o servidor Slave.

  1. IP do slave que vai receber a view interna: 192.168.1.61
  2. IP do slave que vai receber a view externa: 192.168.1.62
  3. IPS do servidor master 192.168.1.60

Aqui no FreeBSD o Bind já vem instalado no sistema por default e ele vem enjaulado em /var/named com isso somente precisamos configurar ele para funcionar de acordo com a nossa necessidade, vamos lá então.

Vamos fazer um backup do arquivo de configuração

cd /var/named/etc/namedb
cp named.conf named.conf.old

Agora vamos deixar o arquivo /var/named/etc/named.conf como abaixo, aqui estou utilizando a rede 192.168.1.0/24 como minha rede local para exemplo, mude conforme necessário.

vim /var/named/etc/namedb/named.conf
#Criando acl para definir as nossas redes internas.
acl "trusted" {
 192.168.1.0/24;
 127.0.0.1;
};

#Acl que define qual vai ser o slave que vai receber a view interna
acl "internal_slave" {
 192.168.1.61;
};

#Acl que define qual vai ser o slave que vai receber a view externa
acl "external_slave" {
 192.168.1.62;
};

options {
    listen-on port 53 { 127.0.0.1; 192.168.1.0/24; };
    directory   "/etc/namedb/working";
    dump-file   "/var/dump/named_dump.db";
    statistics-file "/var/stats/named.stats";
    memstatistics-file "/var/stats/named_mem_stats.txt";
    pid-file    "/var/run/named/pid";
    allow-query     { any; };
    recursion no;
    version "Não Disponível";
};

#Controle
include "/etc/namedb/rndc.key";

controls {
        inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { rndc-key; };
};


#LOGS
logging {
 channel xfer-log {
 file "/var/log/named.log";
 print-category yes;
 print-severity yes;
 print-time yes;
 severity info;
 };
 category xfer-in { xfer-log; };
 category xfer-out { xfer-log; };
 category notify { xfer-log; };

 channel update-debug {
 file "/var/log/named-update-debug.log";
 severity  debug 3;
 print-category yes;
 print-severity yes;
 print-time      yes;
 };
 channel security-info    {
 file "/var/log/named-auth-info.log";
 severity  info;
 print-category yes;
 print-severity yes;
 print-time      yes;
 };
 category update { update-debug; };
 category security { security-info; };

 };

#Incluir os nossos arquivos externos que vão conter as configurações das Views
include "/etc/namedb/named.conf.internal-zones";
include "/etc/namedb/named.conf.external-zones";

Agora vamos gerar a chave do rndc

rndc-confgen -a -c /var/named/etc/namedb/rndc.key -k rndc-key -b 256

Agora precisamos acertar as permissões dos arquivos

chown root:bind /var/named/etc/namedb/rndc.key
chmod 640 /var/named/etc/namedb/rndc.key

Agora vamos criar o nosso arquivo da View Interna /var/named/etc/namedb/named.conf.internal-zones onde somente os nossos clientes da rede local e o nosso servidor local vão poder consultar.

vim /var/named/etc/namedb/named.conf.internal-zones
#Definindo a nossa View interna
view "internal" {

#Definindo quais clientes vão poder consultar esta view, então vão ser a nossa rede interna mesmo o servidor external_slave
 match-clients { !external_slave; trusted; };

#Definindo que os clientes dessa view vão poder efetuar consultas recursivas.
 recursion yes;

#Qual servidor vai poder receber a replica dessa view
allow-transfer {
 internal_slave;
};

#Quem vai ser notificado aqui temos que informar os endereços ips.
also-notify {
 192.168.1.61;
};

#estas zonas abaixo precisam ser desabilitadas senão ficamos recebendo warnings nos logs
disable-empty-zone "255.255.255.255.IN-ADDR.ARPA";
disable-empty-zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";
disable-empty-zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";

#Zona hint aonde temos os arquivos dos root servers
zone "." { type hint; file "/etc/namedb/named.root"; };

#zonas de local host em ipv4 e ipv6
zone "localhost"    { type master; file "/etc/namedb/master/localhost-forward.db"; };
zone "127.in-addr.arpa" { type master; file "/etc/namedb/master/localhost-reverse.db"; };
zone "255.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; };
zone "0.ip6.arpa"   { type master; file "/etc/namedb/master/localhost-reverse.db"; };
zone "0.in-addr.arpa"   { type master; file "/etc/namedb/master/empty.db"; };

#Nosso domínio de teste
zone "douglasqsantos.com.br" {
 type master;
 file "/etc/namedb/master/db.douglasqsantos.com.br.internal";
};

};

Agora vamos criar a nossa View Externa /var/named/etc/named.conf.external-zones aonde qualquer um vai poder consultar não sendo a nossa rede local e nem o nosso servidor local

vim /var/named/etc/namedb/named.conf.external-zones
#Definição da nossa view Externa
view "external" {

#Definindo quais clientes vão poder consultar esta view
 match-clients { external_slave; !trusted; any; };

#Os clientes dessa view não poderão efetuar consultas recursivas
 recursion no;

#Quam vai poder receber replica dessa view
 allow-transfer {
 external_slave;
 };

#Quem vai ser notificado aqui temos que informar o endereço ip
 also-notify {
 192.168.1.62;
 };

#Nosso dominio de teste.
zone "douglasqsantos.com.br" {
 type master;
 file "/etc/namedb/master/db.douglasqsantos.com.br.external";
 };

};

Agora vamos criar o arquivo que os nossos clientes internos vão consultar /var/named/master/db.douglasqsantos.com.br.internal

vim /var/named/etc/namedb/master/db.douglasqsantos.com.br.internal
$TTL 86400
@ IN SOA  dns.douglasqsantos.com.br. root.dns.douglasqsantos.com.br. (
 2013120901  ; Serial
 3600       ; Refresh
 1800        ; Retry
 1209600      ; Expire
 3600 )     ; Minimum

;
@               IN      NS   douglasqsantos.com.br.
douglasqsantos.com.br. IN TXT "v=spf1 a mx ip4:192.168.1.0/24 -all"
mail.douglasqsantos.com.br IN TXT "v=spf1 a -all"

@               IN      NS   ns1.douglasqsantos.com.br.
@               IN      NS   ns2.douglasqsantos.com.br.
@               IN      MX   0 mail.douglasqsantos.com.br.

;NAME SERVERS
@               IN      A    192.168.1.60
ns1             IN      A    192.168.1.60
ns2             IN      A    192.168.1.61
dns             IN      A    192.168.1.60

;MAIL SERVERS
mail            IN      A    192.168.1.60
imap            IN      CNAME mail
pop             IN      CNAME mail
smtp            IN      CNAME mail
webmail         IN      CNAME mail

;WEB SERVERS
www             IN      A    192.168.1.61
ftp             IN      CNAME www
mailadmin       IN      CNAME www

Agora vamos criar o arquivo que os clientes externos vão consultar /var/named/master/db.douglasqsantos.com.br.external

vim /var/named/etc/namedb/master/db.douglasqsantos.com.br.external
$TTL 86400
@ IN SOA  dns.douglasqsantos.com.br. root.dns.douglasqsantos.com.br. (
 2013120901  ; Serial
 3600       ; Refresh
 1800        ; Retry
 1209600      ; Expire
 3600 )     ; Minimum

;
@               IN      NS   douglasqsantos.com.br.
douglasqsantos.com.br. IN TXT "v=spf1 a mx ip4:200.200.200.0/23 -all"
mail.douglasqsantos.com.br IN TXT "v=spf1 a -all"

@               IN      NS   ns1.douglasqsantos.com.br.
@               IN      NS   ns2.douglasqsantos.com.br.
@               IN      MX   0 mail.douglasqsantos.com.br.

;NAME SERVERS
@               IN      A    200.200.200.25
ns1             IN      A    200.200.200.25
ns2             IN      A    200.200.200.27
dns             IN      A    200.200.200.25

;MAIL SERVERS
mail            IN      A    200.200.200.25
imap            IN      CNAME mail
pop             IN      CNAME mail
smtp            IN      CNAME mail
webmail         IN      CNAME mail

;WEB SERVERS
www             IN      A    200.200.200.27
ftp             IN      CNAME www
mailadmin       IN      CNAME www

Vamos agora ajustar o arquivo /etc/resolv.conf para que o nosso servidor consiga encontrar a zona do dominio.com.br

vim /etc/resolv.conf
search douglasqsantos.com.br
domain douglasqsantos.com.br
nameserver 127.0.0.1
nameserver 192.168.1.61

Agora precisamos habilitar o named em /etc/rc.conf da seguinte forma

echo 'named_enable="YES"' >> /etc/rc.conf

Vamos agora iniciar o serviço e testar.

/etc/rc.d/named start

Agora vamos fazer alguns testes.

Vamos consultar o endereço do host www

nslookup www
Server:     127.0.0.1
Address:    127.0.0.1#53

Name:   www.douglasqsantos.com.br
Address: 192.168.1.61

Agora vamos consultar o endereço do host mail.douglasqsantos.com.br aqui poderíamos consultar somente por mail dai ele completaria com o parâmetro domain do resolv.conf

nslookup mail.douglasqsantos.com.br
Server:     127.0.0.1
Address:    127.0.0.1#53

Name:   mail.douglasqsantos.com.br
Address: 192.168.1.60

Vamos consultar os registros do tipo A do nosso domínio.

dig -t A douglasqsantos.com.br

; <<>> DiG 9.8.4-P2 <<>> -t A douglasqsantos.com.br
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1190
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 2

;; QUESTION SECTION:
;douglasqsantos.com.br.           IN  A

;; ANSWER SECTION:
douglasqsantos.com.br.        86400   IN  A   192.168.1.60

;; AUTHORITY SECTION:
douglasqsantos.com.br.        86400   IN  NS  douglasqsantos.com.br.
douglasqsantos.com.br.        86400   IN  NS  ns1.douglasqsantos.com.br.
douglasqsantos.com.br.        86400   IN  NS  ns2.douglasqsantos.com.br.

;; ADDITIONAL SECTION:
ns1.douglasqsantos.com.br.    86400   IN  A   192.168.1.60
ns2.douglasqsantos.com.br.    86400   IN  A   192.168.1.61

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec  9 21:12:37 2013
;; MSG SIZE  rcvd: 127

Vamos agora consultar todos os registros do nosso domínio.

dig -t axfr douglasqsantos.com.br
; <<>> DiG 9.8.4-P2 <<>> -t axfr douglasqsantos.com.br
;; global options: +cmd
; Transfer failed.

Como pode ser notado não temos permissão para efetuar a transferência da zona, porém já permitimos a transferência para o servidor slave.

Como pode ser notado o nosso servidor estar funcionando corretamente em MultiView, agora vamos fazer os ajustes para ele efetuar a replicação como precisamos.

Agora vamos configurar o servidor Slave

Agora vamos fazer um backup do arquivo de configuração do nosso bind.

cd /var/named/etc/namedb
cp named.conf named.conf.old

Agora vamos deixar o arquivo /var/named/etc/named.conf como abaixo, aqui estou utilizando a rede 192.168.1.0/24 como minha rede local para exemplo, mude conforme necessário.

vim /var/named/etc/namedb/named.conf
#Criando acl para definir as nossas redes internas.
acl "trusted" {
 192.168.1.0/24;
 127.0.0.1;
};

#Acl que define qual vai ser o dns master
acl "dns_master" {
 192.168.1.60;
};

options {
    listen-on port 53 { 127.0.0.1; 192.168.1.0/24; };
    directory   "/etc/namedb/working";
    dump-file   "/var/dump/named_dump.db";
    statistics-file "/var/stats/named.stats";
    memstatistics-file "/var/stats/named_mem_stats.txt";
    pid-file    "/var/run/named/pid";
    allow-query     { any; };
    recursion no;
    version "Não Disponível";
};

#Controle
include "/etc/namedb/rndc.key";

controls {
        inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { rndc-key; };
};


#LOGS
logging {
 channel xfer-log {
 file "/var/log/named.log";
 print-category yes;
 print-severity yes;
 print-time yes;
 severity info;
 };
 category xfer-in { xfer-log; };
 category xfer-out { xfer-log; };
 category notify { xfer-log; };

 channel update-debug {
 file "/var/log/named-update-debug.log";
 severity  debug 3;
 print-category yes;
 print-severity yes;
 print-time      yes;
 };
 channel security-info    {
 file "/var/log/named-auth-info.log";
 severity  info;
 print-category yes;
 print-severity yes;
 print-time      yes;
 };
 category update { update-debug; };
 category security { security-info; };

 };

#Incluir os nossos arquivos externos que vão conter as configurações das Views
include "/etc/namedb/named.conf.internal-zones";
include "/etc/namedb/named.conf.external-zones";

Agora vamos gerar a chave do rndc isso demora um pouco ;)

rndc-confgen -a -c /var/named/etc/namedb/rndc.key -k rndc-key -b 256

Agora precisamos acertar as permissões dos arquivos

chown root:bind /var/named/etc/namedb/rndc.key
chmod 640 /var/named/etc/namedb/rndc.key

Agora vamos criar o arquivo da nossa View interna /var/named/etc/named.conf.internal-zones

vim /var/named/etc/namedb/named.conf.internal-zones
#Definindo a nossa View interna
view "internal" {

#Definindo quais clientes vão poder consultar esta view, então vão ser a nossa rede interna mesmo o servidor external_slave
 match-clients { trusted; };

#Definindo que os clientes dessa view vão poder efetuar consultas recursivas.
 recursion yes;

#Qual servidor vai poder receber a replica dessa view
allow-notify {
 dns_master;
};

#Nao disponibiliza transferencia de zona do servidor SLAVE
 allow-transfer {
 none;
};

#Zonas default

#As zonas abaixo precisamos desabilitar para não ficarmos recebendo warnings nos logs
disable-empty-zone "255.255.255.255.IN-ADDR.ARPA";
disable-empty-zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";
disable-empty-zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";

#Zona hint aonde temos os root servers
zone "." { type hint; file "/etc/namedb/named.root"; };

#Zonas de localhost ipv4 e ipv6
zone "localhost"    { type master; file "/etc/namedb/master/localhost-forward.db"; };
zone "127.in-addr.arpa" { type master; file "/etc/namedb/master/localhost-reverse.db"; };
zone "255.in-addr.arpa" { type master; file "/etc/namedb/master/empty.db"; };
zone "0.ip6.arpa"   { type master; file "/etc/namedb/master/localhost-reverse.db"; };
zone "0.in-addr.arpa"   { type master; file "/etc/namedb/master/empty.db"; };

#Nosso domínio de teste.
zone "douglasqsantos.com.br" {
type slave;
masters { 192.168.1.60; };
transfer-source 192.168.1.61; #Especificando qual transferencia do master que eu vou poder receber nessa view
file "/etc/namedb/slave/db.douglasqsantos.com.br.internal";
};

};

Vamos agora configurar a View Externa /var/named/etc/named.conf.external-zones

vim /var/named/etc/namedb/named.conf.external-zones
#Definição da nossa view Externa
view "external" {

#Definindo quais clientes vão poder consultar esta view
 match-clients { !trusted; any; };

#Os clientes dessa view não poderão efetuar consultas recursivas
 recursion no;

#Quem vai ser notificado aqui temos que informar o endereço ip
 allow-notify {
 dns_master;
 };

#Nao disponibiliza transferencia de zona do servidor SLAVE
 allow-transfer {
 none;
};


#Nosso dominio de teste.
zone "douglasqsantos.com.br" {
 type slave;
 masters { 192.168.1.60; };
 transfer-source 192.168.1.62; #Especificando qual transferencia do master que eu vou poder receber nessa view.
 file "/etc/namedb/slave/db.douglasqsantos.com.br.external";
 };

};

Agora vamos ajustar o /etc/resolv.conf

vim /etc/resolv.conf
search douglasqsantos.com.br
domain douglasqsantos.com.br
nameserver 127.0.0.1
nameserver 192.168.1.60

Agora vamos acertar o /etc/rc.conf.local

echo 'named_enable="YES"' >> /etc/rc.conf

Agora vamos iniciar o serviço

/etc/rc.d/named start

Agora podemos acompanhar os logs em

tail -f /var/named/var/log/named.log
09-Dec-2013 20:57:17.552 xfer-in: info: transfer of 'douglasqsantos.com.br/IN/external' from 192.168.1.60#53: connected using 192.168.1.62#17968
09-Dec-2013 20:57:17.651 xfer-in: info: transfer of 'douglasqsantos.com.br/IN/external' from 192.168.1.60#53: Transfer completed: 1 messages, 20 records, 494 bytes, 0.098 secs (5040 bytes/sec)
09-Dec-2013 20:57:17.651 notify: info: zone douglasqsantos.com.br/IN/external: sending notifies (serial 2013120901)
09-Dec-2013 21:00:17.640 notify: info: zone douglasqsantos.com.br/IN/internal: sending notifies (serial 2013120901)
09-Dec-2013 21:00:18.151 xfer-in: info: transfer of 'douglasqsantos.com.br/IN/external' from 192.168.1.60#53: connected using 192.168.1.62#15821
09-Dec-2013 21:00:18.249 xfer-in: info: transfer of 'douglasqsantos.com.br/IN/external' from 192.168.1.60#53: Transfer completed: 1 messages, 20 records, 494 bytes, 0.097 secs (5092 bytes/sec)
09-Dec-2013 21:00:18.249 notify: info: zone douglasqsantos.com.br/IN/external: sending notifies (serial 2013120901)

Vamos conferir o arquivo com a zona interna.

cat /var/named/etc/namedb/slave/db.douglasqsantos.com.br.internal
$ORIGIN .
$TTL 86400  ; 1 day
douglasqsantos.com.br     IN SOA  dns.douglasqsantos.com.br. root.dns.douglasqsantos.com.br. (
                2013120901 ; serial
                3600       ; refresh (1 hour)
                1800       ; retry (30 minutes)
                1209600    ; expire (2 weeks)
                3600       ; minimum (1 hour)
                )
            NS  ns1.douglasqsantos.com.br.
            NS  ns2.douglasqsantos.com.br.
            NS  douglasqsantos.com.br.
            A   192.168.1.60
            MX  0 mail.douglasqsantos.com.br.
            TXT "v=spf1 a mx ip4:192.168.1.0/24 -all"
$ORIGIN douglasqsantos.com.br.
dns         A   192.168.1.60
ftp         CNAME   www
imap            CNAME   mail
mail.douglasqsantos.com.br    TXT "v=spf1 a -all"
mail            A   192.168.1.60
mailadmin       CNAME   www
ns1         A   192.168.1.60
ns2         A   192.168.1.61
pop         CNAME   mail
smtp            CNAME   mail
webmail         CNAME   mail
www         A   192.168.1.61

Agora vamos conferir o arquivo da zona Externa.

cat /var/named/etc/namedb/slave/db.douglasqsantos.com.br.external 
$ORIGIN .
$TTL 86400  ; 1 day
douglasqsantos.com.br     IN SOA  dns.douglasqsantos.com.br. root.dns.douglasqsantos.com.br. (
                2013120901 ; serial
                3600       ; refresh (1 hour)
                1800       ; retry (30 minutes)
                1209600    ; expire (2 weeks)
                3600       ; minimum (1 hour)
                )
            NS  ns1.douglasqsantos.com.br.
            NS  ns2.douglasqsantos.com.br.
            NS  douglasqsantos.com.br.
            A   200.200.200.25
            MX  0 mail.douglasqsantos.com.br.
            TXT "v=spf1 a mx ip4:200.200.200.0/23 -all"
$ORIGIN douglasqsantos.com.br.
dns         A   200.200.200.25
ftp         CNAME   www
imap            CNAME   mail
mail.douglasqsantos.com.br    TXT "v=spf1 a -all"
mail            A   200.200.200.25
mailadmin       CNAME   www
ns1         A   200.200.200.25
ns2         A   200.200.200.27
pop         CNAME   mail
smtp            CNAME   mail
webmail         CNAME   mail
www         A   200.200.200.27

Vamos fazer alguns teste de consulta no servidor Slave.

Vamos consultar o endereço do host www

nslookup www
Server:     127.0.0.1
Address:    127.0.0.1#53

Name:   www.douglasqsantos.com.br
Address: 192.168.1.61

Agora vamos consultar o endereço do host mail.douglasqsantos.com.br aqui poderíamos consultar somente por mail dai ele completaria com o parâmetro domain do resolv.conf

nslookup mail.douglasqsantos.com.br
Server:     127.0.0.1
Address:    127.0.0.1#53

Name:   mail.douglasqsantos.com.br
Address: 192.168.1.60

Vamos consultar os registros do tipo A do nosso domínio.

dig -t A douglasqsantos.com.br

; <<>> DiG 9.8.4-P2 <<>> -t A douglasqsantos.com.br
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20925
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 2

;; QUESTION SECTION:
;douglasqsantos.com.br.           IN  A

;; ANSWER SECTION:
douglasqsantos.com.br.        86400   IN  A   192.168.1.60

;; AUTHORITY SECTION:
douglasqsantos.com.br.        86400   IN  NS  ns1.douglasqsantos.com.br.
douglasqsantos.com.br.        86400   IN  NS  douglasqsantos.com.br.
douglasqsantos.com.br.        86400   IN  NS  ns2.douglasqsantos.com.br.

;; ADDITIONAL SECTION:
ns1.douglasqsantos.com.br.    86400   IN  A   192.168.1.60
ns2.douglasqsantos.com.br.    86400   IN  A   192.168.1.61

;; Query time: 5 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec  9 21:21:38 2013
;; MSG SIZE  rcvd: 127

Agora vamos consultar todos os registros do nosso domínio.

dig -t AXFR douglasqsantos.com.br

; <<>> DiG 9.8.4-P2 <<>> -t AXFR douglasqsantos.com.br
;; global options: +cmd
; Transfer failed.

Como pode ser notado não conseguimos efetuar a transferência pois não configuramos para o servidor transferir dele para ele mesmo que é algo redundante.

Referências