Skip to main content

DNS - Domain Name System



BIND - Berkeley Internet Name Domain


O BIND é um software que implementa o Protocolo de Resolução de Nomes (DNS). Ele é Open Source e é amplamente utilizado em todo o mundo. Ele foi desenvolvido originalmente pela Universidade da Califórnia, em Berkeley, nos Estados Unidos. O BIND é capaz de executar tanto funções de servidor de nomes primários quanto secundários e pode funcionar como um servidor DNS recursivo para consultas de clientes. Além disso, ele suporta todas as principais características do DNS, como registros de recursos (RRs), zonas DNS, atualizações dinâmicas de zona, assinatura de zona DNS com DNSSEC, entre outros recursos avançados.



Formato e estilo de configuração


O BIND usa alguns formato de configurações, podendo agrupar certas configurações num conjunto ou mantê-las e forma individual. As linhas de configuração individual são conhecidas como declarações (statements em inglês) e cada declaração é encerrada com um ponto e vírgula. Essas declarações são organizadas dentro de cláusulas (clauses em inglês), que começam em uma nova linha. Todas as declarações dentro de uma cláusula são colocadas entre chaves e terminam com um ponto e vírgula.


Veja um exemplo de Declaração (*statement*):
recursion yes;

# Ou:
stale-cache-enable false;

Veja um exemplo de Cláusula (clause):

allow-recursion {
127.0.0.0/8;
192.168.121.0/24;
};

Podemos ainda representar uma Cláusula em uma única linha:

# Representando em várias linhas:
allow-recursion {
127.0.0.0/8;
192.168.121.0/24;
};

# Representando numa única linha:
allow-recursion {127.0.0.0/8;192.168.121.0/24;};

# Podemos mesclar os dois usos, veja a parte de 'master':
zone "example.com" {
type slave;
file "slave.example.com";
masters {10.0.0.1;};
};

O BIND já possui as Cláusulas predefinidas, possuindo algumas formas de configurá-las como visto acima, vejamos então um pouco de cada uma.



Options Clause


A Cláusula de Opções é usada para configurar parâmetros gerais do servidor BIND, como endereços IP em que o servidor irá escutar, arquivos de log, configurações de cache, e comportamentos no geral. Um pequeno exemplo dessa Cláusula:

options {
directory "/var/named";
pid-file "/var/run/named/named.pid";
session-keyfile "/var/run/named/session.key";
dnssec-validation auto;
listen-on-v6 { any; };
};


Zone Clause


Essa cláusula é usada para definir uma zona de DNS. Ela especifica o nome da zona, o tipo de zona e a localização do arquivo que contém os dados da zona. Um pequeno exemplo dessa Cláusula:

zone "example.com.br" {
type master;
file "master/example";
};

Define a zona chamada example.com.br com o tipo master e informa que os dados dessa zona estão no arquivo localizado em master/example. O BIND supõe que esse arquivo esteja dentro do diretório configurado na opção directory, que no nosso exemplo é directory "/var/named";, ou seja, o arquivo de zona está em /var/named/master/example.



Acl Clause


Essa cláusula é usada para definir listas de controle de acesso que determinam quais endereços IP ou redes têm permissão para fazer consultas ou atualizações no servidor BIND. Um pequeno exemplo dessa Cláusula:

acl "network-allow" {
172.16.2.10;
172.16.2.15;
};

Cria uma ACL chamada network-allow que possui os dois IP informados abaixo dela.


As ACLs utilizam uma lógica onde a primeira ACL a corresponder será aplicada; se um prefixo de endereço corresponder a um elemento da ACL, então essa ACL é considerada como correspondida, e nenhuma outra ACL depois dela será verificada, mesmo que um elemento posterior pudesse corresponder de forma mais específica. Por exemplo, a ACL { 10/8; !10.0.0.1; } realmente corresponderia a uma consulta de 10.0.0.1, porque o primeiro elemento indica que a consulta deve ser aceita, e o segundo elemento é ignorado (nesse caso, o segundo elemento nega (!) o IP 10.0.0.1).


É possível usar ACLs "aninhadas" (nested), ou seja, ACLs incluídas ou referenciadas dentro de outras ACLs. Isso permite a construção de ACLs complexas, nas quais múltiplas características do cliente podem ser verificadas ao mesmo tempo. Por exemplo:

// Declara uma chave TSIG:
key chave1 { algorithm hmac-sha512; secret "...."; };

// Cria uma ACL com a rede permitida para transferência de zona:
acl rede_permitida { 192.168.1.0/24; };

// ACL contendo a chave TSIG:
acl chave_permitida { key chave123; };

// Cria uma ACL contendo o a rede permitida e achave:
acl acl_allow_transfer { chave_permitida; rede_permitida; };

// Permite a transferência para 'acl_allow_transfer' que possui IP e chave específica:
allow-transfer { acl_allow_transfer; };

Usando negação (!) duas vezes. Quando usamos duas vezes uma negação, estamos negando a negação, e quando se nega algo negado, você está na verdade permitindo, vejamos um exemplo simples:

// Declara uma chave TSIG:
key chave1 { algorithm hmac-sha512; secret "...."; };

// Cria uma ACL com a rede permitida para fazer consultas:
acl rede_permitida { 192.168.1.0/24; };

// Permite consulta para '192.168.1.0/24' e que possui uma chave específica, todos os outros são negados:
allow-query { !{ !rede_permitida; any;} key chave1; };

  • !rede_permitida - Esta expressão nega a lista de endereços IP na ACL rede_permitida. Ou seja, está negando a permissão para a rede 192.168.1.0/24.

  • !{ !rede_permitida; any;} - Aqui, estamos novamente negando a negação da ACL rede_permitida, o que efetivamente a torna uma afirmação positiva. Também estamos negando a qualquer outra origem (any); isso significa que estamos negando a permissão para consultas de qualquer origem.

  • key chave1 - Esta parte da expressão exige que a consulta esteja assinada com a chave específica chave1.


Portanto, a expressão allow-query { !{ !rede_permitida; any;} key chave1; } está permitindo consultas apenas dos endereços IP na rede 192.168.1.0/24 e que estejam assinadas com a chave específica chave1. Todos os outros endereços IP serão negados.



Logging Clause


Essa cláusula permite configurar os logs (registro de eventos) do servidor BIND. É possível especificar os níveis de log, arquivos de log e formatos de registro. Um pequeno exemplo dessa Cláusula:

channel abobrinha {
file "/var/log/named/transfers" versions 3 size 10M;
print-time yes;
severity info;
};

Essa chave declara um canal chamado abobrinha, dentro desse canal, vamos dizer qual o arquivo onde será armazenado o log, isso é fornecido pela opção file. A opção print-time yes; é usada para guardar o Log com hora e data. Já severity info; informa o nível de verbosidade do log (quanta informação deverá ser exibida).



View Clause


Essa cláusula é usada para definir visualizações (views) no servidor BIND, permitindo a configuração de diferentes conjuntos de zonas e políticas de resolução de DNS com base em critérios como endereço IP de origem ou nome do cliente, ou seja, dependendo do endereço IP que está fazendo uma consulta no nosso servidor DNS ele responderá com um grupo de dados. A ordem na qual as instruções de view são definidas é muito importante.


Essa Cláusula é útil para que pessoas consultando dados no nosso servidor DNS recebam um tipo de resposta e pessoas dentro da empresa recebam outro tipo de repostas. Um pequeno exemplo dessa Cláusula:

view RedeInterna {
match-clients { network-allow; 172.16.3.9; };

zone "example.com.br" {
type master;
file "master/example";
};
};

view RedeExterna {
match-clients { any; };

zone "example.com.br" {
type master;
file "master_externo/example";
};
};

Aqui definimos duas views: "RedeInterna" e "RedeExterna". Cada view possui uma cláusula match-clients que define quais clientes podem ser atendidos por cada uma das views.


Na view RedeInterna, apenas o endereço IP 172.16.3.9 e os clientes definidos na ACL network-allow têm permissão para fazer consultas. Se algum desses IP consultarem, eles vão receber os dados da zona armazenados em master/example.


Já na view RedeExterna, qualquer cliente (representado por any) tem permissão para fazer consultas, mas receberá os dados armazenado em master_externo/example que contém informações diferentes daqueles que estão na rede interna.


Apesar de ser muito boa essa configuração, se o sistema de arquivos desse DNS for comprometido por qualquer motivo, uma simples inspeção da zona e dos arquivos de configuração revelará informações sobre a organização.



address_match_list


É usado para dar match em cláusulas que usam condições. As cláusulas que usam são: match-clients, listen-on-v6, acl, allow-recursion e muitas outras.

NomeDescrição
anyCorresponde a todos os hosts.
noneNão corresponde a nenhum host.
localhostCorresponde aos endereços IPv4 e IPv6 de todas as interfaces de rede no servidor, mas apenas quando acessado a partir do próprio servidor—não tem escopo quando o acesso é externo. Por exemplo, se o servidor tiver uma única interface com um endereço IP de 192.168.2.3, então localhost corresponderá a 192.168.2.3 e 127.0.0.1 (o endereço de loopback está sempre presente).
localnetsCorresponde a qualquer host em uma rede IPv4 ou IPv6 para a qual o servidor tenha uma interface, incluindo o endereço de loopback. Ou seja, se o servidor tiver duas interfaces, a primeira com um endereço IP de 192.168.2.3 e uma máscara de sub-rede de 255.255.255.0 (ou 192.168.2/24) e a segunda com um endereço IP de 10.0.2.2 e uma máscara de sub-rede de 255.255.0.0 (ou 10.0/16), localnets corresponderá a 192.168.2.0 a 192.168.2.255, 10.0.0.0 a 10.0.255.255 e 127.0.0.1 (o endereço de loopback é sempre considerado como um único endereço).


Server Clause


A cláusula do server define um servidor de nomes específico (seja um nome ou um endereço IP) ao qual o rndc pode se conectar. Ela pode conter duas declarações. A primeira é a declaração key, que define a chave específica a ser usada para se conectar ao servidor. Se não estiver presente, será usada a declaração default-key. Uma ou mais cláusula server podem ser usadas.


A segunda, a declaração port, define o número da porta a ser usado com o servidor específico. Se não estiver presente, será usada a declaração default-port da cláusula options; caso contrário, será usado o padrão do rndc, que é 953. O exemplo a seguir ilustra uma cláusula de servidor típica.

server "75.119.143.187" {
key "ns1.hermodr.com.br";
port 953;
};

A cláusula do server no arquivo de configuração do rndc também é usada para especificar qual chave TSIG deve ser utilizada durante a transferência de zona. A declaração key dentro da cláusula do servidor aponta para a chave TSIG específica que será usada para autenticar a comunicação entre o servidor de controle (rndc) e o servidor de nomes (BIND) durante a transferência de zona. Essa chave compartilhada é essencial para garantir a segurança e a autenticidade das operações de transferência de zona entre os servidores.

O BIND faz as transferências de zona usando o RNDC.



Key Clause


A cláusula de key define o nome de uma chave secreta compartilhada que pode ser usada por um dos servidores sendo acessados. Uma ou mais cláusulas key podem ser definidas. A cláusula de chave pode conter duas declarações:

  1. A declaração algorithm identifica o algoritmo de criptografia e deve ter o valor insensível a maiúsculas e minúsculas hmac-sha512.

  2. A declaração secret contém a codificação base64 da chave, que deve ser colocada entre aspas.

Aqui está um exemplo de uma cláusula de chave no arquivo rndc.conf:

// Fragmento do arquivo rndc.conf
key "75.119.143.187" {
algorithm hmac-sha512;
secret "oXTEccE3Wkn7JeWzj2qOk5Er37vtdCZpnNEL5chELB24MW5HkcyidBcnyS3qf8roG8jpJ9bWA6G9TqF8/t5aQA==";
};

Para gerar as chaves, reveja sobre TSIG.



Blackhole Clause


A cláusula blackhole é usada para definir uma lista de endereços dos quais o servidor não aceita consultas ou usa para resolver uma consulta. As consultas desses endereços não são respondidas. Qualquer endereçamento IP pode ser configurado aqui caso você não queira que o ser servidor DNS responda, muito útil para servidores recursivos.


Normalmente é usado essa cláusula para ficar em conformidade com a RFC 1918, por duas razões principais:

  • Segurança
    A RFC 1918 define faixas de endereços IP reservados para uso privado dentro de redes locais. Anunciar esses endereços IP em um DNS público pode expor sua rede interna a ataques e vulnerabilidades. O bloqueio de anúncios de endereços RFC 1918 no DNS público, impede que invasores obtenham informações da rede privada.

  • Conformidade com o RFC
    O RFC 1918 proíbe explicitamente o anúncio de endereços IP privados em DNSs públicos. Bloquear esse tipo de consulta garante que você esteja em conformidade com o RFC 1918 e evita problemas com provedores de serviços de internet (ISPs) ou outras entidades.


Crie um ACL contendo as redes que vamos descartar a resposta:

acl bogusnets {
0.0.0.0/8; 192.0.2.0/24; 224.0.0.0/3;
127.0.0.0/8; 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16;
};

Agora, dentro da cláusula options, adicione a opção abaixo:

vim named.conf.options
options {
.
.
.
blackhole { bogusnets; };
.
.
.
};


Masters ou Primaries Clause


Define um lista com os servidores primários para que sejam usado por vários stubs e zonas secundárias em suas listas primárias ou também de notificação. Para forçar o envio das solicitações de transferência de zona por TLS, use a palavra-chave tls, por exemplo.

primaries { 192.0.2.1 tls tls-configuration-name; };

# onde tls-configuration-name refere-se a uma instrução tls definida anteriormente.

A opção primaries ou masters não pode ser usada em conjunto com ACL.



Utilitários do BIND


Vamos ver e entender quais são e para que servem os utilitários do BIND.



named-compilezone


O comando named-compilezone converte um arquivo de zona de texto normal em um formato raw (binário) que pode ser carregado pelo BIND usando a declaração masterfile-format no arquivo named.conf. Quando várias zonas de texto estão sendo carregadas, o tempo de inicialização do BIND pode ser considerável. Ter arquivos de zona em formato raw pode economizar tempo significativo durante o ciclo de reload da zona. O BIND geralmente realiza verificações significativas ao carregar zonas de texto, mas não é capaz de realizar tais verificações quando o formato raw é utilizado.



named-checkconf


O comando named-checkconf verifica a sintaxe do arquivo named.conf que controla a operação do BIND. Sempre que são feitas alterações no arquivo named.conf, este comando deve ser executada antes de reiniciar o BIND para verificar se existem erros.

named-checkconf -t /usr/local/named/ /etc/named.conf

Se não aparecer nada é porque está tudo certo.



RNDC


O comando rndc controla o servidor de nomes e pode ser executada a partir de um ou mais locais, sendo local ou remotos, dependendo do valor da cláusula controls no arquivo named.conf. O BIND é configurado por padrão para permitir acesso rndc a partir do localhost (127.0.0.1), independentemente de ser necessário ou não, a menos que seja compilado.


Se o rndc não for utilizado, ele deve ser explicitamente desabilitado usando uma cláusula controls vazia; ou seja, controls {};.


O rndc utiliza TCP para acessar o servidor de nomes na porta 953 por padrão e requer um segredo compartilhado para fornecer autenticação semelhante a TSIG em cada transação. As diversas funcionalidades suportadas pelo rndc são definidas em um arquivo de configuração chamado rndc.conf. No entanto, para tornar o processo de configuração inicial trivial, o rndc operará sem um arquivo rndc.conf e com um segredo compartilhado padrão.

# Crie o arquivo contendo a chave secreta usada para autenticar comandos RNDC:
rndc-confgen -a -b 512 -c rndc.key

# A cláusula control deve ser assim:
controls {
inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; };
};

# Exibir o status do servidor DNS:
rndc -k /usr/local/named/etc/rndc.key -s localhost status

# Recarregar o arquivo de configuração e zonas:
rndc -k /usr/local/named/etc/rndc.key -s localhost reload

# Atualizar o cache:
rndc -k /usr/local/named/etc/rndc.key -s localhost dumpdb -cache

# Limpa entradas no cache do servidor:
rndc -k /usr/local/named/etc/rndc.key -s localhost flush


nsupdate


O utilitário nsupdate permite a atualização dinâmica dos arquivos de zona para os quais o servidor de nomes é o Primário. O nsupdate geralmente aceita comandos a partir do console, mas opcionalmente pode ser utilizado para ler comandos de um arquivo em lote. Não é possível adicionar ou excluir zonas usando o nsupdate, mas é possível editar o registro SOA da zona. Zonas que estão sendo atualizadas dinamicamente geralmente não devem ser editadas manualmente. Se for necessário realizar uma edição manual, o servidor deve ser interrompido, a edição manual deve ser realizada, os arquivos .jnl da zona devem ser excluídos e o servidor reiniciado.


Alternativamente, você pode usar o comando rndc freeze zone, editar a zona, excluir quaisquer arquivos .jnl da zona e, em seguida, usar rndc thaw/unfreeze zone para habilitar as atualizações dinâmicas para a zona. O nsupdate pode ser protegido usando a segurança de transação TSIG ou SIG(0).


As atualizações dinâmicas são controladas pelas declarações allow-update ou update-policy nas cláusulas view, options ou zone do arquivo named.conf. A declaração update-policy local; gera automaticamente uma chave TSIG adequada que pode ser usada quando nsupdate e o servidor de nomes são executados no mesmo host. Ou seja, o escopo do nsupdate é limitado apenas ao localhost ao usar esse recurso. As atualizações dinâmicas podem ser realizadas em zonas normais e assinadas (DNSSEC).


Exemplo de uso:

nsupdate -k Khermodr.com.br.+005+13579.private
> server ns1.hermodr.com.br
> zone example.com
> update add hermodr.com.br. 36000 IN MX 10 alice.hermodr.com.br.
> send
> show
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERR id: 0
;; flags: ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
> update add alice 36000 IN A 192.168.0.2
> send
> show
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERR id: 0
;; flags: ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
> quit


dnssec-keygen


O comando dnssec-keygen é uma ferramenta de geração de chave criptográfica de propósito geral que gera chaves para uso com operações TSIG, SIG(0), TKEY e DNSSEC, bem como registros genéricos KEY ou DNSKEY. Quando o comando é executado, ele gera uma referência de arquivo de chave. O arquivo de chave é posteriormente usado em comandos como dnssec-signzone e outros.

  • Khostname.+algorithm+key-tag.private
  • Khostname.+algorithm+key-tag.key

Onde K é um identificador fixo, hostname é o valor do nome do host no formato FQDN (encerrado com um ponto) da linha de comando do dnssec-keygen, e + é um separador fixo. algorithm é um número de três dígitos que identifica o algoritmo de chave especificado na linha de comando.


O próximo + é um separador fixo, e key-tag é um valor de cinco dígitos (gerado com um algoritmo de complemento modificado) usado para identificar esta chave entre outras que podem ter o mesmo nome de host. O key-tag é usado explicitamente e implicitamente em outros lugares, como no Registro Delegado (DS) do DNSSEC.


O arquivo .private contém a chave privada de um algoritmo de chave pública (assimétrica), como o RSA-SHA-1, ou o segredo compartilhado em um algoritmo simétrico, como o HMAC-MD5. O arquivo .key contém um RR KEY ou DNSKEY formatado, dependendo dos argumentos -T e -n que seguem, de modo que o arquivo pode ser diretamente incluído quando apropriado em um arquivo de zona usando a diretiva $INCLUDE.


O arquivo .private de qualquer sistema de chave pública contém informações altamente sensíveis. Quando é utilizado, por exemplo, para assinatura de zonas, deve ser retirado do sistema, o que pode significar removê-lo fisicamente ou movê-lo para outro local e protegê-lo com privilégios apropriados. No entanto, ao usar atualização dinâmica com arquivos de zona assinados, o arquivo .private da ZSK deve estar online o tempo todo e deve ser protegido com permissões mínimas de leitura.



dnssec-revoke


O dnssec-revoke é uma ferramenta de linha de comando usada para revogar uma chave DNSSEC. O utilitário altera a data e hora de revogação nos metadados, adiciona a flag REVOKE ao registro DNSKEY e altera o identificador de chave (keytag) associado à chave. Como consequência da mudança no identificador de chave, ele escreve um novo conjunto de arquivos de chave.

dnssec-revoke Khermodr.com.br.+005+13579
Khermodr.com.br.+005+13579


dnssec-signzone


O comando dnssec-signzone é usado para assinar criptograficamente com o uso de um algoritmo de chave pública (assimétrica) uma zona. Isso é feito no contexto do DNSSEC para criar uma zona assinada. Zonas são assinadas utilizando uma ou mais ZSKs (Chaves de Assinatura de Zona) e, opcionalmente, uma ou mais KSKs (Chaves de Assinatura de Chave).


O dnssec-signzone assina cada conjunto de registros (RRset) em uma zona com registros RRSIG (Resource Record Signature). Esses registros RRSIG têm um valor de tempo de início (quando se tornam válidos) e um valor de tempo de término (quando expiram). Se nada mais for feito no arquivo de zona assinado, ele se tornará inválido após esse período. Ambos os valores de início e término podem ser alterados por argumentos.


O arquivo de zona de entrada, que é o arquivo de zona a ser assinado ou re-assinado, pode ser um arquivo de zona não assinado ou pode ser um arquivo de zona assinado. Se for um arquivo assinado, as assinaturas existentes podem ser renovadas, dependendo do período restante de validade delas. O comportamento padrão é que qualquer assinatura que tenha menos de um quarto do tempo restante seja renovada para o valor padrão ou um valor definido pelo usuário. Assim, se o período original da assinatura foi de 30 dias, apenas registros RRSIG com menos de 7,5 dias restantes serão renovados.


Se os valores de ZSK (Zone Signing Key) e KSK (Key Signing Key) a serem usados no processo de assinatura não forem definidos explicitamente, o comando dnssec-signzone usará qualquer valor DNSKEY no arquivo de zona para o qual ele puder encontrar uma chave privada correspondente no diretório atual para assinar o arquivo.

# Exemplo de uso
dnssec-signzone -k KKhermodr.com.br.+003+12488 -o hermodr.com.br -t hermodr Khermodr.com.br.+005+13245


Criptografia no BIND


Por padrão, o BIND 9 é construído para utilizar as funcionalidades criptográficas do OpenSSL. Alternativamente, o dnssec-keygen (assim como dnssec-signzone e named) pode ser configurado para usar um HSM ao gerar e usar chaves para algoritmos criptográficos assimétricos, como SIG(0) e DNSSEC. Um HSM gerará chaves sem divulgar a parte privada da chave (e também pode fornecer aceleração de hardware criptográfico) e é frequentemente usado em sites altamente seguros ou de alto valor.



Recursos avançados de DNS no BIND


Neste tópico dos recursos avançados do DNS para o BIND.



Gerando Chave Compartilhada


As chaves TSIG podem ser geradas usando o comando tsig-keygen, a saída desse comando é uma diretiva de chave para ser incluída na configuração do Bind. O nome da chave, algoritmo e tamanho podem ser especificados por parâmetros de linha de comando; os padrões são tsig-key, HMAC-SHA256 e 256 bits, respectivamente.


Qualquer string que seja um nome DNS válido pode ser usada como nome de chave. Esta chave pode ser gerada usando:

# Estou usando um algoritmo mais forte no exemplo abaixo:
tsig-keygen -a hmac-sha512 example.com > example.com

Esta chave pode então ser copiada para ambos os hosts. O nome e o segredo da chave devem ser idênticos em ambos os hosts.

O tsig-keygen também pode ser executado como ddns-confgen, nesse caso, a saída inclui texto de configuração adicional para configurar o DNS dinâmico no named.



Gerando Par de Chaves


O programa dnssec-keygen é utilizado para gerar um par chaves, normalmente usado para criar chaves que vão assinar zonas DNSSEC. Uma zona segura deve conter uma ou mais chaves de zona. As chaves de zona assinam todos os outros registros na zona, bem como as chaves de zona de quaisquer zonas delegadas seguras.


As chaves de zona devem ter o mesmo nome da zona, ter um tipo de nome ZONE e ser utilizáveis para autenticação. Recomenda-se que as chaves de zona usem um algoritmo criptográfico designado como "obrigatório para implementação" pelo IETF. Atualmente, existem dois algoritmos, RSASHA256 e ECDSAP256SHA256; ECDSAP256SHA256 é recomendado para implementações atuais e futuras.


O comando a seguir gera uma chave ECDSAP256SHA256 para a zona child.example:

# Gere o par de chaves para ZSK:
dnssec-keygen -a ECDSAP256SHA256 -b 4096 -n ZONE hermodr.com.br

# Gere o par de chaves para KSK:
dnssec-keygen -a ECDSAP256SHA256 -b 4096 -f KSK hermodr.com.br

Dois arquivos são criados: Kchild.example.+013+12345.key e Kchild.example.+013+12345.private (onde 12345 é um exemplo de keytag da chave DNSKEY associada).


  1. Os nomes de arquivo da chave contêm o nome da chave (child.example.);
  2. O algoritmo é o 13 (5 é RSASHA1, 8 é RSASHA256, 13 é ECDSAP256SHA256, 15 é ED25519, etc.);
  3. A keytag é 12345;
  4. A chave privada está no arquivo .private, é usada para gerar assinaturas, e a chave pública (no arquivo .key) é usada para verificação de assinatura.

O programa dnssec-keyfromlabel é utilizado para obter um par de chaves de um dispositivo criptográfico e construir os arquivos de chave. Sua utilização é semelhante à do dnssec-keygen. As chaves públicas devem ser inseridas no arquivo da zona, incluindo os arquivos .key usando declarações $INCLUDE.


Existem outras opções que podemos usar com a opção -n do comando dnssec-keygen, são elas:

  1. ZONE (Para uma chave de zona DNSSEC):

    • A chave gerada é tipicamente usada para assinar digitalmente a zona DNS e garantir a integridade e autenticidade dos registros DNS dentro dessa zona.
  2. HOST (Para uma chave associada a um host):

    • Uma chave com o tipo HOST é geralmente associada a um host específico. Isso significa que a chave gerada será usada para autenticar e garantir a integridade das comunicações entre esse host específico e outros hosts ou servidores.
  3. ENTITY (Para uma chave associada a uma entidade):

    • O tipo ENTITY é semelhante ao tipo HOST, mas é mais genérico. Pode ser usado para chaves associadas a qualquer entidade identificável, seja um host, um serviço ou algo mais amplo.
  4. USER (Para uma chave associada a um usuário):

    • Este tipo de chave está associado a um usuário específico. Pode ser usado em cenários onde a autenticação de usuário é necessária, garantindo que apenas o usuário autorizado possa acessar recursos específicos.
  5. OTHER (DNSKEY):

    • Quando você escolhe este tipo, a chave gerada é uma DNSKEY.


DNSSEC


Quando o DNSSEC foi introduzido inicialmente, a única maneira de assinar dados DNS era usando o comando dnssec-signzone, isso pegava um arquivo de zona não assinado e gerava um novo arquivo de zona contendo assinaturas. Esse arquivo seria carregado pelo named e servido da mesma forma que qualquer outro arquivo de zona. Como as assinaturas DNSSEC expiram, a zona precisaria ser periodicamente re-assinada e recarregada.


Posteriormente, o named adquiriu a capacidade de assinar zonas internamente. O servidor principal de uma zona poderia agora adicionar e remover chaves, gerar e regenerar automaticamente assinaturas DNSSEC, permanecendo atualizado sem intervenção do operador. No entanto, isso exigia que a zona fosse configurada como dinâmica, o que é incompatível com algumas configurações DNS existentes.


Com o lançamento do BIND 9.9, a ISC introduziu uma nova opção inline-signing para o BIND 9, que permite ao named assinar zonas de forma completamente transparente. Um servidor pode carregar ou transferir uma zona não assinada e criar uma versão assinada dela que responde a todas as consultas e solicitações de transferência, sem alterar a versão original não assinada. À medida que a zona não assinada é atualizada, o named detectará as alterações feitas a ela e aplicará essas alterações à versão assinada. Isso permite uma transição tranquila para o DNSSEC com mínima interrupção nos sistemas existentes.


Com o inline-signing, não é mais necessário carregar explicitamente um arquivo de zona assinada. Em vez disso, o BIND gerencia dinamicamente as assinaturas DNSSEC enquanto a zona é atualizada. Essa opção permite que o servidor DNS BIND assine automaticamente os registros da zona no momento em que são atualizados, sem a necessidade de um processo separado para assinar manualmente a zona e recarregá-la. Isso simplifica a administração do DNSSEC, tornando a implementação e a manutenção do DNSSEC mais eficientes.


Este método novo é conhecido como Fully Automated (Key and Signing Policy).



Chaves de zona (Zone Keys)


Independentemente do método de assinatura da zona em uso, as chaves criptográficas são armazenadas em arquivos com nomes como Khermodr.com.br.+013+46468.key e Khermodr.com.br.+013+46468.private. A chave privada (no arquivo .private) é usada para gerar assinaturas, e a chave pública (no arquivo .key) é usada para verificação de assinatura. Além disso, o método Fully Automated (Key and Signing Policy) cria um terceiro arquivo, Khermodr.com.br.+013+46468.state, que é usado para acompanhar os tempos das chaves DNSSEC e realizar rollovers de chaves com segurança.


Esses nomes de arquivo contêm:

  1. Os nomes de arquivo da chave contêm o nome da chave;
  2. O algoritmo é o 13 (5 é RSASHA1, 8 é RSASHA256, 13 é ECDSAP256SHA256, 15 é ED25519, etc.);
  3. A keytag é 12345;
  4. A chave privada está no arquivo .private, é usada para gerar assinaturas, e a chave pública (no arquivo .key) é usada para verificação de assinatura.


Fully Automated (Key and Signing Policy)


O Key and Signing Policy (KASP) é um método de configuração que descreve como manter chaves de assinatura DNSSEC e como assinar a zona. Esta é a maneira recomendada pela documentação oficial do Bind. Para a maioria dos casos de uso, os usuários podem simplesmente utilizar a política padrão incorporada.


A instrução dnssec-policy requer que o DNS dinâmico seja configurado ou que inline-signing esteja ativada. Isso é suficiente para criar as chaves de assinatura necessárias e gerar registros DNSKEY, RRSIG e NSEC para a zona. O BIND também cuida de qualquer manutenção DNSSEC para esta zona, incluindo a substituição de assinaturas prestes a expirar e a gestão de Key Rollovers.


A política padrão cria uma chave (CSK) que é usada para assinar a zona completa e utiliza o NSEC para possibilitar a negação autenticada de existência (uma forma segura de identificar quais registros não existem em uma zona). Essa política é recomendada e geralmente não precisa ser alterada. Se necessário, uma política personalizada pode ser definida adicionando uma instrução dnssec-policy na configuração.

dnssec-policy "custom" {
dnskey-ttl 600;

keys {
ksk key-directory lifetime P1Y algorithm ecdsap384sha384;
zsk key-directory lifetime 60d algorithm ecdsap384sha384;
};

nsec3param iterations 0 optout no salt-length 0;
};

Essa política personalizada, por exemplo:

  • Usa um TTL DNSKEY muito curto (600 segundos).

  • Utiliza duas chaves para assinar a zona: uma Chave de Assinatura de Chave (KSK) para assinar os conjuntos de RR relacionados à chave (DNSKEY, CDS e CDNSKEY), e uma Chave de Assinatura de Zona (ZSK) para assinar o restante da zona. A KSK é automaticamente rotacionada após um ano e a ZSK após 60 dias.

  • As chaves configuradas têm um tempo de vida definido e utilizam o algoritmo ECDSAP384SHA384.

  • A última linha instrui o BIND a gerar registros NSEC3 para Prova de Não Existência, utilizando zero iterações extras e nenhum salt. O opt-out NSEC3 está desativado, o que significa que as delegações inseguras também recebem um registro NSEC3.


Abaixo seguem as opções default do bind 9.19.21:

dnssec-policy "default" {
keys {
csk key-directory lifetime unlimited algorithm 13;
};

cdnskey yes;
cds-digest-types { 2; };
dnskey-ttl 3600;
inline-signing yes;
publish-safety 3600;
retire-safety 3600;
purge-keys P90D;
signatures-refresh P5D;
signatures-validity P14D;
signatures-validity-dnskey P14D;
max-zone-ttl 86400;
zone-propagation-delay 300;
parent-ds-ttl 86400;
parent-propagation-delay 3600;
};

A tabela abaixo explica cada uma das opções definidas na política padrão do DNSSEC do Bind (visto acima):

OpçãoDescrição
keysDefine as características das chaves DNSSEC associadas a esta política.
cskEspecifica as configurações para a chave do tipo "Key Signing Key" (CSK).
key-directoryEspecifica o diretório onde as chaves DNSSEC serão armazenadas.
lifetimeDefine a vida útil das chaves, que é ilimitada neste caso.
unlimitedIndica que não há um limite definido para a validade da chave.
algorithmEspecifica o algoritmo de assinatura de chave, neste caso, o algoritmo 13 (ECDSAP256SHA256).
cdnskeyHabilita a criação de registros CDNSKEY.
cds-digest-typesEspecifica os tipos de digest que podem ser usados no registro CDS.
dnskey-ttlDefine o TTL (Time-to-Live) para os registros DNSKEY assinados.
inline-signingHabilita a assinatura em linha, permitindo que o BIND assine a zona dinamicamente.
publish-safetyDefine a margem de segurança entre a data de publicação de chaves e a data de expiração das chaves.
retire-safetyDefine a margem de segurança entre a data de aposentadoria de chaves e a data de expiração das chaves.
purge-keysDefine o período após o qual as chaves DNSSEC podem ser eliminadas após serem retiradas de serviço.
signatures-refreshDefine a frequência com que as assinaturas DNSSEC devem ser atualizadas.
signatures-validityDefine por quanto tempo as assinaturas DNSSEC são consideradas válidas.
signatures-validity-dnskeyDefine por quanto tempo as assinaturas DNSKEY são consideradas válidas.
max-zone-ttlDefine o TTL máximo que pode ser usado para registros em uma zona DNS.
zone-propagation-delayDefine o tempo de propagação da zona, ou seja, quanto tempo leva para as atualizações serem propagadas para todos os servidores autoritativos.
parent-ds-ttlDefine o TTL do registro DS pai.
parent-propagation-delayDefine o tempo de propagação do registro DS pai.

Sobre a configuração de NSEC3 que devemos nos atentar. Usar um número alto de iterações no NSEC3 (no caso iterations) não é mais considerado uma medida de segurança eficaz. Muitas iterações também sobrecarregam desnecessariamente os servidores DNS. A melhor prática atualmente é definir o valor de iteração NSEC3 como 0 (sem hash adicional além do inicial, ou seja, salt-length 0). Mais detalhes aqui.



Rollover de Chave


O termo "Rollover de Chave" se refere ao processo de substituir uma chave criptográfica antiga por uma nova. É um procedimento importante para manter a segurança de sistemas que dependem de criptografia, como o DNSSEC. Se você estiver assinando sua zona usando uma declaração dnssec-policy, você não precisa se preocupar.


O named implementa tudo para você automaticamente, além de fazer upload dos novos registros DS para sua zona pai.


Ao utilizar uma dnssec-policy, o tempo de vida de uma chave pode ser definido para acionar rollovers de chave. Rollovers de ZSK são totalmente automáticos, mas para rollovers de KSK e CSK, um registro DS precisa ser enviado ao domínio superior (pai).


Uma vez que o DS está no superior (e o DS da chave predecessora é retirado), é necessário informar ao BIND que esse evento ocorreu. Isso pode ser feito automaticamente configurando agentes parentais:

zone "dnssec.example" {
type primary;
file "dnssec.example.db";
dnssec-policy default;
parental-agents { 192.0.2.1; };
checkds explicit;
};

Aqui, um servidor, 192.0.2.1, está configurado para que o BIND envie consultas DS, verificando o conjunto de registros DS para dnssec-example durante os rollovers de chave. Isso precisa ser um servidor confiável, pois o BIND não valida a resposta. A opção checkds faz com que o BIND utilize explicitamente os agentes parentais configurados, em vez de procurá-los consultando os registros NS do superior.


Se configurar um agente parental for indesejável, também é possível informar ao BIND que o DS está publicado no superior com:

rndc dnssec -checkds -key 12345 published dnssec.example.

e que o DS da chave predecessora foi removido com:

rndc dnssec -checkds -key 54321 withdrawn dnssec.example.

onde 12345 e 54321 são as marcas de chave da chave sucessora e predecessora, respectivamente. Para renovar uma chave mais cedo do que o programado ou para rolar uma chave com tempo de vida ilimitado, use:

rndc dnssec -rollover -key 12345 dnssec.example.

Para reverter uma zona assinada de volta para uma zona não segura, altere a configuração da zona para usar a política interna insecure. Existem várias maneiras de atualizar registros DS na zona superior. Geralmente, as opções são, da mais recomendada para a menos recomendada:

  1. Atualizar automaticamente o registro DS na zona superior usando registros CDS/CDNSKEY gerados automaticamente pelo BIND:
    Isso requer suporte ao RFC 7344 na zona superior, no registro ou no registrador. Nesse caso, configure o BIND para monitorar registros DS na zona superior, e tudo acontecerá automaticamente no momento certo.

  2. Consultar a zona para registros CDS ou CDNSKEY gerados automaticamente usando o dig e inserir esses registros na zona superior usando o método especificado pela zona superior:
    Pode ser um formulário web, e-mail, API, etc.

  3. Gerar manualmente registros DS usando o utilitário dnssec-dsfromkey nas chaves da zona e, em seguida, inseri-los na zona superior.
    Um dos mais comuns casos...



DNSSEC Validation


O BIND configurado como resolver valida respostas de servidores autoritativos por padrão. Esse comportamento é controlado pela declaração de configuração dnssec-validation. Por padrão, é utilizado um trust anchor para a zona raiz do DNS. Esse trust anchor é fornecido como parte do BIND e é mantido atualizado usando o Dynamic Trust Anchor Management.


Para validar respostas, o resolvedor precisa de pelo menos um ponto de partida confiável, um trust anchor. Essencialmente, trust anchors são cópias de registros DNSKEY para zonas que são usadas para formar o primeiro elo na cadeia criptográfica de confiança. Trust anchors alternativos podem ser especificados usando trust-anchors, mas essa configuração é muito incomum e é recomendada apenas para uso especializado.


O servidor autoritativo BIND não verifica assinaturas durante o carregamento, portanto, as chaves de zona para zonas autoritativas não precisam ser especificadas no arquivo de configuração e a validação DNSSEC não precisa ser habilitda.



Instalação do BIND


Durante toda a documentação eu vou usar o BIND instalado via código fonte para ter a versão mais recente, além disso, vou fazer a instalação usando Chroot Jail já que é o método mais recomendado para um servidor de produção com acesso na Internet. No ambiente teremos dois servidores com Ubuntu 22.04, cada um vai ser Autoritativo do seu próprio domínio, mas também serão secundário um do domínio do outro.


Para seguir, cada servidor já deve estar instalado e com configurações básicas de rede e dns para que consiga baixar e instalar pacotes. Vou cobrir apenas as configurações que tenham relação com a parte de DNS.


server configuration


Os servidores DNS que estamos prestes a configurar entrarão em produção e devem ser configurados em conjunto com o registro.br. Para que tudo dê certo, é essencial seguir algumas regras:


  1. Para configurar os servidores DNS apontando para o mesmo nome de domínio, como exemplo, ao estabelecer a configuração dos servidores DNS para o domínio 'wlf.eti.br' usando o nome do servidor como 'ns1.wlf.eti.br', é necessário fornecer dois servidores que já estejam respondendo por esse domínio. Essa abordagem se deve ao fato de que o nome do servidor DNS coincide com o nome do próprio domínio ('wlf.eti.br'), indicando que o DNS é específico para esse domínio e não está associado a outro domínio.

    Como ainda não existem registros DNS para esse domínio, é crucial fornecer o endereçamento necessário para permitir que os servidores DNS do registro.br alcancem os novos servidores DNS, responsáveis pelo domínio 'wlf.eti.br'. A representação visual dessa configuração pode ser vista na imagem abaixo:

Registro br configuration


regras para cadastrar os servidores DNS

As regras são:

  1. É necessário ter dois servidores DNS
  2. Os IP de ambos devem ser diferentes (não podem ser o mesmo IP)
  3. Ambos servidores DNS já precisam estar configurados e respondendo pelo domínio em questão.

No momento de aplicar a configuração, o registro.br fará uma consulta e verificará se o SOA de ambos os servidores estão iguais e se ambos respondem pelo domínio. O que da para fazer para ter somente um servidor, teríamos que ter dois IPv4 diferentes no mesmo servidor, com isso conseguimos burlar o sistema.

  1. Para configurar os servidores DNS apontando para um outro nome de domínio, basta apenas informar os nomes e cadastrar os RR A e RR AAAA para os nomes informados. Esse tipo de configuração podemos burlar a questão de ter 2 servidores diferentes, basta os nomes cadastrados apontarem para o mesmo IP (o sistema nao faz essa verificação).

Registro br 1 configuration


No nosso exemplo vamos usar o primeiro método, para que dê tudo certo, vamos primeiro configurar o servidor primário para wlf.eti.br e para hermodr.com.br, essa configuração já vai incluir DNSSEC. Depois vamos configurar eles como secundário um do outro (usando TSIG) e após isso vamos colocar eles no site do registro.br.



Instalação com Chroot Jail no wlf.eti.br


Nesse método fazemos com que o servidor DNS rode preso dentro de um diretório do Sistema Operacional. Para isso vamos usar o comando chroot para simular o Root em outro ponto ou sistema; significa que não da para ver ou acessar arquivos do bind de fora de sua pequena árvore de diretórios. Os termos chroot jail é nomeado a partir da chamada do sistema chroot, que recebe um argumento de diretório base e não permite que o aplicativo leia ou grave fora desse diretório base.


Todos os arquivos e caminhos referenciados no chroot são anexados ao diretório base. Portanto, se o diretório base do chroot for /usr/local/named e o aplicativo acessar um arquivo chamado /etc/named.conf, o caminho completo será convertido para /usr/local/named/etc/named.conf. Ao executar o BIND, o argumento de linha de comando -t DIR indica que o BIND deve ser executado em chroot e define o diretório base a ser usado. Em um ambiente chroot, os argumentos -t e -u (BIND UID) devem estar presentes para fornecer um ambiente seguro.


Para executar o BIND usando Chroot Jail podemos fazer via instalação usando repositório ou fazendo a compilação do BIND, nesse tutorial vou optar pela compilação. Para mais detalhes consulte o link.



Preparando o ambiente


Vamos começar preparando o ambiente para rodar com o chroot jail, nessa etapa vamos criar o usuário no qual o BIND vai rodar sob e o diretório de onde os arquivos vão ficar armazenados. Toda a configuração abaixo será feita com o usuário root.

# Mude o nome do servidor:
hostnamectl set-hostname wlf.eti.br

# Desative o resolvectl:
systemctl stop systemd-resolved
systemctl disable systemd-resolved

# Remova o link abaixo:
unlink /etc/resolv.conf

# Por desativar o resolvectl, temos que configurar um outro servidor DNS como recursivo até finalizar a instalação do BIND:
echo -e "nameserver 9.9.9.11\nnameserver 2620:fe::fe:11" > /etc/resolv.conf

# Atualize o sistema:
apt update

# Instalação:
apt install -y chrony

# Configure a hora do servidor:
timedatectl set-ntp false
timedatectl set-timezone America/Sao_Paulo

Agora vamos configurar o Chrony para usar servidores NTP no Brasil (pool.ntp.br) para sincronização de tempo:

vim /etc/chrony/chrony.conf

## Comente os 'pools' abaixo e adicion um novo:

#pool ntp.ubuntu.com iburst maxsources 4
#pool 0.ubuntu.pool.ntp.org iburst maxsources 1
#pool 1.ubuntu.pool.ntp.org iburst maxsources 1
#pool 2.ubuntu.pool.ntp.org iburst maxsources 2
pool pool.ntp.br iburst maxsources 4

Agora vamos configurar o etc/hosts:

vim /etc/hosts
127.0.0.1       localhost
127.0.1.1 wlf.eti.br wlf

# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
94.72.123.149 wlf.eti.br wlf

Agora vamos reiniciar o Chrony para fazer as alterações entrarem em vigor e criar o grupo e usuário que o Bind vai usar.

# Reinicie o serviço:
systemctl restart chrony

# Crie o grupo para o usuário do BIND:
groupadd -g 53 bind

# Crie o usuário de sistema que vamos usar para executar o BIND:
adduser --system --uid 53 --gid 53 --disabled-login --disabled-password --home /usr/local/named bind
Adding system user `bind' (UID 53) ...
Adding new user `bind' (UID 53) with group `bind' ...
Creating home directory `/usr/local/named' ...

# Bloqueie a conta para que não seja possível efetuar login:
usermod -L bind

# Verifique se foi criado:
getent passwd bind
bind:x:53:53::/usr/local/named:/usr/sbin/nologin

# Verifique se o grupo foi criado (provavelmente foi):
getent group bind
named:x:53:

A opção --system cria um usuário de sistema, --uid define qual será o ID do usuário, o mesmo para --gid, mas nesse caso define o ID de grupo. A opção --disabled-login faz com que a conta seja criada, mas será desativada até que uma senha seja definida. A opção --disabled-password não definirá uma senha, mas o login ainda é possível (por exemplo, com chaves SSH). O --home informa o local padrão do diretório home do usuário.


Instale os pacotes necessário para fazer a compilação:

apt install build-essential libssl-dev libuv1-dev perl pkgconf libcap-dev liburcu-dev libnghttp2-dev libnghttp2-doc libjemalloc-dev bind9-utils -y

# bind9-utils = Não é necessário para a compilação, mas vamos usar mais para frente.


Compilando o BIND


Agora vamos compilar a versão mais recente do BIND e utilizar as técnicas que Chroot Jail para proteger ainda mais a aplicação.

# Crie o diretório para deixar os arquivos do bind e fazer a compilação:
mkdir /usr/src/bind-9.19.21

# Entre no diretório:
cd /usr/src/bind-9.19.21

# Baixe o código fonte do BIND:
wget -c https://ftp.isc.org/isc/bind9/cur/9.19/bind-9.19.21.tar.xz

# Baixe o arquivo contendo a assinatura para validação:
wget https://ftp.isc.org/isc/bind9/cur/9.19/bind-9.19.21.tar.xz.asc

# Baixe a chave pública:
wget https://www.isc.org/docs/isc-keyblock.asc

# Importe a chave pública:
gpg --import isc-keyblock.asc

# Faça a verificação da integridade e autenticidade do arquivo baixado:
gpg --verify bind-9.19.21.tar.xz.asc bind-9.19.21.tar.xz
gpg: Signature made Wed May 10 11:52:18 2023 UTC
gpg: using RSA key D99CCEAF879747014F038D63182E23579462EFAA
gpg: Good signature from "Michal Nowak (Code-Signing Key) <mnowak@isc.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: D99C CEAF 8797 4701 4F03 8D63 182E 2357 9462 EFAA

# A mensagem "Good signature" indica que a assinatura do arquivo foi verificada com sucesso e é considerada válida.
# Isso significa que o arquivo foi assinado com a chave privada correspondente à chave pública que temos, e que o conteúdo não foi alterado desde a assinatura.

# Descompacte e extraia o código fonte:
tar xf bind-9.19.21.tar.xz

# Entre no diretório contendo o código fonte:
cd bind-9.19.21/

# Configure o ambiente para a compilação:
./configure --prefix=/usr/local/named
.
.
.
===============================================================================
Configuration summary:
-------------------------------------------------------------------------------
Optional features enabled:
Memory allocator: jemalloc
DNSSEC validation active by default (--enable-auto-validation)
-------------------------------------------------------------------------------
Library versions:
OpenSSL: 3.0.2
libuv: 1.43.0
Userspace-RCU: 0.13.1
jemalloc: 5.2.1_0
-------------------------------------------------------------------------------
Features disabled or unavailable on this platform:
Allow 'dnstap' packet logging (--enable-dnstap)
GeoIP2 access control (--enable-geoip)
GSS-API (--with-gssapi)
DNS Response Policy Service interface (--enable-dnsrps)
Allow 'fixed' rrset-order (--enable-fixed-rrset)
FIPS mode in OpenSSL (--enable-fips-mode)
Very verbose query trace logging (--enable-querytrace)
Single-query trace logging (--enable-singletrace)
CMocka Unit Testing Framework (--with-cmocka)
XML statistics (--with-libxml2)
JSON statistics (--with-json-c)
HTTP zlib compression (--with-zlib)
LMDB database to store configuration for 'addzone' zones (--with-lmdb)
IDN support (--with-libidn2)
-------------------------------------------------------------------------------
Configured paths:
prefix: /usr/local/named
sysconfdir: ${prefix}/etc
localstatedir: ${prefix}/var
-------------------------------------------------------------------------------
Compiler: gcc
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

CFLAGS: -Wall -Wextra -Wwrite-strings -Wpointer-arith -Wno-missing-field-initializers -Wformat -Wshadow -Werror=implicit-function-declaration -Werror=missing-prototypes -Werror=format-security -Werror=parentheses -Werror=implicit -Werror=strict-prototypes -Werror=vla -fno-strict-aliasing -fno-delete-null-pointer-checks -fdiagnostics-show-option -g -O2 -I/usr/include/x86_64-linux-gnu -pthread
CPPFLAGS: -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
LDFLAGS:
-------------------------------------------------------------------------------
For more detail, use --enable-full-report.
===============================================================================

# Compile o código:
make

# Instalar o código já compilado:
make install

# Agora crie o diretório e copie o arquivo de data/hora para que o BIND tenha acesso:
mkdir /usr/local/named/etc/ && cp /etc/localtime /usr/local/named/etc/

# Crie os diretórios abaixo:
mkdir -p /usr/local/named/var/named
mkdir -p /usr/local/named/var/run/named
mkdir -p /usr/local/named/var/log/named
mkdir /usr/local/named/dev

O comando gpg --verify..., supondo que tudo esteja correto, irá indicar uma assinatura válida, porém com uma mensagem de aviso informando que a chave ISC não possui uma certificação confiável verificável. Isso é apenas um efeito secundário da sequência de comandos utilizada.


Uma vez que o BIND está rodando sob de chroot jail, ele não será capaz de acessar arquivos fora do diretório configurado. No entanto, ele precisa acessar alguns arquivos-chave.


Um arquivo que o BIND precisará dentro do chroot jail é o /dev/null. Alguns sistemas também podem exigir /dev/zero, que pode ser criado de forma semelhante. Também é necessário instalar o /dev/random e /dev/urandom. Para a maioria dos sistemas Linux, podemos usar os seguintes comandos:

# Entre no diretório abaixo:
cd /usr/local/named/dev

# Crie os arquivos abaixo:
mknod random c 1 8
mknod urandom c 1 9
mknod null c 1 3
mknod zero c 1 5

Agora vamos configurar o RNDC, com ele vamos conseguir recarregar zonas individualmente, sem precisar mexer diretamente no daemon do Bind, também vamos baixar o arquivo de configuração inicial do Bind.

# Entre no diretório abaixo:
cd /usr/local/named/etc

# Crie o arquivo contendo a chave secreta usada para autenticar comandos RNDC:
rndc-confgen -a -c rndc.key

# Baixe os arquivos abaixo:
wget https://gitlab.com/sysnetbr/codes/-/raw/main/DNS/named.conf
wget https://gitlab.com/sysnetbr/codes/-/raw/main/DNS/named.conf.options

Agora vamos corrigir as permissões:

# Agora configure as permissões abaixo:
chown -R bind: /usr/local/named/{etc,var}

Agora crie o serviço para executar o BIND:

# Baixe o arquivo abaixo:
wget -O /etc/systemd/system/named.service https://gitlab.com/sysnetbr/codes/-/raw/main/DNS/named.service

# Recarregue as units:
systemctl daemon-reload

# Inicie o serviço:
systemctl start named.service

# Verifique se está tudo certo com o serviço:
systemctl status named.service
● named.service - BIND Domain Name Server
Loaded: loaded (/etc/systemd/system/named.service; disabled; vendor preset: enabled)
Active: active (running) since Sat 2024-02-24 19:30:53 -03; 6min ago
Docs: man:named(8)
Process: 28538 ExecStart=/usr/local/named/sbin/named -u bind -t /usr/local/named -c /etc/named.conf (code=exited, status=0/SUCCESS)
Main PID: 28539 (named)
Tasks: 10 (limit: 7037)
Memory: 12.0M
CPU: 58ms
CGroup: /system.slice/named.service
└─28539 /usr/local/named/sbin/named -u bind -t /usr/local/named -c /etc/named.conf

Feb 24 19:30:53 wlf.eti.br named[28539]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA
Feb 24 19:30:53 wlf.eti.br named[28539]: automatic empty zone: EMPTY.AS112.ARPA
Feb 24 19:30:53 wlf.eti.br named[28539]: automatic empty zone: HOME.ARPA
Feb 24 19:30:53 wlf.eti.br named[28539]: command channel listening on 127.0.0.1#953
Feb 24 19:30:53 wlf.eti.br named[28539]: managed-keys-zone: loaded serial 0
Feb 24 19:30:53 wlf.eti.br named[28539]: all zones loaded
Feb 24 19:30:53 wlf.eti.br named[28539]: FIPS mode is disabled
Feb 24 19:30:53 wlf.eti.br named[28539]: running
Feb 24 19:30:53 wlf.eti.br systemd[1]: Started BIND Domain Name Server.
Feb 24 19:30:53 wlf.eti.br named[28539]: managed-keys-zone: Initializing automatic trust anchor management for zone '.'; DNSKEY ID 20326 is now trusted, waiving the normal 30-day waiting period.


# Habilite o serviço para subir no boot:
systemctl enable named
Created symlink /etc/systemd/system/bind9.service → /etc/systemd/system/named.service.
Created symlink /etc/systemd/system/multi-user.target.wants/named.service → /etc/systemd/system/named.service.

Por fim para facilitar, ajuste a variável PATH para não ter que especificar o caminho absoluto dos binários do BIND. O procedimento abaixo funciona para o Shell Bash:

# Adicionando '/usr/local/named/sbin' a variável 'PATH':
echo 'PATH="$PATH:/usr/local/named/sbin:"' >> ~/.bashrc

# Agora recarregue as opções em '~/.bashrc':
source ~/.bashrc




Logging


A partir daqui, as configurações são as mesmas para ambos os servidores. Por padrão os logs do named são enviados para o /var/log/syslog pelo Syslog no Debian ou para /var/log/messages também pelo serviço do Syslog mas no CentOS.

O CentOS possui uma declaração de log que grava os logs de Debug em /etc/named/data/named.run.


Severidade


Os logs possuem tipos de severidade ou severity em Inglês, que ditam qual o nível de verbosidade vamos armazenar em Log, apesar de já deixar um esquema de log pronto, veja abaixo as severidades disponíveis para que você consiga configurar de acordo com sua necessidade:

SeveridadeDescrição
criticalSomente erros criticos.
errorErros (não criticos) e também inclui erros criticos.
warningAqui temos Warning e as duas opções acima.
noticeNoticia e as três opções acima.
infoInformação e as quatro opções acima.
debugDebig e as cinco opções acima. Podemos escolher vários níveis de Debug, informando debug 0 significa sem debug.
dynamicDepurar e as seis opções acima. Significa assumir o nível de depuração global definido pelo parâmetro de linha de comando -d ou executando rndc trace.

Além das severidades vamos trabalhar com canais ou channel em Inglês, um canal é apenas um nome para facilitar a identificação da chave onde vamos configurar um arquivo para guardar os logs, por exemplo:

    channel abobrinha {
file "/var/log/named/transfers" versions 3 size 10M;
print-time yes;
severity info;
};

Essa chave declara um canal chamado abobrinha, dentro desse canal, vamos dizer qual o arquivo onde será armazenado o log, isso é fornecido pela opção file. A opção print-time yes; é usada para guardar o Log com hora e data. Já severity info; informa o nível de verbosidade do log (quanta informação deverá ser exibida).


Além desse print-time ainda temos outros:

OpçãoDescrição
print-severityControla se o nível de severidade vai ser escrito no log ou não. Padrão é não.
print-categoryControla se a categoria vai ser escrito no log ou não. Padrão é não.

Versions


Em versions devemos dizer quantas versões vamos querer armazenar para esse arquivo. Os arquivos de versão são criados pelo BIND anexando .0, .1 e etc ao nome do arquivo. Podemos usar a palavra versions unlimited para não criar versões de arquivos, mas tome cuidado, caso seja definido tamanho para os arquivos de log essa opção não terá efeito e serão criadas várias versões para o mesmo arquivo (É uma espécie de Log Rotate).

Novas versões de log serão criadas apenas quando o BIND for reiniciado.


Os arquivos são renomeados ou sobrescritos de modo que .0 sempre conterá as últimas informações de log antes de iniciar o novo log, .1 será o segundo e assim por diante. Se nenhuma instrução de versão for definida, um único arquivo de log de tamanho ilimitado será usado e, na reinicialização, novos dados serão anexados ao arquivo definido. Isso pode chegar a ser um arquivo muito grande.


Size


Em size devemos dizer o tamanho que cada arquivo de log deve ter. Para a dimensão podemos usar as letras (pode ser maiúsculas ou minúsculas): k , m, g.


Agora se atente ao seguinte:

  1. Se você especificar um valor para size e não especificar o parâmetro versions, quando o limite de tamanho for atingido, o BIND interromperá o registro até que o tamanho do arquivo seja reduzido abaixo do limite definido, ou seja, excluindo ou truncando o arquivo.


  2. Se você especificar o parâmetro size (com valor) e o parâmetro versions (com valor), os arquivos de log serão rotacionados quando o limite de tamanho for atingido.


  3. Se você não especificar o parâmetro size e versions, os arquivos de log serão rotacionados somente quando o BIND for reiniciado.


Category


A opção category controla quais categorias serão registradas, para isso, nós fornecemos para essa opção o nome do canal que criamos ou um que seja padrão. Veja um exemplo:

    channel abobrinha {
file "/var/log/named/transfers" versions 3 size 10M;
print-time yes;
severity info;
};
category config { abobrinha; };
category default { abobrinha; };

Nesse exemplo acima estamos dizendo para registrar os logs do tipo config e default no canal chamado abobrinha, ou seja, esses tipos de logs serão registrados no arquivo específicado na configuração do Canal.


E para saber quais tipos de categorias ou logs existem veja a tabela abaixo:

CategoriaDescrição
clientProcessamento de solicitações de clientes.
configAnálise e processamento do arquivo de configuração.
databaseMensagens relacionadas aos bancos de dados usados internamente pelo servidor de nomes para armazenar dados de zona e cache.
defaultRegistra todos os valores que não são explicitamente definidos em declarações de categoria, ou seja, se esta for a única categoria definida, ele registrará todas as categorias listadas nesta tabela, com exceção das consultas que não são ativadas por padrão.
delegation-onlyRegistra as consultas que retornaram NXDOMAIN como resultado de uma zona somente de delegação ou uma instrução somente de delegação em uma dica ou declaração de zona de stub.
dispatchEnvio de pacotes recebidos para os módulos do servidor onde serão processados.
dnssecProcessamento do protocolo DNSSEC e TSIG.
generalQualquer coisa que não seja classificada como qualquer outro item nesta lista é padronizada para esta categoria.
lame-serversSão servidores chatos (ou conhecidos também como servidores lame). São servidores DNS que não estão configurados corretamente para responder a consultas de nomes de domínio. Essas mensagens podem ser úteis para administradores de rede para identificar servidores lame e corrigir suas configurações. Se o volume dessas mensagens for alto, muitos usuários optam por enviá-las para o canal nulo, por exemplo: category lame-servers { null; };.
networkRegistra todas as operações de rede.
notifyRegistra todas as operações NOTIFY.
queriesRegistra todas as transações de consulta. A instrução querylog pode ser usada para substituir esta instrução de categoria. Esta entrada pode gerar um volume substancial de dados muito rapidamente. Esta categoria não está ativada por padrão e, portanto, o tipo padrão acima não registrará essas informações.
resolverResolução de nomes, incluindo pesquisas recursivas realizadas em nome de clientes por um servidor de nomes de cache.
rpzTodas as operações relacionadas ao processamento da Zona de Política de Resposta (RPZ). Mesmo quando as zonas RPZ estão desativadas (usando o parâmetro policy disabled na declaração de política de resposta) o a operação é concluída, registrada e descartada (a resposta real é retornada ao usuário).
rate-limitTodas as operações relacionadas a uma ou mais declarações rate-limit nas options ou view cláusulas.
securityAprovação e negação de pedidos.
unmatchedNenhuma cláusula de exibição correspondente ou valor de classe não reconhecido. Um resumo de uma linha também é registrado na categoria do cliente. Por padrão, esta categoria é enviada para o canal nulo.
updateRegistro de todas as transações de atualização dinâmica (DDNS).
update-securityAprovação e negação de solicitações de atualização usadas com DDNS.
xfer-inDetalhes das transferências de zona que o servidor está recebendo.
xfer-outDetalhes das transferências de zona que o servidor está enviando.

O que vamos fazer é tornar as informações de Log mais útil e fácil de visualização. Os passos demonstrados aqui servem em ambos os sitemas, o que já existir de configuração de log (vide CentOS) será substituido.

### Deixe como dono o usuário em que Bind roda:

## No Debian:
chown bind. /usr/local/named/var/log/named

Agora vamos configurar as opções de log. Como logging é uma cláusula, ela não deve ficar dentro da cláusula options, então cole cláusula logging após a linha };.

vim /usr/local/named/etc/named.conf.options
logging {
channel transfers {
file "/var/log/named/transfers" versions 3 size 10M;
print-time yes;
severity info;
};
channel notify {
file "/var/log/named/notify" versions 3 size 10M;
print-time yes;
severity info;
};
channel dnssec {
file "/var/log/named/dnssec" versions 3 size 10M;
print-time yes;
severity info;
};
channel query {
file "/var/log/named/query" versions 5 size 10M;
print-time yes;
severity info;
};
channel general {
file "/var/log/named/general" versions 3 size 10M;
print-time yes;
severity info;
};
channel slog {
syslog security;
severity info;
};

category xfer-out { transfers; slog; };
category xfer-in { transfers; slog; };
category notify { notify; };

category lame-servers { general; };
category config { general; };
category default { general; };
category security { general; slog; };
category dnssec { dnssec; };

category queries { query; };
};

Agora vamos fazer uma verificação para verificar se existem erros no arquivo de configuração:

named-checkconf -t /usr/local/named/ /etc/named.conf

Se não aparecer nada é porque está tudo certo.


Agora reinicie o servidor do Bind:

systemctl restart named


AppArmor


Caso a instalação seja realizada usando repositório da distribuição e caso a distro seja Ubuntu/Debian ou conter o AppArmor, é necessário fazer uma atualização nas regras dele para permitir escrita nos arquivos em /var/log/named/, caso contrário não será possível registrar os logs. No meu caso que fiz a instalação usando código fonte com Chroot Jail, isso não será necessário.

vim /etc/apparmor.d/usr.sbin.named
  # /etc/bind should be read-only for bind
# /var/lib/bind is for dynamically updated zone (and journal) files.
# /var/cache/bind is for slave/stub data, since we're not the origin of it.
# See /usr/share/doc/bind9/README.Debian.gz
/etc/bind/** r,
/var/lib/bind/** rw,
/var/lib/bind/ rw,
/var/cache/bind/** lrw,
/var/cache/bind/ rw,

Após a linha /var/cache/bind/ rw vamos adicionar as duas linhas abaixo para permitir a escrita:

/etc/apparmor.d/usr.sbin.named
  /var/log/named/** rw,
/var/log/named/ rw,

Agora reinicie o serviço do AppArmor:

systemctl restart apparmor

Agora reinicie o servidor do Bind, serve em ambos os sistemas (Debian e CentOS):

systemctl restart named

Em versões mais recentes do DNS BIND, o log não está sendo iniciado automaticamente após a inclusão da configuração sem reiniciar o serviço.

Para que o log passe a ser registrado, com o serviço rodando, é preciso utilizar o seguinte comando:

# rndc querylog

Ou reiniciando totalmente o serviço:

# rndc stop

# rndc start


Configurando servidor DNS Recursivo/Cache/Forward


Vamos ver como configurar o servidor DNS para atuar como Recursivo, Cache e Forward.



Configurando um servidor Recursivo/Cache


Existem pontos importantes aqui, um servidor DNS de Cache é diferente de um servidor DNS Recursivo. Embora seja normal termos armazenamento de Cache para servidores DNS Recursivo, mas ser Recursivo não significa que ele terá Cache (mesmo que em 99% do casos ele tenha).


O BIND por padrão já vem configurado para ser um servidor de Recursivo, podemos ver isso pelo uso da opção recursion yes;. Porém no Ubuntu 22.04 e algumas outras possíveis distribuições essa configuração não fica explicita. Para saber se está configurado como Recursivo, faça uma pesquisa nos arquivos para ver se encontrar essa config:

named -C | grep -i 'recursion true'
recursion true;

Configurando o servidor para atuar como Recursivo, com armazenamento de Cache para os RR que forem consultados, isso é feito dentro da Declaração options, vou manter a configuração no arquivo (mesmo que seja padrão) apenas para ficar mais fácil de visualizar.

vim /usr/local/named/etc/named.conf.options
    // Define a versão que é apresentada como 'not currently available', é mais uma medida para impedir que consigam ver a versão do BIND:
version "not currently available";

// Habilita o BIND para responder consultas recursivas (feitas por servidor de Cache):
recursion yes;

// Por questões de segurança, vamos limitar os endereços que podem fazer consultas no nosso servidor.
// Nao esquecer de mudar para somente as redes necessárias.
allow-recursion { any; };

// Especifica as redes ou endereços IP que têm permissão para enviar consultas de cache para o servidor DNS.
// Nao esquecer de mudar para somente as redes necessárias.
allow-query-cache { any; };

// Especifica para quais endereços IP o servidor deve escutar para consultas de cache:
allow-query-cache-on { any; };

// Essa configuração define o tamanho máximo do cache DNS em relação à memória disponível no servidor:
max-cache-size 90%;

// Essa configuração define o tempo máximo de vida (TTL) para os registros armazenados em cache:
max-cache-ttl 604800; /* 1 week */

// Essa configuração define o TTL máximo para os registros de negativo armazenados em cache:
max-ncache-ttl 10800; /* 3 hours */

// Essa configuração define o TTL mínimo para os registros de negativo armazenados em cache. 0 significa que os registros de negativo não serão armazenados em cache:
min-ncache-ttl 0; /* 0 hours */

// Essa configuração define o TTL mínimo para os registros armazenados em cache. 0 significa que não há um limite mínimo para o tempo de vida dos registros em cache:
min-cache-ttl 0; /* 0 seconds */

// Essa configuração desativa o uso de registros em cache que já expiraram, também conhecidos como registros "stale".
// Quando definido como false, o BIND não usará registros "stale" e solicitará uma nova resolução caso o registro em cache tenha expirado:
stale-cache-enable false;

// Essa configuração define se o servidor deve armazenar em cache o valor zero (0) para o TTL de registros SOA (Start of Authority):
zero-no-soa-ttl-cache no;

Se remover algumas configurações que habilitam o Cache (com remover quero dizer configurá-las para não armazenar em Cache), verá que as respostas sempre vão demorar um pouco, isso acontece porque não terá mais o armazenamento em Cache e o servidor DNS sempre terá que fazer a pesquisa do RR solicitado.


Reinicie o serviço do BIND:

# Verifique se existe algum erro no arquivo de configuração:
named-checkconf -t /usr/local/named/ /etc/named.conf

# Reinicie o serviço:
systemctl restart named

Agora de uma outra máquina vamos testar:

# Faça uma consulta no servidor DNS e perceba que ele vai demorar para responder:
dig @94.72.123.149 google.com.br | grep msec
;; Query time: 1392 msec

# Faça o mesmo teste e perceba que a resposta será mais rápida, isso é porque a resposta já está em cache:
dig @94.72.123.149 google.com.br | grep msec
;; Query time: 184 msec

# Faça mais uma vez:
dig @94.72.123.149 google.com.br | grep msec
;; Query time: 184 msec

Sei que acabei deixando bastante configuração no arquivo e pode ficar confuso, por isso, existem duas configurações de extrema importância (e aqui vou deixar de lado as configurações de Cache, já que elas são padronizadas no BIND) para fazer o servidor recursivo funcionar, são elas:

  • recursion yes;
    Essa configuração habilita o modo recursivo, ou seja, o servidor DNS vai passar a responder consultas recursivas.

  • allow-recursion {127.0.0.0/8;192.168.121.0/24;};
    Essa configuração define os endereços IP e/ou Redes que têm permissão para emitir consultas recursivas, no nosso caso usamos any; que define qualquer origem. É muito importante que essa configuração seja adicionada para que o servidor DNS de Cache não fique aberto e respondendo requisições para outras Redes, caso ele fique aberto, poderia ser usado por terceiros mal-intencionados em ataques DDoS e até mesmo responder consultas que só deveriam ser respondidas internamente numa configuração mais generalizada.

    Aqui poderíamos configurar Views mas deixaremos de lado por enquanto.



Root Zones


Para um servidor Cache (recursivo) é importante ter habilitado a declaração abaixo, por padrão ela ficava declarada no arquivo named.conf ou named.conf.default-zones, então não era necessário declarar. Sem essa configuração, pode ser que uma aplicação de DNS não saiba quem são os Root Servers e se ele não souber, não irá conseguir fazer consultas recursivas.

zone "." {
type hint;
file "/etc/root.hints";
};

# Uma forma de obter a configuração desse arquivo é com o comando abaixo:
dig ns . @l.root-servers.net > root.hints

Todas as versões modernas e suportadas do BIND são construídas com a zona . (root) para o tipo hint. Portanto, não é necessário ter esse arquivo, a não ser que queira ter os endereços/servidores atualizados, já que a configuração que vem pré-compilada no BIND pode acabar estando defasada, mas dificilmente estará defasada a ponto de comprometer o funcionamento da aplicação.


Essa configuração fica em lib/dns/rootns.c, ou mais especificamente em /usr/src/bind-9.19.21/bind-9.19.21/lib/dns/rootns.c.



Configurando um servidor DNS de Forward


O BIND permite a configuração do Forward usando as instruções forward e forwarders em nível global (usando o arquivo de configuração principal), nesse caso todas as consultas vão ser redirecionadas, se for realizado por zona (em uma cláusula de zona) apenas as consultas daquela zona serão redirecionadas. Os forward e forwarders são sempre usados juntos.


  • forward only; versus forward first;
    O comportamento normal do servidor DNS é usar as lista de servidores Root durante uma resolução de nome (a menos que ele seja autoritativo). Quando habilitamos o forward only;, esse processo é completamente desativado e todas as solicitações de DNS são encaminhadas para algum outro servidor (normalmente um que configuramos). Portanto, esse servidor DNS que vai receber o encaminhamento fará todo o trabalho.

    Quando é ativado o forward first;, seu servidor DNS tentará encaminhar uma solicitação para outro servidor e, se houver uma falha ou um tempo limite, a solicitação voltará a ser resolvida usando o método padrão (começando nos servidores Root).


Para essa configuração, vou usar uma máquina virtual na rede local. Vamos configurar então o nosso servidor para fazer Forward:

vim /usr/local/named/etc/named.conf.options
    // Define a versão que é apresentada como 'not currently available', é mais uma medida para impedir que consigam ver a versão do BIND:
version "not currently available";

// Essa configuração impede transferências de zonas globalmente, caso seja necessário será definida na configuração específica da zona:
allow-transfer { "none" };

// Desativa o BIND para responder consultas recursivas já que será apenas um servidor Forward:
recursion no;

// Habilitar o acesso ao cache para usuários na Rede Local:
allow-query-cache { localnets; };

// Essa configuração define forward para todas as consultas (já que está na configuração global)
// usando o método de sempre fazer o encaminhamento:
forward only;

// Essa configuração define quem será o servidor DNS que vamos encaminhar a solicitação:
forwarders {
8.8.8.8;
8.8.4.4;
};

Agora vamos verificar se existem algum erro na configuração do Bind e caso negativo, vamos reiniciar o serviço do Bind:

# Verifique se existe algum erro no arquivo de configuração:
named-checkconf -t /usr/local/named/ /etc/named.conf

# Reinicie o serviço:
systemctl restart named

Para testar vou usar o tcpdump para fazer capturas de pacote e conseguir mostrar o comportamento:

# Primeiro no servidor DNS faça captura de pacotes:
tcpdump port 53 -n

# Agora num cliente DNS faça uma consulta pedindo IP do nic.br:
dig @192.168.121.15 nic.br

# O resultado será o seguinte:
16:55:07.669878 IP 192.168.121.1.50516 > 192.168.121.15.53: 33557+ [1au] A? nic.br. (47)
16:55:07.670880 IP 192.168.121.15.54809 > 8.8.4.4.53: 7807+% [1au] A? nic.br. (47)
16:55:07.679152 IP 8.8.4.4.53 > 192.168.121.15.54809: 7807$ 2/0/1 A 200.160.4.6, RRSIG (153)
16:55:07.679959 IP 192.168.121.15.48980 > 8.8.4.4.53: 1386+% [1au] DNSKEY? nic.br. (47)
16:55:07.694560 IP 8.8.4.4.53 > 192.168.121.15.48980: 1386 2/0/1 DNSKEY, RRSIG (217)
16:55:07.696118 IP 192.168.121.15.50741 > 8.8.4.4.53: 3435+% [1au] DS? nic.br. (47)
16:55:07.708522 IP 8.8.4.4.53 > 192.168.121.15.50741: 3435 2/0/1 DS, RRSIG (181)
16:55:07.711362 IP 192.168.121.15.53 > 192.168.121.1.50516: 33557$ 1/0/1 A 200.160.4.6 (79)

# O IP 192.168.121.1 pertence ao Cliente DNS;
# O IP 192.168.121.15 pertence ao servidor DNS;
# O IP 8.8.4.4 é servidor DNS do Google que configuramos no forwarders;

Com a saída acima podemos ver que o Cliente DNS faz uma consulta no servidor DNS (192.168.121.15) de Forward:

16:55:07.669878 IP 192.168.121.1.50516 > 192.168.121.15.53: 33557+ [1au] A? nic.br. (47)

O DNS de Forward por sua vez refaz a consulta em outro servidor DNS, no caso o servidor DNS do Google (8.8.4.4):

16:55:07.670880 IP 192.168.121.15.54809 > 8.8.4.4.53: 7807+% [1au] A? nic.br. (47)

O servidor DNS do Google responde a consulta realizada pelo nosso servidor DNS de Forward:

16:55:07.679152 IP 8.8.4.4.53 > 192.168.121.15.54809: 7807$ 2/0/1 A 200.160.4.6, RRSIG (153)

As duas próximas consultas e repostas que se seguem são validações de DNSSEC para fornecer autenticação e integridade dos registros DNS.

16:55:07.679959 IP 192.168.121.15.48980 > 8.8.4.4.53: 1386+% [1au] DNSKEY? nic.br. (47)
16:55:07.694560 IP 8.8.4.4.53 > 192.168.121.15.48980: 1386 2/0/1 DNSKEY, RRSIG (217)
16:55:07.696118 IP 192.168.121.15.50741 > 8.8.4.4.53: 3435+% [1au] DS? nic.br. (47)
16:55:07.708522 IP 8.8.4.4.53 > 192.168.121.15.50741: 3435 2/0/1 DS, RRSIG (181)

Por fim o servidor DNS de Forward já tem a resposta para a consulta do cliente DNS, muito além disso, ele também tem a certeza que de a resposta não foi alterada e de que o servidor DNS conseguiu fornece a resposta mais recente e correta possível. Com isso ele já pode retornar a resposta para o cliente DNS:

16:55:07.711362 IP 192.168.121.15.53 > 192.168.121.1.50516: 33557$ 1/0/1 A 200.160.4.6 (79)

Essa foi uma configuração global de Forward, ou seja, toda consulta, não importa o domínio consultado será redirecionado para outro servidor DNS. Mas vejamos agora como redirecionar apenas um domínio em particular, para isso vou partir do ponto em que o servidor não tem nenhuma opção relacionada a Forward.


Primeiro crie a zona no servidor:

vim /usr/local/named/etc/forward_zones.conf
zone "maddogs.com.br" {
type forward;
forwarders { 8.8.8.8;8.8.4.4; };
forward only;
};

Agora temos que configurar o Bind para importar o arquivo acima, para que a configuração passe a funcionar:

vim /usr/local/named/etc/named.conf
# Adicione a linha abaixo:
include "/etc/forward_zones.conf";

Dessa maneira apenas quando consultado o domínio maddogs.com.br será redirecionado para o IP do Google.



Zona WLF


Aqui vamos configurar primeiramente o servidor DNS par wlf.eti.br usando DNSSEC com geração de chave automatizada. Depois iremos configurar o slave de wlf que é o servidor hermodr e por fim configurar ele juntamente com o registro.br.


Após ter finalizado com o domínio wlf.eti.br, vamos fazer o mesmo processo com o hermodr.com.br, porém, nele não vamos usar uma assinatura de zona automática, o processo para usar DNSSEC será um pouco mais manual. Farei isso para abordar os dois métodos de configuração.



Configurando um servidor Primário para wlf.eti.br


O servidor Master transfere todas as informações de uma determinada Zona para um servidor Slave. Pensando em segurança, essa ação sempre deve ser restrita apenas a servidores DNS autorizados a receber essas informações. É muito comum SysAdmins deixar a Transferência de Zona aberta no Servidor, causando uma brecha de segurança.


Para testar essa brecha, execute o seguinte comando:

dig SERVIDOR DNS axfr

Como mencionado anteriormente, no servidor DNS Master temos que usar as configurações abaixo para criar uma camada de proteção, não é o melhor método, mas é um bom começo.

Para melhorar temos que configurar o TSIG e SIG.

  • allow-transfer
    Restringir a transferência de zona globalmente, apenas para Servidores Autorizados. Essa opção pode ser usada com ACL.

  • notify e also-notify
    As opções determinam se o servidor primário notifica servidores secundários, quando a informação de zona for atualizada. A opção also-notify não pode ser usada com ACL.


Primeiro vou estruturar onde vão ficar os arquivos de zonas (levando em conta que eles ficarão dentro de /usr/local/named):

  • /var/named
    É o diretório padrão para armazenar o cache de consultas DNS em sistemas Linux, também guarda as "chaves gerenciadas" lá.

  • /var/named/master
    Aqui dentro ficarão os arquivos de zonas para cada domínio.


Vamos começar configurando o comportamento do servidor DNS Master:

vim /usr/local/named/etc/named.conf.options
    // Define a versão que é apresentada como 'not currently available', é mais uma medida para impedir que consigam ver a versão do BIND:
version "not currently available";

// Essa configuração impede transferências de zonas globalmente, caso seja necessário será definida na configuração específica da zona:
allow-transfer { none; };

// Desativa o BIND para responder consultas recursivas, já que será apenas um servidor Master:
recursion no;

// Como não tem recursivo, podemos impedir a consulta recursiva no servidor:
allow-recursion { none; };

// Vamos desativar também a consulta para o Cache:
allow-query-cache { none; };

// Especifica para quais endereços IP o servidor deve escutar para consultas de cache:
allow-query-cache-on { none; };

// Se você não estiver executando um resolver, não precisará da validação DNSSEC.
dnssec-validation no;

// Habilita transferências incrementais (IXFR - Incremental Zone Transfer) para a zona.
provide-ixfr yes;

// Indica que o servidor secundário deve usar transferência incremental apenas se houver diferenças detectadas desde a última transferência.
ixfr-from-differences yes;

// As notificações de transferência de zona só ocorrerão se solicitadas explicitamente pelo servidor primário.
notify explicit;

Agora vamos criar a zona primária de wlf:

vim /usr/local/named/etc/master_zones.conf
zone "wlf.eti.br" {
type master;
file "master/wlf";
dnssec-policy default;
inline-signing yes;
};

Agora é necessário adicionar o arquivo que foi criado acima na configuração do BIND, dessa forma ele será carregado:

vim /usr/local/named/etc/named.conf
include "/etc/master_zones.conf";

Desativar a consulta de Cache não é um passo obrigatório até porque nosso servidor não vai sofrer com requisições DNS de alto volume, mas é uma boa prática já que é um servidor somente autoritativo. Outras configurações podem ser realizadas para impedir o armazenamento de cache, mas nesse nosso caso, não deve ocorrer.


Vejamos uma explicação detalhada das opções usadas em /usr/local/named/etc/master_zones.conf.

  1. zone "wlf.eti.br":

    • Indica que a configuração a seguir se aplica à zona "wlf.eti.br".
  2. type master;:

    • Define o tipo da zona como "master". Isso significa que este servidor DNS é a fonte autoritativa para essa zona e que os dados da zona são configurados localmente.
  3. file "master/wlf";:

    • Especifica o caminho do arquivo que contém as informações da zona.
  4. dnssec-policy default;:

    • Indica que a política de DNSSEC padrão (default) será aplicada a esta zona, ou seja, vamos usar DNSSEC. Para mais detalhes veja aqui
  5. inline-signing yes;:

    • Ativa a assinatura inline, que foi introduzida no Bind 9.16, ou seja, a zona será assinada automaticamente pelo servidor DNS, conforme especificado pela política de DNSSEC padrão.

Essa configuração geralmente seria encontrada no arquivo de configuração principal do servidor DNS (por exemplo, o arquivo named.conf). Certifique-se de ajustar os caminhos dos arquivos e outras configurações de acordo com a sua implementação específica do BIND.


O que define o servidor DNS como Master da zona é a configuração type master;, já file "master/wlf"; informa o nome do arquivo onde vamos adicionar a configuração para essa zona.

# Crie o diretório abaixo:
mkdir /usr/local/named/var/named/master

Agora vamos cria o arquivo de zona:

vim /usr/local/named/var/named/master/wlf
; $Id$
; zone wlf.eti.br

$TTL 86400
@ IN SOA ns1.wlf.eti.br. admin.wlf.eti.br. (
2023052403 ; Serial
3600 ; Refresh (1 hora)
1800 ; Retry (30 minutos)
604800 ; Expire (1 semana)
86400 ) ; Negative Cache TTL (1 dia)
;
IN NS ns1.wlf.eti.br.
IN NS ns2.wlf.eti.br.

ns1 IN A 94.72.123.149
IN AAAA 2605:a141:2167:7657::1

ns2 IN A 75.119.143.187
IN AAAA 2a02:c206:2120:1140::1

; Registro de recurso (RR):
@ IN A 94.72.123.149
IN AAAA 2605:a141:2167:7657::1

Corrija o usuário e grupo para o arquivo criado, depois verifique se não existem erros no arquivo de zona e então reinicie o Bind:

# Mude o dono dos arquivos para ser o Bind (Apesar de não ser necessário):
chown -R bind: /usr/local/named/{etc,var}

# Verifique se existem erros de configuração:
named-checkzone -t /usr/local/named/ wlf.eti.br /var/named/master/wlf
zone wlf.eti.br/IN: loaded serial 2023052403
OK

# Recarregue os arquivos de configuração e zona:
systemctl restart named


Configurando um servidor Secundário para wlf.eti.br


Os servidores DNS Secundários (ou slaves) ajudam a fornecer equilíbrio de carga e tolerância a falhas. Eles mantêm uma cópia somente leitura dos dados da zona transferidos periodicamente do servidor DNS Primário.


Primeiro vou estruturar onde vão ficar os arquivos de zonas:

  • /var/named
    É o diretório padrão para armazenar o cache de consultas DNS em sistemas Linux, também guarda as "chaves gerenciadas" lá.

  • /var/named/slave
    Aqui dentro ficarão os arquivos de zonas para cada domínio.


A configuração abaixo deve ser realizada no servidor hermodr.com.br, ele será o slave de wlf.eti.br.


# Crie o diretório abaixo:
mkdir /usr/local/named/var/named/slave

Agora vamos cria a zona secundária:

vim /usr/local/named/etc/slave_zones.conf
zone "wlf.eti.br" {
type secondary;
file "slave/wlf";
primaries { 94.72.123.149; 2605:a141:2167:7657::1; };
};

Adicione o arquivo criado acima na configuração do BIND:

vim /usr/local/named/etc/named.conf
### Adicione a opção abaixo:
include "/etc/slave_zones.conf";

Verifique se existem erros de configuração:

named-checkconf -t /usr/local/named/ /etc/named.conf

A linha file "slave/wlf"; é opcional e permite que os dados da zona sejam salvos no arquivo especificado após receber uma transferência do servidor Master. Se o servidor DNS for reiniciado, ele poderá ler os dados da zona desse arquivo em vez de forçar uma nova transferência de zona do Master, como seria o caso se nenhuma instrução de file estivesse presente. Com essa declaração podemos economizar tempo e recursos.

A opção primaries ou masters não pode ser usada em conjunto com ACL.


A configuração abaixo deve ser realizada no servidor wlf.eti.br, vamos permitir a transferência de zona nele.


Primeiro vamos criar uma ACL com os IPs do servidor slave, é somente para introduzirmos a configuração de ACLs:

vim /usr/local/named/etc/named.conf
### Adicione a opção abaixo
acl hermodrips {
75.119.143.187;
2a02:c206:2120:1140::1;
};

vim /usr/local/named/etc/master_zones.conf
zone "wlf.eti.br" {
type master;
file "master/wlf";
dnssec-policy default;
inline-signing yes;
allow-transfer { hermodrips; };
also-notify { 75.119.143.187; 2a02:c206:2120:1140::1; };
};

Verifique se existem erros de configuração:

named-checkconf -t /usr/local/named/ /etc/named.conf

Vejamos uma explicação detalhada das novas opções usadas em /usr/local/named/etc/master_zones.conf.

  1. allow-transfer
  • Define quais hosts ou redes estão autorizados a solicitar transferências de zona do servidor, se o IP não for o mesmo que está aqui, a zona não será transferida.
  1. notify
  • Define se o servidor enviará notificações automáticas para outros servidores autoritativos quando a zona for modificada. Quando notify é definido como "yes", o servidor enviará notificações para os servidores listados na diretiva masters.

Nesse ponto ambos os servidores estão configurados, só falta reiniciar o serviço, mas antes que isso seja feito, vamos configurar o TSIG. O passo abaixo é realizado no wlf.eti.br.

# Primeiro crie um diretório para armazenar as chaves e entre no diretório criado:
mkdir /usr/local/named/tsig-keys && cd /usr/local/named/tsig-keys

# Gere as chaves:
tsig-keygen -a hmac-sha512 wlf.eti.br > wlf.eti.br

# Faça com que apenas o root possa ler o conteúdo do arquivo:
chmod 700 wlf.eti.br

Coloque a chave TSIG do wlf em named.conf:

vim /usr/local/named/etc/named.conf
key "wlf.eti.br" {
algorithm hmac-sha512;
secret "oXTEccE3Wkn7JeWzj2qOk5Er37vtdCZpnNEL5chELB24MW5HkcyidBcnyS3qf8roG8jpJ9bWA6G9TqF8/t5aQA==";
};

Agora edite a zona do wlf e configure para que somente quem tiver o IP na acl hermodrips e possui a chave wlf.eti.br possa fazer receber a transferência de zona:

vim /usr/local/named/etc/master_zones.conf
# Deixe como está abaixo:
allow-transfer { key wlf.eti.br; hermodrips; };

Verifique se não existem erros:

named-checkconf -t /usr/local/named/ /etc/named.conf

O passo abaixo é realizado no hermodr.com.br.


Adicione a chave TSIG de wlf no servidor hermodr e configure para que o hermodr use a chave para o IPv4 e IPv6 de WLF:

vim /usr/local/named/etc/named.conf
### Adicione a chave TSIG abaixo:
key "wlf.eti.br" {
algorithm hmac-sha512;
secret "oXTEccE3Wkn7JeWzj2qOk5Er37vtdCZpnNEL5chELB24MW5HkcyidBcnyS3qf8roG8jpJ9bWA6G9TqF8/t5aQA==";
};

server 94.72.123.149 {
keys { wlf.eti.br; };
};

server 2605:a141:2167:7657::1 {
keys { wlf.eti.br; };
};

Verifique se não existem erros:

named-checkconf -t /usr/local/named/ /etc/named.conf

Agora vamos recarregar os arquivos de configuração das zona:

# No servidor wlf.eti.br:
rndc -k /usr/local/named/etc/rndc.key -s localhost reload

# No servidor hermodr.com.br:
rndc -k /usr/local/named/etc/rndc.key -s localhost reload

# Veja se deu certo, pode rodar em qualquer um dos servidores:
grep 'wlf' /usr/local/named/var/log/named/transfers
25-Feb-2024 13:38:58.513 zone wlf.eti.br/IN: Transfer started.
25-Feb-2024 13:38:58.665 0x7f77b3416400: transfer of 'wlf.eti.br/IN' from 94.72.123.149#53: connected using 94.72.123.149#53 TSIG wlf.eti.br
25-Feb-2024 13:38:58.825 zone wlf.eti.br/IN: transferred serial 2023052405: TSIG 'wlf.eti.br'
25-Feb-2024 13:38:58.825 0x7f77b3416400: transfer of 'wlf.eti.br/IN' from 94.72.123.149#53: Transfer status: success
25-Feb-2024 13:38:58.825 0x7f77b3416400: transfer of 'wlf.eti.br/IN' from 94.72.123.149#53: Transfer completed: 1 messages, 24 records, 1641 bytes, 0.159 secs (10320 bytes/sec) (serial 2023052405)

### Funcionou !!!


Tornando nosso DNS da WLF público


Agora vamos obter os dados para cadastrar o DS no site do registro.br:

# Entre no diretório abaixo no wlf:
cd /usr/local/named/var/named

# Rode o comando para obter as informações da chave:
/usr/local/named/bin/dnssec-dsfromkey Kwlf.eti.br.+013+04462.key
wlf.eti.br. IN DS 14414 13 2 57324B7F2D14A3828C0577E5864A5754401C5258AC2AA3A307101F66DB1F9945

# O keytag do DS é 14414 e a Digest é 57324B7F2D14A3828C0577E5864A5754401C5258AC2AA3A307101F66DB1F9945

Agora que temos os servidores instalados e configurados, vamos configurar o registro.br para redirecionar todas as consultas sobre o domínio wlf.eti.br para nosso servidor. Acesse o site do registro.br e logue com a conta na qual tem o poder de administrar o domínio.


Clique em Alterar servidores DNS, clique no botão + DNSSEC para colocar os dados do DS, agora é só preencher os dados, veja a imagem abaixo para ver como ficou no meu caso, depois é só clicar em SALVAR ALTERAÇÕES.


wlf_registro.br


Com o clinte DNS podemos fazer um teste enquanto temos que esperar a publicação da mudança surtir efeito:

# Consulta o registro SOA para o domínio wlf.eti.br no servidor DNS Primário:
dig @94.72.123.149 wlf.eti.br soa +short
ns1.wlf.eti.br. admin.wlf.eti.br. 2023052406 3600 1800 604800 86400

# Consulta o registro SOA para o domínio wlf.eti.br no servidor DNS Secundário:
dig @75.119.143.187 wlf.eti.br soa +short
ns1.wlf.eti.br. admin.wlf.eti.br. 2023052406 3600 1800 604800 86400

# Consulta o registro A para wlf.eti.br:
dig @75.119.143.187 wlf.eti.br A +short
94.72.123.149

# Verifique quais são os servidores DNS do nosso domínio:
dig wlf.eti.br ns +short
b.auto.dns.br.
a.auto.dns.br.

## Isso significa que a publicação ainda não foi finalizada; Para os servidores DNS Globais
## a zona 'wlf.eti.br' é gerenciada pelos servidores DNS do nic.br.

# Faça o mesmo teste mas pergunte para o ns1 quem são os servidores DNS:
dig @94.72.123.149 wlf.eti.br ns +short
ns2.wlf.eti.br.
ns1.wlf.eti.br.

## Se perguntar novamente, verá que a ordem será diferente, isso é por causa do load balance via DNS:
dig @94.72.123.149 wlf.eti.br ns +short
ns1.wlf.eti.br.
ns2.wlf.eti.br.

Como um bonus segue uma forma de ver as zonas carregadas no servidor:

named-checkconf -z -t /usr/local/named /etc/named.conf
zone wlf.eti.br/IN: loaded serial 2023052408


Zona HERMODR


Aqui vamos configurar primeiramente o servidor DNS par hermodr.com.br usando DNSSEC com geração de chave manual com uma política de DNSSEC personalizada. Depois iremos configurar o slave de hermodr que é o servidor wlf e por fim configurar ele juntamente com o registro.br.



Configurando um servidor Primário para hermodr.com.br


O servidor Master transfere todas as informações de uma determinada Zona para um servidor Slave. Pensando em segurança, essa ação sempre deve ser restrita apenas a servidores DNS autorizados a receber essas informações. É muito comum SysAdmins deixar a Transferência de Zona aberta no Servidor, causando uma brecha de segurança.


Para testar essa brecha, execute o seguinte comando:

dig SERVIDOR DNS axfr

Como mencionado anteriormente, no servidor DNS Master temos que usar as configurações abaixo para criar uma camada de proteção, não é o melhor método, mas é um bom começo.

Para melhorar temos que configurar o TSIG e SIG.

  • allow-transfer
    Restringir a transferência de zona globalmente, apenas para Servidores Autorizados. Essa opção pode ser usada com ACL.

  • notify e also-notify
    As opções determinam se o servidor primário notifica servidores secundários, quando a informação de zona for atualizada. A opção also-notify não pode ser usada com ACL.


Primeiro vou estruturar onde vão ficar os arquivos de zonas (levando em conta que eles ficarão dentro de /usr/local/named):

  • /var/named
    É o diretório padrão para armazenar o cache de consultas DNS em sistemas Linux, também guarda as "chaves gerenciadas" lá.

  • /var/named/master
    Aqui dentro ficarão os arquivos de zonas para cada domínio.


Vamos começar configurando o servidor o comportamento do DNS Primário:

vim /usr/local/named/etc/named.conf.options
    // Define a versão que é apresentada como 'not currently available', é mais uma medida para impedir que consigam ver a versão do BIND:
version "not currently available";

// Essa configuração impede transferências de zonas globalmente, caso seja necessário será definida na configuração específica da zona:
allow-transfer { none; };

// Desativa o BIND para responder consultas recursivas, já que será apenas um servidor Master:
recursion no;

// Como não tem recursivo, podemos impedir a consulta recursiva no servidor:
allow-recursion { none; };

// Vamos desativar também a consulta para o Cache:
allow-query-cache { none; };

// Especifica para quais endereços IP o servidor deve escutar para consultas de cache:
allow-query-cache-on { none; };

// Se você não estiver executando um resolver, não precisará da validação DNSSEC.
dnssec-validation no;

Ainda no mesmo arquivo acima, mas fora da cláusula options, vamos criar uma política de DNSSEC para nós:

vim /usr/local/named/etc/named.conf.options
dnssec-policy "mydnssec" {

keys {
ksk key-directory lifetime unlimited algorithm 13;
zsk key-directory lifetime P60D algorithm 13;
};

nsec3param iterations 0 optout no salt-length 0;
dnskey-ttl 3600;
cdnskey yes;
publish-safety 3600;
retire-safety 3600;
purge-keys P90D;
signatures-refresh P5D;
signatures-validity P14D;
signatures-validity-dnskey P14D;
max-zone-ttl 86400;
zone-propagation-delay 300;
parent-ds-ttl 86400;
parent-propagation-delay 3600;
};

É uma boa prática colocar uma data de validade para KSK, mas no mundo real poderia passar da data e o domínio teria problemas com DNSSEC, então vou deixar sem uma data para que a troca seja realizada sem um prazo que pode implicar em problemas para o domínio.


Agora vamos colocar nossa chave na configuração da zona:

vim /usr/local/named/etc/master_zones.conf
zone "hermodr.com.br" {
type master;
file "master/hermodr";
key-directory "/var/named";
dnssec-policy mydnssec;
};

Adicione o arquivo criado acima na configuração do BIND:

vim /usr/local/named/etc/named.conf
include "/etc/master_zones.conf";

Desativar a consulta de Cache não é um passo obrigatório até porque nosso servidor não vai sofrer com requisições DNS de alto volume, mas é uma boa prática já que é um servidor somente autoritativo. Outras configurações podem ser realizadas para impedir o armazenamento de cache, mas nesse nosso caso, não deve ocorrer.


Vejamos uma explicação detalhada das opções usadas em /usr/local/named/etc/master_zones.conf.

  1. zone "hermodr.com.br":

    • Indica que a configuração a seguir se aplica à zona "hermodr.com.br".
  2. type master;:

    • Define o tipo da zona como "master". Isso significa que este servidor DNS é a fonte autoritativa para essa zona e que os dados da zona são configurados localmente.
  3. file "master/hermodr";:

    • Especifica o caminho do arquivo que contém as informações da zona.
  4. key-directory "/var/named";

    • Indica o diretório onde as chaves DNSSEC são armazenadas. Este diretório conterá os arquivos de chaves públicas e privadas usadas para assinar a zona.
  5. dnssec-policy mydnssec;

    • Indica que a política de DNSSEC é a nossa (mydnssec) será aplicada a esta zona, ou seja, vamos usar DNSSEC. Para mais detalhes veja aqui

O que define o servidor DNS como Master da zona é a configuração type master;, já file "master/hermodr"; informa o nome do arquivo onde vamos adicionar a configuração para essa zona.

# Crie o diretório abaixo:
mkdir /usr/local/named/var/named/master

Agora vamos cria o arquivo de zona:

vim /usr/local/named/var/named/master/hermodr
; $Id$
; zone hermodr.com.br

$TTL 86400
@ IN SOA ns1.hermodr.com.br. admin.hermodr.com.br. (
2023052402 ; Serial
3600 ; Refresh (1 hora)
1800 ; Retry (30 minutos)
604800 ; Expire (1 semana)
86400 ) ; Negative Cache TTL (1 dia)

IN NS ns1.hermodr.com.br.
IN NS ns2.hermodr.com.br.

ns1 IN A 75.119.143.187
IN AAAA 2a02:c206:2120:1140::1

ns2 IN A 94.72.123.149
IN AAAA 2605:a141:2167:7657::1

; Registro de recurso (RR):
@ IN A 75.119.143.187
IN AAAA 2a02:c206:2120:1140::1

Corrija o usuário e grupo para o arquivo criado, depois verifique se não existem erros no arquivo de zona e então reinicie o Bind:

# Mude o dono dos arquivos para ser o Bind (Apesar de não ser necessário):
chown -R bind: /usr/local/named/{etc,var}

# Verifique se existem erros de configuração:
named-checkzone -t /usr/local/named/ hermodr.com.br /var/named/master/hermodr
zone hermodr.com.br/IN: loaded serial 2023052402
OK

# Recarregue os arquivos de configuração e zona:
systemctl restart named

# Podemos verificar se está assinando:
grep signed /usr/local/named/var/log/named/general
25-Feb-2024 15:52:41.551 zone hermodr.com.br/IN (unsigned): loaded serial 2023052402
25-Feb-2024 15:52:41.555 zone hermodr.com.br/IN (signed): loaded serial 2023052405 (DNSSEC signed)

# Faça um teste usando DNSSEC:
dig @75.119.143.187 hermodr.com.br A +dnssec +short
75.119.143.187
A 13 3 86400 20240307181853 20240225164619 32756 hermodr.com.br. VLYndOkmdTJyl5OseZF4nWSLQuL5xW8G/rzMAflyW/XEFSppGoyv6tv+ V7JUcWDxTxg3bI3LSMi7BeGUktSalw==

# Faça outro sem DNSSEC:
dig @75.119.143.187 hermodr.com.br A +nodnssec +short
75.119.143.187


Configurando um servidor Secundário para hermodr.com.br


Os servidores DNS Secundários (ou slaves) ajudam a fornecer equilíbrio de carga e tolerância a falhas. Eles mantêm uma cópia somente leitura dos dados da zona transferidos periodicamente do servidor DNS Primário.


Primeiro vou estruturar onde vão ficar os arquivos de zonas:

  • /var/named
    É o diretório padrão para armazenar o cache de consultas DNS em sistemas Linux, também guarda as "chaves gerenciadas" lá.

  • /var/named/slave
    Aqui dentro ficarão os arquivos de zonas para cada domínio.


A configuração abaixo deve ser realizada no servidor wlf.eti.br, ele será o slave de hermodr.com.br.


# Crie o diretório abaixo:
mkdir /usr/local/named/var/named/slave

Cria a zona secundária no servidor wlf.

vim /usr/local/named/etc/slave_zones.conf
zone "hermodr.com.br" {
type secondary;
file "slave/hermodr";
primaries { 75.119.143.187; 2a02:c206:2120:1140::1; };
};

Adicione o arquivo criado acima na configuração do BIND:

vim /usr/local/named/etc/named.conf
include "/etc/slave_zones.conf";

Verifique se existem erros de configuração:

named-checkconf -t /usr/local/named/ /etc/named.conf

A linha file "slave/hermodr"; é opcional e permite que os dados da zona sejam salvos no arquivo especificado após receber uma transferência do servidor Master. Se o servidor DNS for reiniciado, ele poderá ler os dados da zona desse arquivo em vez de forçar uma nova transferência de zona do Master, como seria o caso se nenhuma instrução de file estivesse presente. Com essa declaração podemos economizar tempo e recursos.

A opção primaries ou masters não pode ser usada em conjunto com ACL.


A configuração abaixo deve ser realizada no servidor hermodr.com.br, vamos permitir a transferência de zona nele.


Primeiro vamos criar uma ACL com os IPs do servidor slave, é somente para introduzirmos a configuração de ACLs:

vim /usr/local/named/etc/named.conf
acl wlfips {    
94.72.123.149;
2605:a141:2167:7657::1;
};

vim /usr/local/named/etc/master_zones.conf
zone "hermodr.com.br" {
type master;
file "master/hermodr";
key-directory "/var/named";
dnssec-policy mydnssec;
allow-transfer { wlfips; };
also-notify { 94.72.123.149; 2605:a141:2167:7657::1; };
};

Verifique se existem erros de configuração:

vim /usr/local/named/etc/named.conf
named-checkconf -t /usr/local/named/ /etc/named.conf

Nesse ponto ambos os servidores estão configurados, só falta reiniciar o serviço, mas antes que isso seja feito, vamos configurar o TSIG. O passo abaixo é realizado no hermodr.com.br.

# Primeiro crie um diretório para armazenar as chaves e entre no diretório criado:
mkdir /usr/local/named/tsig-keys && cd /usr/local/named/tsig-keys

# Gere as chaves:
tsig-keygen -a hmac-sha512 hermodr.com.br > hermodr.com.br

# Faça com que apenas o root possa ler o conteúdo do arquivo:
chmod 700 hermodr.com.br

Coloque a chave TSIG no named.conf. Para criar a chave reveja aqui.

vim /usr/local/named/etc/named.conf
key "hermodr.com.br" {
algorithm hmac-sha512;
secret "4A/otFTFASxHtEyVilNvS52P4I4b3itO+jmjHLKXyQxfmvBfQfdQyYmeI+CI6XIbFaLx4ck6JmPl+VkGlpGwNA==";
};

Nesse momento vamos ter duas chaves, uma do wlf e outra do hermodr! Agora vamos adicionar a chave na configuração da zona, para restringir a transferência de zona para servidores que possuem a chave.

vim /usr/local/named/etc/master_zones.conf
### Deixe como está abaixo ###
allow-transfer { key hermodr.com.br; wlfips; };

Verifique se não existem erros:

named-checkconf -t /usr/local/named/ /etc/named.conf

O passo abaixo é realizado no wlf.eti.br.

vim /usr/local/named/etc/named.conf
### Adicione as opções abaixo:
key "hermodr.com.br" {
algorithm hmac-sha512;
secret "4A/otFTFASxHtEyVilNvS52P4I4b3itO+jmjHLKXyQxfmvBfQfdQyYmeI+CI6XIbFaLx4ck6JmPl+VkGlpGwNA==";
};

acl hermodrservers {
75.119.143.187;
2a02:c206:2120:1140::1;
};

server 75.119.143.187 {
keys { hermodr.com.br; };
};

server 2a02:c206:2120:1140::1 {
keys { hermodr.com.br; };
};

Verifique se não existem erros:

named-checkconf -t /usr/local/named/ /etc/named.conf

Agora vamos recarregar os arquivos de configuração das zona:

# No servidor hermodr.com.br:
rndc -k /usr/local/named/etc/rndc.key -s localhost reload

# No servidor wlf.eti.br:
rndc -k /usr/local/named/etc/rndc.key -s localhost reload

# Veja se deu certo, pode rodar em qualquer um dos servidores:
grep 'hermodr' /usr/local/named/var/log/named/transfers
25-Feb-2024 16:34:49.997 zone hermodr.com.br/IN: Transfer started.
25-Feb-2024 16:34:50.153 0x7f6f26fe1000: transfer of 'hermodr.com.br/IN' from 75.119.143.187#53: connected using 75.119.143.187#53 TSIG hermodr.com.br
25-Feb-2024 16:34:50.309 zone hermodr.com.br/IN: transferred serial 2023052405: TSIG 'hermodr.com.br'
25-Feb-2024 16:34:50.309 0x7f6f26fe1000: transfer of 'hermodr.com.br/IN' from 75.119.143.187#53: Transfer status: success
25-Feb-2024 16:34:50.309 0x7f6f26fe1000: transfer of 'hermodr.com.br/IN' from 75.119.143.187#53: Transfer completed: 1 messages, 28 records, 2086 bytes, 0.155 secs (13458 bytes/sec) (serial 2023052405)

### Funcionou !!!


Tornando nosso DNS da HERMODR público


Agora vamos obter os dados para cadastrar o DS no site do registro.br:

# Entre no diretório abaixo no hermodr:
cd /usr/local/named/var/named

# Rode o comando para obter as informações da chave da chave KSK:
/usr/local/named/bin/dnssec-dsfromkey Khermodr.com.br.+013+19348.key
hermodr.com.br. IN DS 19348 13 2 672AC14996E76992DE619C134193D2D90F6F6A098BD929B8B1C6F6E4A19A2B62

# O keytag do DS é 19348 e a Digest é 672AC14996E76992DE619C134193D2D90F6F6A098BD929B8B1C6F6E4A19A2B62

Agora que temos os servidores instalados e configurados, vamos configurar o registro.br para redirecionar todas as consultas sobre o domínio wlf.eti.br para nosso servidor. Acesse o site do registro.br e logue com a conta na qual tem o poder de administrar o domínio.


Clique em Alterar servidores DNS, clique no botão + DNSSEC para colocar os dados do DS, agora é só preencher os dados, veja a imagem abaixo para ver como ficou no meu caso, depois é só clicar em SALVAR ALTERAÇÕES.


Com o clinte DNS podemos fazer um teste enquanto temos que esperar a publicação da mudança surtir efeito:

# Consulta o registro SOA para o domínio hermodr.com.br servidor DNS Primário:
dig @75.119.143.187 hermodr.com.br soa +short
ns1.hermodr.com.br. admin.hermodr.com.br. 2023052405 3600 1800 604800 86400

# Consulta o registro SOA para o domínio hermodr.com.br no servidor DNS Secundário:
dig @94.72.123.149 hermodr.com.br soa +short
ns1.hermodr.com.br. admin.hermodr.com.br. 2023052405 3600 1800 604800 86400

# Consulta o registro A para hermodr.com.br:
dig @75.119.143.187 hermodr.com.br A +short
75.119.143.187

# Verifique quais são os servidores DNS do nosso domínio:
dig hermodr.com.br ns +short
ns1.hermodr.com.br.
ns2.hermodr.com.br.

# Faça o mesmo teste mas pergunte para o ns1 quem são os servidores DNS:
dig @94.72.123.149 hermodr.com.br ns +short
ns2.hermodr.com.br.
ns1.hermodr.com.br.

## Se perguntar novamente, verá que a ordem será diferente, isso é por causa do load balance via DNS:
dig @94.72.123.149 hermodr.com.br ns +short
ns1.hermodr.com.br.
ns2.hermodr.com.br.


Configurações relacionadas ao BIND


Nessa etapa, veremos algumas configurações relacionadas diretamente ao Bind, mais na parte operacional dele e não da forma como o servidor DNS deve se comportar.



Configurando View Clauses em hermodr


Vamos configurar um servidor Primário mas com View Clauses para criar uma camada de proteção, de forma que o DNS possa responder com dados diferentes dependendo de quem está consultando. Normalmente esse tipo de configuração é aplicado no hidden master, e cada view nele é replicada para servidores DNS secundários distintos, ou seja, um servidor secundário não vai ter uma view interna e externa no mesmo servidor.


Como nosso ambiente não é hidden master, vou configurar as duas views em ambos os servidores. Estou assumindo que não temos nada configurado no servidor DNS Master. Como view é uma cláusula, ela não deve ficar dentro da cláusula options, para não ficar confuso, vou colocar ela em um arquivo novo.


O Bind vai sempre responer pela view que der match primeiro, ou seja, quando se trata de views internas e externas, a view que responderá à consulta dependerá da ordem de match e do tipo de consulta. O BIND verifica as views na ordem em que são definidas no arquivo de configuração. A primeira view que corresponder ao endereço IP de origem da consulta será usada para responder à consulta.


Como temos um servidor Primário e um Secundário, as views tem que ser criados em ambos os servidores, caso negativo, apenas o servidor com as views vai responder de forma correta.


Comenta a linha allow-query-cache { none; }; no arquivo abaixo, para liberar a consulta recursiva na view internal:

vim /usr/local/named/etc/named.conf.options
# allow-query-cache { none; };

Agora vamos editar o arquivo abaixo para adicionar alguns conteúdos:

vim /usr/local/named/etc/named.conf
// Chaves TSIG para transferência de zona:
key hermodr_ex {
algorithm hmac-sha512;
secret "4A/otFTFASxHtEyVilNvS52P4I4b3itO+jmjHLKXyQxfmvBfQfdQyYmeI+CI6XIbFaLx4ck6JmPl+VkGlpGwNA==";
};

key hermodr_in {
algorithm hmac-sha512;
secret "3du0VtsAvOPrqzf70dnObKa72rAZ0b5D/2Gq1hSzinRtQjbVGoQNpbrAauZpjckhLU9aZsw9Fz3PJ1r8Tn7NXQ==";
};

key "wlf.eti.br" {
algorithm hmac-sha512;
secret "oXTEccE3Wkn7JeWzj2qOk5Er37vtdCZpnNEL5chELB24MW5HkcyidBcnyS3qf8roG8jpJ9bWA6G9TqF8/t5aQA==";
};

// ACL para rede Interna:
acl internal-ip {
191.162.62.254;
// Precisa colocar o IP do slave para que ele possa conectar e transferir a view interna:
94.72.123.149;
};

// ACL para rede Externa:
acl external-ip {
any;
};

// View internal
view "internal" {
match-clients { internal-ip; };

include "/etc/named_in.conf";
};

// View external
view "external" {
match-clients { external-ip; };

include "/etc/named_ex.conf";

};

Ainda no mesmo arquivo, comente as linhas abaixo:

vim /usr/local/named/etc/named.conf
//include "/etc/master_zones.conf";
//include "/etc/slave_zones.conf";

Agora vamos criar os arquivos para as zonas que estão na view internal.

vim /usr/local/named/etc/named_in.conf
// Zona hermodr autoritativa dentro da View internal
zone "hermodr.com.br" {
type master;
file "InternalMaster/hermodr";
key-directory "/var/named";
dnssec-policy mydnssec;
allow-transfer { key hermodr_in; };
notify yes;
also-notify { 94.72.123.149; };
};

server 94.72.123.149 { keys { wlf.eti.br; }; };

// Zona wlf secundária dentro da View internal
zone "wlf.eti.br" {
type secondary;
file "InternalSlave/wlf";
primaries { 94.72.123.149; };
};

Agora vamos criar os arquivos para as zonas que estão na view external.

vim /usr/local/named/etc/named_ex.conf
// Zona hermodr autoritativa dentro da View external
zone "hermodr.com.br" {
type master;
file "ExternalMaster/hermodr";
key-directory "/var/named";
dnssec-policy mydnssec;
allow-transfer { key hermodr_ex; };
notify yes;
also-notify { 2605:a141:2167:7657::1; };
};

server 2605:a141:2167:7657::1 { keys { wlf.eti.br; }; };

// Zona wlf secundária dentro da View external
zone "wlf.eti.br" {
type secondary;
file "ExternalSlave/wlf";
primaries { 94.72.123.149; 2605:a141:2167:7657::1; };
};

Verifique se existem erros no arquivo de configuração:

named-checkconf -t /usr/local/named/ /etc/named.conf

Para não dar conflito de chave e misturar as views, a zona external só vai ser transferida se o IP do secundário for 2605:a141:2167:7657::1, a internal só vai ser transferida ser o IP do secundário for 94.72.123.149. Além disso, cada uma das views precisa de uma TSIG específica para transferência (veja allow-transfer).


Agora vamos criar os arquivos de zona:

# Crie os diretórios abaixo:
mkdir /usr/local/named/var/named/{InternalMaster,ExternalMaster}
mkdir /usr/local/named/var/named/{InternalSlave,ExternalSlave}

# Primeiro copie o arquivo de zona atual para InternalMaster:
cp /usr/local/named/var/named/master/hermodr /usr/local/named/var/named/InternalMaster/hermodr

# Agora copie o arquivo de zona atual para ExternalMaster:
cp /usr/local/named/var/named/master/hermodr /usr/local/named/var/named/ExternalMaster/hermodr

Agora edite o arquivo em ExternalMaster/hermodr:

vim /usr/local/named/var/named/ExternalMaster/hermodr
; $Id$
; zone hermodr.com.br

$TTL 86400
@ IN SOA ns1.hermodr.com.br. admin.hermodr.com.br. (
2024022800 ; Serial
3600 ; Refresh (1 hora)
1800 ; Retry (30 minutos)
604800 ; Expire (1 semana)
86400 ) ; Negative Cache TTL (1 dia)

IN NS ns1.hermodr.com.br.
IN NS ns2.hermodr.com.br.

ns1 IN A 75.119.143.187
IN AAAA 2a02:c206:2120:1140::1

ns2 IN A 94.72.123.149
IN AAAA 2605:a141:2167:7657::1

; Registro de recurso (RR):
external IN A 75.119.143.187

Agora faça o mesmo para InternalMaster/hermodr:

vim /usr/local/named/var/named/InternalMaster/hermodr
; $Id$
; zone hermodr.com.br

$TTL 86400
@ IN SOA ns1.hermodr.com.br. admin.hermodr.com.br. (
2024022800 ; Serial
3600 ; Refresh (1 hora)
1800 ; Retry (30 minutos)
604800 ; Expire (1 semana)
86400 ) ; Negative Cache TTL (1 dia)

IN NS ns1.hermodr.com.br.
IN NS ns2.hermodr.com.br.

ns1 IN A 75.119.143.187
IN AAAA 2a02:c206:2120:1140::1

ns2 IN A 94.72.123.149
IN AAAA 2605:a141:2167:7657::1

; Registro de recurso (RR):
@ IN A 75.119.143.187
IN AAAA 2a02:c206:2120:1140::1
internal IN A 75.119.143.187

Agora vamos terminar a configuração, corrigindo o user/group dos arquivos criados, verificando se existem erros de configuração e reiniciando o serviços do Bind:

# Mude o dono dos arquivos para ser o Bind:
chown -R bind: /usr/local/named/{etc,var}

_________________________________________________________________________________

# Verifique se existem erros de configuração:
named-checkzone -t /usr/local/named/ hermodr.com.br /var/named/InternalMaster/hermodr
zone hermodr.com.br/IN: loaded serial 2024022800
OK

named-checkzone -t /usr/local/named/ hermodr.com.br /var/named/ExternalMaster/hermodr
zone hermodr.com.br/IN: loaded serial 2024022800
OK

_________________________________________________________________________________

# Verifique se não existem erros:
named-checkconf -t /usr/local/named/ /etc/named.conf

_________________________________________________________________________________

# Recarregue os arquivos de configuração e zona:
systemctl restart named

Também podemos usar os comandos abaixo verificar o status da zona:

# Verifique o status da zona hermodr.com.br para view internal:
/usr/local/named/sbin/rndc zonestatus hermodr.com.br IN internal
name: hermodr.com.br
type: primary
files: InternalMaster/hermodr
serial: 2024022800
signed serial: 2023052422
nodes: 4
last loaded: Thu, 29 Feb 2024 02:24:12 GMT
secure: yes
inline signing: yes
key maintenance: automatic
next key event: Sat, 02 Mar 2024 01:32:15 GMT
next resign node: internal.hermodr.com.br/NSEC
next resign time: Sat, 02 Mar 2024 06:22:53 GMT
dynamic: no
reconfigurable via modzone: no

_________________________________________________________________________________

# Verifique o status da zona hermodr.com.br para view external:
/usr/local/named/sbin/rndc zonestatus hermodr.com.br IN external
name: hermodr.com.br
type: primary
files: ExternalMaster/hermodr
serial: 2024022800
signed serial: 2023052422
nodes: 3
last loaded: Thu, 29 Feb 2024 05:12:59 GMT
secure: yes
inline signing: yes
key maintenance: automatic
next key event: Sat, 02 Mar 2024 01:32:15 GMT
next resign node: external.hermodr.com.br/NSEC
next resign time: Tue, 05 Mar 2024 13:35:18 GMT
dynamic: no
reconfigurable via modzone: no

Abaixo segue uma explicação das principais informações apresentadas acima:

  1. name: hermodr.com.br: O nome da zona DNS é "hermodr.com.br".

  2. type: primary: Indica que o servidor DNS onde essas informações foram obtidas é o servidor primário (primary) para a zona "hermodr.com.br". O servidor primário é responsável por armazenar a cópia principal dos dados da zona.

  3. files: InternalMaster/hermodr: Especifica o local do arquivo que contém as informações da zona no sistema de arquivos. Neste caso, o arquivo está localizado em "InternalMaster/hermodr".

  4. serial: 2024022800: O número de série atual da zona, mais conhecido como SOA.

  5. signed serial: 2023052422: Este é o número de série assinado, é o SOA para zona com DNSSEC.

  6. nodes: 4: O número de nós (ou entradas) na zona DNS.

  7. last loaded: Thu, 29 Feb 2024 02:24:12 GMT: A data e hora da última vez que a zona foi carregada no servidor.

  8. secure: yes: Indica se a zona é segura (signed).

  9. inline signing: yes: Indica se a assinatura dos registros DNS é feita inline (durante o processo de carregamento da zona) ou não, neste caso é realizado durante o processo de carregamento da zona.

  10. key maintenance: automatic: Indica que a manutenção das chaves de assinatura é feita automaticamente.

  11. next key event: Fri, 01 Mar 2024 12:32:13 GMT: A próxima data e hora em que ocorrerá um evento relacionado à troca ou manutenção de chaves de assinatura.

  12. next resign node: internal.hermodr.com.br/NSEC: Indica o próximo nó (neste caso, um NSEC, que é usado para provar a não existência de um nome) que será assinado durante o próximo evento de resignação.

  13. next resign time: Sat, 02 Mar 2024 06:22:53 GMT: A próxima data e hora em que ocorrerá o próximo evento de resignação.

  14. dynamic: no: Indica se a zona permite atualizações dinâmicas. Neste caso, "no" significa que as atualizações dinâmicas não são permitidas.

  15. reconfigurable via modzone: no: Indica se a zona pode ser reconfigurada usando o comando "modzone".



Configuração no WLF


Os passoa abaixo demonstram a configuração no servidor secundário.


Comenta a linha allow-query-cache { none; }; no arquivo abaixo, para liberar a consulta recursiva na view internal:

vim /usr/local/named/etc/named.conf.options
# allow-query-cache { none; };

Primeiro edite o arquivo abaixo para adicionar alguns conteúdos:

vim /usr/local/named/etc/named.conf
// Chaves TSIG para transferência de zona:
key hermodr_ex {
algorithm hmac-sha512;
secret "4A/otFTFASxHtEyVilNvS52P4I4b3itO+jmjHLKXyQxfmvBfQfdQyYmeI+CI6XIbFaLx4ck6JmPl+VkGlpGwNA==";
};

key hermodr_in {
algorithm hmac-sha512;
secret "3du0VtsAvOPrqzf70dnObKa72rAZ0b5D/2Gq1hSzinRtQjbVGoQNpbrAauZpjckhLU9aZsw9Fz3PJ1r8Tn7NXQ==";
};


// ACL para rede Interna:
acl internal-ip {
191.162.62.254;
75.119.143.187;
};


// ACL para rede Externa:
acl external-ip {
any;
};


// View internal
view "internal" {
match-clients { internal-ip; };

include "/etc/named_in.conf";
};

// View external
view "external" {
match-clients { external-ip; };

include "/etc/named_ex.conf";

};

Ainda no mesmo arquivo, comente as linhas abaixo:

vim /usr/local/named/etc/named.conf
//include "/etc/master_zones.conf";
//include "/etc/slave_zones.conf";

Agora vamos criar os arquivos para as zonas que estão na view internal.

vim /usr/local/named/etc/named_in.conf
// Chave que será usada para o IP 75.119.143.187
server 75.119.143.187 { keys { hermodr_in; }; };

// Zona hermodr autoritativa dentro da View external
zone "hermodr.com.br" {
type secondary;
file "InternalSlave/hermodr";
primaries { 75.119.143.187; };
};

// Zona wlf primária dentro da View internal
zone "wlf.eti.br" {
type master;
file "InternalMaster/wlf";
dnssec-policy default;
inline-signing yes;
allow-transfer { key wlf.eti.br; };
also-notify { 75.119.143.187; };
};

Agora temos que pagar o arquivo de zona e mover ele para o local onde está configurada as Views:

# Crie os diretório abaixo:
mkdir /usr/local/named/var/named/{ExternalMaster,InternalMaster}

# Mova o arquivo atual da zona master para o novo local:
cp /usr/local/named/var/named/master/* /usr/local/named/var/named/{ExternalMaster,InternalMaster}/

wlf mesmo nao tem nada de diferente na view internal tem que estar em ambas as views, se não fizer isso, vai dar alguns erros de resposta para quem estiver na view internal.


Agora vamos criar os arquivos para as zonas que estão na view external.

vim /usr/local/named/etc/external-zones/hermodr
zone "wlf.eti.br" {
type master;
file "ExternalMaster/wlf";
dnssec-policy default;
inline-signing yes;
allow-transfer { key wlf.eti.br; };
also-notify { 2a02:c206:2120:1140::1; };
};

// Chave que será usada para o IP 2a02:c206:2120:1140::1
server 2a02:c206:2120:1140::1 { keys { hermodr_ex; }; };

// Zona hermodr autoritativa dentro da View external
zone "hermodr.com.br" {
type secondary;
file "ExternalSlave/hermodr";
primaries { 2a02:c206:2120:1140::1; };
};

Agora vamos finalizar a configuração:

# Agora crie os diretórios abaixo:
mkdir /usr/local/named/var/named/{InternalSlave,ExternalSlave}

# Verifique se existem erros no arquivo de configuração:
named-checkconf -t /usr/local/named/ /etc/named.conf

# Corrija as permissões:
chown -R bind: /usr/local/named/{etc,var}

# Reinicie o Bind:
systemctl restart named

Com o clinte DNS da Rede Interna faça um teste:

# Consulta o registro A para internal.hermodr.com.br:
dig @ns1.hermodr.com.br internal.hermodr.com.br A +noquestion +short
75.119.143.187

dig @ns2.hermodr.com.br internal.hermodr.com.br A +noquestion +short
75.119.143.187

# Consulta o registro A para external.hermodr.com.br (não vai retornar nada):
dig @ns1.hermodr.com.br external.hermodr.com.br +short +noquestion
dig @ns2.hermodr.com.br external.hermodr.com.br +short +noquestion

# Consulte o registro SOA:
dig hermodr.com.br SOA +short +noquestion
ns1.hermodr.com.br. admin.hermodr.com.br. 2023052408 3600 1800 604800 86400

Com o clinte DNS fora da Rede Interna faça um teste:

# Consulta o registro A para internal.hermodr.com.br (não vai retornar nada):
dig internal.hermodr.com.br A +short +noquestion

# Consulta o registro A para external.hermodr.com.br:
dig external.hermodr.com.br +short +noquestion
75.119.143.187

# Consulte o registro SOA:
dig hermodr.com.br SOA +short
ns1.hermodr.com.br. admin.hermodr.com.br. 2023052407 3600 1800 604800 86400

Coloquei exemplos simples mas que permitem ver a diferença de quando usamos view clauses, dessa forma um único servidor DNS poderia ser configurado para responder consultas recursivas dentro da rede local mas estar desativado para a mesma em consultas externas e ainda responder consultas autoritativamente para Interna e Externa.


Outro detalhe é que, se uma única cláusula View for definida, todas as zonas especificadas no servidor DNS Master devem estar dentro das Views, não podemos ter nenhuma zona fora de uma View.



Delegando um subdomínio


Vamos ver como delegar a responsabilidade sobre um subdomínio para outra instituição. Antes vejamos os dados sobre o domínio:

  • Nome do domínio: hermodr.com.br
  • Nome do subdomínio: sp.hermodr.com.br

Vamos começar configurando o novo servidor DNS, nesse caso será o wlf.eti.br, esse subdomínio não terá slave (não é recomendado fazer isso, mas deixarei apenas para demosntração).


Crie a zona para view external:

vim /usr/local/named/etc/named_ex.conf
zone "sp.hermodr.com.br" {
type master;
file "ExternalMaster/sp.hermodr";
dnssec-policy default;
inline-signing yes;
};

Agora vamos criar o arquivo de zona:

vim /usr/local/named/var/named/ExternalMaster/sp.hermodr
; $Id$
; zone sp.hermodr.com.br

$TTL 86400
@ IN SOA ns1.sp.hermodr.com.br. admin.sp.hermodr.com.br. (
2024022902 ; Serial
3600 ; Refresh (1 hora)
1800 ; Retry (30 minutos)
604800 ; Expire (1 semana)
86400 ) ; Negative Cache TTL (1 dia)
;
IN NS ns1.wlf.eti.br.

; Registro de recurso (RR):
teste IN A 94.72.123.149

Agora vamos finalizar a configuração:

# Verifique se existem erros no arquivo de configuração:
named-checkconf -t /usr/local/named/ /etc/named.conf

# Verifique se existem erros na zona:
named-checkzone -t /usr/local/named/ sp.hermodr.com.br /var/named/ExternalMaster/sp.hermodr
zone sp.hermodr.com.br/IN: loaded serial 2024022902
OK

# Corrija as permissões:
chown -R bind: /usr/local/named/{etc,var}

# Reinicie o Bind:
systemctl restart named

# Verifique o status da zona:
/usr/local/named/sbin/rndc zonestatus sp.hermodr.com.br IN external
name: sp.hermodr.com.br
type: primary
files: ExternalMaster/sp.hermodr
serial: 2024022904
signed serial: 2024022906
nodes: 2
last loaded: Fri, 08 Mar 2024 00:17:07 GMT
secure: yes
inline signing: yes
key maintenance: automatic
next key event: Fri, 08 Mar 2024 02:22:07 GMT
next resign node: sp.hermodr.com.br/NS
next resign time: Tue, 12 Mar 2024 02:34:17 GMT
dynamic: no
reconfigurable via modzone: no

Agora vamos criar a zona no servidor autoritativo (no hermodr.com.br) da nova zona.

vim /usr/local/named/var/named/ExternalMaster/hermodr
#### Adicione as informações abaixo:
; Delegando subdomínio sp.hermodr.com.br
sp IN NS ns1.wlf.eti.br.

#####################################
# NÃO SE ESQUEÇA DE ALTERAR O SOA!! #
#####################################

Agora vamos finalizar a configuração:

# Verifique se existem erros no arquivo de configuração:
named-checkconf -t /usr/local/named/ /etc/named.conf

# Reinicie o Bind:
systemctl restart named

Outro método para delegação

Nesse caso, ns1.wlf.eti.br é responsivo, então não precisamos adicionar os endereços desse servidor, mas poderíamos por questões de boas práticas:

; Delegando subdomínio sp.hermodr.com.br
sp IN NS ns1.wlf.eti.br.

ns1.wlf.eti.br. IN A 94.72.123.149
IN AAAA 2605:a141:2167:7657::1

Quando adicionamos os registros A e AAAA para o servidor DNS autoritativo no domínio pai, dizemos que configuramos o "glue records". Os glue records são registros adicionados ao domínio pai para fornecer informações de IP sobre os servidores de nomes do subdomínio, ajudando na resolução de nomes.


Nesse momento já podemos testar:

$ host teste.sp.hermodr.com.br
teste.sp.hermodr.com.br has address 94.72.123.149

$ dig sp.hermodr.com.br ns +short
ns1.wlf.eti.br.

Não configuramos o DS para estabelecer a cadeia de confiança, por isso o DNSSEC não está funcionando:

# O delv precisa testar com um nome que tenha A ou AAAA:
$ delv @8.8.8.8 teste.sp.hermodr.com.br
;; resolution failed: ncache nxrrset
; negative response, unsigned answer
; sp.hermodr.com.br. 1800 IN \-A ;-$NXRRSET
; sp.hermodr.com.br. SOA ns1.sp.hermodr.com.br. admin.sp.hermodr.com.br. 2024022906 3600 1800 604800 86400

# Veja como seria para um dominio funcionando:
$ delv @8.8.8.8 hermodr.com.br
; fully validated
hermodr.com.br. 21600 IN A 75.119.143.187
hermodr.com.br. 21600 IN RRSIG A 13 3 86400 20240320040146 20240306033705 19348 hermodr.com.br. 3XQqVDT2RwGQPVAA3FjQLqZgMRb8HpZDnB7WsjAKsz4f+lbub0CJCeWp CLiT+Lu4WZJaCD8oU3Ru4kdxCrtnRw==

No servidor wlf.eti.br vamos pegar o DS:

# Entre no diretório abaixo no wlf:
cd /usr/local/named/var/named

# Rode o comando para obter as informações da chave:
/usr/local/named/bin/dnssec-dsfromkey Ksp.hermodr.com.br.+013+59600.key
sp.hermodr.com.br. IN DS 59600 13 2 EA640902279286DB81A1B46E7AE0B5AAA1BA2727718AC29D11D93F550B036602

# O keytag do DS é 59600 e a Digest é EA640902279286DB81A1B46E7AE0B5AAA1BA2727718AC29D11D93F550B036602

No servidor hermodr.com.br vamos criar o registro do DS:

vim /usr/local/named/var/named/ExternalMaster/hermodr
#### Adicione as informações abaixo:
; Delegando subdomínio sp.hermodr.com.br
sp IN NS ns1.wlf.eti.br.
IN DS 59600 13 2 EA640902279286DB81A1B46E7AE0B5AAA1BA2727718AC29D11D93F550B036602

#####################################
# NÃO SE ESQUEÇA DE ALTERAR O SOA!! #
#####################################

Agora vamos finalizar a configuração:

# Verifique se existem erros no arquivo de configuração:
named-checkconf -t /usr/local/named/ /etc/named.conf

# Verifique se existem erros na zona:
named-checkzone -t /usr/local/named/ hermodr.com.br /var/named/ExternalMaster/hermodr
zone hermodr.com.br/IN: loaded serial 2024022802
OK

# Reinicie o Bind:
systemctl restart named

# Verifique o status da zona:
/usr/local/named/sbin/rndc zonestatus hermodr.com.br IN external
name: hermodr.com.br
type: primary
files: ExternalMaster/hermodr
serial: 2024022802
signed serial: 2023052427
nodes: 5
last loaded: Thu, 07 Mar 2024 23:40:13 GMT
secure: yes
inline signing: yes
key maintenance: automatic
next key event: Fri, 08 Mar 2024 01:39:36 GMT
next resign node: ns1.hermodr.com.br/A
next resign time: Fri, 08 Mar 2024 01:03:54 GMT
dynamic: no
reconfigurable via modzone: no

Agora faça os testes novamente para verificar se existe assinatura:

# O delv precisa testar com um nome que tenha A ou AAAA:
$ delv @8.8.8.8 teste.sp.hermodr.com.br
; fully validated
teste.sp.hermodr.com.br. 21600 IN A 94.72.123.149
teste.sp.hermodr.com.br. 21600 IN RRSIG A 13 5 86400 20240317023417 20240307231707 59600 sp.hermodr.com.br. WXF3eFubTetroOzr1WYFn28hI42HEPf0tguooJYICeP+pHS3srsL5Tpc 6KFkJYAL8wAD9h2dTqAmofbbZyoK/Q==

$ dig @8.8.8.8 sp.hermodr.com.br DS +dnssec +short
59600 13 2 EA640902279286DB81A1B46E7AE0B5AAA1BA2727718AC29D11D93F55 0B036602
DS 13 4 86400 20240317202018 20240307233936 19348 hermodr.com.br. USyhbuXiMR485eWLrWU0LBuPRi28sU7DwK5cnUsaNmsAPmY8uvAhCtjp OOu40lg6F6MV2m9dRGC3yMP6FPGuNA==

Podemos usar esses sites para validar o DNSSEC: verisignlabs e DNS VIZ.


A configuração que usamos pode ser escrita de outras formas, se lembre bem disso para não se confundir, vamos entender as linhas:

  • ; Delegando subdomínio sp.hermodr.com.br
    Apenas um comentário para ficar fácil de identificar a configuração que vem após ele.

  • sp IN NS ns1.wlf.eti.br.
    Essa linha cria um Registro de Recurso (Resource Records) ou RR para NS, ou seja, servidor DNS. Essa linha informa que estamos declarando um servidor DNS para o subdomínio sp.hermodr.com.br. O sp será traduzido para sp.hermodr.com.br, que nesse caso vai definir o nome do subdomínio. O IN é a classe do RR, já NS é tipo do RR que informa estar declarando um servidor DNS e ns1.wlf.eti.br. é o servidor DNS para o subdomínio, que será traduzidor para o endereço IP 94.72.123.149 e 2605:a141:2167:7657::1.


Uma boa prática que poderia ser feita é fazer com que o servidor que delegou o subdomínio seja um Slave para ele.



Criando um mapeamento reverso


Como já foi dito em aqui, para podermos configurar o DNS reverso, temos que ter recebido a delegação de uma autoridade superior, no caso do Brasil é a Numeração, que delega os blocos IP para os ASN, também delegam a autoridade sobre o reverso para os blocos de endereços IPv4 e IPv6.


Como não tenho autoridade, vou criar um mapeamento reverso para endereços internos, os endereços serão 192.168.121/24.

vim /usr/local/named/etc/named_in.conf
### Adicione a cláusula abaixo:
zone "121.168.192.in-addr.arpa" {
type master;
file "InternalMaster/db.192.168.121";
};

Vamos criar o arquivo da zona reversa:

vim /usr/local/named/var/named/InternalMaster/db.192.168.121
; Reverse mapping of 192.168.121/24
$TTL 86400
@ in soa ns1.hermodr.com.br. hostmaster.hermodr.com.br. (
2023061001 ;serial
86400 ;refresh 24 horas
3600 ;retry 1 hora
604800 ;expire 7 dias
86400 ) ;min. ttl 1 dia

@ IN NS ns1.hermodr.com.br.

; Mapeamento reverso
0 in ptr 121.0.hermodr.com.br.
1 in ptr 121.1.hermodr.com.br.
2 in ptr hermodr.com.br.
3 in ptr site.hermodr.com.br.

Agora vamos finalizar a configuração:

# Verifique se não existem erros nos arquivos de zona que foram criados:
named-checkzone -t /usr/local/named/ 121.168.192.in-addr.arpa /var/named/InternalMaster/db.192.168.121
zone 121.168.192.in-addr.arpa/IN: loaded serial 2023061001
OK

# Reinicie o BIND:
systemctl restart named

Agora vamos consultar:

# Consulta o reverso abaixo pelo cliente DNS interno:
$ dig @ns1.hermodr.com.br -x 192.168.121.2 +short
hermodr.com.br.

$ dig @ns1.hermodr.com.br -x 192.168.121.3 +short
site.hermodr.com.br.

O certo seria cadastrar uma dessa para view interna e outra para view externa, mas deixei apenas na interna para exemplificar como fazer. Por questões de boas práticas, é recomendado cadastrar todos os reversos para os IP que serão responsivos globalmente, um nome padrão deve ser seguido caso o IP não tenha um reverso final ainda.

O nome para o IP 192.168.121.0 seria 121.0.hermodr.com.br., o importante é ter o domínio no nome. Isso deve ser feito para todos os IP.



Delegando um mapeamento reverso


Vamos delegar o mapeamento reverso para outro servidor DNS, nesse exemplo é como se fôssemos os responsáveis por administrar os blocos de endereço. Os servidores possuem o prefixo in-addr-servers.arpa. no nome. Como aqui estou simulando um teste e não fazendo algo real, já que eu não tenho essa autorização, vou apenas para demonstrar como se faz.


Veja quem são os servidores que respondem pelo domínio 200.in-addr.arpa. que é um bloco brasileiro:

# Verificando os Servidores DNS para 200.in-addr.arpa:
$ dig 200.in-addr.arpa ns +short
a.arpa.dns.br.
a.lactld.org.
ns.lacnic.net.
ns2.lacnic.net.
ns3.afrinic.net.
ns4.apnic.net.
rirns.arin.net.
lacnic.authdns.ripe.net.

Vale lembrar que para ter esse tipo de consulta é preciso ter recursion yes; e allow-recursion definidos no servidor DNS.


Agora vamos configurar a nossa delegação:

vim /usr/local/named/etc/named_ex.conf
### Adicione a cláusula abaixo:

// Delegando o reverso de 192.168.2/24

zone "2.168.192.in-addr.arpa" {
type master;
file "InternalMaster/db.192.168.2";
};

Agora crie o arquivo da zona:

vim /usr/local/named/var/named/InternalMaster/db.192.168.2
; Reverse mapping of 192.168.2/24
$ORIGIN 2.168.192.IN-ADDR.ARPA.
$TTL 86400
@ in soa ns1.hermodr.com.br. hostmaster.hermodr.com.br. (
2023061002 ;serial
86400 ;refresh 24 horas
3600 ;retry 1 hora
604800 ;expire 7 dias
86400 ) ;min. ttl 1 dia

@ IN NS ns1.hermodr.com.br.

; Nossa sub-rede é 192.168.2.0/24
; Os servidores DNS para mapeamento reverso são:
0/24 IN NS ns1.sp.hermodr.com.br.

;; O mapeamento acima poderia ter sido escrito assim:
; 0/24.2.168.192.IN-ARDDR.ARPA. IN NS ns1.sp.hermodr.com.br.

; 0/24 = 0 é o endereço de Rede e /24 é o CIDR.

Agora vamos finalizar a configuração:

# Verifique se não existem erros nos arquivos de zona que foram criados:
named-checkzone -t /usr/local/named/ 2.168.192.in-addr.arpa /var/named/InternalMaster/db.192.168.2
zone 2.168.192.in-addr.arpa/IN: loaded serial 2023061002
OK

# Reinicie o BIND:
systemctl restart named

Agora vamos consultar a partir de duas fontes, um cliente DNS interno e outro externo. Veja quem são os servidores DNS para o domínio 2.168.192.in-addr.arpa.:

$ dig @ns1.hermodr.com.br 2.168.192.in-addr.arpa ns +short
ns1.sp.hermodr.com.br.


DNS over TLS


Vamos ver como configurar o DNS para responder com menssagens criptografadas usando TLS. Para começarmos, vamos usar a cnfiguração mais simples, usando ephemeral. Adicione a configuração abaixo do TLS no arquivo específicado:

vim /usr/local/named/etc/named.conf.options
options {
.
.
.
listen-on port 8853 tls ephemeral { 94.72.123.149; };
listen-on port 53 { 94.72.123.149; };
};

  • listen-on port 8853: Esta parte indica que o servidor DNS está configurado para escutar conexões na porta 8853.

  • listen-on port 53: Devemos colocar também essa porta, se não o DNS vai escutar apenas TLS na 8853 e consultas normais não irão funcionar mais e ainda quero que funcione via 53.

  • tls: Isso indica que as conexões serão protegidas pelo protocolo TLS, que é usado para criptografar a comunicação entre o cliente e o servidor, garantindo assim a confidencialidade e a integridade dos dados transmitidos.

  • ephemeral: Usa uma chave temporária e um certificado criado apenas para a sessão do Bind atual. Chaves efêmeras são geradas dinamicamente e não são armazenadas em disco, o que as torna mais seguras contra ataques de quebra de chaves.

  • { 94.72.123.149; }: É o IP da interface que o servidor vai ouvir as requisições DNS, nesse caso é IPv6.


Agora é só reiniciar o Bind para aplicar as mudanças, então poderemos testar. Para testar com o comando dig, basta executar o comando abaixo como exemplo:

dig -4 @94.72.123.149 wlf.eti.br A -p 8853 +tls +do 

; <<>> DiG 9.18.18-0ubuntu0.23.04.1-Ubuntu <<>> -4 @94.72.123.149 wlf.eti.br A -p 8853 +tls +do
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56561
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: fb58e7c22f9a613c0100000065fa3717b99eb91949f6dc28 (good)
;; QUESTION SECTION:
;wlf.eti.br. IN A

;; ANSWER SECTION:
wlf.eti.br. 60 IN A 94.72.123.149
wlf.eti.br. 60 IN RRSIG A 13 3 60 20240326092556 20240316131248 55692 wlf.eti.br. EMIqMX4Xwk7Gor202ST6MMiLVZN006SX++5WFBNX5wWT7toVPmzai2R8 G2u8943wzFNw6QyuY8eIBg8HK4uktw==

;; Query time: 388 msec
;; SERVER: 94.72.123.149#8853(94.72.123.149) (TLS)
;; WHEN: Tue Mar 19 22:08:31 -03 2024
;; MSG SIZE rcvd: 189

Análises com Wireshark mostram que a comunicação está encriptada.



DNS over TLS sem ephemeral


Vamos ver como configurar o DoT mas usando um certificado, podemos usar um certificado válido (assinado por uma CA reconhecida) ou usar um auto assinado. No caso do auto assinado, o cliente deve ter a CA para não dar erro.


Crie a configuração do TLS:

vim /usr/local/named/etc/named.conf
tls dot-tls {
dhparam-file "/etc/ffdhe4096.pem";
cert-file "/etc/wlf.eti.br.crt";
key-file "/etc/wlf.eti.br.key";
protocols { TLSv1.3; };
ciphers "HIGH:!kRSA:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SHA1:!SHA256:!SHA384";
prefer-server-ciphers yes;
session-tickets no;
};

Um bom arquivo para dhparam-file pode ser obtido assim: wget https://raw.githubusercontent.com/internetstandards/dhe_groups/master/ffdhe4096.pem.


Agora é só reiniciar o Bind para aplicar as mudanças. Após isso, podemos testar a configuração usando DoT:

dig -4 @ns1.wlf.eti.br wlf.eti.br A -p 8853 +norec +tls +do 

; <<>> DiG 9.18.18-0ubuntu0.23.04.1-Ubuntu <<>> -4 @ns1.wlf.eti.br wlf.eti.br A -p 8853 +tls +do
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7177
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: 73787f0e5c77922f0100000065fa475c7cd0899341864232 (good)
;; QUESTION SECTION:
;wlf.eti.br. IN A

;; ANSWER SECTION:
wlf.eti.br. 60 IN A 94.72.123.149
wlf.eti.br. 60 IN RRSIG A 13 3 60 20240326092556 20240316131248 55692 wlf.eti.br. EMIqMX4Xwk7Gor202ST6MMiLVZN006SX++5WFBNX5wWT7toVPmzai2R8 G2u8943wzFNw6QyuY8eIBg8HK4uktw==

;; Query time: 224 msec
;; SERVER: 94.72.123.149#8853(ns1.wlf.eti.br) (TLS)
;; WHEN: Tue Mar 19 23:17:56 -03 2024
;; MSG SIZE rcvd: 189

No caso do cliente, não precisa da CA para fazer a consulta, mas você pode forçar o uso da mesma, e como requisito deve fornecer um hostname que esteja em AltNames no certificado do servidor:

dig -4 @ns1.wlf.eti.br wlf.eti.br A -p 8853 +norec +tls +do +tls-ca=ca.crt +tls-hostname=dns.wlf.eti.br

; <<>> DiG 9.18.18-0ubuntu0.23.04.1-Ubuntu <<>> -4 @ns1.wlf.eti.br wlf.eti.br A -p 8853 +tls +do +tls-ca=ca.crt +tls-hostname=dns.wlf.eti.br
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4073
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: f7c7a2c757afa1190100000065fad67c2f1d15b0d5a74a6a (good)
;; QUESTION SECTION:
;wlf.eti.br. IN A

;; ANSWER SECTION:
wlf.eti.br. 60 IN A 94.72.123.149
wlf.eti.br. 60 IN RRSIG A 13 3 60 20240331221840 20240317212352 55692 wlf.eti.br. PFWDXYXDyp0rbSXK5INXDa/OTrxuJWl4D5ewpQTP0ijidYKa1q/7XkQi eWptEXlAXXrhgqvQBuFqO/sHdCeUbQ==

;; Query time: 431 msec
;; SERVER: 94.72.123.149#8853(ns1.wlf.eti.br) (TLS)
;; WHEN: Wed Mar 20 09:28:36 -03 2024
;; MSG SIZE rcvd: 189

No meu caso, AltNames possui: DNS:wlf.eti.br, DNS:dns.wlf.eti.br, qualquer um desses nomes no +tls-hostname vai funcionar.



XRF over TLS


Vamos ver como configurar o DNS para fazer transferência de zona com criptografia, usando TLS. Crie a cláusula do TLS no servidor Primário:

vim /usr/local/named/etc/named.conf
tls xot-tls {
dhparam-file "/etc/ffdhe4096.pem";
cert-file "/etc/wlf.eti.br.crt";
key-file "/etc/wlf.eti.br.key";
remote-hostname "wlf.eti.br";
protocols { TLSv1.3; };
ciphers "HIGH:!kRSA:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SHA1:!SHA256:!SHA384";
prefer-server-ciphers yes;
session-tickets no;
};

Um bom arquivo para dhparam-file pode ser obtido assim: wget https://raw.githubusercontent.com/internetstandards/dhe_groups/master/ffdhe4096.pem.


Agora vamos configurar para o BIND ouvir na porta correta usando TLS e incluindo nossa configuração acima:

vim /usr/local/named/etc/named.conf.options
options {
.
.
.
listen-on port 8853 tls xot-tls { 94.72.123.149; };
listen-on port 53 { 94.72.123.149; };
.
.
.
};

Agora vamos configurar a zona wlf para ser transferida usando TLS (ainda no wlf):

vim /usr/local/named/etc/named_in.conf
zone "wlf.eti.br" {
type master;
file "InternalMaster/wlf";
dnssec-policy default;
inline-signing yes;
allow-transfer transport tls { key wlf.eti.br; };
also-notify { 75.119.143.187; };
};

Agora no servidor secundário, vamos configurar a cláusula TLS:

vim /usr/local/named/etc/named.conf
tls xot-tls {
remote-hostname "ns1.wlf.eti.br";
protocols { TLSv1.3; };
ciphers "HIGH:!kRSA:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SHA1:!SHA256:!SHA384";
prefer-server-ciphers yes;
session-tickets no;
};

remote-hostname

Esta opção permite a verificação do certificado do servidor remoto. De acordo com o RFC 8310, Seção 8.1 o campo Subject não deve ser inspecionado ao verificar um certificado remoto ao estabelecer uma conexão DNS-over-TLS, isso se aplica para XFR-over-TLS também. Apenas o subjectAltName deve ser verificado para o propósito de validação.


Infelizmente, algumas versões bastante antigas de bibliotecas criptográficas podem não ter a capacidade de ignorar o campo Subject. Isso deveria ter consequências mínimas para uso em produção, já que a maioria dos certificados prontos para produção emitidos por autoridades de certificação terão subjectAltName configurado. Nesses casos, o campo Subject é ignorado.


Qualquer nome que esteja subjectAltName do certificado vale como nome de verificação em remote-hostname, caso seja usado um nome que não esteja lá, dará o erro abaixo:

zone wlf.eti.br/IN/internal: Transfer started.
transfer of 'wlf.eti.br/IN/internal' from 94.72.123.149#8853: failed to connect: TLS peer certificate verification failed
transfer of 'wlf.eti.br/IN/internal' from 94.72.123.149#8853: Transfer status: TLS peer certificate verification failed
transfer of 'wlf.eti.br/IN/internal' from 94.72.123.149#8853: Transfer completed: 0 messages, 0 records, 0 bytes, 0.312 secs (0 bytes/sec) (serial 0)

Ainda sobre remote-hostname. Se ca-file não for especificado, então o armazenamento de certificados específico da plataforma é usado para verificação. Você pode usar essa opção no servidor Primário, mas terá mais efeito nos servidores Secundários. Esta opção é usada apenas ao se conectar a um par remoto e, portanto, é ignorada quando as declarações tls são referenciadas por declarações listen-on ou listen-on-v6, novamente, no caso de servidores Secundários.


Se o remote-hostname não for declarado, então o endereço IP do servidor remoto é usado para fazer a verificação do certificado, nesses casos o IP deve estar em subjectAltName, se não dará erro.


Agora configure a zona no servidor secundário para usar a configuração de TLS:

vim /usr/local/named/etc/named_in.conf
zone "wlf.eti.br" {
type secondary;
file "InternalSlave/wlf";
primaries { 94.72.123.149 port 8853 tls "xot-tls"; };
};

Podemos ver a transferência de zona sendo realizada na porta 8853:

19-Mar-2024 23:46:36.084 zone wlf.eti.br/IN/internal: Transfer started.
19-Mar-2024 23:46:36.388 0x7f03c2425800: transfer of 'wlf.eti.br/IN/internal' from 94.72.123.149#8853: connected using 94.72.123.149#8853 TSIG wlf.eti.br
19-Mar-2024 23:46:36.568 zone wlf.eti.br/IN/internal: transferred serial 2024031485: TSIG 'wlf.eti.br'
19-Mar-2024 23:46:36.568 0x7f03c2425800: transfer of 'wlf.eti.br/IN/internal' from 94.72.123.149#8853: Transfer status: success
19-Mar-2024 23:46:36.572 0x7f03c2425800: transfer of 'wlf.eti.br/IN/internal' from 94.72.123.149#8853: Transfer completed: 1 messages, 14 records, 1086 bytes, 0.180 secs (6033 bytes/sec) (serial 2024031485)


Gerenciando DNSSEC manualmente


Como foi dito, o Bind gerencia as chaves automaticamente e a opção recomendada é exatamente essa. Mas deixei uma breve explicação de como funciona o gerenciamento de chaves manuais. Começaremos criando as chaves DNSSEC:

# Gere o par de chaves ZSK:
dnssec-keygen -a ECDSAP256SHA256 -b 4096 -n ZONE hermodr.com.br

# Agora gere o par de chaves KSK:
dnssec-keygen -a ECDSAP256SHA256 -b 4096 -f KSK hermodr.com.br

Minha KSK já está publicada na zona pai, não se esqueça desse detalhe.


A configuração da zona deve estar assim:

vim /usr/local/named/etc/named_in.conf
# Precisa comentar `dnssec-policy default;` se não o Bind vai criar novas chaves sempre.
zone "hermodr.com.br" {
type master;
file "InternalMaster/hermodr";
key-directory "/var/named";
//dnssec-policy default;
allow-transfer { key hermodr_in; };
notify yes;
also-notify { 94.72.123.149; };
};

vim /usr/local/named/etc/named_ex.conf
# Precisa comentar `dnssec-policy default;` se não o Bind vai criar novas chaves sempre.
zone "hermodr.com.br" {
type master;
file "ExternalMaster/hermodr";
key-directory "/var/named";
//dnssec-policy default;
allow-transfer { key hermodr_ex; };
notify yes;
also-notify { 2605:a141:2167:7657::1; };
};

Agora vamos adicionr as chaves nas zonas:

vim /usr/local/named/var/named/InternalMaster/hermodr
$INCLUDE "/var/named/Khermodr.com.br.+013+46468.key"; ZSK
$INCLUDE "/var/named/Khermodr.com.br.+013+19348.key"; KSK

#####################################
# NÃO SE ESQUEÇA DE ALTERAR O SOA!! #
#####################################

vim /usr/local/named/var/named/ExternalMaster/hermodr
$INCLUDE "/var/named/Khermodr.com.br.+013+46468.key"; ZSK
$INCLUDE "/var/named/Khermodr.com.br.+013+19348.key"; KSK

#####################################
# NÃO SE ESQUEÇA DE ALTERAR O SOA!! #
#####################################

Reinicie o Bind:

systemctl restart named

Agora vamos assinar os arquivos de zona:

# Assinando a zona hermodr para view external:
dnssec-signzone -k Khermodr.com.br.+013+19348 -o hermodr.com.br -t ExternalMaster/hermodr Khermodr.com.br.+013+46468
Verifying the zone using the following algorithms:
- ECDSAP256SHA256
Zone fully signed:
Algorithm: ECDSAP256SHA256: KSKs: 1 active, 0 stand-by, 0 revoked
ZSKs: 1 active, 0 stand-by, 0 revoked
ExternalMaster/hermodr.signed
Signatures generated: 18
Signatures retained: 0
Signatures dropped: 0
Signatures successfully verified: 0
Signatures unsuccessfully verified: 0
Signing time in seconds: 0.040
Signatures per second: 450.000
Runtime in seconds: 0.060

#### Khermodr.com.br.+013+19348 = KSK
#### Khermodr.com.br.+013+46468 = ZSK

# Assinando a zona hermodr para view internal:
dnssec-signzone -k Khermodr.com.br.+013+19348 -o hermodr.com.br -t InternalMaster/hermodr Khermodr.com.br.+013+46468
Verifying the zone using the following algorithms:
- ECDSAP256SHA256
Zone fully signed:
Algorithm: ECDSAP256SHA256: KSKs: 1 active, 0 stand-by, 0 revoked
ZSKs: 1 active, 0 stand-by, 0 revoked
InternalMaster/hermodr.signed
Signatures generated: 18
Signatures retained: 0
Signatures dropped: 0
Signatures successfully verified: 0
Signatures unsuccessfully verified: 0
Signing time in seconds: 0.044
Signatures per second: 409.090
Runtime in seconds: 0.052

#### Khermodr.com.br.+013+19348 = KSK
#### Khermodr.com.br.+013+46468 = ZSK

Agora vamos informar ao Bind para entregar as zonas assinadas:

vim /usr/local/named/etc/named_in.conf
# Precisa comentar `dnssec-policy default;` se não o Bind vai criar novas chaves sempre.
zone "hermodr.com.br" {
type master;
file "InternalMaster/hermodr.signed";
key-directory "/var/named";
//dnssec-policy default;
allow-transfer { key hermodr_in; };
notify yes;
also-notify { 94.72.123.149; };
};

vim /usr/local/named/etc/named_ex.conf
# Precisa comentar `dnssec-policy default;` se não o Bind vai criar novas chaves sempre.
zone "hermodr.com.br" {
type master;
file "ExternalMaster/hermodr.signed";
key-directory "/var/named";
//dnssec-policy default;
allow-transfer { key hermodr_ex; };
notify yes;
also-notify { 2605:a141:2167:7657::1; };
};

O problema de fazer é assim é sempre ter que assinar as zonas depois de modificar elas. Abaixo segue uma imagem mostrando que a assinatura de DNSSEC está válida e como funciona todo o chain of trust.

DNSSEC chain of trust



Algumas opções interessantes do Bind


OpçãoDescrição
server-id hostname;Define a identificação do servidor para exibição em consultas de informações especiais (por exemplo, consultas de informações sobre o servidor usando dig CH TXT id.server).
masterfile-format text;Especifica o formato do arquivo de zona no servidor. Neste caso, está configurado como texto (text), indicando um formato de arquivo de zona legível por humanos.
update-check-ksk no;Desativa a verificação de atualizações para a chave de assinatura de chave (KSK) ao atualizar registros de DNSSEC.
dnssec-dnskey-kskonly yes;Indica que apenas chaves de assinatura de chave (KSK) devem ser usadas ao assinar registros DNSSEC nesta zona.
serial-update-method date;Define o método de atualização de serial. Neste caso, a atualização é baseada na data.
sig-validity-interval 70;Especifica o intervalo de validade padrão (em dias) para assinaturas DNSSEC nesta zona. As assinaturas expirarão após esse período.
edns-udp-size 1252;DNSSEC utiliza EDNS0 (RFC 2671) para, entre outras coisas, permitir a utilização de datagramas UDP maiores do que 512 bytes, o que pode gerar fragmentação dos pacotes. Com essa opção você pode configurar seu servidor recursivo para que solicite respostas UDP menores.


Fazendo o Rollover das chaves KSK


Vamos ver como fazer o Rollover das chaves DNSSEC para alguns cenários.



Aplicando o Rollover na prática - Pre-Publish em wlf.eti.br


Vamos ver como fazer o rollover usando o método de Pre-Publish. O servidor que estou usando contém inline-signing yes; com dnssec-policy default;. Como o default é usar CSK, vamos trabalhar com apenas uma única chave (KSK).


Primeiro, analise a chave atualmente em uso:

# Entre no diretório onde estão as chaves:
cd /usr/local/named/var/named/

# Liste a chave atual:
ls Kwlf.eti.br*
Kwlf.eti.br.+013+04462.key Kwlf.eti.br.+013+04462.private Kwlf.eti.br.+013+04462.state

# Aqui só tenho KSK (ZSK - DNSKEY 257 o Bind gerencia internamente),
# que nesse caso está sendo usada como CSK pela política padrão do Bind:
cat Kwlf.eti.br.+013+04462.key
; This is a key-signing key, keyid 4462, for wlf.eti.br.
; Created: 20240314231944 (Thu Mar 14 20:19:44 2024)
; Publish: 20240314231944 (Thu Mar 14 20:19:44 2024)
; Activate: 20240314231944 (Thu Mar 14 20:19:44 2024)
; SyncPublish: 20240316002444 (Fri Mar 15 21:24:44 2024)
wlf.eti.br. 3600 IN DNSKEY 257 3 13 lENQ/w9A9dvpqBAaH4K/TlI2o7nhrkcwdRzSiwkjeowyskRNpoF6Mnb2 xzkvPz3RUcowGJwAzPEEHS9MW5OjgA==

Agora vamos fazer um backup das chaves atuais por precaução, agendar a chave KSK atual para ser desativada e deletada numa certa data, depois vamos criar a nova chave e calcular o DS RRSet dessa nova chave:

# Crie um diretório e faça backup dos dados para o diretório criado:
mkdir ../keys-bkp && cp -r * ../keys-bkp/

# Agende a chave antiga para ser retirada daqui 1 hora (para todas as views que tem no server):
rndc -k /usr/local/named/etc/rndc.key -s localhost dnssec -checkds -key 4462 -alg 13 -when 20240315165900 withdrawn wlf.eti.br IN external
rndc -k /usr/local/named/etc/rndc.key -s localhost dnssec -checkds -key 4462 -alg 13 -when 20240315165900 withdrawn wlf.eti.br IN internal

# Crie o par de chaves KSK:
dnssec-keygen -a ECDSAP256SHA256 -f KSK -n ZONE wlf.eti.br
Generating key pair.
Kwlf.eti.br.+013+55692

# Corrija as permissões apenas para a chave nova:
chown bind: *55692*

# Nesse momento, as permissões estão assim:
ls -l Kwlf*
-rw-r--r-- 1 bind bind 400 Mar 15 15:22 Kwlf.eti.br.+013+04462.key
-rw------- 1 bind bind 215 Mar 15 15:22 Kwlf.eti.br.+013+04462.private
-rw-r--r-- 1 bind bind 646 Mar 15 15:22 Kwlf.eti.br.+013+04462.state
-rw-r--r-- 1 bind bind 339 Mar 15 15:26 Kwlf.eti.br.+013+55692.key
-rw------- 1 bind bind 187 Mar 15 15:26 Kwlf.eti.br.+013+55692.private

withdrawn: Indica que a assinatura DNSSEC deve ser marcada como retirada na data e hora especificadas.


Agendamento da chave

Quando for agendar para que a chave seja removida, coloque um data futura distante, pelo menos 1 semana em trocas normais, mas sempre olhe o TTL. Após o agendamento, vamos ter tempo de sobra para cadastrar o novo DS na zona pai e aguardar o Bind remover a chave antiga e reassinar a zona com a chave nova.


Podemos consultar o DS e o DNSKEY publicado da chave atual com os comandos abaixo:

# Mostra o Digest e a keytag da chave KSK atual:
/usr/local/named/bin/dnssec-dsfromkey Kwlf.eti.br.+013+04462.key
wlf.eti.br. IN DS 4462 13 2 81AD27CC4D2C72FA08370B84B9B6677A5263CA185B6B3FAA3A65C22870DB039B

# Mostra o RR DNSKEY atualmente publicado:
dig @ns1.wlf.eti.br wlf.eti.br. DNSKEY +dnssec +multiline +short
257 3 13 lENQ/w9A9dvpqBAaH4K/TlI2o7nhrkcwdRzSiwkjeowyskRNpoF6Mnb2 xzkvPz3RUcowGJwAzPEEHS9MW5OjgA==
DNSKEY 13 3 3600 20240329135242 20240315125242 4462 wlf.eti.br. Cs7HdbZVtZdma0JX/EQmSfyLI2nW/1VRkVpmzGH6DgmmLMXVu6tEqptI zFgqKHEPugpVxxisJ+OfEWQ5vlBWjA==

# Mostra o Digest e a keytag atualmente publicado na zona pai:
dig @a.dns.br wlf.eti.br. DS +dnssec +multiline +short
4462 13 2 81AD27CC4D2C72FA08370B84B9B6677A5263CA185B6B3FAA3A65C228 70DB039B
DS 13 3 3600 20240328233508 20240314223508 57034 eti.br. vMdzRiHG3wbH1vt9h4d7ME7jBwklDzUTx/qx61ALTRqUE4biGImfTsij EJn4gxF/2u/g9HsLVaOO2+Mxd2pGJg==

Agora vamos inserir a nova chave na zona para que o Bind tenha conhecimento dela:

vim /usr/local/named/var/named/ExternalMaster/wlf
; Nova KSK
$INCLUDE "/var/named/Kwlf.eti.br.+013+55692.key";

#####################################
# NÃO SE ESQUEÇA DE ALTERAR O SOA!! #
#####################################

vim /usr/local/named/var/named/InternalMaster/wlf
; Nova KSK
$INCLUDE "/var/named/Kwlf.eti.br.+013+55692.key";

#####################################
# NÃO SE ESQUEÇA DE ALTERAR O SOA!! #
#####################################

Agora vamos reiniciar o Bind para aplicar as mudanças na zona, dessa forma o Bind passa a conhecer a chave nova e vai usar ela.

# Reinicie o bind para aplicar as mudanças:
systemctl restart named

# Nesse ponto a zona está com ambas as chaves:
rndc -k /usr/local/named/etc/rndc.key -s localhost dnssec -status wlf.eti.br IN external
dnssec-policy: default
current time: Fri Mar 15 15:54:49 2024

key: 55692 (ECDSAP256SHA256), CSK
published: yes - since Fri Mar 15 15:52:29 2024
key signing: yes - since Fri Mar 15 15:52:29 2024
zone signing: yes - since Fri Mar 15 15:52:29 2024

No rollover scheduled
- goal: omnipresent
- dnskey: rumoured
- ds: hidden
- zone rrsig: rumoured
- key rrsig: rumoured

key: 4462 (ECDSAP256SHA256), CSK
published: yes - since Thu Mar 14 20:19:44 2024
key signing: yes - since Thu Mar 14 20:19:44 2024
zone signing: no

Key is retired, will be removed on Mon Mar 25 16:58:33 2024
- goal: hidden
- dnskey: omnipresent
- ds: rumoured
- zone rrsig: unretentive
- key rrsig: omnipresent

Certifique que os servidores secundários estão sincronizados com o primário. Se não estiverem, vai dar erro no momento de adicionar o novo DS.


Nesse momento, podemos ver que a nova chave KSK foi incluida na assinatura:

/usr/local/named/var/log/named/dnssec
Fetching wlf.eti.br/ECDSAP256SHA256/55692 (KSK) from key repository.
DNSKEY wlf.eti.br/ECDSAP256SHA256/55692 (KSK) is now published
DNSKEY wlf.eti.br/ECDSAP256SHA256/55692 (KSK) is now active
Fetching wlf.eti.br/ECDSAP256SHA256/55692 (CSK) from key repository.
DNSKEY wlf.eti.br/ECDSAP256SHA256/55692 (CSK) is now published
DNSKEY wlf.eti.br/ECDSAP256SHA256/55692 (CSK) is now active

Agora verifique novamente o DNSKEY (podemos ver a nova chave em destaque):

dig @ns1.wlf.eti.br wlf.eti.br. DNSKEY +dnssec +multi +short
257 3 13 ceDRBftq4XPj831QU2v6oy8DDRY1zc8b7V7Ol42bIonmZZexXg4/BM22 fhndom6jXyFEYpGt5qVHGhQHQdftNw==
257 3 13 lENQ/w9A9dvpqBAaH4K/TlI2o7nhrkcwdRzSiwkjeowyskRNpoF6Mnb2 xzkvPz3RUcowGJwAzPEEHS9MW5OjgA==
DNSKEY 13 3 3600 20240329170908 20240315160908 4462 wlf.eti.br. cG9qnfYmUpdA/4prDHCcu6EUhHXSly0ibfz4czJiliGChQNpeQdcBdmh N7isFm1Ld72npDlRbYjZz67JIVXjKw==
DNSKEY 13 3 3600 20240329171147 20240315161147 55692 wlf.eti.br. v/8SaDBs3Rh2wchsGu5/ogUD4qUyJnoviyLWu5MaK0O/Lz1e7x6CNUSB XlyTDOXe1CALq7hdQjDCmER/XeKOjQ==

Cada DNSKEY possui um RRSIG, ou seja, cada assinatura da zona está duplicada, cada um com ambas as chaves KSK. Podemos ver isso com o comando abaixo:

dig @ns1.wlf.eti.br wlf.eti.br. DNSKEY +dnssec +multi

; <<>> DiG 9.18.18-0ubuntu0.23.04.1-Ubuntu <<>> @ns1.wlf.eti.br wlf.eti.br. DNSKEY +dnssec +multi
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15849
;; flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
; COOKIE: 54deb95d7f6be83c0100000065f482041e503da0e9fac563 (good)
;; QUESTION SECTION:
;wlf.eti.br. IN DNSKEY

;; ANSWER SECTION:
wlf.eti.br. 3600 IN DNSKEY 257 3 13 (
lENQ/w9A9dvpqBAaH4K/TlI2o7nhrkcwdRzSiwkjeowy
skRNpoF6Mnb2xzkvPz3RUcowGJwAzPEEHS9MW5OjgA==
) ; KSK; alg = ECDSAP256SHA256 ; key id = 55692
wlf.eti.br. 3600 IN DNSKEY 257 3 13 (
lENQ/w9A9dvpqBAaH4K/TlI2o7nhrkcwdRzSiwkjeowy
skRNpoF6Mnb2xzkvPz3RUcowGJwAzPEEHS9MW5OjgA==
) ; KSK; alg = ECDSAP256SHA256 ; key id = 4462
wlf.eti.br. 3600 IN RRSIG DNSKEY 13 3 3600 (
20240329170908 20240315160908 4462 wlf.eti.br.
cG9qnfYmUpdA/4prDHCcu6EUhHXSly0ibfz4czJiliGC
hQNpeQdcBdmhN7isFm1Ld72npDlRbYjZz67JIVXjKw== )
wlf.eti.br. 3600 IN RRSIG DNSKEY 13 3 3600 (
20240329171147 20240315161147 55692 wlf.eti.br.
v/8SaDBs3Rh2wchsGu5/ogUD4qUyJnoviyLWu5MaK0O/
Lz1e7x6CNUSBXlyTDOXe1CALq7hdQjDCmER/XeKOjQ== )

A assinatura na zona está assim apenas para DNSKEY, outros registros possuem apenas a KSK antiga:

dig @ns1.wlf.eti.br wlf.eti.br. A +dnssec +multi +short
94.72.123.149
A 13 3 60 20240321055104 20240315180038 4462 wlf.eti.br. 9dbllQEaCH5LK+L49Oc+QsBmpbbFOVS4/s6NZzO6cQhrZ9l3653Hj6IC Ny7KdAuq92h6YhfqoVU4ujshLsIVwA==

Apenas uma assinatura!!


A imagem abaixo reforça que estamos assinando somente com a chave antiga.

DNSSEC chain of trust wlf


Adicione o novo DS na zona pai !

Vai levar um tempo até epublicação do novo DS, os servidores fazem transferência de zona de tempos em tempo, mas nao demorará mais que 10 minutos.


Verifique novamente o DS consultando o servidor NS da zona superior:

# Verifique novamente o DS:
dig @a.dns.br wlf.eti.br. DS +dnssec +multiline +short
4462 13 2 81AD27CC4D2C72FA08370B84B9B6677A5263CA185B6B3FAA3A65C228 70DB039B
55692 13 2 0365CE59B4EE9AD9AAF01B2228974118254C7F4A80BF9DD7FA1DCEDA F75DC863
DS 13 3 3600 20240329191009 20240315181009 57034 eti.br. KdrQA/vU+wvcRxVtrEZK8pOYICQ6vH2MEa5BYZjwpoCLAltqRTEgd9yD Mxtq4guYEKZ9gdZ/Z0Qznq4w030ytQ==

Os passos a frente só devem ser executados depois de pelo menos 1 dia.

# Veja o status da zona:
rndc -k /usr/local/named/etc/rndc.key -s localhost dnssec -status wlf.eti.br IN external
dnssec-policy: default
current time: Fri Mar 15 16:19:48 2024

key: 55692 (ECDSAP256SHA256), CSK
published: yes - since Fri Mar 15 16:02:22 2024
key signing: yes - since Fri Mar 15 16:02:22 2024
zone signing: yes - since Fri Mar 15 16:02:22 2024

No rollover scheduled
- goal: omnipresent
- dnskey: rumoured
- ds: hidden
- zone rrsig: rumoured
- key rrsig: rumoured

key: 4462 (ECDSAP256SHA256), CSK
published: yes - since Thu Mar 14 20:19:44 2024
key signing: yes - since Thu Mar 14 20:19:44 2024
zone signing: no

Key is retired, will be removed on Mon Mar 25 17:08:15 2024
- goal: hidden
- dnskey: omnipresent
- ds: rumoured
- zone rrsig: unretentive
- key rrsig: omnipresent


## Verifique a informação: Key is retired, will be removed on Mon Mar 25 17:08:15 2024

Caso esteja tudo certo, e você queira forçar o Bind a reassinar a zona com outra chave (muito importante em momentos de desespero), basta fazer assim:

# Apague os arquivo .signed, .signed.jnl e os arquivo tmp:
rm {Ex,In}ternalMaster/wlf.* {Ex,In}ternalMaster/tmp*

# Agora basta reiniciar o Bind:
systemctl restart named

# Verifique qual DNSKEY está em uso:
dig @ns1.wlf.eti.br wlf.eti.br. DNSKEY +dnssec +multi +short
257 3 13 ceDRBftq4XPj831QU2v6oy8DDRY1zc8b7V7Ol42bIonmZZexXg4/BM22 fhndom6jXyFEYpGt5qVHGhQHQdftNw==
DNSKEY 13 3 3600 20240329201348 20240315191348 55692 wlf.eti.br. p8wS0zCLtrs7UaL2hJoUj0X9uBb0a/X7uOenUbmvSs8+icYeE9oDUjxA c+cscC8JYKL8/ZwIVjCMNdvCdb61oA==

A área em destaque mostra que a nova DNSKEY está em vigor.


Agora ao rodar o status, será mostrado apenas uma única chave:

rndc -k /usr/local/named/etc/rndc.key -s localhost dnssec -status wlf.eti.br IN external
dnssec-policy: default
current time: Fri Mar 15 17:15:23 2024

key: 55692 (ECDSAP256SHA256), CSK
published: yes - since Fri Mar 15 16:02:22 2024
key signing: yes - since Fri Mar 15 16:02:22 2024
zone signing: yes - since Fri Mar 15 16:02:22 2024

No rollover scheduled
- goal: omnipresent
- dnskey: rumoured
- ds: hidden
- zone rrsig: rumoured
- key rrsig: rumoured

Com a troca das chaves sem nenhum efeito colateral, podemos remover a chave KSK da zona (pode deixar lá também, não fará mal):

vim /usr/local/named/var/named/ExternalMaster/wlf
; Nova KSK
;$INCLUDE "/var/named/Kwlf.eti.br.+013+55692.key";

#####################################
# NÃO SE ESQUEÇA DE ALTERAR O SOA!! #
#####################################

vim /usr/local/named/var/named/InternalMaster/wlf
; Nova KSK
;$INCLUDE "/var/named/Kwlf.eti.br.+013+55692.key";

#####################################
# NÃO SE ESQUEÇA DE ALTERAR O SOA!! #
#####################################

Agora reinicie o Bind:

systemctl restart named

Remova o DS antiga da zona superior!

Agora podemos remover o RR DS na zona pai.



Fontes


https://ftp.registro.br/pub/doc/tutorial-dnssec.pdf

https://registro.br/tecnologia/provedores-de-hospedagem/dnsshim/

https://registro.br/tecnologia/dnssec/root-anchor/

https://bind9.readthedocs.io/en/v9.18.14

https://kb.isc.org/docs

https://www.cloudflare.com/pt-br/dns/dnssec/how-dnssec-works/

https://ftp.registro.br/pub/doc/configuracao_dnssec_dominio.pdf

https://serverfault.com/questions/1001616/whats-the-difference-between-dns-forwarding-first-and-forwarding-only

https://digital.nhs.uk/services/health-and-social-care-network/hscn-technical-guidance/transition-network-guidance-for-dns-local-forwarding-and-server-configuration/4-forward-first-vs-forward-only

https://www.losurs.org/docs/howto/Chroot-BIND-1.html

https://kb.isc.org/docs/why-does-my-authoritative-server-make-recursive-queries

https://kb.isc.org/docs/916-dnssec-validation-automatic-trust-anchor-management

Automatic empty zones (including RFC 1918 prefixes):
https://kb.isc.org/docs/aa-00800

http://www.unixwiz.net/techtips/bind9-chroot.html

https://kb.isc.org/docs/aa-01309

Inline Signing in ISC BIND 9.9.0 -- Examples
https://kb.isc.org/docs/aa-00626

https://bind9.readthedocs.io/en/latest/dnssec-guide.html#advanced-discussions-manual-signing

https://blog.remontti.com.br/4672

https://bind9.readthedocs.io/en/v9.18.14/dnssec-guide.html#what-s-edns-all-about-and-why-should-i-care

https://unix.stackexchange.com/questions/735368/how-to-use-dns-over-tls-with-bind9-forwarders

https://gitlab.isc.org/isc-projects/bind9/-/issues/2776

https://dnsprivacy.org/encrypted-zone-transfer/