Melhorando a performance e resiliencia da rede com Recursive DNS Anycast

De Wiki BPF
Ir para navegação Ir para pesquisar

Melhorando a performance e resiliência da rede com Recursive DNS Anycast

Introdução

Uma das melhoras práticas hoje em dia é termos um servidor de DNS recursivo dentro de nossos ambientes, para que assim tenhamos como melhorar a experiência de nossos usuários, quando estes desejarem acessar seus destinos de Internet e conteúdos.

Diante do exposto acima, nem precisamos citar o quão importante é termos o nosso próprio DNS recursivo em nossa rede, uma vez que ao, confiarmos 100% em estruturas externas, podemos experimentar algumas sérias complicações em casos de falhas (DNS da Google fica fora para usuários brasileiros). Conforme esta dinâmica, quero mostrar neste artigo como podemos construir o nosso próprio DNS Recursivo, e de modo eficiente e com resiliência, e ainda podendo contar com técnicas tais como DNS Anycast, a qual é seguida por diversos servidores públicos de DNS. A maioria dos serviços de DNS autoritativos seguem este padrão, pois utilizam o conceito de anycast, à exemplo do Google (8.8.8.8, 8.8.4.4), e isto pode ser verificado com um simples traceroute partindo de uma localidade dentro do território nacional, onde o tráfego deverá permanecer no Brasil. Por outro lado, ao realizarmos o mesmo traceroute a partir de algum looking glass posicionado fora do país, poderemos observar que os caminhos são outros, completamente distintos, e que o tráfego percorre os sistemas autônomos fora do país.

Tratando-se de DNS Anycast, a maioria dos provedores de conteúdos adotam esta técnica, visando trazer uma cópia de seus autoritativos para mais próximo dos usuários, assim com fazem os Root Servers espalhados pelo mundo (https://root-servers.org/).

No entanto, uma boa solução para obtermos um ótimo desempenho neste tipo de cenário seria com a combinação das técnicas do DNS Hyperlocal, RFC 7706.

O que é DNS Anycast?

É um método de roteamento que permite que se tenha o mesmo endereço IP espalhado através de vários servidores ao longo da topologia da rede, e onde o cliente poderá se comunicar com aquele servidor de DNS que estiver mais próximo dele, independentemente da localidade, o que, consequentemente, promoverá uma diminuição da latência e do tempo de resposta sobre as consultas ao serviço de DNS. Em adição, esta técnica provê boa proteção contra ataques DDoS lançados contra seus servidores recursivos.

Topologia simplificada comparativa entre DNS unicast e DNS anycast

Geralmente os servidores de DNS recursivo são implementados no regime convencional (unicast), o que promove um ponto central de falhas, conforme mostrado na imagem acima. Por estas razões é que a implementação no regime anycast acaba representando um cenário mais eficiente, resiliente e confiável.

Exemplo de implementação do DNS Anycast

Para exemplificar este cenário, utilizarei a última versão do BIND, mas, caso queira preferir, o Unbound poderá ser utilizado, ficando a seu critério a escolha do serviço DNS para o seu projeto.

Pacotes necessários para a configuração de cada servidor

  • S.O – Linux Debian, instalação básica
  • DNS Server Recursivo – Bind (atual da distribuição)
  • Protocolo de roteamento dinâmico – FRR
  • Postfix + mailutils
  • 2vCPU
  • 2Gb RAM
  • 10GB HDD

Topologia

No cenário abordado teremos duas cidades, e cada uma destas duas cidades terá os seus próprios servidores de DNS. A observação mais importante aqui está no conceito Anycast: todos os servidores serão configurados e compartilharão o mesmo endereço IP!

Topologia do cenário DNS anycast demonstrado neste artigo

Instalação e configuração

Instalação do bind9
# apt-get install bind9 dnsutils -y

Uma vez instalado, as configurações do DNS recursivo são simples, porém é muito importante lembrar de sempre ativar o DNSSEC nos recursivos também, e configurar as permissões de recursividade somente originadas de endereços IP confiáveis. Os nossos servidores, neste exemplo, estarão escutando as consultas recursivas sobre o endereço IP 192.168.7.200.

Configuração do named.conf.options
acl mynetwork {
  //ACL contendo redes trusted para consulta recursiva
    127.0.0.1;
    ::1;
    192.168.7.0/24;
    10.0.0.0/24;
    };

options {
    directory "/var/cache/bind";
    dnssec-validation auto;
    dnssec-enable yes;
    auth-nxdomain no;
    listen-on-v6 { any; };
    listen-on { 192.168.7.200; 127.0.0.1; };
    dump-file "/var/cache/bind/cache_dump.db";
    statistics-file "/var/cache/bind/named_stats.txt";
    memstatistics-file "/var/cache/bind/named_mem_stats.txt";
    recursing-file "/var/cache/bind/named.recursing";
    secroots-file "/var/cache/bind/named.secroots";
    bindkeys-file "/var/cache/bind/named.iscdlv.key";
    managed-keys-directory "/var/cache/bind/dynamic";
    pid-file "/var/cache/bind/named.pid";
    session-keyfile "/var/cache/bind/session.key";
    allow-query {any;};
    version "ISP DNS SERVER 1.0";
};

Nesta etapa, configuraremos o Bind para que este trabalhe também como Hyperlocal, aumentando assim a eficiência e resiliência dos recursivos. Um ponto importante é sempre manter o slave fazendo consultas externas nos root-servers, para caso de panes do principal.

Configuração do named.conf.default-zones
view rootservers {
       //View somente para o cópia do rootservers - Hyperlocal

zone "localhost" {
   type master;
   file "/etc/bind/db.local";
};

zone "." {
   type slave;
   file "db.rootzone";
   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 clientes_interno {
   dnssec-validation auto;
   allow-recursion { mynetwork; };
   allow-query-cache {mynetwork; };
   recursion yes;

zone "." {
   type static-stub;
   server-addresses {127.0.0.1;};
      };
};
Configuração do Router e dns resolver das Cidades

O endereço IP anycast (192.168.7.200) dos servidores ficará atribuído às suas respectivas interfaces loopback, tendo, como endereço p2p, qualquer um da sua rede, desde que tenha acesso à Internet para consultar os outros autoritativos. Neste ponto estaremos fechando uma seção BGP entre o router e o servidor DNS da Cidade A ou B, de modo que o mesmo publique somente o IP da loopback para os routers de respectivas cidades.

  • ASN da Rede: 12345
  • ASN dos DNS: 65123

Router cidade A/B:

router bgp 12345
 neighbor 192.168.0.X remote-as 65123
 neighbor 192.168.0.X description DC-DNS_Anycast-Cidade-A
 neighbor 192.168.0.X activate
 neighbor 192.168.0.X default-originate
 neighbor 192.168.0.X soft-reconfguration inbound
 neighbor 192.168.0.X prefx-list anycast-DNS-in in
 neighbor 192.168.0.X prefx-list default out
!
ip prefx-list anycast-DNS-in seq 10 permit 192.168.7.200/32
ip prefx-list default seq 5 permit 0.0.0.0/0

Configuração do bgp nos Dns da Cidade A/B

#cat /etc/frr/bgpd.conf
router bgp
 neighbor 192.168.0.Y remote-as 12345
 neighbor 192.168.0.Y description RouterA/b
 neighbor 192.168.0.Y update-source 192.168.0.X
!
 address-family ipv4 unicast
  network 192.168.7.200/32
  neighbor 192.168.0.Y prefix-list anycast_dns out
 exit-address-family
!
!
ip prefix-list anycast_dns seq 10 permit 192.168.7.200/32
ip prefix-list anycast_dns seq 100 deny any

Pronto, aqui já teremos o DNS sendo propagado para dentro da rede e as cidades utilizando dos seus respectivos servidores de DNS locais.

Segue meu script de monitoramento

Agora o ponto chave: como monitorar o serviço para que, caso ocorra alguma falha na resolução, o mesmo possa reiniciar o serviço, e, caso isto não solucione o problema, o servidor possa ser derrubado para que tudo seja encaminhado para o outro DNS da rede, até que você tenha a oportunidade de analisar o problema ocorrido no servidor afetado. Sinta-se livre para realizar quaisquer modificações.

welisson@meudomain.com.br"
DNS_local="192.168.7.200"
DNS_Result2="IP_DO_MEUDominio"

if [ "$DIG" = "127.0.0.1" ] ; then
      logger " DNS Anycast Bind - OK"
else
      logger " DNS Anycast Bind - Failure"
      logger " DNS Anycast Bind - Checking stage 2"

      DIG2=`/usr/bin/dig @"$DNS_local" -t A www.meudomain.com.br +timeout=1 +short`

      if [ "$DIG2" != "$DNS_Result2" ] ; then
            /etc/init.d/bind9 stop && /etc/init.d/bind9 start3
            logger "DNS Anycast Bind - Restarted"
            logger "DNS Anycast Bind - Checking again"
            DIG3=`/usr/bin/dig @127.0.0.1 -t A localhost +short`
                if [ "$DIG3" = "127.0.0.1" ] ; then
                      echo "DNS Anycast Cidade X - Restored" | mail -s "DNS Anycast Restored" $MAILGROUP
                      else
                      /etc/init.d/frr stop
                      echo "DNS Anycast Cidade X - Crashed" | mail -s "DNS Anycast CRASHED" $MAILGROUP
                      logger "DNS Anycast Bind - Crashed"
                fi
      fi
fi

Qualquer dúvida ou pergunta, estou à disposição.

e-mail: welissontome [at] gmail.com

Autor: Welisson