Administrar um servidor DNS é uma tarefa essencial para administradores de rede. Portanto, neste post, vamos demonstrar os passos de como você pode instalar um servidor de DNS, utilizando o BIND no CentOS. Como sempre, seremos breves e abordaremos de uma maneira também bem simples com o objetivo de agregar o máximo da forma mais rápida.

Requisitos

Para executar este post e entender sobre o BIND, vamos falar um pouco sobre o que será necessário você entender e ter conhecimento.

Informações Necessárias

  • Endereço IP do servidor;
    • Endereço do NAT (caso seja o caso);
  • Endereço IP do servidor secundário (que irá replicar as informações deste servidor);
  • Qual é a rede interna, na forma ciderizada (rede/máscara_binária);
  • Nome do domínio DNS;
  • Qual é a Zona reversa (bloco de IP reservado pela sua operadora, que você tenha delegação/autonomia sobre ela), também na forma ciderizada (rede/máscara_binária);
  • Opcional – Para realizar o backup em uma pasta de rede
    • IP do Servidor de arquivos;
    • Nome da pasta compartilhada;
    • Nome do domínio LDAP;
    • Usuário com acesso à pasta compartilhada;
    • Senha deste usuário.

Qual a diferença entre DNS primário e secundário

DNS secundários replicam suas informações de seus servidores primários. Ou seja, os servidores primários são atualizados suas zonas, enquanto os secundários possuem cópias de arquivos de zona somente para leitura e não são modificados.

Usando este entendimento, uma boa estratégia de migração (considerando que não há problemas em seu DNS) pode ser:

  • Criar o servidor como secundário;
  • Dar permissão (no servidor primário) para este novo servidor replicar suas zonas;
  • Replicar as informações do primário;
  • Alterar as zonas, neste servidor, para primário;
  • Alterar as configurações de rede, apontando este novo servidor como o principal da rede, e;
  • Configurar os servidores secundários para replicar deste novo servidor primário.

Entendendo o conceito de Views no BIND

No BIND pode trabalhar com views, modos/configurações diferentes e independentes para determinadas fontes e/ou destinos de consultas. Para entender view, por exemplo, imagine que você precisa ter dois servidores DNS em sua rede, da seguinte forma:

ServidorObjetivoClientes que consultarãoZonas DNS que possuíRecursividade
(consultar nomes externos)
DNS1Publicação do seu domínioExternos (internet)A zona seudominio.comNão
DNS2DNS para seu AD e para os usuários navegarem na InternetInternos (rede local)A zona intranet.localSim

Entendendo essas duas realidades distintas, a view permitiria no mesmo servidor ter essas duas configurações diferentes, dependendo da origem da consulta DNS (de quem “perguntou”). Permitindo criar uma view para conexões da rede interna (por exemplo com uma zona secundária, replicando de seu AD e permitirá recursividade) e uma segunda view, para demais conexões (por exemplo, com uma zona primária e sem recursividade). Resumindo, a view permitirá que seu DNS aja de formas totalmente diferente para cada requisição.

Em nosso post, iremos criar como exemplo duas views, uma para a consulta global (com zonas e sem recursividade) e uma para o próprio servidor (sem nenhuma zona e com recursividade), por isso iremos separar as zonas nas pastas internal e external (nomes das views). Também deixaremos alguns comentários para facilitar o entendimento de como fazer uma zona primária e uma secundária, adapte conforme seu interesse.

Entendendo o registro SOA

O registro SOA no DNS contém informações administrativas sobre transferências de zona. Ele identifica quando há atualizações na zona, como novos registros, e é essencial para a replicação entre servidores. Sempre que uma zona DNS é atualizada, o número do SOA deve ser incrementado. Ele possuí 10 dígitos, geralmente representado no formato AAAAMMDDID, o comum é utilizar a data de atualização como informação para o SOA, escrevendo os números mais relevantes ficando à esquerda, tornando o padrão AAAAMMDDID, sendo:

  • AAAA o ano, em 4 dígitos: Por exemplo 2024;
  • MM o mês, em 2 dígitos: Por exemplo 08;
  • DD o dia, em 2 dígitos: Por exemplo 16;
  • ID o número da atualização do dia (caso não seja a primeira): Por exemplo: 02;

Desta forma, uma alteração no ano, que aparece à esquerda, torna o número mais significativo do que mudanças no dia ou mês. Veja o exemplo com os números abaixo:

DataPadrão DDMMAAAAPadrão AAAAMMDD
13/12/20241312202420241213
31/05/20223105202220220531

Se usarmos o padrão DIA MÊS ANO, o primeiro número seria menor que o segundo, pois o dia 13, estando à esquerda, seria mais relevante numericamente. Porém, isso não reflete a data mais atual. Para garantir que a data mais recente represente um número maior, o ANO deve vir primeiro, seguido do MÊS e, por último, o DIA, com o ID de atualização ao final. Sendo assim a segunda atualização do dia 16/08/2024 gera o SOA 2024081602.

Apesar de ser importante entender isso, em nosso post vamos sugerir um script de atualização automática do SOA.

Entendendo alguns registros DNS

No DNS você pode criar vários tipos de registros e esse conhecimento é necessário para se administrar de forma eficiente, os mais comuns são:

RegistroFinalidade
ACadastro de um host (padrão)
CNAMEApontar um nome para um host já existente
MXPara troca de e-mails (define a responsabilidade de e-mails para esse servidor)
NSServidor de nomes (um servidor DNS)
TXTRegistro de texto

Algumas dicas:

  • Tanto o MX, CNAME e NS precisam apontar para um registro A existentes;
  • Para registrar o servidor de e-mail para responder em nome de joao@seudominio.com você deve ir na zona do seudominio.com e cadastrar um registro MX sem nome, apontando para o servidor de e-mail. Se você colocar um nome (por exemplo email) você criará um registro o domínio joao@email.seudominio.com
  • Caso você tenha dois servidores de e-mail, mas apenas um deve receber e-mails (o outro é usado apenas para enviar em nome de @seudominio.com) basta você definir prioridades diferentes para cada um (o que recebe e-mail, deve ter uma prioridade menor).
  • Imagine o seguinte cenário: Você possuí um servidor WEB que hospeda 10 diferentes sites de sua empresa, em seu DNS você pode:
  • Criar 10 registros A para o mesmo IP, ou;
  • Criar um registro A para o servidor e 10 registros CNAME apontando para o registro A.

Apesar da segunda opção gerar um registro a mais, se for necessário alterar o endereço desse servidor (uma migração, por exemplo) seria necessário alterar apenas o registro A original, que todos os registros CNAME (que apontam para aquele host A) começariam a ir para o novo endereço IP. É importante pensar desta forma para administrar o DNS de uma forma eficiente.

Preparando o CentOS

Após instalar o servidor e fazer a Configuração padrão após a instalação do CentOS9, remova alguns pacotes e desabilite o IPv6. Para isso, execute os comandos:

yum remove desktop-file-utils cairo samba-common dosfstools man-pages mcelog nano smartmontools usbutils words adobe-source-code-pro-fonts dejavu-sans-fonts groff-base sssd-client pixman plymouth freetype rsyslog -y
echo "OPTIONS=\"-4\"" >> /etc/sysconfig/named

Ao final reinicie o servidor.

Instalando o BIND

Para instalar o BIND, execute os comandos:

yum install bind bind-utils -y

firewall-cmd --permanent --add-service=dns
firewall-cmd --reload
systemctl enable named

Configurando o BIND

Depois do BIND instalado, execute o seguinte comando para editar seu arquivo de configuração:

vim /etc/named.conf

Dentro do arquivo, pressione INSERT para entrar modo de edição, apague tudo e deixe-o com o seguinte conteúdo (no exemplo acima cadastraremos apenas uma zona DNS, cadastre quantas forem relativas ao seu ambiente, altere também as partes em cinza conforme sua realidade):

options {
              listen-on port 53               { any; };
              directory                           "/var/named";
              dump-file                          "data/cache_dump.db";
              statistics-file                     "data/named_stats.txt";
              memstatistics-file             "data/named_mem_stats.txt";
              version                              "Versao Indisponivel";
              dnssec-enable                   yes;
              dnssec-validation               yes;
};
 
logging {
              channel default_log {
                            file            "/var/log/named/named.log" versions 3 size 10M;
                            print-time      yes;
                            print-category  yes;
                            print-severity  yes;
                            severity        info;
              };
};
 
acl "dns_slaves" {  IP_SERVIDOR_DNS_SECUNDARIO; };

server ::/0 {
        bogus yes;
};

view "internal" {
       match-clients                        {  localhost; IP_DO_SERVIDOR; };
       match-destinations               { any; };
       recursion                                yes;
               forwarders {
                             9.9.9.9;
       };
       include                 "/etc/named.rfc1912.zones";
};
 
view "external" {
              match-clients                      { any; };
              match-destinations            { any; };
              recursion                             no;
              allow-query-cache              { none; };
              allow-transfer                     { dns_slaves; };
              include                                "/etc/named.rfc1912.zones";
              zone "IP_Reverso.in-addr.arpa" in {
                            type                       master;
                            file                         "zones/external/IP_Reverso.in-addr.arpa.dns";
              };
              zone "nome_dominio_dns" {
#                          type                        slave;
#                          masters                   { IP_DNS_MASTER; };
#                          masterfile-format   text;
                            type                         master;
                            file                           "zones/external/nome_dominio_dns.dns";
              };
};

Por fim, pressione ESC para sair do modo de edição e digite :wq! para sair e salvar. Em seguida, execute:

rm -rf /etc/named
ln -s /var/named /etc/named

foldernamed=`grep directory /etc/named.conf | grep -v '-' | cut -d\" -f2`
mkdir -p $foldernamed/zones/external
mkdir -p $foldernamed/zones/internal
chown -R named.named $foldernamed/zones; chmod -R 775 $foldernamed

for i in `grep "file" /etc/named.conf | grep .dns | cut -d\" -f2`; do touch $foldernamed/$i; chown named.named $foldernamed/$i;chmod 660  $foldernamed/$i; done;

mkdir -p /var/log/named
touch /var/log/named/named.log
touch /var/log/named/named_debug.log
touch /var/log/named/named_transfers.log
chown named.named /var/log/named/*
sed -i "s/\/var\/named\/data\/named.run/\/var\/log\/named\/*.log/g" /etc/logrotate.d/named

Criando a zona DNS

Agora vamos criar um arquivo com os dois servidores DNS (primário e secundário), com o objetivo de importar esse arquivo em toda zona DNS (todo domínio) que utilizarmos. Desta forma para alterar a lista de servidores DNS é necessário alterar apenas um arquivo (em vez de dezenas de zonas DNS). Para isso, execute:

echo "                    NS      srv-dns-pri.nome_dominio_dns." > /etc/named/zones/external/dns_servers.db
echo "                    NS      srv-dns-sec.nome_dominio_dns." >> /etc/named/zones/external/dns_servers.db

chown named.named /etc/named/zones/external/dns_servers.db
chmod 660 /etc/named/zones/external/dns_servers.db

Agora vamos criar o arquivo do domínio e cadastrar alguns registros de exemplo, para isso execute o comando:

vim zones/external/nome_dominio_dns.dns

Dentro do arquivo, pressione INSERT para entrar modo de edição, apague tudo e deixe-o com o seguinte conteúdo (altere as partes em cinza conforme sua realidade):

; ---------------- CONFIGURACOES DO SERVIDOR -----------------------
$ORIGIN nome_dominio_dns
$TTL 3600 ; 1 hour
@ IN SOA srv-dns-pri.nome_dominio_dns. suporte.nome_dominio_dns. (
                                            2024081601 ; serial
                                            3600 ; refresh (1 hour)
                                            3600 ; retry (1 hour)
                                            1209600 ; expire (2 weeks)
                                            3600 ; minimum (1 hour)
                                            )
; ---------------- REGISROS DE DOMINIO ----------------
$INCLUDE /etc/named/zones/external/dns_servers.db
                               MX    100    srv-mail.nome_dominio_dns.
; ---------------- LISTA DE SERVIDORES ----------------
srv-dns-pri                    A            200.200.200.1
srv-dns-sec                    A            200.200.200.2
srv-mail                       A            200.200.200.3
srv-web                        A            200.200.200.4
www                            CNAME        srv-web

Lembre-se de deixar os registros (depois da parte LISTA DE SERVIDORES) em ordem alfabética e também de alterar o SOA (lembrando que o padrão é AAAAMMDDID). Ao final, pressione ESC para sair do modo de edição e digite :wq! para sair e salvar.

Testando seu servidor

Para testar sua configuração, execute os comandos:

named-checkconf
named-checkconf -z /etc/named.conf

ATENÇÃO no resultado deste comando, não deve haver erros (ou o DNS não irá funcionar ainda)

systemctl start named

Abra os arquivos das zonas (.dns) e verifique se os arquivos estão sendo populados. Vá também no site https://mxtoolbox.com/DNSCheck.aspx e faça os testes DNS. Se desejar verificar as conexões que estão ocorrendo ao servidor, utilize o comando:

ss -antpl | grep named

Opcional – Script para Atualização e Backup

Sugerimos fazer esse procedimento apenas no servidor de DNS primário. Vamos sugerir um script que:

  • Liste todas as zonas que foram atualizadas há menos de 15 minutos e, se houver, atualize o SOA delas;
    • Tendo zona atualizada, teste a configuração do BIND e reinicie o serviço;
  • Crie um arquivo compactado, com toda a configuração do BIND, e envie para uma pasta de rede compartilhada em outro servidor (CIFS)

Primeiramente, vamos configurar o necessário para o CentOS acessar um compartilhamento. Em seguida, iremos criar um script para backup e envio. Para começar, a fim de instalar o necessário para o CentOS acessar compartilhamentos CIFS, execute:

yum install samba-client -y

Para criar um script de backup, execute:

touch /etc/named/bind_check.sh
chmod 755 /etc/named/bind_check.sh
ln -s /etc/named/bind_check.sh /usr/bin/bind_check.sh
ln -s /etc/named/bind_check.sh /usr/bin/named_check.sh

vim /etc/named/bind_check.sh

Dentro do vim, pressione a tecla INSERT para entrar em modo de edição e insira o seguinte:

#!/bin/bash
# ----------------------------- Define VARIAVEIS ----------------------------- 
ControlDate=$(date '+%Y-%m-%d %H:%M:%S')
CurrentSOA=$(date --date="$ControlDate" '+%Y%m%d')01
CIFSServer="IP_servidor_CIFS"
CIFSFolder="Pasta_compartilhada"
CIFSUsername="usuario_cifs@dominio_autenticacao"
CIFSPassword="senha_da_conta"
echo"";echo " ----------------------------- Updating Zones -----------------------------";echo""
UpdateSerialZone () {
        for BindZone in $(find /etc/named/zones/$1 -type f -cmin -15 | grep dns); do
                BindZoneSOA=$(grep "serial" $BindZone | head -n1 | cut -d\; -f1 | tr -d -c 0-9)
                if [[ ! -z $BindZoneSOA && ! -z $CurrentSOA ]];then
                        if [ $BindZoneSOA -ge $CurrentSOA ]; then
                                NewSOA=$(($BindZoneSOA + 1))
                        else
                                NewSOA=$CurrentSOA
                        fi
                        sed -i "s/$BindZoneSOA ; serial/"$NewSOA" ; serial/g" $BindZone
                        echo "$BindZoneSOA ---- $BindZone"
                        vairestartar=true
                fi
        done
}
UpdateSerialZone internal
UpdateSerialZone external
if [ $vairestartar ];then
    echo"";echo " ----------------------------- Restarting DNS ----------------------------- ";echo""
    if [ ! -z $(named-checkconf) ];then
        echo "Error - Please ${bold} Check${normal} "
        exit 0
    fi
    if [ ! -z $( named-checkconf -z /etc/named.conf | grep "ignoring out-of-zone data") ];then
        echo "Error - Please ${bold} Check${normal} "
        exit 0
    fi
    systemctl restart named
fi
echo"";echo " ----------------------------- BackUping files -----------------------------";echo""
tar cvzf /tmp/$(hostname -s)_$(date --date="$ControlDate" '+%Y%m%d_%H%M%S').tgz /etc/named* 2>/dev/null
echo"";echo " ----------------------------- Copying  Files to FileServer -----------------------------";echo""
for file in `ls /tmp | grep $(hostname -s) | grep _ | grep tgz`; do
        echo "Copying $file"
        smbclient //$CIFSServer/$CIFSFolder -U $CIFSUsername -pass $CIFSPassword -c "lcd /tmp/; put $file"
        rm -rf /tmp/$file
done
echo"";echo " ----------------------------- Done -----------------------------";echo""

Ao final, pressione ESC para sair do modo de edição e digite :wq! para sair e salvar.

Por fim iremos agendar a execução do script para toda segunda-feira, às 23:00. Para isso execute:

echo "SHELL=/bin/bash" > /etc/cron.d/bkp_dns
echo "PATH=/sbin:/bin:/usr/sbin:/usr/bin" >> /etc/cron.d/bkp_dns
echo "0 23 * * 1 root /usr/bin/named_check.sh" >> /etc/cron.d/bkp_dns

Fontes/Referências

NVLAN – Configuração padrão após a instalação do CentOS9
NVLAN – Copiar arquivos do Linux CentOS para um pasta compartilhada de rede SMB (Cifs)

https://bobcares.com/blog/bind9-disable-ipv6
https://cloudinfrastructureservices.co.uk/how-to-install-bind-dns-on-centos-stream-9-server-setup-configure
https://cloudflare.com/pt-br/learning/dns/glossary/primary-secondary-dns
https://crontab.guru/every-monday
https://digitalocean.com/community/tutorials/how-to-configure-bind-as-a-caching-or-forwarding-dns-server-on-ubuntu-14-04
https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/4/html/reference_guide/s2-bind-configuration-zone-reverse
https://en.wikipedia.org/wiki/SOA_record
https://kb.isc.org/docs/aa-00851
https://kb.isc.org/docs/aa-01526
https://rosehosting.com/blog/how-to-set-up-private-dns-servers-with-bind-on-centos-8
https://serverfault.com/questions/833270/why-am-i-seeing-ipv6-resolve-errors-despite-having-disabled-ipv6-in-bind
https://serverfault.com/questions/954269/bind-force-zone-update-on-slave
https://stackoverflow.com/questions/31260837/how-to-run-a-cron-job-on-every-monday-wednesday-and-friday

Mais Informações

Esperamos ter ajudado e estamos à disposição para mais informações.

Se você tem interesse em algum assunto específico, tem alguma dúvida, precisa de ajuda, ou quer sugerir um post, entre em contato conosco pelo e-mail equipe@nvlan.com.br.

NVLAN - Consultoria