Mudanças entre as edições de "DNS Recursivo Anycast Hyperlocal"

De Wiki BPF
Ir para: navegação, pesquisa
Linha 1: Linha 1:
== Descrição ==
+
==Introdução==
Um dos recursos extremamente importante para o acesso à Internet é o '''DNS (Domain Name System)''' e sem ele teríamos que decorar milhares de endereços IP para acessar sites e serviços na Internet. Basicamente temos 2 tipos de DNS, o recursivo e o autoritativo. O recursivo é um serviço que utilizamos para fazer consultas aos DNS(es) Autoritativos que são aqueles responsáveis pelas tabelas que associam o host name a um IP e no caso de resolução reversa, o IP ao host name. O exemplo mais comum de DNS recursivo é o do Google, os IPs 8.8.8.8, 8.8.4.4, 2001:4860:4860::8888 e 2001:4860:4860::8844. Se você está estranhando os 2 últimos endereços, é porque provavelmente ainda não ouviu falar de IPv6 e isso não é bom. Procure estudar sobre isso e um bom lugar para começar é [http://ipv6.br/pagina/curso-basico-ead aqui]. O serviço de DNS deve ser levado muito a sério pelas empresas que o implementam, porque a sua falha pode literalmente parar a Internet para milhares de pessoas que confiam nele ou até pior, um DNS mal intencionado ou comprometido, pode ser usado para direcionar usuários a acessarem sites falsos. Esse artifício visa coletar as credenciais dos usuários e assim poderem aplicar golpes e outras formas danosas e prejudiciais à vítima. Ter um DNS recursivo é muito bom para o ISP, mas cuidar dele, mantê-lo atualizado e protegido, é mais importante ainda.
+
Você sabe como funciona a Internet? Essa é uma pergunta que meu amigo '''Thiago Ayub''' sempre faz aos seus candidatos à vagas de emprego e não importa o quanto tenham de experiência em '''Engenharia de Redes''', todos sempre travam nesse momento. Todos estão sempre prontos e preparados para resolver os problemas mais cabeludos em '''BGP''', '''OSPF''', '''MPLS''', etc mas travam com essa simples pergunta. Para contextualizar e visualizarmos melhor vamos nos atentar à imagem abaixo e uma explicação simplificada de como funciona:
 +
[[Arquivo:Como funciona a Internet.png|esquerda|commoldura]]
 +
Tudo começa com um usuário sentado confortavelmente e querendo acessar um conteúdo disponível na Internet. Ele digita em seu navegador preferido a URL: '''<nowiki>https://wiki.ispconfig.com.br</nowiki>''', nesse momento '''seta''' '''<big>1</big>'''<big>, o navegador irá requisitar do '''DNS Recursivo''' utilizado pelo usuário, qual o IP responde pelo hostname '''wiki.ispup.com.br'''. Isso porque todos os acessos se dão na Internet através do '''IP Address''' e não através do '''hostname'''. Imaginem se tivéssemos que decorar os IPs de todos os sites e serviços que quiséssemos acessar na Internet? Só que a primeira vez que consultamos um hostname, o '''DNS Recursivo''' não tem a resposta de imediato porque ele não é o dono dessa informação. Então ele faz o trabalho de buscar e consultar o '''DNS Autoritativo''', responsável por aquele domínio em questão '''ispup.com.br''' e vemos isso na '''seta''' '''2'''. O '''DNS Autoritativo''' sabe quais são os IPs que respondem pelo hostname '''wiki.ispup.com.br''' e devolve a informação para o '''DNS Recursivo''', '''seta 3'''. Na sequência, '''seta 4''', o '''DNS Recursivo''' devolve para o navegador do usuário, o '''IP Address do wiki.ispup.com.br''' e que pode ser mais de um e de famílias diferentes como '''IPv4''' e '''IPv6'''. Cabe ao navegador decidir por qual acessar mas normalmente a preferência é sempre por '''IPv6''', se houver conectividade IPv6 entre o usuário e o conteúdo acessado. Por último, '''seta 5''', o navegador faz o acesso ao site '''wiki.ispup.com.br''' através do '''IP Address'''.</big>
  
Nesse artigo mostrarei a configuração de um '''DNS recursivo anycast''', diferente dos '''DNS recursivos unicast''' comumente encontrados pelos ISPs a fora. No modelo Unicast, normalmente se tem um ou mais servidores de DNS que são consultados e estão fisicamente em um local. O problema é que essa abordagem não poderia ter por exemplo, 5 servidores, e utilizar todos configurados ao mesmo tempo nos sistemas, porque muitos sistemas só aceitam até 3 servidores recursivos em suas configurações e mais que isso são ignorados. Você poderia então utilizar apenas 2 servidores, isso resolveria o problema mas eles precisariam estar em um determinado local. Mas e se lá na frente você resolver abrir seu negócio em uma outra cidade e em outro estado? Nesse caso poderia continuar usando os mesmos servidores mas aumentando um pouco a latência. Mas se acontecesse algo na interconexão desses servidores? Com o uso do DNS Anycast você poderia ter um servidor DNS recursivo em cada cidade e respondendo pelo mesmo IP. Em caso de problemas com qualquer servidor, o outro passaria a responder para todos os seus assinantes. Além desse recurso, usaremos o '''Hyperlocal''' que é uma técnica que faz uma cópia das tabelas dos DNS Root Servers e mantém localmente no seu servidor recursivo. Isso deixa rápida toda resposta que seria endereçada primeiramente aos DNS(es) Raiz da Internet, principalmente consultas de domínios inválidos ou digitados erradamente.
+
Como que se dá a comunicação entre os '''DNS(s) Recursivos''' e '''Autoritativos'''? Como que o navegador do usuário, após receber o IP do site, consegue chegar no servidor que tem o conteúdo? Isso só é possível devido ao protocolo chamado '''BGP (Border Gateway Protocol)''', todos os caminhos que conhecemos como rotas de destino, são anunciadas por milhares de participantes na '''Internet''' conhecidos como '''AS (Autonomous System)''', esses participantes se interligam para disponibilizar conteúdos e acessos pelo mundo aos milhares de usuários. É uma imensa rede colaborativa formada por Empresas, Universidades, Governos e todos que queiram se interconectar. Percebam que sem o '''BGP''', que serve de caminho para chegarmos nos conteúdos e sem o '''DNS (Domain Name System)''' para traduzir o hostname para o IP Address, a '''Internet''' não funcionaria e por isso precisamos cuidar muito bem desses dois serviços.
  
== Diagrama ==
+
Mas não acaba por aí. O '''DNS Recursivo''' tem um papel muito importante para o Provedor de Internet e que envolve segurança, qualidade de acesso à Internet e a disponibilidade do serviço entregue ao cliente. Quando bem configurado acelera as consultas dos acessos graças ao seu cache interno, mas para que isso seja percebido pelo assinante, é necessário que esteja o mais próximo possível do seu cliente.
Para que possamos visualizar nossa configuração, abaixo temos um diagrama hipotético dos nossos servidores e da rede em si:
 
[[Arquivo:Diagrama dns anycast2.png|nenhum|miniaturadaimagem|807x807px]]
 
Explicando o cenário: cada servidor DNS fechará uma sessão iBGP com o seu router através dos endereços /30 IPv4 e /64 IPv6 (usando IPs de documentação [https://datatracker.ietf.org/doc/html/rfc3849 RFC3849] e [https://datatracker.ietf.org/doc/html/rfc5737 RFC5737] representando seus IPs públicos). Nessa sessão BGP serão anunciados os IPs privados [https://datatracker.ietf.org/doc/html/rfc1918 RFC1918] e [https://datatracker.ietf.org/doc/html/rfc4193 RFC4193] configurados nas loopbacks que serão: 10.10.10.10 e fc00::10:10:10:10. Divulgando esses IPs privados para os assinantes, você esconde o real IP público dos servidores, evitando que alguém de fora envie ataques para seus servidores DNS.
 
== Servidores utilizados ==
 
* VM com 4 cores (Intel(R) Xeon(R) Silver 4214R CPU @ 2.40GHz).
 
* 4Gb memória.
 
* 20Gb disco.
 
  
== Softwares utilizados ==
+
== Um erro que destrói a qualidade do nosso serviço[editar | editar código-fonte] ==
Para instalação e configuração dos Servidores DNS Recursivos utilizaremos Software Livre, o que nos permite uma economia em licenças de sistemas fechados e proprietários. Abaixo a descrição deles:
+
Um erro muito comum que muitas operadoras cometem é utilizar DNS Recursivo externo, como o '''8.8.8.8''', '''1.1.1.1''' e outros, para seus clientes. Quanto mais próximo dos seus clientes, mais qualidade de serviço estará entregando a eles. Conteúdos serão entregues mais rapidamente pois serão resolvidos e armazenados em caches locais e não consultados remotamente na Internet. Para falar mais sobre isso, te convido leitor desse documento, que assista essa palestra do '''Thiago Ayub''' no '''GTER 51/GTS 37''' (2022) '''8.888 MOTIVOS PARA NÃO USAR DNS RECURSIVO EXTERNO EM SEU AS''': <nowiki>https://www.youtube.com/watch?v=Rsvpu5uF2Io</nowiki>
* [https://www.debian.org/ Debian Linux Buster (10.x).]
 
* [https://frrouting.org/ FRRouting 7.5.1.]
 
* Unbound 1.9.0 (pacote da distribuição Debian). Obs.: essa versão do Unbound já possui suporte ao Hyperlocal nativo.
 
* IRQBalance (pacote do Debian).
 
* OpenNTPd (também pacote do Debian).
 
* Shell script em bash, para checar se o DNS está OK e se não tiver retirar ele do anúncio.
 
  
== Gráfico de utilização desse sistema em produção ==
+
== Objetivo[editar | editar código-fonte] ==
[[Arquivo:Dns Anycast Grafico.png|nenhum|miniaturadaimagem|816x816px]]
+
O objetivo desta documentação não é te ensinar tudo sobre '''DNS''', '''BGP''', '''OSPF''' e nem tão pouco sobre GNU/Linux e sim te mostrar um exemplo de servidor DNS Recursivo implementado pensando em segurança, qualidade e resiliência. Usaremos em todas as nossas documentações o Debian GNU/Linux, por ser uma distribuição que considero uma obra de arte criada por uma enorme comunidade séria, com vasta experiência de anos, qualidade no empacotamento dos programas, estável e com uma equipe de segurança excelente e ativa. Caso você leitor, utilize alguma outra distribuição GNU/Linux, todo conteúdo apresentado aqui pode ser aplicado em outras distros, desde que respeitando as particularidades de cada uma.
  
== Instalação e configuração do Servidor 1 ==
+
Aqui construiremos um sistema do tipo '''Anycast''', ou seja, terás o serviço rodando em diversas localidades da sua Rede utilizando o mesmo endereçamento IP e que atenderá seu cliente mais próximo. Em caso de falhas, seus clientes automaticamente e de forma transparente continuarão consultando o DNS mais próximo deles. Para que ele funcione dessa forma você precisará ter uma '''Rede OSPF''' implementada no seu Provedor Internet ou algum outro protocolo como por exemplo o '''ISIS,''' mas esse documento não irá abordar o '''ISIS'''. Também utilizaremos o '''Hyperlocal''' como recurso adicional para gerar algumas proteções de segurança e velocidade na resposta relacionada aos servidores de DNS Raiz da Internet.
Instale um sistema Debian 10 com o mínimo necessário, uma versão que costumo utilizar bastante é a que vem com firmwares e pode ser encontrado [https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/10.10.0+nonfree/amd64/iso-cd/firmware-10.10.0-amd64-netinst.iso aqui]. Atualmente está na versão 10.10, mas caso lancem uma versão mais recente, basta alterar o link. Não cobriremos a instalação do Debian, pois existem diversos vídeos no Youtube ensinando como proceder. Após a instalação faremos os ajustes na configuração para que possa então acomodar nosso serviço de DNS.
 
  
=== Instalação dos pacotes ===
+
== Diagrama[editar | editar código-fonte] ==
 +
Para exemplificar nosso servidor de DNS Recursivo, usaremos como base das explicações um diagrama demonstrando o uso do DNS Recursivo em uma Rede fictícia. Adotaremos IPs privados e reservados para demonstrar todo o ambiente do Provedor de Internet.
 +
[[Arquivo:Diagrama dns recursivo.drawio.png|esquerda|commoldura]]
 +
Nesse diagrama podemos observar alguns detalhes técnicos como por exemplo: existem '''3 servidores de DNS Recursivo''' posicionados em locais diferentes, que poderiam estar em bairros diferentes e até em cidades diferentes. Em cada servidor teremos '''2 loopbacks''' com os IPs:
  
==== FRR ====
+
'''10.10.10.10/32'''
Vamos configurar o repositório oficial do FRR e instalar os pacotes. O FRR é um fork do Quagga e será o responsável pela sessão BGP entre o servidor DNS e o router:<pre>
 
# echo "deb https://deb.frrouting.org/frr buster frr-stable" > /etc/apt/sources.list.d/frr.list
 
# curl -s https://deb.frrouting.org/frr/keys.asc | apt-key add -
 
# apt update
 
# apt install frr frr-doc frr-pythontools
 
</pre>
 
  
==== Unbound ====
+
'''10.10.9.9/32'''
O Unbound é exatamente o serviço de DNS recursivo que vamos utilizar nesse artigo. Por que o Unbound? Porque ele só faz recursividade, que é o que desejamos e faz isso com uma excelente performance e segurança. Ele é desenvolvido pela [https://www.nlnetlabs.nl/ NLNet Labs]mesma empresa que desenvolve o '''Krill''' e '''Routinator''', utilizados na implantação do '''RPKI''' e o '''NSD''' (servidor DNS autoritativo) e todos sempre pensando em segurança.<pre>
 
# apt install unbound
 
</pre>
 
  
==== IRQBalance ====
+
Esses IPs serão entregues pelos concentradores '''PPPoE''' ou '''IPoE''' ('''BNG''') para seus clientes como '''DNS primário''' e '''secundário'''. Podemos usar IPs privados como DNS primário e secundário em um ambiente real? Sim podemos, desde que não sejam IPs que possam ter problemas com as redes privadas dos clientes. Ex.: rede do cliente usando '''192.168.0.0/24'''. Se entregarmos o DNS sendo '''192.168.0.10''' e '''192.168.0.20''' teremos problemas e o cliente ficará sem Internet, porque '''192.168.0.10''' e '''192.168.0.20''' fazem parte da rede '''192.168.0.0/24'''.
O IRQBalance é um programa bem conhecido por distribuir o processamento entre os cores do servidor.<pre>
 
# apt install irqbalance
 
# systemctl enable irqbalance
 
</pre>
 
  
==== OpenNTPd ====
+
Agora entregando '''10.10.10.10''' e '''10.10.9.9''' não teríamos problemas com a rede '''192.168.0.0/24'''.
Para manter o sistema sempre com o horário correto, usaremos o OpenNTPd configurado para usar o Pool do [https://ntp.br/ Nic.BR]. <pre>
 
# apt install openntpd
 
  
Deixe o arquivo /etc/openntpd/ntpd.conf conforme abaixo e reinicie o serviço openntpd:
+
'''Motivos para usarmos IPs privados:'''
 +
* O principal motivo está relacionado com a segurança, uma vez que sendo um IP privado, não pode sofrer ataques DDoS direcionados diretamente para ele, vindos da Internet.
 +
* Nem mesmo o cliente da sua rede conhece os '''IPs públicos''' utilizados para recursividade na Internet.
 +
* Memorizar os IPs '''10.10.10.10''' e '''10.10.9.9''' é tão fácil quanto memorizar o '''8.8.8.8''' e o '''1.1.1.1'''. Mais fácil para o seu técnico guardar essa informação e utilizar onde for necessário.
 +
Cada servidor DNS Recursivo possui um '''IPv4 público''', aqui representado por '''198.18.x.x/27''' e um '''IPv6 global''' representado por um IP dentro do prefixo '''2001:db8::/32'''. Cada servidor precisa ter os seus próprios IPs e são através destes IPs que as consultas de DNS serão realizadas na Internet.
  
# $OpenBSD: ntpd.conf,v 1.14 2015/07/15 20:28:37 ajacoutot Exp $
+
Nessa topologia usando '''Anycast''', o cliente será sempre atendido pelo '''DNS Recursivo''' mais próximo, desde que os pesos no '''OSPF''' estejam ajustados corretamente.
# sample ntpd configuration file, see ntpd.conf(5)
 
  
# Addresses to listen on (ntpd does not listen by default)
+
== Dados do servidor[editar | editar código-fonte] ==
#listen on *
+
Podemos utilizar um sistema virtualizado ou não. Sistemas virtualizados são bem vindos pois são mais simples quando precisamos fazer backups, levantar outros sistemas sem complicações e se precisarmos restaurar rapidamente algum sistema que ficou indisponível por algum motivo. A configuração abaixo tem capacidade para atender algo em torno a '''50.000 assinantes ou mais'''. O DNS Recursivo é um serviço que pode ser utilizado até mesmo em um '''Raspberry Pi''' e atender operações pequenas, nesse caso com o intuito de economizar energia e espaço. Nosso foco aqui é montar uma rede de '''DNS Recursivo Anycast com HyperLocal'''. Como comentei acima o servidor deve ficar o mais próximo dos clientes para termos a '''menor latência possível''' e '''sempre menor que 5ms''' entre o cliente e o servidor.
#listen on 127.0.0.1
+
{| class="wikitable"
#listen on ::1
+
|+
 +
!CPU
 +
!Memória
 +
!Disco
 +
!Sistema
 +
|-
 +
|2.4Ghz 6 cores
 +
|16G DDR4
 +
|30G
 +
|Debian 11 amd64 (Bullseye)
 +
|}
  
# sync to a single server
+
== Softwares utilizados[editar | editar código-fonte] ==
#server ntp.example.org
+
* Debian 11 amd64 (Bullseye) instalação mínima.
servers pool.ntp.br
 
  
# use a random selection of NTP Pool Time Servers
+
* FRRouting.
# see http://support.ntp.org/bin/view/Servers/NTPPoolServers
+
* Unbound.
#servers pool.ntp.org
+
* IRQBalance.
 +
* Chrony (NTP/NTS).
 +
* Shell script em bash.
  
# Choose servers announced from Debian NTP Pool
+
== Funcionalidades que teremos[editar | editar código-fonte] ==
#servers 0.debian.pool.ntp.org
+
* Sistema em Anycast.
#servers 1.debian.pool.ntp.org
+
* Hyperlocal.
#servers 2.debian.pool.ntp.org
+
* Controle de acesso por <abbr>ACL</abbr>.
#servers 3.debian.pool.ntp.org
+
* RPZ (Response Policy Zone).
 +
* Bloqueio de consultas do tipo ANY.
 +
* QNAME minimization habilitado. (habilitado por default no Unbound)
 +
* Recursividade em IPv4 e IPv6.
 +
* DNSSEC habilitado.
 +
* <abbr>DoH (DNS</abbr> over HTTPS) habilitado.
  
# use a specific local timedelta sensor (radio clock, etc)
+
== Monitoramento[editar | editar código-fonte] ==
#sensor nmea0
+
O monitoramento é algo bem específico e não é o foco deste documento mas é extremamente importante que você monitore seus servidores de DNS por alguma ferramenta como o Zabbix. Aqui mostrarei apenas como enviar as informações para o Zabbix. Algumas coisas que você deveria monitorar nos servidores de DNS Recursivo:
 
+
* Serviço do unbound parou.
# use all detected timedelta sensors
+
* Perda de pacotes.
#sensor *
+
* Latência alta de pacotes.
</pre>
+
* Lentidão na resolução de queries.
 
+
* CPU alta.
=== Configurando a rede ===
+
* Load alto.
'''/etc/network/interfaces:'''
+
* Memória com uso alto.
<pre>
+
* Disco com pouco espaço.
# This file describes the network interfaces available on your system
+
* Queda brusca nas queries.
# and how to activate them. For more information, see interfaces(5).
+
* A recursividade parou de funcionar.
 
+
* A recursividade voltou a funcionar.
source /etc/network/interfaces.d/*
+
Este abaixo é um exemplo de monitoramento de um sistema de DNS Recursivo que atende 50.000 assinantes:
 
 
# The loopback network interface
 
auto lo
 
iface lo inet loopback
 
 
 
auto lo:0
 
iface lo:0 inet static
 
      address 10.10.10.10/32
 
 
 
iface lo:0 inet6 static
 
      address fc00::10:10:10:10
 
      netmask 128
 
 
 
# The primary network interface
 
auto ens160
 
iface ens160 inet static
 
        address 192.0.2.2/30
 
        gateway 192.0.2.1
 
 
 
iface ens160 inet6 static
 
        address 2001:db8::192:0:2:2
 
        netmask 64
 
        gateway 2001:db8::192:0:2:1
 
 
 
</pre>
 
 
 
=== Configurando o FRR e a sessão BGP com o router ===
 
Em '''/etc/frr/daemons''' modifique o valor '''bgpd=no''' para '''bgpd=yes''', dessa forma habilitaremos o BGP no FRR. Feito isso precisaremos reiniciar o serviço frr:<pre>
 
# systemctl restart frr.service
 
</pre>Nosso arquivo '''/etc/frr/frr.conf''' ficará assim:
 
frr version 7.5
 
frr defaults traditional
 
hostname unbound1
 
log syslog informational
 
no ip forwarding
 
no ipv6 forwarding
 
service integrated-vtysh-config
 
!
 
router bgp 65000
 
  bgp router-id 192.0.2.2
 
  no bgp ebgp-requires-policy
 
  no bgp network import-check
 
  neighbor 192.0.2.1 remote-as 65000
 
  neighbor 2001:db8::192:0:2:1 remote-as 65000
 
  !
 
  address-family ipv4 unicast
 
  network 10.10.10.10/32
 
  neighbor 192.0.2.1 prefix-list BLOQUEIA-TUDO in
 
  neighbor 192.0.2.1 prefix-list RECURSIVO out
 
  exit-address-family
 
  !
 
  address-family ipv6 unicast
 
  network fc00::10:10:10:10/128
 
  neighbor 2001:db8::192:0:2:1 activate
 
  neighbor 2001:db8::192:0:2:1 prefix-list BLOQUEIA-TUDO_V6 in
 
  neighbor 2001:db8::192:0:2:1 prefix-list RECURSIVO_V6 out
 
  exit-address-family
 
!
 
ip prefix-list BLOQUEIA-TUDO seq 5 deny any
 
ip prefix-list RECURSIVO seq 5 permit 10.10.10.10/32
 
!
 
ipv6 prefix-list BLOQUEIA-TUDO_V6 seq 5 deny any
 
ipv6 prefix-list RECURSIVO_V6 seq 5 permit fc00::10:10:10:10/128
 
!
 
line vty
 
!
 
Após configurar a sessão BGP no lado do router, verifique se as sessões foram estabelecidas IPv4 e IPv6. No nosso servidor podemos checar assim:<pre>
 
# vtysh -c 'show bgp summary'
 
</pre>Deve exibir algo parecido assim:
 
IPv4 Unicast Summary:
 
BGP router identifier 192.0.2.2, local AS number 65000 vrf-id 0
 
BGP table version 1
 
RIB entries 1, using 192 bytes of memory
 
Peers 2, using 43 KiB of memory
 
 
Neighbor        V        AS  MsgRcvd  MsgSent  TblVer  InQ OutQ  Up/Down State/PfxRcd  PfxSnt
 
192.0.2.1      4      65000    427529    407165        0    0    0 20w1d08h            0        1
 
2001:db8::192:0:2:1 4      65000    427517    407160        0    0    0 20w1d08h NoNeg
 
 
Total number of neighbors 2
 
 
IPv6 Unicast Summary:
 
BGP router identifier 192.0.2.2, local AS number 65000 vrf-id 0
 
BGP table version 1
 
RIB entries 1, using 192 bytes of memory
 
Peers 1, using 21 KiB of memory
 
 
Neighbor        V        AS  MsgRcvd  MsgSent  TblVer  InQ OutQ  Up/Down State/PfxRcd  PfxSnt
 
2001:db8::192:0:2:1 4      65000    427517    407160        0    0    0 20w1d08h            0        1
 
 
Total number of neighbors 1
 
Podemos observar que não estamos recebendo nenhum prefixo do router e estamos apenas anunciando 1 prefixo IPv4 e 1 IPv6. Vejamos quais são:
 
# vtysh -c 'show ip bgp neighbors 192.0.2.1 advertised-routes'
 
BGP table version is 1, local router ID is 192.0.2.2, vrf id 0
 
Default local pref 100, local AS 65000
 
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
 
                i internal, r RIB-failure, S Stale, R Removed
 
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
 
Origin codes:  i - IGP, e - EGP, ? - incomplete
 
 
    Network          Next Hop            Metric LocPrf Weight Path
 
*> 10.10.10.10/32  0.0.0.0                  0    100  32768 i
 
 
Total number of prefixes 1
 
 
 
# vtysh -c 'show ip bgp ipv6 neighbors 2001:db8::192:0:2:1 advertised-routes'
 
BGP table version is 1, local router ID is 192.0.2.2, vrf id 0
 
Default local pref 100, local AS 65000
 
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
 
                i internal, r RIB-failure, S Stale, R Removed
 
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
 
Origin codes:  i - IGP, e - EGP, ? - incomplete
 
 
    Network          Next Hop            Metric LocPrf Weight Path
 
*> fc00::10:10:10:10/128
 
                    ::                      0    100  32768 i
 
 
Total number of prefixes 1
 
Podemos observar que nossos IPs já estão sendo anunciados para o router e vocês devem checar se estão sendo recebidos pelo router. Não estamos entrando em detalhes na parte do router pois este pode ser de qualquer fabricante como por exemplo: Cisco, Huawei, Juniper, Mikrotik, outro FRR, etc.
 
 
 
=== Configurando o Unbound ===
 
Não entraremos em detalhes sobre cada parâmetro da configuração do Unbound, porque isso fugiria bastante do objetivo deste artigo. Ao invés disso, criaremos o arquivo '''/etc/unbound/unbound.conf.d/local.conf''' e dentro dele teremos o seguinte:
 
server:
 
        verbosity: 1
 
        statistics-interval: 0
 
        statistics-cumulative: no
 
        extended-statistics: yes
 
        num-threads: 4
 
        interface: 127.0.0.1
 
        interface: 10.10.10.10
 
        interface: fc00::10:10:10:10
 
        interface: ::1
 
        interface-automatic: no
 
        outgoing-interface: 192.0.2.2
 
        outgoing-interface: 2001:db8::192:0:2:2
 
        outgoing-range: 8192
 
        outgoing-num-tcp: 20
 
        incoming-num-tcp: 20
 
        so-rcvbuf: 4m
 
        so-sndbuf: 4m
 
        edns-buffer-size: 1232
 
        msg-cache-size: 100m
 
        msg-cache-slabs: 4
 
        num-queries-per-thread: 8192
 
        rrset-cache-size: 200m
 
        rrset-cache-slabs: 4
 
        infra-cache-slabs: 4
 
        do-ip4: yes
 
        do-ip6: yes
 
        do-udp: yes
 
        do-tcp: yes
 
        access-control: 203.0.113.0/24 allow
 
        access-control: 2001:db8:1111::/48 allow
 
        chroot: ""
 
        username: "unbound"
 
        directory: "/etc/unbound"
 
        logfile: "/var/log/unbound/unbound.log"
 
        use-syslog: no
 
        log-time-ascii: yes
 
        log-queries: no
 
        pidfile: "/var/run/unbound.pid"
 
        root-hints: "/etc/unbound/named.cache"
 
        hide-identity: yes
 
        hide-version: yes
 
        unwanted-reply-threshold: 10000000
 
        prefetch: yes
 
        prefetch-key: yes
 
        rrset-roundrobin: yes
 
        minimal-responses: yes
 
        val-clean-additional: yes
 
        val-log-level: 1
 
        key-cache-slabs: 4
 
 
python:
 
 
remote-control:
 
        control-enable: yes
 
        server-key-file: "/etc/unbound/unbound_server.key"
 
        server-cert-file: "/etc/unbound/unbound_server.pem"
 
        control-key-file: "/etc/unbound/unbound_control.key"
 
        control-cert-file: "/etc/unbound/unbound_control.pem"
 
 
auth-zone:
 
    name: "."
 
    master: "b.root-servers.net"
 
    master: "c.root-servers.net"
 
    master: "f.root-servers.net"
 
    master: "g.root-servers.net"
 
    master: "k.root-servers.net"
 
    master: "lax.xfr.dns.icann.org"
 
    master: "iad.xfr.dns.icann.org"
 
    fallback-enabled: yes
 
    for-downstream: no
 
    for-upstream: yes
 
    zonefile: "/var/lib/unbound/root.zone"
 
Os parâmetros relevantes acima são:
 
Como nosso servidor possui 4 cores, colocamos 4 em num-threads também:
 
        num-threads: 4
 
 
O interface indica quais IPs ficarão escutando o serviço na porta 53/udp/tcp para serem consultados pelo servidor e assinantes:
 
        interface: 127.0.0.1
 
        interface: 10.10.10.10
 
        interface: fc00::10:10:10:10
 
        interface: ::1
 
 
O outgoing-interface indica por quais IPs serão feitas as consultas de DNS para o mundo:
 
        outgoing-interface: 192.0.2.2
 
        outgoing-interface: 2001:db8::192:0:2:2
 
 
Habilita consultas IPv4 e IPv6, udp e tcp:
 
        do-ip4: yes
 
        do-ip6: yes
 
        do-udp: yes
 
        do-tcp: yes
 
 
Libera a consulta DNS para origem desses prefixos, troque pelos prefixos reais do seu ASN:
 
        access-control: 203.0.113.0/24 allow
 
        access-control: 2001:db8:1111::/48 allow
 
 
Esse trecho abaixo é referente à configuração do Hyperlocal:
 
 
auth-zone:
 
    name: "."
 
    master: "b.root-servers.net"
 
    master: "c.root-servers.net"
 
    master: "f.root-servers.net"
 
    master: "g.root-servers.net"
 
    master: "k.root-servers.net"
 
    master: "lax.xfr.dns.icann.org"
 
    master: "iad.xfr.dns.icann.org"
 
    fallback-enabled: yes
 
    for-downstream: no
 
    for-upstream: yes
 
    zonefile: "/var/lib/unbound/root.zone"
 
 
 
Após a configuração do Unbound basta reiniciar o serviço unbound e verificar se o arquivo '''/var/lib/unbound/root.zone''' foi criado com o conteúdo dos Root Servers.
 
 
 
Vamos alterar o '''/etc/resolv.conf''' para acertar as consultas locais e diminuir o timeout que precisaremos mais a frente no script que fará o teste se o DNS continua funcionando e em caso negativo, retirar o anúncio dos IPs:<pre>
 
nameserver 127.0.0.1
 
nameserver ::1
 
options timeout:1 attempts:1
 
</pre>
 
Feito isso teste se seu servidor está resolvendo os hosts na Internet por exemplo:
 
# host www.uol.com.br 127.0.0.1
 
Using domain server:
 
Name: 127.0.0.1
 
Address: 127.0.0.1#53
 
Aliases:
 
 
www.uol.com.br is an alias for dftex7xfha8fh.cloudfront.net.
 
dftex7xfha8fh.cloudfront.net has address 99.84.22.115
 
dftex7xfha8fh.cloudfront.net has address 99.84.22.71
 
dftex7xfha8fh.cloudfront.net has address 99.84.22.8
 
dftex7xfha8fh.cloudfront.net has address 99.84.22.27
 
dftex7xfha8fh.cloudfront.net has IPv6 address 2600:9000:21ed:6200:1:5a19:8b40:93a1
 
dftex7xfha8fh.cloudfront.net has IPv6 address 2600:9000:21ed:f000:1:5a19:8b40:93a1
 
dftex7xfha8fh.cloudfront.net has IPv6 address 2600:9000:21ed:f400:1:5a19:8b40:93a1
 
dftex7xfha8fh.cloudfront.net has IPv6 address 2600:9000:21ed:7800:1:5a19:8b40:93a1
 
dftex7xfha8fh.cloudfront.net has IPv6 address 2600:9000:21ed:ac00:1:5a19:8b40:93a1
 
dftex7xfha8fh.cloudfront.net has IPv6 address 2600:9000:21ed:8a00:1:5a19:8b40:93a1
 
dftex7xfha8fh.cloudfront.net has IPv6 address 2600:9000:21ed:f200:1:5a19:8b40:93a1
 
dftex7xfha8fh.cloudfront.net has IPv6 address 2600:9000:21ed:fc00:1:5a19:8b40:93a1
 
 
# host www.terra.com.br ::1
 
Using domain server:
 
Name: ::1
 
Address: ::1#53
 
Aliases:
 
 
www.terra.com.br is an alias for www.terra.com.br.edgesuite.net.
 
www.terra.com.br.edgesuite.net is an alias for a1799.dscb.akamai.net.
 
a1799.dscb.akamai.net has address 23.73.211.226
 
a1799.dscb.akamai.net has address 23.73.211.186
 
a1799.dscb.akamai.net has IPv6 address 2600:1419:d400::1749:d78a
 
a1799.dscb.akamai.net has IPv6 address 2600:1419:d400::1749:d7d9
 
Ok funcionando e resolvendo tanto via IPv4 quanto via IPv6. Caso queira testar localmente com os IPs '''10.10.10.10''' e '''fc00::10:10:10:10''' você terá que adicioná-los no nosso '''local.conf''' do Unbound no parâmetro '''access-control''' liberando o '''10.10.10.10/32''' e '''fc00::10:10:10:10/128'''. Você também pode usar o programa '''dig''' para testar seu DNS recursivo:
 
# apt install bind9-dnsutils
 
 
 
# dig @127.0.0.1 www.terra.com.br
 
 
; <<>> DiG 9.16.15-Debian <<>> @127.0.0.1 www.terra.com.br
 
; (1 server found)
 
;; global options: +cmd
 
;; Got answer:
 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33258
 
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
 
 
;; OPT PSEUDOSECTION:
 
; EDNS: version: 0, flags:; udp: 1232
 
;; QUESTION SECTION:
 
;www.terra.com.br.              IN      A
 
 
;; ANSWER SECTION:
 
www.terra.com.br.      58      IN      CNAME  www.terra.com.br.edgesuite.net.
 
www.terra.com.br.edgesuite.net. 21512 IN CNAME  a1799.dscb.akamai.net.
 
a1799.dscb.akamai.net.  18      IN      A      23.196.224.219
 
a1799.dscb.akamai.net.  18      IN      A      23.196.225.9
 
 
;; Query time: 0 msec
 
;; SERVER: 127.0.0.1#53(127.0.0.1)
 
;; WHEN: qua jun 30 10:09:19 -03 2021
 
;; MSG SIZE  rcvd: 153
 
 
 
# dig @::1 www.terra.com.br
 
 
; <<>> DiG 9.16.15-Debian <<>> @::1 www.terra.com.br
 
; (1 server found)
 
;; global options: +cmd
 
;; Got answer:
 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63261
 
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
 
 
;; OPT PSEUDOSECTION:
 
; EDNS: version: 0, flags:; udp: 1232
 
;; QUESTION SECTION:
 
;www.terra.com.br.              IN      A
 
 
;; ANSWER SECTION:
 
www.terra.com.br.      17      IN      CNAME  www.terra.com.br.edgesuite.net.
 
www.terra.com.br.edgesuite.net. 21471 IN CNAME  a1799.dscb.akamai.net.
 
a1799.dscb.akamai.net.  17      IN      A      23.196.225.9
 
a1799.dscb.akamai.net.  17      IN      A      23.196.224.219
 
 
;; Query time: 0 msec
 
;; SERVER: ::1#53(::1)
 
;; WHEN: qua jun 30 10:10:00 -03 2021
 
;; MSG SIZE  rcvd: 153
 
 
Vamos testar se nosso Hyperlocal está funcionando? Vamos fazer uma consulta de um host com nome absurdo e que não existe na Internet, sem o Hyperlocal habilitado:
 
# dig @127.0.0.1 wws.sssss.ssss
 
 
; <<>> DiG 9.16.15-Debian <<>> @127.0.0.1 wws.sssss.ssss
 
; (1 server found)
 
;; global options: +cmd
 
;; Got answer:
 
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 51541
 
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
 
 
;; OPT PSEUDOSECTION:
 
; EDNS: version: 0, flags:; udp: 1232
 
;; QUESTION SECTION:
 
;wws.sssss.ssss.                        IN      A
 
 
;; AUTHORITY SECTION:
 
.                      3600    IN      SOA    a.root-servers.net. nstld.verisign-grs.com. 2021063000 1800 900 604800 86400
 
 
;; Query time: 312 msec
 
;; SERVER: 127.0.0.1#53(127.0.0.1)
 
;; WHEN: qua jun 30 10:49:24 -03 2021
 
;; MSG SIZE  rcvd: 118
 
 
Repare que a resposta do Root Server levou 312 msec. Agora vamos fazer a mesma consulta com o Hyperlocal habilitado e unbound reiniciado:
 
# dig @127.0.0.1 wws.sssss.ssss
 
 
; <<>> DiG 9.16.15-Debian <<>> @127.0.0.1 wws.sssss.ssss
 
; (1 server found)
 
;; global options: +cmd
 
;; Got answer:
 
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 48429
 
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
 
 
;; OPT PSEUDOSECTION:
 
; EDNS: version: 0, flags:; udp: 1232
 
;; QUESTION SECTION:
 
;wws.sssss.ssss.                        IN      A
 
 
;; AUTHORITY SECTION:
 
.                      86397  IN      SOA    a.root-servers.net. nstld.verisign-grs.com. 2021063000 1800 900 604800 86400
 
 
;; Query time: 0 msec
 
;; SERVER: 127.0.0.1#53(127.0.0.1)
 
;; WHEN: qua jun 30 10:52:21 -03 2021
 
;; MSG SIZE  rcvd: 118
 
Com as tabelas locais, a mesma consulta levou 0 msec. Muito bom não é mesmo?
 
 
 
Próximo passo é configurar os IPs '''10.10.10.10''' e '''fc00::10:10:10:10''' em algum dispositivo ou estação da rede e testar se está funcionando a resolução de nomes. Se chegamos até aqui com tudo funcionando então perfeito.
 
 
 
Vamos configurar agora um script que vai checar se o nosso DNS parou de resolver nomes e se isso ocorrer, ele deixará de anunciar os IPs de DNS para o router. Nesse caso o outro DNS continuará respondendo com os mesmos IPs.
 
 
 
=== Script do Servidor 1 ===
 
'''/root/teste_dns.sh'''
 
#!/usr/bin/env bash
 
<nowiki>#</nowiki>Script para teste de DNS v1.2
 
<nowiki>#</nowiki>-----------------------------------------------------------------------
 
<nowiki>#</nowiki>Informe um domínio por linha:
 
dominios_testar=(
 
www.google.com
 
www.terra.com.br
 
www.uol.com.br
 
www.globo.com
 
www.facebook.com
 
www.youtube.com
 
www.twitch.com
 
www.discord.com
 
www.debian.org
 
www.redhat.com
 
)
 
corte_taxa_falha=100 #Porcentagem de falha para executar uma ação
 
<nowiki>#</nowiki>-----------------------------------------------------------------------
 
qt_falhas=0
 
qt_total="${#dominios_testar[@]}"
 
echo "total_dominios: $qt_total"
 
for site in "${dominios_testar[@]}"
 
do
 
<nowiki> </nowiki> resp=<nowiki>''</nowiki>
 
<nowiki> </nowiki> resolver="127.0.0.1"
 
<nowiki> </nowiki> echo " - dominio $site - $resolver"
 
<nowiki> </nowiki> resp=$( host $site $resolver | grep "connection timed out" )
 
<nowiki> </nowiki> if [ ! -z "$resp" ]; then
 
<nowiki> </nowiki>    ((qt_falhas++))
 
<nowiki> </nowiki>    echo "[$resp]"
 
<nowiki> </nowiki> fi
 
done
 
 
taxa_falha=$((qt_falhas*100/qt_total))
 
echo "Falhas $qt_falhas/$qt_total ($taxa_falha%)"
 
 
if [ "$taxa_falha" -ge "$corte_taxa_falha" ]; then
 
<nowiki> </nowiki>  habilitado="`vtysh -c 'show run' | grep \"neighbor 192.0.2.1 prefix-list BLOQUEIA-TUDO out\"`"
 
<nowiki> </nowiki>  if [ "$habilitado" == "" ]; then
 
<nowiki> </nowiki>    vtysh -c 'conf t' -c 'router bgp 65000' -c 'address-family ipv4 unicast' -c 'no neighbor 192.0.2.1 prefix-list RECURSIVO out' -c 'neighbor 192.0.2.1 prefix-list BLOQUEIA-TUDO out' -c 'end' -c 'wr'
 
<nowiki> </nowiki>    vtysh -c 'conf t' -c 'router bgp 65000' -c 'address-family ipv6 unicast' -c 'no neighbor 2001:db8::192:0:2:1 prefix-list RECURSIVO_V6 out' -c 'neighbor 2001:db8::192:0:2:1 prefix-list BLOQUEIA-TUDO out' -c 'end' -c 'wr'
 
<nowiki> </nowiki>    echo "caiu: `date`" >> /root/dnsreport.log
 
<nowiki> </nowiki>  fi
 
<nowiki> </nowiki>  exit
 
fi
 
 
habilitado="`vtysh -c 'show run' | grep \"neighbor 192.0.2.1 prefix-list RECURSIVO out\"`"
 
if [ "$habilitado" == "" ]; then
 
<nowiki> </nowiki>  vtysh -c 'conf t' -c 'router bgp 65000' -c 'address-family ipv4 unicast' -c 'no neighbor 192.0.2.1 prefix-list BLOQUEIA-TUDO out' -c 'neighbor 192.0.2.1 prefix-list RECURSIVO out' -c 'end' -c 'wr'
 
<nowiki> </nowiki>  vtysh -c 'conf t' -c 'router bgp 65000' -c 'address-family ipv6 unicast' -c 'no neighbor 2001:db8::192:0:2:1 prefix-list BLOQUEIA-TUDO out' -c 'neighbor 2001:db8::192:0:2:1 prefix-list RECURSIVO_V6 out' -c 'end' -c 'wr'
 
<nowiki> </nowiki>  echo "voltou: `date`" >> /root/dnsreport.log
 
fi
 
 
 
Sim. Para entender o que está escrito acima você precisa conhecer um pouco de linguagem de shell script em bash. Fique à vontade em melhorar ou até mesmo criar seu próprio script em outra linguagem. O conceito é bem simples e usado apenas para testar se nosso DNS está resolvendo pra fora. Porque você pode não estar conseguindo, por algum motivo, consultar na Internet pelas portas '''53/udp''' e/ou '''53/tcp''' e que poderia ser causado por algum bloqueio ou problema de fato na rede. Caso is aconteça usaremos os comandos '''vtysh''' via shell, para alterar a nossa configuração no FRR e bloquear os anúncios. Uma outra coisa que fica como dever de casa: no script ele gera um relatório de quando tem problema no DNS e quando volta a funcionar. Você pode pesquisar e utilizar os pacotes do Debian '''msmtp''' e '''msmtp-mta''', configurar ele e o script para enviar um e-mail em caso de problemas. Como não sou mau, você pode achar informação sobre isso, nos slides de uma palestra que apresentei no '''[https://www.youtube.com/watch?v=Wz2IAg6MMlU FiqueEmCasaUseDebian]''' bem [https://debianbrasil.gitlab.io/FiqueEmCasaUseDebian/arquivos/2020-05-29-sysadmin-apps-ferramentas-uteis-para-sysadmins.pdf aqui].
 
 
 
Vamos agora colocar o script para rodar no cron adicionando a seguinte linha em /etc/crontab:<pre>
 
*/1 *  * * *  root    /root/teste_dns.sh
 
</pre>Terminamos aqui o Servidor 1 de DNS Anycast com Hyperlocal. Para configurar o servidor 2, basta fazer os mesmos procedimentos usados no servidor 1 mas mudando os dados de conexão. Vou colocar abaixo apenas as configurações que serão diferentes.
 
 
 
== Instalação e configuração do Servidor 2 - apenas as diferenças ==
 
 
 
=== Configurando a rede ===
 
'''/etc/network/interfaces:'''
 
# This file describes the network interfaces available on your system
 
# and how to activate them. For more information, see interfaces(5).
 
 
source /etc/network/interfaces.d/*
 
 
# The loopback network interface
 
auto lo
 
iface lo inet loopback
 
 
auto lo:0
 
iface lo:0 inet static
 
      address 10.10.10.10/32
 
 
iface lo:0 inet6 static
 
      address fc00::10:10:10:10
 
      netmask 128
 
 
# The primary network interface
 
auto ens160
 
iface ens160 inet static
 
        address 192.0.2.6/30
 
        gateway 192.0.2.5
 
 
iface ens160 inet6 static
 
        address 2001:db8:aaaa::192:0:2:6
 
        netmask 64
 
        gateway 2001:db8:aaaa::192:0:2:5
 
 
 
 
 
=== Configurando o FRR e a sessão BGP com o router ===
 
Em '''/etc/frr/daemons''' modifique o valor '''bgpd=no''' para '''bgpd=yes''', dessa forma habilitaremos o BGP no FRR. Feito isso precisaremos reiniciar o serviço frr:
 
# systemctl restart frr.service
 
Nosso arquivo '''/etc/frr/frr.conf''' ficará assim:
 
frr version 7.5
 
frr defaults traditional
 
hostname unbound2
 
log syslog informational
 
no ip forwarding
 
no ipv6 forwarding
 
service integrated-vtysh-config
 
!
 
router bgp 65000
 
  bgp router-id 192.0.2.6
 
  no bgp ebgp-requires-policy
 
  no bgp network import-check
 
  neighbor 192.0.2.5 remote-as 65000
 
  neighbor 2001:db8:aaaa::192:0:2:5 remote-as 65000
 
 !
 
  address-family ipv4 unicast
 
  network 10.10.10.10/32
 
  neighbor 192.0.2.5 prefix-list BLOQUEIA-TUDO in
 
  neighbor 192.0.2.5 prefix-list RECURSIVO out
 
  exit-address-family
 
 !
 
  address-family ipv6 unicast
 
  network fc00::10:10:10:10/128
 
  neighbor 2001:db8:aaaa::192:0:2:5 activate
 
  neighbor 2001:db8:aaaa::192:0:2:5 prefix-list BLOQUEIA-TUDO_V6 in
 
  neighbor 2001:db8:aaaa::192:0:2:5 prefix-list RECURSIVO_V6 out
 
  exit-address-family
 
!
 
ip prefix-list BLOQUEIA-TUDO seq 5 deny any
 
ip prefix-list RECURSIVO seq 5 permit 10.10.10.10/32
 
!
 
ipv6 prefix-list BLOQUEIA-TUDO_V6 seq 5 deny any
 
ipv6 prefix-list RECURSIVO_V6 seq 5 permit fc00::10:10:10:10/128
 
!
 
line vty
 
!
 
 
 
=== Configurando o Unbound ===
 
Não entraremos em detalhes sobre cada parâmetro da configuração do Unbound, porque isso fugiria bastante do objetivo deste artigo. Ao invés disso, criaremos o arquivo '''/etc/unbound/unbound.conf.d/local.conf''' e dentro dele teremos o seguinte:
 
server:
 
        verbosity: 1
 
        statistics-interval: 0
 
        statistics-cumulative: no
 
        extended-statistics: yes
 
        num-threads: 4
 
        interface: 127.0.0.1
 
        interface: 10.10.10.10
 
        interface: fc00::10:10:10:10
 
        interface: ::1
 
        interface-automatic: no
 
        outgoing-interface: 192.0.2.6
 
        outgoing-interface: 2001:db8:aaaa::192:0:2:6
 
        outgoing-range: 8192
 
        outgoing-num-tcp: 20
 
        incoming-num-tcp: 20
 
        so-rcvbuf: 4m
 
        so-sndbuf: 4m
 
        edns-buffer-size: 1232
 
        msg-cache-size: 100m
 
        msg-cache-slabs: 4
 
        num-queries-per-thread: 8192
 
        rrset-cache-size: 200m
 
        rrset-cache-slabs: 4
 
        infra-cache-slabs: 4
 
        do-ip4: yes
 
        do-ip6: yes
 
        do-udp: yes
 
        do-tcp: yes
 
        access-control: 203.0.113.0/24 allow
 
        access-control: 2001:db8:1111::/48 allow
 
        chroot: ""
 
        username: "unbound"
 
        directory: "/etc/unbound"
 
        logfile: "/var/log/unbound/unbound.log"
 
        use-syslog: no
 
        log-time-ascii: yes
 
        log-queries: no
 
        pidfile: "/var/run/unbound.pid"
 
        root-hints: "/etc/unbound/named.cache"
 
        hide-identity: yes
 
        hide-version: yes
 
        unwanted-reply-threshold: 10000000
 
        prefetch: yes
 
        prefetch-key: yes
 
        rrset-roundrobin: yes
 
        minimal-responses: yes
 
        val-clean-additional: yes
 
        val-log-level: 1
 
        key-cache-slabs: 4
 
 
python:
 
 
remote-control:
 
        control-enable: yes
 
        server-key-file: "/etc/unbound/unbound_server.key"
 
        server-cert-file: "/etc/unbound/unbound_server.pem"
 
        control-key-file: "/etc/unbound/unbound_control.key"
 
        control-cert-file: "/etc/unbound/unbound_control.pem"
 
 
auth-zone:
 
    name: "."
 
    master: "b.root-servers.net"
 
    master: "c.root-servers.net"
 
    master: "f.root-servers.net"
 
    master: "g.root-servers.net"
 
    master: "k.root-servers.net"
 
    master: "lax.xfr.dns.icann.org"
 
    master: "iad.xfr.dns.icann.org"
 
    fallback-enabled: yes
 
    for-downstream: no
 
    for-upstream: yes
 
    zonefile: "/var/lib/unbound/root.zone"
 
=== Script do Servidor 2 ===
 
'''/root/teste_dns.sh'''
 
#!/usr/bin/env bash
 
<nowiki>#</nowiki>Script para teste de DNS v1.2
 
<nowiki>#</nowiki>-----------------------------------------------------------------------
 
<nowiki>#</nowiki>Informe um domínio por linha:
 
dominios_testar=(
 
www.google.com
 
www.terra.com.br
 
www.uol.com.br
 
www.globo.com
 
www.facebook.com
 
www.youtube.com
 
www.twitch.com
 
www.discord.com
 
www.debian.org
 
www.redhat.com
 
)
 
corte_taxa_falha=100 #Porcentagem de falha para executar uma ação
 
<nowiki>#</nowiki>-----------------------------------------------------------------------
 
qt_falhas=0
 
qt_total="${#dominios_testar[@]}"
 
echo "total_dominios: $qt_total"
 
for site in "${dominios_testar[@]}"
 
do
 
<nowiki> </nowiki> resp=<nowiki>''</nowiki>
 
<nowiki> </nowiki> resolver="127.0.0.1"
 
<nowiki> </nowiki> echo " - dominio $site - $resolver"
 
<nowiki> </nowiki> resp=$( host $site $resolver | grep "connection timed out" )
 
<nowiki> </nowiki> if [ ! -z "$resp" ]; then
 
<nowiki> </nowiki>    ((qt_falhas++))
 
<nowiki> </nowiki>    echo "[$resp]"
 
<nowiki> </nowiki> fi
 
done
 
 
taxa_falha=$((qt_falhas*100/qt_total))
 
echo "Falhas $qt_falhas/$qt_total ($taxa_falha%)"
 
 
if [ "$taxa_falha" -ge "$corte_taxa_falha" ]; then
 
<nowiki> </nowiki>  habilitado="`vtysh -c 'show run' | grep \"neighbor 192.0.2.5 prefix-list BLOQUEIA-TUDO out\"`"
 
<nowiki> </nowiki>  if [ "$habilitado" == "" ]; then
 
<nowiki> </nowiki>    vtysh -c 'conf t' -c 'router bgp 65000' -c 'address-family ipv4 unicast' -c 'no neighbor 192.0.2.5 prefix-list RECURSIVO out' -c 'neighbor 192.0.2.5 prefix-list BLOQUEIA-TUDO out' -c 'end' -c 'wr'
 
<nowiki> </nowiki>    vtysh -c 'conf t' -c 'router bgp 65000' -c 'address-family ipv6 unicast' -c 'no neighbor 2001:db8:aaaa::192:0:2:5 prefix-list RECURSIVO_V6 out' -c 'neighbor 2001:db8:aaaa::192:0:2:5 prefix-list BLOQUEIA-TUDO out' -c 'end' -c 'wr'
 
<nowiki> </nowiki>    echo "caiu: `date`" >> /root/dnsreport.log
 
<nowiki> </nowiki>  fi
 
<nowiki> </nowiki>  exit
 
fi
 
 
habilitado="`vtysh -c 'show run' | grep \"neighbor 192.0.2.5 prefix-list RECURSIVO out\"`"
 
if [ "$habilitado" == "" ]; then
 
<nowiki> </nowiki>  vtysh -c 'conf t' -c 'router bgp 65000' -c 'address-family ipv4 unicast' -c 'no neighbor 192.0.2.5 prefix-list BLOQUEIA-TUDO out' -c 'neighbor 192.0.2.5 prefix-list RECURSIVO out' -c 'end' -c 'wr'
 
<nowiki> </nowiki>  vtysh -c 'conf t' -c 'router bgp 65000' -c 'address-family ipv6 unicast' -c 'no neighbor 2001:db8:aaaa::192:0:2:5 prefix-list BLOQUEIA-TUDO out' -c 'neighbor 2001:db8:aaaa::192:0:2:5 prefix-list RECURSIVO_V6 out' -c 'end' -c 'wr'
 
<nowiki> </nowiki>  echo "voltou: `date`" >> /root/dnsreport.log
 
fi
 
Chegamos ao final deste artigo e espero que tenha sido útil para a comunidade. Lembre-se que temos que pensar no futuro da Internet e é muito importante que usemos IPv6 em todas as nossas implementações de rede, sejam servidores, equipamentos ou aplicações.
 
  
 
Autor: [[Usuário:Gondim|Marcelo Gondim]]
 
Autor: [[Usuário:Gondim|Marcelo Gondim]]
 
[[Categoria:Infraestrutura]]
 
[[Categoria:Infraestrutura]]
 
__FORCARTDC__
 
__FORCARTDC__

Edição das 20h51min de 12 de março de 2023

Introdução

Você sabe como funciona a Internet? Essa é uma pergunta que meu amigo Thiago Ayub sempre faz aos seus candidatos à vagas de emprego e não importa o quanto tenham de experiência em Engenharia de Redes, todos sempre travam nesse momento. Todos estão sempre prontos e preparados para resolver os problemas mais cabeludos em BGP, OSPF, MPLS, etc mas travam com essa simples pergunta. Para contextualizar e visualizarmos melhor vamos nos atentar à imagem abaixo e uma explicação simplificada de como funciona:

Como funciona a Internet.png

Tudo começa com um usuário sentado confortavelmente e querendo acessar um conteúdo disponível na Internet. Ele digita em seu navegador preferido a URL: https://wiki.ispconfig.com.br, nesse momento seta 1, o navegador irá requisitar do DNS Recursivo utilizado pelo usuário, qual o IP responde pelo hostname wiki.ispup.com.br. Isso porque todos os acessos se dão na Internet através do IP Address e não através do hostname. Imaginem se tivéssemos que decorar os IPs de todos os sites e serviços que quiséssemos acessar na Internet? Só que a primeira vez que consultamos um hostname, o DNS Recursivo não tem a resposta de imediato porque ele não é o dono dessa informação. Então ele faz o trabalho de buscar e consultar o DNS Autoritativo, responsável por aquele domínio em questão ispup.com.br e vemos isso na seta 2. O DNS Autoritativo sabe quais são os IPs que respondem pelo hostname wiki.ispup.com.br e devolve a informação para o DNS Recursivo, seta 3. Na sequência, seta 4, o DNS Recursivo devolve para o navegador do usuário, o IP Address do wiki.ispup.com.br e que pode ser mais de um e de famílias diferentes como IPv4 e IPv6. Cabe ao navegador decidir por qual acessar mas normalmente a preferência é sempre por IPv6, se houver conectividade IPv6 entre o usuário e o conteúdo acessado. Por último, seta 5, o navegador faz o acesso ao site wiki.ispup.com.br através do IP Address.

Como que se dá a comunicação entre os DNS(s) Recursivos e Autoritativos? Como que o navegador do usuário, após receber o IP do site, consegue chegar no servidor que tem o conteúdo? Isso só é possível devido ao protocolo chamado BGP (Border Gateway Protocol), todos os caminhos que conhecemos como rotas de destino, são anunciadas por milhares de participantes na Internet conhecidos como AS (Autonomous System), esses participantes se interligam para disponibilizar conteúdos e acessos pelo mundo aos milhares de usuários. É uma imensa rede colaborativa formada por Empresas, Universidades, Governos e todos que queiram se interconectar. Percebam que sem o BGP, que serve de caminho para chegarmos nos conteúdos e sem o DNS (Domain Name System) para traduzir o hostname para o IP Address, a Internet não funcionaria e por isso precisamos cuidar muito bem desses dois serviços.

Mas não acaba por aí. O DNS Recursivo tem um papel muito importante para o Provedor de Internet e que envolve segurança, qualidade de acesso à Internet e a disponibilidade do serviço entregue ao cliente. Quando bem configurado acelera as consultas dos acessos graças ao seu cache interno, mas para que isso seja percebido pelo assinante, é necessário que esteja o mais próximo possível do seu cliente.

Um erro que destrói a qualidade do nosso serviço[editar | editar código-fonte]

Um erro muito comum que muitas operadoras cometem é utilizar DNS Recursivo externo, como o 8.8.8.8, 1.1.1.1 e outros, para seus clientes. Quanto mais próximo dos seus clientes, mais qualidade de serviço estará entregando a eles. Conteúdos serão entregues mais rapidamente pois serão resolvidos e armazenados em caches locais e não consultados remotamente na Internet. Para falar mais sobre isso, te convido leitor desse documento, que assista essa palestra do Thiago Ayub no GTER 51/GTS 37 (2022) 8.888 MOTIVOS PARA NÃO USAR DNS RECURSIVO EXTERNO EM SEU AS: https://www.youtube.com/watch?v=Rsvpu5uF2Io

Objetivo[editar | editar código-fonte]

O objetivo desta documentação não é te ensinar tudo sobre DNS, BGP, OSPF e nem tão pouco sobre GNU/Linux e sim te mostrar um exemplo de servidor DNS Recursivo implementado pensando em segurança, qualidade e resiliência. Usaremos em todas as nossas documentações o Debian GNU/Linux, por ser uma distribuição que considero uma obra de arte criada por uma enorme comunidade séria, com vasta experiência de anos, qualidade no empacotamento dos programas, estável e com uma equipe de segurança excelente e ativa. Caso você leitor, utilize alguma outra distribuição GNU/Linux, todo conteúdo apresentado aqui pode ser aplicado em outras distros, desde que respeitando as particularidades de cada uma.

Aqui construiremos um sistema do tipo Anycast, ou seja, terás o serviço rodando em diversas localidades da sua Rede utilizando o mesmo endereçamento IP e que atenderá seu cliente mais próximo. Em caso de falhas, seus clientes automaticamente e de forma transparente continuarão consultando o DNS mais próximo deles. Para que ele funcione dessa forma você precisará ter uma Rede OSPF implementada no seu Provedor Internet ou algum outro protocolo como por exemplo o ISIS, mas esse documento não irá abordar o ISIS. Também utilizaremos o Hyperlocal como recurso adicional para gerar algumas proteções de segurança e velocidade na resposta relacionada aos servidores de DNS Raiz da Internet.

Diagrama[editar | editar código-fonte]

Para exemplificar nosso servidor de DNS Recursivo, usaremos como base das explicações um diagrama demonstrando o uso do DNS Recursivo em uma Rede fictícia. Adotaremos IPs privados e reservados para demonstrar todo o ambiente do Provedor de Internet.

Diagrama dns recursivo.drawio.png

Nesse diagrama podemos observar alguns detalhes técnicos como por exemplo: existem 3 servidores de DNS Recursivo posicionados em locais diferentes, que poderiam estar em bairros diferentes e até em cidades diferentes. Em cada servidor teremos 2 loopbacks com os IPs:

10.10.10.10/32

10.10.9.9/32

Esses IPs serão entregues pelos concentradores PPPoE ou IPoE (BNG) para seus clientes como DNS primário e secundário. Podemos usar IPs privados como DNS primário e secundário em um ambiente real? Sim podemos, desde que não sejam IPs que possam ter problemas com as redes privadas dos clientes. Ex.: rede do cliente usando 192.168.0.0/24. Se entregarmos o DNS sendo 192.168.0.10 e 192.168.0.20 teremos problemas e o cliente ficará sem Internet, porque 192.168.0.10 e 192.168.0.20 fazem parte da rede 192.168.0.0/24.

Agora entregando 10.10.10.10 e 10.10.9.9 não teríamos problemas com a rede 192.168.0.0/24.

Motivos para usarmos IPs privados:

  • O principal motivo está relacionado com a segurança, uma vez que sendo um IP privado, não pode sofrer ataques DDoS direcionados diretamente para ele, vindos da Internet.
  • Nem mesmo o cliente da sua rede conhece os IPs públicos utilizados para recursividade na Internet.
  • Memorizar os IPs 10.10.10.10 e 10.10.9.9 é tão fácil quanto memorizar o 8.8.8.8 e o 1.1.1.1. Mais fácil para o seu técnico guardar essa informação e utilizar onde for necessário.

Cada servidor DNS Recursivo possui um IPv4 público, aqui representado por 198.18.x.x/27 e um IPv6 global representado por um IP dentro do prefixo 2001:db8::/32. Cada servidor precisa ter os seus próprios IPs e são através destes IPs que as consultas de DNS serão realizadas na Internet.

Nessa topologia usando Anycast, o cliente será sempre atendido pelo DNS Recursivo mais próximo, desde que os pesos no OSPF estejam ajustados corretamente.

Dados do servidor[editar | editar código-fonte]

Podemos utilizar um sistema virtualizado ou não. Sistemas virtualizados são bem vindos pois são mais simples quando precisamos fazer backups, levantar outros sistemas sem complicações e se precisarmos restaurar rapidamente algum sistema que ficou indisponível por algum motivo. A configuração abaixo tem capacidade para atender algo em torno a 50.000 assinantes ou mais. O DNS Recursivo é um serviço que pode ser utilizado até mesmo em um Raspberry Pi e atender operações pequenas, nesse caso com o intuito de economizar energia e espaço. Nosso foco aqui é montar uma rede de DNS Recursivo Anycast com HyperLocal. Como comentei acima o servidor deve ficar o mais próximo dos clientes para termos a menor latência possível e sempre menor que 5ms entre o cliente e o servidor.

CPU Memória Disco Sistema
2.4Ghz 6 cores 16G DDR4 30G Debian 11 amd64 (Bullseye)

Softwares utilizados[editar | editar código-fonte]

  • Debian 11 amd64 (Bullseye) instalação mínima.
  • FRRouting.
  • Unbound.
  • IRQBalance.
  • Chrony (NTP/NTS).
  • Shell script em bash.

Funcionalidades que teremos[editar | editar código-fonte]

  • Sistema em Anycast.
  • Hyperlocal.
  • Controle de acesso por ACL.
  • RPZ (Response Policy Zone).
  • Bloqueio de consultas do tipo ANY.
  • QNAME minimization habilitado. (habilitado por default no Unbound)
  • Recursividade em IPv4 e IPv6.
  • DNSSEC habilitado.
  • DoH (DNS over HTTPS) habilitado.

Monitoramento[editar | editar código-fonte]

O monitoramento é algo bem específico e não é o foco deste documento mas é extremamente importante que você monitore seus servidores de DNS por alguma ferramenta como o Zabbix. Aqui mostrarei apenas como enviar as informações para o Zabbix. Algumas coisas que você deveria monitorar nos servidores de DNS Recursivo:

  • Serviço do unbound parou.
  • Perda de pacotes.
  • Latência alta de pacotes.
  • Lentidão na resolução de queries.
  • CPU alta.
  • Load alto.
  • Memória com uso alto.
  • Disco com pouco espaço.
  • Queda brusca nas queries.
  • A recursividade parou de funcionar.
  • A recursividade voltou a funcionar.

Este abaixo é um exemplo de monitoramento de um sistema de DNS Recursivo que atende 50.000 assinantes:

Autor: Marcelo Gondim