Bind9: Guia Completo para Configurar um Nameserver no Seu Homelab com Docker

Configurar um nameserver no seu homelab pode parecer complicado, mas com o Bind9 e Docker, o processo fica bem mais simples. Neste tutorial, vou te mostrar passo a passo como instalar e configurar o Bind9, explicando cada etapa de forma prática.

Por: Filipe | Adicionado em 09/01/2025

Este artigo começará com duas questões simples: O que é DNS? E porque você deveria ter seu próprio servidor de DNS no seu HomeLab?


Domain Name System (DNS) ou Sistema de Nomes de Domínio é um sistema hierárquico, este sistema “resolve” endereços de IP em domínios, ou seja, serve como um dicionário para associar um domínio a um endereço de IP.


Basicamente quando digitamos, por exemplo, techlabhub.com que é um domínio, este é resolvido para o IP onde este blog está hospedado, é assim que a internet associa os domínios de sites (e demais serviços) com os servidores onde estes domínios estão.


Mas porque ter o próprio servidor de nomes de DNS no seu HomeLab? Afinal, já existem vários ao redor do mundo que já resolvem os domínios da internet aos IP’s dos servidores onde as aplicações destes domínios estão hospedadas. A resposta é bem simples: praticidade em acessar suas aplicações locais.


Diagrama DNS

Imagino que se vocês estão lendo este artigo, assim como eu, possuem inúmeros serviços sendo executados no HomeLab de vocês, e ter seu próprio servidor autoritativo de DNS te permite usar domínios de forma local sem a necessidade de expor estes serviços na internet, caso utilize um domínio registrado que você possua, ainda é possível configurar formas de automatizar a emissão de certificados de SSL para aplicações locais, aprimorando a segurança desses serviços (será tema para um futuro artigo).


No meu HomeLab eu utilizo o servidor autoritativo de DNS Bind9 em conjunto com o Pihole. O Bind9 para resolver as consultas de DNS locais e o Pihole para resolver as querys de DNS externas e para funcionar como um filtro de DNS na rede inteira servindo como um adblock.


Neste artigo irei abordar sobre a instalação e configuração do Bind9 utilizando Docker, o sistema operacional utilizado é o Debian.


Já partindo do pressuposto que possuem o Docker instalado na sua máquina virtual, caso não tenha, pode estar verificando na documentação oficial do Docker CLICANDO AQUI para instalar no seu sistema.


O primeiro passo para iniciar a configuração do Docker do Bind9 será criar uma pasta (no meu caso no diretório principal), a minha será nomeada de Bind9, mas podem nomeá-la como desejar. Dentro deste diretório, crie um arquivo chamado docker-compose.yaml.


Configuração do docker-compose.yaml:

1
2
3
4
5
---
services:
  bind9:
    container_name: techlab-dns
    image: ubuntu/bind9:latest

Aqui, é definido o início do arquivo, o nome do serviço, do contêiner e a imagem que será utilizada. A imagem escolhida é a do Ubuntu, a versão LTS da canonical, mas podem utilizar a imagem que desejar.

Até pouco tempo atrás, era definido a versão da imagem do docker no início do arquivo, mas essa configuração está depreciada, então começamos o arquivo assim:

1
2
3
  environment:
    - BIND9_USER=root
    - TZ=SouthAmerica/Sao_Paulo

Já aqui no ambiente, é definido o usuário do Bind9 como root, e o fuso horário para América do Sul São Paulo.


1
2
3
  ports:
    - "53:53/tcp"
    - "53:53/udp"

Aqui é definido as portas para expor o servidor do Bind9, na porta 53 (padrão do DNS) usando os protocolos TCP e UDP. O docker por padrão quando definimos as portas, expõem apenas no protocolo TCP, então defini manualmente os dois protocolos para que a porta 53 seja exposta em ambos.


1
2
3
4
  volumes:
    - ./config:/etc/bind
    - ./cache:/var/cache/bind
    - ./records:/var/lib/bin

Aqui é definido para “montar” três volumes para o contêiner. Sendo o primeiro a pasta de configuração, o segundo para o cache e o terceiro para os registros que serão gerados.

Lembrando que, a pasta que foi criada no início é a pasta raiz, então as pastas config, cache e records devem ser criadas no mesmo diretório que está o arquivo docker-compose.yaml.


1     restart: unless-stopped

E por último é configurado a política de quando e como o contêiner deve ser iniciado/parado, no contexto atual, é imperativo que o servidor de autoridade de DNS sempre esteja em execução, mesmo que a máquina virtual ou hospedeiro seja reiniciado, pois assim que forem ligados, o contêiner é iniciado automaticamente.


Ficando assim, compose completo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
services:
  bind9:
    container_name: techlab-dns
    image: ubuntu/bind9:latest
    environment:
      - BIND9_USER=root
      - TZ=SouthAmerica/Sao_Paulo
    ports:
      - "53:53/tcp"
      - "53:53/udp"
    volumes:
      - ./config:/etc/bind
      - ./cache:/var/cache/bind
      - ./records:/var/lib/bin
    restart: unless-stopped

Após definir o arquivo compose do docker, é necessário criar o arquivo de configuração principal. Este arquivo deve ser criado no diretório config, o nome do arquivo deve ser named.conf. Neste arquivo vamos definir os redirecionamentos e demais configurações necessárias.


Configuração do arquivo named.conf:

1
2
3
4
5
acl internal {
    192.168.0.0/24;
    192.168.1.0/24;
    192.168.2.0/24;
};

Aqui é definido cada interface de rede que o Bind9 deve atender resolvendo as consultas de DNS.


1
2
3
4
5
options {
    forwarders {
      1.1.1.1;
      1.0.0.1;
    };
    allow-query { internal; }
};

Como este servidor autoritativo de DNS será apenas local, ele não será capaz de resolver consultas de DNS externas, por isso é necessário configurar um redirecionamento para servidor(es) autoritativos externos, neste caso, aqui está definido para utilizar o servidor de DNS da Cloudflare e permitir apenas consultas internas definidas na configuração do ACL, onde foram listadas quais interfaces de rede podem fazer as consultas de DNS através do Bind9.


Até o momento já temos o básico para que possamos realizar um teste para ver se está tudo funcionando antes de configurar as zonas de domínios. Portando só executar com o terminal estando no mesmo diretório do arquivo docker-compose.yaml o seguinte comando:

1 sudo docker compose up

Caso esteja utilizando Ubuntu ou alguma outra distro que venha com servidor de DNS nativo para resolver DNS internamente, provavelmente terá algum erro de que a porta 53 já está em uso e isso impedirá que o contêiner seja iniciado. Para resolver essa questão, em distros baseadas no Debian, basta editar o arquivo resolved.conf com o seguinte comando:

1 sudo nano /etc/systemd/resolved.conf

E então procurar pela linha chamada DNSStubListener=yes e remover o # e mudar o valor para no, e executar o seguinte comando no terminal:

1 sudo systemctl restart systemd-resolved

Isso desativará o uso da porta 53 e será possível agora executar o contêiner sem erros, caso esteja usando o debian com a instalação mínima, este processo não será necessário.


Para testar se está funcionando, tente fazer um teste usando o nslookup com o IP local do Bind9 no final, no terminal:

1 nslookup techlabhub.com 192.168.0.10

Caso o endereço de IP local do Bind9 não seja definido no final, o nslookup irá utilizar o seu servidor de DNS padrão já configurado no seu sistema.


Após realizar o teste e constatar que está funcionando, é o momento de configurar a zona de DNS, nesta parte eu recomendo utilizar um domínio que você tenha a propriedade, pois abre um leque maior para personalização, permite emitir certificados de SSL (sem ser os autoassinados) e automatizar a emissão destes certificados, etc. Caso não queira utilizar um domínio próprio, é possível utilizar um domínio falso, já que a resolução das consultas de DNS será local.


1
2
3
4
zone "local.techlabhub.com" IN {
    type master;
    file "/etc/bind/local.techlabhub.com";
    };

Utilizei o subdomínio “local.techlabhub.com” do meu domínio para ser a zona local, poderia ser um domínio falso também, mas recomendo utilizar um domínio que seja seu. É importante mencionar que o Bind9 suporta múltiplas zonas de DNS, mas para este artigo, iremos abordar a configuração de apenas uma. No tipo, especifiquei como “master” que indica ao Bind9 ele é responsável pela consulta deste subdomínio (zona) e que não precisa redirecionar a consulta externamente.


Ficando assim, o arquivo named.conf completo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
acl internal {
    192.168.0.0/24;
    192.168.1.0/24;
    192.168.2.0/24;
};
options {
    forwarders {
        1.1.1.1;
        1.0.0.1;
    }
    allow-query { internal; };
};
zone "local.techlabhub.com" IN {
    type master;
    file "/etc/bind/local.techlabhub.com";
};

Por fim, devemos criar o arquivo local.techlabhub.com, este arquivo deve ficar dentro da pasta config, pois na linha “file” foi especificado o caminho onde o Bind9 encontrará o arquivo com as entradas dos registros de DNS, no arquivo docker foi definido que a pasta config é a pasta /etc/bind do contêiner.


Configuração do arquivo local.techlabhub.com:

1
2
$TTL 1d
$ORIGIN local.techlabhub.com.

O arquivo é iniciado com o TTL(time to live / tempo de vida), isso define quanto tempo as entradas de DNS devem ser mantidas em cache, nesta configuração, ficou definido em um dia. E também é definido a origem, que é o nome da zona de DNS que será configurado, pois ao definir o nome da zona de DNS podemos adicionar as entradas de DNS apenas com o nome do host, sem precisar definir o nome do domínio completo todas as vezes quando for criar um registro de DNS.


1
2
3
4
5
6
7
@ IN SOA ns.local.techlabhub.com. info.techlabhub.com. (
       1112202400 ; número de série
       12h ; intervalo de atualização
       15m ; intervalo de nova tentativa
       3w ; tempo de expiração
       2h ; ttl mínimo
       )

Este é o primeiro registro com configurações administrativas, este registro é a base da configuração da zona de DNS, seguimos o padrão utilizado em todas.

@: representa o domínio principal, na qual o registro se aplica, no contexto atual o local.techlabhub.com.

IN: representa o tipo de classe de DNS, que significa “Internet”, é o mais comum para registros de DNS.

SOA: indica o ponto de autoridade inicial para o domínio, pois este é o servidor que possui a cópia principal da zona de DNS, este é obrigatório em qualquer arquivo de zona de DNS.

ns.home.techlabhub.com: específica o nome do servidor DNS primário (Primary Name Server), ou o servidor de nome (nameserver), que por sua vez é responsável pela manutenção e propagação dos registros de DNS dessa zona de DNS.

info.techlabhub.com: embora aparente ser um domínio comum, no formato de DNS o “@” do endereço de e-mail é substituído por um ponto (.).

Por exemplo: ([email protected]) se torna (info.techlabhub.com.).


As demais informações em ordem são:

Número de série: que é representado por uma sequência numérica de 10 dígitos, o valor que eu defini foi a data de quando eu implementei o servidor que deve ser incrementado sempre que a configuração for atualizada.

Intervalo de atualização: este é o tempo que os servidores de DNS secundários consultam o servidor primário para verificar se há atualização na zona de DNS.

Intervalo de nova tentativa: este se refere ao intevalo de tempo que um servidor de DNS secundário deve esperar antes de tentar novamente contatar o servidor primário, caso uma tentativa anterior de atualização da zona tenha falhado.

Tempo de Expiração: é o tempo máximo que um servidor de DNS secundário pode armaszenar dados da zona em cache sem conseguir atualizá-los a partir do servidor primário. Após este tempo, os dados são considerados inválidos e não serão mais servidos.

TTL Mínimo(Tempo de Vida Mínimo): é o tempo em segundos que um registro de DNS pode ser armazenado em cache por servidores ou resolvers antes de ser descartado ou atualizado.


1
2
3
IN NS ns.home.techlabhub.com.
ns  IN A 192.168.0.10
; -- adicione os registros de DNS abaixo

Este é o segundo registro que define o servidor de nome, este registro é o que dirá a todos, qual servidor, é o responsável por conter os registros de DNS desta zona. Ele não precisa do nome do host, então começamos diretamente com o tipo IN seguido pelo tipo de registro que é o NS (servidor de nome) e então especificamos o servidor de nome. O terceiro registro começamos com ns sendo o nome do servidor, adicionamos o IN e o tipo do registro será o A, para definir o IP do servidor de nomes que é o IP do servidor de DNS.


Abaixo desta linha podemos adicionar qualquer registros de DNS que desejarmos, se você tiver uma aplicação web como o Jellyfin ou Plex por exemplo, você pode adicionar um subdomínio localmente para esta aplicação adicionando um registro do tipo A assim:

1 jellyfin    IN  A  192.168.0.15

Ficando assim o completo:
1
2
3
4
5
6
7
8
9
10
11
12
13
$TTL 1d
$ORIGIN local.techlabhub.com.
@ IN SOA ns.local.techlabhub.com. info.techlabhub.com. (
    1112202400 ; número de série
    12h ; intervalo de atualização
    15m ; intervalo de nova tentativa
    3w ; tempo de expiração
    2h ; ttl mínimo
    )
    IN NS ns.home.techlabhub.com.
ns IN A 192.168.0.10
; -- adicione os registros de DNS abaixo
jellyfin IN A 192.168.0.15

Há vários outros registros de DNS que você pode utilizar, cada um com sua funcionalidade específica, como MX para e-mail, CNAME para aliase, etc.


Agora, para utilizar este servidor de DNS, basta iniciar o contêiner e executar no terminal no mesmo diretório onde se encontra o arquivo docker-compose.yaml e digitar:

1 sudo docker compose up -d

Para adicionar o servidor autoritativo de DNS na sua rede interna, você pode configurar manualmente nos seus dispositivos colocando o IP do servidor nos campos de DNS nas configurações de rede, ou definindo no DHCP do seu router e/ou servidor de DHCP caso tenha algum dedicado, o IP do servidor de DNS.


Lembrando que esta configuração foi feita para um ambiente local, se for utilizar o Bind9 para ser um servidor de DNS externo, algumas modificações de segurança nas configurações devem ser feitas.