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 - 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. O servidor foi configurado com o IP 198.51.100.1 em sua interface.
Exemplo abaixo de configuração da zona raiz:
view root { # IP da interface onde chegarão às requisições match-destinations { 198.51.100.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.0.47.132; # xfr.cjr.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 }; }; };
Iniciando o serviço do Bind você pode conferir a criação da base com o comando: ls /var/named/rootzone.db” É possível melhorar de diversas formas esse exemplo de configuração do Bind, a 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 "REDE" { 127.0.0.0/8; 192.168.0.0/16; }; view root { # é possível fazer match por origem ou destino conforme abaixo match-clients { 127.0.0.1; 172.16.1.1; 172.16.1.2; } ; #match-destinations { 198.51.100.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.0.47.132; # xfr.cjr.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 recursivos { dnssec-validation auto; allow-recursion { REDE; }; recursion yes; zone "." { type static-stub; server-addresses { 198.51.100.1; }; }; };
Com essa configuração é possível já sentir os benefícios do Hyperlocal em sua rede, no exemplo acima, os endereços 172.16.1.1 e 172.16.1.2 são servidores recursivos externos rodando Unbound, para completar a configuração adicione ao Unbound a seguinte configuração para que ele consulte o Hyperlocal:
stub-zone: name: "." stub-prime: no stub-addr: 198.51.100.1
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.