Tutorial DNS Hyperlocal
Introdução
A Zona Raiz do Sistema de Nomes de Domínios (DNS) é servida por 12 organizações que operam instâncias anycast de servidores de nomes autoritativos provendo respostas para a raiz do DNS. Estas instâncias estão distribuídas em mais de 1000 localidades ao redor do mundo. Apesar deste grande número de servidores e alta capacidade provisionada para a resolução da raiz de nomes, ainda existe a possibilidade de que um grande ataque coordenado de negação de serviço (DDoS) possa comprometer o acesso à internet para muitos usuários.
Para minimizar e prevenir esta ameaça, existe a possibilidade de adicionar um fator de resiliência na configuração dos servidores recursivos do provedor de internet através do uso de uma cópia local da zona raiz, chamada de Hyperlocal. Hyperlocal é apresentado em detalhes na RFC7706 e, resumidamente, consiste em executar uma cópia da zona raiz no mesmo servidor de serviços de resolução recursiva. Desta forma, as consultas à zona raiz dos clientes são respondidas localmente sem necessidade comunicação externa entre os servidores. Isso resulta em maior robustez do serviço em caso de ataques e ganhos na velocidade de provimento de respostas às consultas ao DNS dos usuários.
Este tutorial foi criado para compartilhar a prática de implementação de um sistema Hyperlocal para a configuração de servidores de DNS do tipo BIND9. Outras configurações e softwares mencionados na RFC 7706 não são abordados neste tutorial.
Implementação - BIND (CentOS)
Requisitos para instalação do Hyperlocal:
- Instalação básica CentOS Linux 7
- 1vCPU
- 1GB de RAM
- 20GB de Disco
Baixe o ISO do Sistema Operacional no link http://isoredirect.centos.org/centos/7/isos/x86_64/
Sistema operacional instalado e atualizado, agora devemos instalar o Bind9 com o comando:
yum install bind bind-utils
A configuração para o funcionamento da zona raiz é bem simples como podemos ver abaixo.
Os arquivos de configuração do Bind no Centos7 por padrão estão no arquivo /etc/named.conf.
No exemplo de configuração abaixo, o servidor Hyperlocal foi configurado com o IPv4 198.51.100.1 e IPv6 2001:db8::1 em sua interface de rede. No caso do servidor Hyperlocal ser instalado como uma instância adicional no mesmo servidor que o Recursivo é recomendado que ele escute apenas no endereço de Looopback, (127.0.0.1 e ::1) e permita apenas consultas locais. Para isso será necessário alterar o match-destinations e as partes de acl "ServidorRecursivo_A" e B não serão necessárias.
view root { # IPs das interfaces onde chegarão as requisições para cópia loca da zona raiz match-destinations { 198.51.100.1; 2001:db8::1; }; zone "." { type slave; file "rootzone.db"; notify no; masters { 192.228.79.201; # b.root-servers.net 192.33.4.12; # c.root-servers.net 192.5.5.241; # f.root-servers.net 192.112.36.4; # g.root-servers.net 193.0.14.129; # k.root-servers.net 192.0.47.132; # xfr.cjr.dns.icann.org 192.0.32.132; # xfr.lax.dns.icann.org 2001:500:84::b; # b.root-servers.net 2001:500:2f::f; # f.root-servers.net 2001:7fd::1; # k.root-servers.net 2620:0:2830:202::132; # xfr.cjr.dns.icann.org 2620:0:2d0:202::132; # xfr.lax.dns.icann.org }; }; };
Obs: Os servidores utilizados devem permitir transferência de zona (axfr), como nem todos os root server permitem o axfr, sendo assim deve ser verificada na versão atual da RFC no link a seguir https://tools.ietf.org/html/rfc7706 os root servers que estão preparados para a sincronização do Hyperlocal.
O processo de atualização acontece uma vez ao dia, e ela requer que seja baixada toda a zona raiz que atualmente chega a ~1.5Mb.
Iniciando o serviço do Bind você pode conferir a criação da base com o comando:
ls /var/named/rootzone.db
Segue abaixo um exemplo de arquivo de configuração para o BIND já contendo as configurações de Hyperlocal e de recursividade .
É possível melhorar de diversas formas esse exemplo de configuração.
O configuração padrão do Bind com o adicional de views no exemplo seguinte já é bem funcional.
options { listen-on port 53 { any; }; listen-on-v6 port 53 { any; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; recursing-file "/var/named/data/named.recursing"; secroots-file "/var/named/data/named.secroots"; dnssec-enable yes; dnssec-validation yes; /* Path to ISC DLV key */ bindkeys-file "/etc/named.iscdlv.key"; managed-keys-directory "/var/named/dynamic"; pid-file "/run/named/named.pid"; session-keyfile "/run/named/session.key"; }; logging { channel default_debug { file "data/named.run"; severity dynamic; }; }; acl "MinhaRede_v4" { 127.0.0.0/8; 198.51.100.0/24; }; acl "MinhaRede_v6" { ::1; 2001:db8::/32; }; acl "ServidorRecursivo_A" { 203.0.113.10; 2001:db8::10; }; acl "ServidorRecursivo_B" { 203.0.113.20; 2001:db8::20; }; view root { # Como exemplo, especificamos abaixo os dois servidores recursivos autorizados a fazer consulta na copia local de zona Raiz match-clients { 127.0.0.1; ServidorRecursivo_A; ServidorRecursivo_B; } ; zone "." { type slave; file "rootzone.db"; notify no; masters { 192.228.79.201; # b.root-servers.net 192.33.4.12; # c.root-servers.net 192.5.5.241; # f.root-servers.net 192.112.36.4; # g.root-servers.net 193.0.14.129; # k.root-servers.net 192.0.47.132; # xfr.cjr.dns.icann.org 192.0.32.132; # xfr.lax.dns.icann.org 2001:500:84::b; # b.root-servers.net 2001:500:2f::f; # f.root-servers.net 2001:7fd::1; # k.root-servers.net 2620:0:2830:202::132; # xfr.cjr.dns.icann.org 2620:0:2d0:202::132; # xfr.lax.dns.icann.org }; }; }; view "externa" { match-clients { any; }; recursion no; }; view clientes-recursivos { # Esta é a view que permite que clientes façam consultas recursivas a este servidor dnssec-validation auto; allow-recursion { MinhaRede_v4; MinhaRede_v6; }; recursion yes; # Esta é parte aonde instruímos o Bind sobre os servidores a serem utilizados para consulta de zona Raiz. zone "." { type static-stub; server-addresses { 127.0.0.1; ::1; }; # Aqui definimos o IP do servidor Hyperlocal aonde serão feitas as consultas recursivas da zona Raiz. # Como neste exemplo o Hyperlocal roda neste mesmo servidor, especificamos o endereço de Loopback. No caso das consultas serem feitas desde um servidor diferente outro IP deverá ser especificado no lugar. }; };
Com essa configuração é possível já sentir os benefícios do Hyperlocal em sua rede, no exemplo acima, configuramos o Hyperlocal e o servidor recursivo na mesma instancia do Bind, para usuários do Unbound é possível fazer a consulta na instância Hyperlocal Bind com um pequeno ajuste na configuração, adicione ao final do arquivo de configuração do "unbound.conf" o seguinte trecho para que ele consulte o Hyperlocal:
stub-zone: name: "." stub-prime: no stub-addr: 198.51.100.1 stub-addr: 2001:db8::1
Bind 9.14
Na versão do Bind 9.14 que ainda é release futuro é possível configurar um mirror local da zona raíz com uma configuração bem menor e mais simples. Isso é possível porque nesta versão a configuração "type mirror" porque o Bind incorporou a lista de servidores raiz da IANA. Este exemplo é válido para a zona raiz. Para qualquer outra zona é necessário especificar a lista dos servidores primários. Para qualquer outro detalhe relacionado consulte a documentação do Bind 9.14 quando lançado oficialmente.
O exemplo de configuração para o o Bind 9.14 é:
zone "." { type mirror; };
Implementação - Unbound
Para que o Unbound possa ser utilizado para replicar a zona raiz sem a utilização de nenhum outro software de DNS é necessário utilizar a versão 1.7 ou mais nova. No caso da utilização de versões anteriores é necessário haver uma instância separada do BIND sendo executada com o Unbound para ser consultada conforme as instruções acima. A versão padrão do Unbound disponibilizada por algumas das distribuições mais utilizadas atualmente como Ubuntu, CentOS e Debian é a 1.6. Para utilizar uma versão superior é necessário compilar manualmente a versão mais nova ou então utilizar alguma técnica de containers como docker.
Para rodar o Hyperlocal utilizando Unbound 1.7, 1.8 e 1.9 na mesma instância do Unbound adicione as seguintes configurações à configuração existente do Unbound de acordo com a versão.
Unbound 1.7 e 1.8
auth-zone: name: "." master: 192.228.79.201 # b.root-servers.net master: 192.33.4.12 # c.root-servers.net master: 192.5.5.241 # f.root-servers.net master: 192.112.36.4 # g.root-servers.net master: 193.0.14.129 # k.root-servers.net master: 192.0.47.132 # xfr.cjr.dns.icann.org master: 192.0.32.132 # xfr.lax.dns.icann.org master: 2001:500:84::b # b.root-servers.net master: 2001:500:2f::f # f.root-servers.net master: 2001:7fd::1 # k.root-servers.net master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org master: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org fallback-enabled: yes for-downstream: no for-upstream: yes
Unboud 1.9
A única diferença no Unbound 1.9 é a linha zonefile: "root.zone" para onde será feito o espelhamento da zona raiz.
auth-zone: name: "." master: 192.228.79.201 # b.root-servers.net master: 192.33.4.12 # c.root-servers.net master: 192.5.5.241 # f.root-servers.net master: 192.112.36.4 # g.root-servers.net master: 193.0.14.129 # k.root-servers.net master: 192.0.47.132 # xfr.cjr.dns.icann.org master: 192.0.32.132 # xfr.lax.dns.icann.org master: 2001:500:84::b # b.root-servers.net master: 2001:500:2f::f # f.root-servers.net master: 2001:7fd::1 # k.root-servers.net master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org master: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org fallback-enabled: yes for-downstream: no for-upstream: yes zonefile: "root.zone"
Implementação - Microsoft Windows Server 2012
O Windows Server 2012 contém um servidor DNS dentro do componente DNS Manager. Quando ativado este componente atua como servidor Recursivo e pode também atuar como servidor Autoritativo.
Utilizando os passos abaixo é possível reproduzir o Hyperlocal para este cenário.
- Abre o "DNS Manager GUI". É possível abrir utilizando também a linha de comando através do comando dnsmgmt.msc
- Na hierarquia abaixo do serviço, clique com o botão direito em "Forward Lookup Zones" e selecione "New Zone". Isso mostrará uma sucessão opções para preencher.
- Em "Zone Type" selecione "Secondary Zone"
- Em "Zone Name" digite ".".
- Em "Master DNS Server" digite "b.root-servers.net". O sistema irá validar que é possível fazer a transferência da zona daquele servidor. Após este configuração ser finalizada o DNS Manager irá tentar transferir a zona desde todos servidores raiz.
- Em "Completing the New Zone Wizard" clique em "Finish"
- Verifique que o DNS Manager está atuando como um resolver recursivo. Clique com o botão direito no servidor na parte de hierarquia, selecione a tab "Advanced". Veja se "Disable recursion (also disabled forwarders)" não está selecionada e que "Enable DNSSEC validation for remote responses" está selecionada.
Conclusão
Em testes o desempenho ficou muito bom. Abaixo algumas comparações consultando domínios inválidos para forçar o recursivo a procurar nos Root Servers.
// Teste 1 servidor público Google dig @8.8.8.8 domaininvalid.com.br.xxxxxxx ;; Query time: 29 msec // Teste 2 servidor publico Google dig @8.8.8.8 domaininvalid.com.br.xxxxxxx ;; Query time: 27 msec // Teste 1 no Unbound recursivo sem o Hyperlocal dig @172.16.1.1 domaininvalid.com.br.xxxxxxx ;; Query time: 21 msec // Teste 2 (cached) no Unbound recursivo sem o hyperlocal dig @172.16.1.1 domaininvalid.com.br.xxxxxxx ;; Query time: 0 msec // Teste 1 direto no Hyperlocal dig @192.168.0.1 domaininvalid.com.br.xxxxxxx ;; Query time: 0 msec // Teste 2 (cached) direto no Hyperlocal dig @192.168.0.1 domaininvalid.com.br.xxxxxxx ;; Query time: 0 msec // Teste 1 no Unbound recursivo apontando para o Hyperlocal dig @172.16.1.1 domaininvalid.com.br.xxxxxxx ;; Query time: 2 msec // Teste 2 (cached) no Unbound recursivo apontando para o Hyperlocal dig @172.16.1.1 domaininvalid.com.br.xxxxxxx ;; Query time: 0 msec
É possível portanto visualizar o melhor desempenho quando feitas consultas utilizando o Hyperlocal, sendo essa uma ótima implementação para manter no provedor.
É importante lembrar que em caso haver somente um Hyperlocal na rede, o recomendado é deixar somente o servidor primário apontando para o mesmo afim de evitar ponto único de falha, ou fazer dupla implementação um para cada servidor recursivo.
Referências
https://www.isc.org/docs/Apricot2017.pdf
https://datatracker.ietf.org/doc/draft-ietf-dnsop-7706bis
Autores: Fabio Ortlieb e Daniel Fink e adaptação de Fernando Frediani