Tutorial DNS Hyperlocal

De Wiki BPF
Ir para: navegação, pesquisa

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, Unbound e NSD. Outras configurações e softwares mencionados na  RFC 7706 podem não serem abordados neste tutorial.

Implementação - BIND (CentOS)

Bind dns logo.png

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

Unbound-dns-logo.png

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. As versões padrão do Unbound disponibilizadas por algumas das distribuições mais utilizadas atualmente como Ubuntu, CentOS e Debian são até 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 a seguinte configuração à existente do Unbound.

Unbound

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 - Unbound + NSD

NSDNLL.png

Se você estiver utilizando uma versão empacotada com sua distribuição como Ubuntu, CentOS e Debian, tenha em mente que você encontrará o Unbound até a 1.6, para que você possa operar com hyperlocal será necessário um autoritativo externo, seja ele o BIND ou NSD, iremos apresentar as configurações necessárias para operar com NSD.

NSD

Instalação.

  • CentOS
yum install nsd
  • Debian
apt-get install nsd

Crie o arquivo /etc/nsd/nsd.conf.d/hyperlocal.conf com o conteúdo a seguir.

   server:
       ip-address: 127.12.12.12
   zone:
       name: "."
       request-xfr: 192.228.79.201 NOKEY # b.root-servers.net
       request-xfr: 192.33.4.12 NOKEY    # c.root-servers.net
       request-xfr: 192.5.5.241 NOKEY    # f.root-servers.net
       request-xfr: 192.112.36.4 NOKEY   # g.root-servers.net
       request-xfr: 193.0.14.129 NOKEY   # k.root-servers.net
       request-xfr: 192.0.47.132 NOKEY   # xfr.cjr.dns.icann.org
       request-xfr: 192.0.32.132 NOKEY   # xfr.lax.dns.icann.org
       request-xfr: 2001:500:84::b NOKEY # b.root-servers.net
       request-xfr: 2001:500:2f::f NOKEY # f.root-servers.net
       request-xfr: 2001:7fd::1 NOKEY    # k.root-servers.net
       request-xfr: 2620:0:2830:202::132 NOKEY  # xfr.cjr.dns.icann.org
       request-xfr: 2620:0:2d0:202::132 NOKEY  # xfr.lax.dns.icann.org

Unbound
Edite o arquivo /etc/unbound/unbound.conf, localize a linha do parâmetro abaixo e comente-a

root-hints: "/var/unbound/etc/root.hints"

Agora adicione

    stub-zone:
        name: "."
        stub-prime: no
        stub-addr: 127.12.12.12

Salve o arquivo, inicie o NSD e reinicie o Unbound.

services nsd start
unbound-control stop
unbound-control start

Implementação - Microsoft Windows Server 2012

Microsoft-dns-logo.png

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.

  1. Abre o "DNS Manager GUI". É possível abrir utilizando também a linha de comando através do comando dnsmgmt.msc
  2. 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.
  3. Em "Zone Type" selecione "Secondary Zone"
  4. Em "Zone Name" digite ".".
  5. 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.
  6. Em "Completing the New Zone Wizard" clique em "Finish"
  7. 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

Adaptações: Fernando Frediani e Diego Canton