Servidor DNS autoritativo com Raspberry Pi - MakerHero

Servidor DNS autoritativo com Raspberry Pi 5

Imagine que você esteja procurando por um médico ortopedista infantil na lista telefônica. Um caminho seria ir até as páginas amarelas e procurar pela seção médico, em seguida procurar a seção ortopedista, possivelmente encontrar a seção infantil e finalmente encontrar o nome (Dra. Julia) e o telefone do médico. Pois bem, nesse exemplo você seria o DNS recursivo, fazendo as consultas necessárias para obter o resultado desejado – o nome e telefone da Dra. Julia. Por outro lado, cada seção das páginas amarelas – médico, ortopedista e infantil – seria um servidor DNS autoritativo respondendo ao DNS recursivo com uma referência a próxima seção ou resultado desejado. Assim funciona na Internet. Nesse post abordaremos o servidor DNS autoritativo no ambiente da rede local, uma versão mais simplificada, onde as páginas amarelas terão apenas uma única seção respondendo ao DNS recursivo com nome e telefone (nome de domínio e endereço IP) dos dispositivos da rede local.

Material necessário

Para realizar este projeto, vamos precisar de :

E ter concluído o post Servidor DNS recursivo com Raspberry Pi.

O que é um servidor DNS autoritativo?

  • O Sistema de Nomes de Domínio (DNS) é um banco de dados hierárquico e distribuído, ele armazena informações para mapear nomes para endereços IP e vice-versa.
  • Os dados armazenados no DNS são chamados de nomes de domínio (domain names), e são organizados como uma árvore.
    • Cada nó dessa árvore, chamado domínio (domain), recebe um rótulo.
    • O nome de domínio (domain name) é a concatenação de todos os rótulos.
  • O banco de dados é dividido em seções chamadas zonas, que são distribuídas entre os servidores DNS autoritativos.
    • Os dados de cada zona são armazenados no servidor DNS autoritativo.
    • Cada zona é servida por pelo menos um servidor DNS autoritativo.

Mas como uma imagem vale mais do que mil palavras, elaborei o diagrama abaixo que ilustra os conceitos anteriores usando como exemplo o nome de domínio www.makerhero.com.

Servidor DNS autoritativo 1

Dito isso, a proposta desse post é adicionar mais uma funcionalidade ao Raspberry Pi, transformando-o em um servidor DNS recursivo e também autoritativo. Falando especificamente do servidor DNS autoritativo, a ideia é basicamente nomear os dispositivos da rede local, pois se assim como eu, você possui vários dispositivos conectados a sua rede local, vai preferir acessá-los por um nome como rasp3.example.com ao invés de um número como 192.168.0.103, por exemplo.

Por ser uma rede local, usaremos o domínio example.com, reservado para esse tipo de aplicação, ficando assim os dispositivos da rede local com nomes de domínio no formato nomedehost.example.com. Outra particularidade da rede local, é possuir apenas uma zona, ou seja, o servidor DNS autoritativo será responsável por todo banco de dados, o que pode ser observado na imagem abaixo:

Servidor DNS autoritativo 2

Montando o servidor DNS autoritativo com Raspberry Pi

Para começar precisamos de algum tipo de acesso ao terminal, seja remoto via ssh ou local via teclado. Tudo certo? Então vamos lá.

Primeiro vamos instalar os pacotes, nosso servidor DNS autoritativo será baseado no Bind.

apt-get update                                 
apt-get install bind9 dnsutils

É uma boa prática fazer uma cópia do arquivo de configuração antes de editá-lo.

cp -p /etc/bind/named.conf.options /etc/bind/named.conf.options.default

Agora iremos limpar o conteúdo do arquivo.

echo "" > /etc/bind/named.conf.options

Editá-lo.

vim /etc/bind/named.conf.options

E incluir o conteúdo abaixo (fique atento aos comentários)!

options {
    # Diretório de trabalho do servidor.
    directory "/var/cache/bind";
    
    # Para servidores autoritativos o modo recursivo é desligado.
    recursion no;

    # Interface (any = todas) e porta (5300) que o servidor responderá às consultas.
    # Como já temos o servidor DNS recursivo na porta 53, vamos alterar
    # a porta do DNS autoritativo para 5300.
    listen-on port 5300 { any; };

    # Desativando IPv6.
    listen-on-v6 { none; };
};

Agora vamos adicionar as configurações das zonas. Vamos fazer uma cópia do arquivo de configuração.

cp -p /etc/bind/named.conf.local /etc/bind/named.conf.local.default

Editá-lo.

vim /etc/bind/named.conf.local

E incluir o conteúdo abaixo no final (fique atento aos comentários!).

zone "example.com" {
        # O servidor tem uma cópia original dos dados para a zona.
        type master;
        # Local onde serão armazenados os dados da zona.
        file "/etc/bind/db.example.com";
};

# MODIFIQUE OS TRÊS PRIMEIROS OCTETOS DE ACORDO COM SUA REDE. PARA 192.168.0  SERIA 0.168.192.in-addr.arpa.
zone "0.168.192.in-addr.arpa" {
        # O servidor tem uma cópia original dos dados para a zona.
        type master;
        # Local onde serão armazenados os dados da zona.
        # MODIFIQUE OS TRÊS PRIMEIROS OCTETOS (192.168.0) DE ACORDO COM SUA REDE.
        file "/etc/bind/db.192.168.0";
};

Vamos então criar os arquivos para armazenar os dados das zonas.

vim /etc/bind/db.example.com

E incluir o conteúdo abaixo (fique atento aos comentários!).

;; BIND data file for example.com zone

;; Define o tempo de vida (TTL) padrão para registros sem TTLs definidos.
;; O TTL é enviado pelo servidor autoritativo em resposta as consultas feitas pelos servidores recursivos,
;; e descreve por quanto tempo um registro pode ser armazenado em cache antes de ser descartado.
$TTL    604800    ; [604800 seg = 7 dias]

;; "@"   Nome da zona (example.com) seguido por um ponto final.
;; "IN"  Significa Internet.
;; "SOA" Identifica o início de uma zona.
;; "ns.example.com." é o nome do servidor autoritativo da zona example.com.
;; "root.example.com." é o endereço de e-mail do responsável pela zona, substituindo @ por um ponto.
;; SUBSTITUA "ns.example.com." PELO NOME DE DOMÍNIO DO SEU RASPBERRY PI, POR EXEMPLO "raspberrypi.example.com."
;; SUBSTITUA "root.example.com." POR UM EMAIL VÁLIDO, POR EXEMPLO "meuemail.provedor.com."
@    IN    SOA    ns.example.com. root.example.com. (

;; Os parâmetros "Serial", "Refresh", "Retry" e "Expire", dizem respeito a configuração de múltiplos servidores,
;; também conhecido como master (primário) e slave (secundário), embora fora do escopo desse post, será brevemente comentado.
;; "Serial" Número de série que deve ser incrementado a cada mudança no arquivo.
;; "Refresh" Define o período de atualização entre os servidores.
;; "Retry" Se ocorrer um erro durante a atualização, será repetida após o tempo expirar.
;; "Expire" O servidor é considerado indisponível após o tempo expirar.
;; "Negative Cache TTL" Define o tempo de vida de uma resposta NXDOMAIN.
             2019041801        ; Serial [2019 = ano, 04 = mês, 18 = dia, 01 = número sequencial]
             604800        ; Refresh [604800 seg = 7 dias]
              86400        ; Retry [86400 seg = 1 dia]
            2419200        ; Expire [2419200 = 28 dias]
             604800 )    ; Negative Cache TTL [604800 seg = 7 dias]

;; "NS"  Servidor autoritativo.
;; "A"   Associa um nome de host a um endereço IP.
;; SUBSTITUA "ns.example.com." PELO NOME DE DOMÍNIO DO SEU RASPBERRY PI, POR EXEMPLO "raspberrypi.example.com."
;; SUBSTITUA "ns" PELO NOME DE HOST DO SEU RASPBERRY PI, POR EXEMPLO "raspberrypi"
;; SUBSTITUA 192.168.0.14 PELO ENDEREÇO IP DO SEU RASPBERRY PI.
@       IN      NS      ns.example.com.
ns      IN      A       192.168.0.14

;; Alguns exemplos de nomes de hosts associados a endereços IP.
;; MODIFIQUE DE ACORDO COM SUA REDE, SEGUINDO O PADRÃO :
;; NOME_DE_HOST        IN     A     ENDEREÇO_IP
esp32      IN      A       192.168.0.100
esp8266 IN      A       192.168.0.101
nodemcu IN      A       192.168.0.102
rasp3    IN      A       192.168.0.103
note    IN      A       192.168.0.104
pc    IN      A       192.168.0.105
tablet    IN      A       192.168.0.106

ATENÇÃO! Não se esqueça de modificar os três primeiros octetos do nome do arquivo (192.168.0) de acordo com sua rede.

vim /etc/bind/db.192.168.0

E incluir o conteúdo abaixo (fique atento aos comentários)!

;; BIND reverse data file for example.com zone

;; Define o tempo de vida (TTL) padrão para registros sem TTLs definidos.
;; O TTL é enviado pelo servidor autoritativo em resposta as consultas feitas pelos servidores recursivos,
;; e descreve por quanto tempo um registro pode ser armazenado em cache antes de ser descartado.
$TTL    604800    ; [604800 seg = 7 dias]

;; "@"   Nome da zona (example.com) seguido por um ponto final.
;; "IN"  Significa Internet.
;; "SOA" Identifica o início de uma zona.
;; "ns.example.com." é o nome do servidor autoritativo da zona example.com.
;; "root.example.com." é o endereço de e-mail do responsável pela zona, substituindo @ por um ponto.
;; SUBSTITUA "ns.example.com." PELO NOME DE DOMÍNIO DO SEU RASPBERRY PI, POR EXEMPLO "raspberrypi.example.com."
;; SUBSTITUA "root.example.com." POR UM EMAIL VÁLIDO, POR EXEMPLO "meuemail.provedor.com."
@    IN    SOA    ns.example.com. root.example.com. (

;; Os parâmetros "Serial", "Refresh", "Retry" e "Expire", dizem respeito a configuração de múltiplos servidores,
;; também conhecido como master (primário) e slave (secundário), embora fora do escopo desse post, será brevemente comentado.
;; "Serial" Número de série que deve ser incrementado a cada mudança no arquivo.
;; "Refresh" Define o período de atualização entre os servidores.
;; "Retry" Se ocorrer um erro durante a atualização, será repetida após o tempo expirar.
;; "Expire" O servidor é considerado indisponível após o tempo expirar.
;; "Negative Cache TTL" Define o tempo de vida de uma resposta NXDOMAIN.
             2019041801        ; Serial [2019 = ano, 04 = mês, 18 = dia, 01 = número sequencial]
             604800        ; Refresh [604800 seg = 7 dias]
              86400        ; Retry [86400 seg = 1 dia]
            2419200        ; Expire [2419200 = 28 dias]
             604800 )    ; Negative Cache TTL [604800 seg = 7 dias]

;; "NS"  Servidor autoritativo.
;; "PTR" Associa um endereço IP a um nome de host (o oposto do tipo "A").
;; SUBSTITUA "ns.example.com." PELO NOME DE DOMÍNIO DO SEU RASPBERRY PI, POR EXEMPLO "raspberrypi.example.com."
;; SUBSTITUA 14 PELO ÚLTIMO OCTETO DO ENDEREÇO IP DO SEU RASPBERRY PI. PARA 192.168.0.14 SERIA 14.
@    IN    NS    ns.example.com.
14    IN    PTR    ns.example.com.

;; Alguns exemplos de endereços IP associados a nomes de hosts.
;; MODIFIQUE DE ACORDO COM SUA REDE, SEGUINDO O PADRÃO :
;; ÚLTIMO_OCTETO_IP     IN     PTR     NOME_DE_HOST
100    IN    PTR    esp32.example.com.
101    IN    PTR    esp8266.example.com.
102    IN    PTR    nodemcu.example.com.
103    IN    PTR    rasp3.example.com.
104    IN    PTR    note.example.com.
105    IN    PTR    pc.example.com.
106    IN    PTR    tablet.example.com.

Vamos checar se o arquivos possuem algum erro de sintaxe.

named-checkconf -z

Se a resposta for algo como :

zone example.com/IN: loaded serial 2019041801
zone 0.168.192.in-addr.arpa/IN: loaded serial 2019041801
zone localhost/IN: loaded serial 2
zone 127.in-addr.arpa/IN: loaded serial 1
zone 0.in-addr.arpa/IN: loaded serial 1
zone 255.in-addr.arpa/IN: loaded serial 1

Está tudo certo.

E agora reiniciar o serviço.

systemctl restart bind9

O último passo é informar ao servidor recursivo – configurado no post anterior – que as consultas para o domínio example.com serão respondidas pelo servidor autoritativo.

Para isso vamos editar o arquivo de configuração:

vim /etc/unbound/unbound.conf

E incluir o conteúdo abaixo no final (fique atento aos comentários!):

# Desativar a validação DNSSEC para domínio privado (example.com).
domain-insecure: "example.com"

# Configurar uma zona local.
# MODIFIQUE OS DOIS PRIMEIROS OCTETOS (192.168 = 168.192) DE ACORDO COM SUA REDE.
local-zone: "168.192.in-addr.arpa." nodefault

# As consultas para o domínio "example.com" serão respondidas pelo servidor autoritativo.
stub-zone:
	name: "example.com"
	# SUBSTITUA 192.168.0.14 PELO ENDEREÇO IP DO SEU RASPBERRY PI.
	stub-addr: 192.168.0.14@5300

stub-zone:
	# MODIFIQUE OS TRÊS PRIMEIROS OCTETOS (192.168.0 = 0.168.192) DE ACORDO COM SUA REDE.
	name: "0.168.192.in-addr.arpa"
	# SUBSTITUA 192.168.0.14 PELO ENDEREÇO IP DO SEU RASPBERRY PI.
	stub-addr: 192.168.0.14@5300

Vamos checar se o arquivo /etc/unbound/unbound.conf possui algum erro de sintaxe:

unbound-checkconf

Se a resposta for “unbound-checkconf: no errors in /etc/unbound/unbound.conf” está tudo certo

E agora reiniciar o serviço:

systemctl restart unbound

Seu servidor DNS autoritativo com Raspberry Pi está pronto!!

Uma ótima ferramenta para testes é o dig, ele faz consultas a servidores DNS, e sua sintaxe é bem simples.

Para consultar um nome de domínio em busca do endereço IP correspondente, você pode digitar no próprio servidor :

dig nome_de_domínio

Ou de qualquer computador na rede local :

dig @ip_servidor nome_de_domínio

Na imagem abaixo o resultado de uma consulta utilizando o dig.

Servidor DNS autoritativo com Raspberry Pi 1

Aqui é possível observar o comando (amarelo), a pergunta (vermelho) – qual o endereço IP de rasp3.example.com? – e a resposta (azul) – o endereço IP 192.168.0.103.

É possível também fazer a consulta reversa, ou seja, consultar um endereço IP em busca do nome de domínio correspondente, para isso você pode digitar no próprio servidor :

dig -x endereço_ip

Ou de qualquer computador na rede local :

dig @ip_servidor -x endereço_ip

Na imagem abaixo o resultado de uma consulta reversa utilizando o dig.

Servidor DNS autoritativo com Raspberry Pi 2 Aqui é possível observar o comando (amarelo), a pergunta (vermelho) – qual o nome associado ao endereço IP 192.168.0.103? – e a resposta (azul) – o nome de domínio rasp3.example.com.

E para finalizar um exemplo prático, onde hipoteticamente o dispositivo rasp3.example.com (Raspberry Pi) possui um servidor web instalado (apt-get install apache2). Antes de configurar o servidor DNS autoritativo, o acesso a esse servidor web era feito obrigatoriamente digitando no navegador o endereço IP 192.168.0.13. Agora com o servidor DNS autoritativo configurado, podemos digitar simplemente seu nome de domínio rasp3.example.com, como ilustrado na imagem abaixo.

Servidor DNS autoritativo com Raspberry Pi Apache2

É importante entender que para o correto funcionamento do DNS autoritativo é preciso que os dipositivos da rede local estejam associados aos endereços IP conforme os arquivos de configuração do DNS autoritativo. Em outras palavras, se no arquivo de configuração do DNS autoritativo o dispositivo rasp3.example.com está associado ao endereço IP 192.168.0.103, é preciso que o dispositivo rasp3.example.com, por suposto um Raspberry Pi, esteja de fato configurado com o endereço IP 192.168.0.103. Geralmente em residências e pequenas empresas quem faz a atribuição dos endereços IP é o roteador sem fio, que possui o recurso de servidor DHCP. No próximo post vamos migrar o DHCP do roteador sem fio para o Raspberry Pi, pois assim teremos um servidor DHCP, com mais recursos, mais customizável e escalável.

Gostou de criar um servidor DNS autoritativo com Raspberry Pi? Ajude-nos a melhorar o blog comentando abaixo sobre este tutorial.

Até a próxima.

Faça seu comentário

Acesse sua conta e participe

5 Comentários

  1. Cara… não deu certo, meu dns se funciona não reconhece meu dominio interno.

    1. Olá igor,
      O post foi corrigido, por favor tente novamente e nos avise.
      Obrigado.

      1. Marcos e se eu quiser usar somente o autoritativo com forwarders? Eu to usando assim, e meus clientes não conseguem resolver nomes do dominio, só externos.

  2. Muito bom seu artigo.
    Gostaria de saber ser teria como implementar o controle por estação ou por horário.

    1. Oi Alexandre,
      Para atender sua demanda seria necessário trabalhar com proxy (squid) e firewall (iptables), além de adicionar mais uma inteface de rede (usb) ao Raspberry Pi. Complicado mas possível. Uma boa ideia para um post futuro. Obrigado.