Introdução:
Um componente fundamental das redes atualmente é o serviço de tradução de nomes em endereços conhecido como DNS(Domain Name Server/Domain Name System) e a causa principal disso é que nós seres humanos não somos muito bons de memória, logo memorizar endereços IPv4 que em decimal são compostos por 4 campos(conhecidos como octetos, porquẽ em binário são 8 valores em cada campo) separados por pontos, algo do tipo 127.0.0.1 se tornam tarefas complicadas.
Nos antepassados a galera da Network Information Center(NIC)utiliza algo que tipo, um servidor central com os registros dos sites e seus respectivos endereços como se fosse uma tabela grande contendo nome e endereço IP, na real era um arquivo HOSTS.TXT que era distribuido por FTP para outros hosts conectados na Internet, logo um usuário poderia digitar http://www.oldasfuck.com e o servidor iria traduzir isso para um endereço IPv4 válido e então a camada 3 estaria pronta pra agir com um destino. O problema é que antigamente tinham poucos sites e isso foi exponencialmente crescendo a sei lá quantos elevados e hoje nós temos vários sites, eu googlei e achei isso 1,316,958,499 e aparentemente subindo o número de sites existentes hoje, então fica meio insano guardar tudo isso num lugar só em forma de lista, por questões de segurança e disponibilidade e várias outras.
O ponto é, tudo isso mudou e agora temos os Domain Names que possuem distribuição de atualizações e cache local melhorando a performance, e atualmente é utilizada a ideia de querys, root servers e toplevel domains e vários outros bagulhos de árvore invertida alien, é basicamente lido de trás pra frente, logo, vocẽ quer acessar o site, o meu site, então digita diesec.sytes.net e o que acontece é o seguinte.
Uma query é disparada para um root server, uma query é uma requisição de tradução de um dominio para endereço IP. O RootServer conhece os TLD’s(Top Level Domains), então ele vai te direcionar para o servidor que contém as informações sobre o .net. então vocẽ pega esse endereço do TLD e pergunta pra ele sobre o servidor DNS do dominio, ou também conhecido como second level domains, e então você chega no servidor de dominio do .sytes.net., e esse cara vai informar o IPv4 do host diesec e então só agora você vai colocar o endereço ipv4 do host diesec do dominio sytes.net como destino do protocolo IP over TCP sendo usado pelo HTTP e então vai acessar o site e isso tudo ocorre em menos de duas piscadas de olhos. Uma vez eu li uma pesquisa de um cara que tentou medir a velocidade dos pacotes trafegando e era uma fração que não lembro de quanto da velocidade da luz, muito boa a pesquisa uma pena não lembrar. Repare que as querys começam de trás pra frente ou seja começando pelo rootserver então vai pro TLD .net e pergunta onde está o .sytes.net., então de lá ele vai pro .sytes.net. e de lá ele pergunta onde está o host diesec.sytes.net. e BUMM, mind crashes.

Então a ideia é implementar dois servidores, um servidor DNS master e outro Slave. Falando de forma superficial, a estrutura Master-Slave é para ter uma melhor disponibilidade, os registros são inseridos no servidor DNS master e então o servidor Slave faz uma transfêrencia de zona e copia os registros para ele, estando hábil à responder as querys DNS da mesma forma que o Master. Então, posteriormente o servidor slave ter feito a transferência de zona, mesmo se o servidor master cair, o servidor slave vai poder responder as querys dependendo das configurações, poderá responder por dias.
Instalação
Vamos precisar de dois servidores:
- ns1.diesec.killall.die
- ns2.diesec.killall.die
Então os servidores ns1 e ns2 serão os nossos servidores DNS de autoridade, o ns1 será o master e o ns2 será o slave, os hosts deles serão uns mano que ta ligado na minha rede aqui, mas vou explicar no caminho.
Master
Pacotes básicos tanto no Master como no Slave em sistemas CentOS:
# yum install bind bind-utils
Pacotes básicos tanto no Master como no Slave em sistemas Debian:
# apt install bind9 bind9utils
Depois de instalado os pacotes referentes ao bind que é um software DNS é necessário configurar seu arquivo de configuração principal /etc/named.conf.
CentOS
# vim /etc/named.conf
Dentro do campo Options, desabilite a exposição da versão do server:
version "not revealed";
Depois do bloco Options crie uma ACL chamada “trusted”:
acl "trusted"{
127.0.0.1; # Localhost
10.0.0.5; # ns1 - masterSlave
10.0.0.11; # ns2 - SlaveI
10.0.0.0/16; # Sei que as duas entradas acima estão na mesma rede e que essa entrada liberaria para ambas, mas é um howto né;
};
Lembre-se de utilizar “;” (ponto e virgula) sempre que fechar uma linha. Os jogos das velha expressa comentário, comentário está para algo que é ignorado pelo interpretador.
Outro ponto interessante de citar é que você não deve fazer o que eu fiz em ambientes de produção, ter os dois servidores de Name Server na mesma rede é um problema sério de ponto central de falha. É um tiro na cara da redundância.
Agora voltando ao bloco options{}, vamos realizar algumas alterações:
listen-on port 53 { 127.0.0.1; 10.0.0.5; };
allow-query { trusted; };
allow-transfer { 10.0.0.11; };
Remova a linha referente à Ipv6 listen-on-v6 e adiciona o ipv4 do servidor na linha “listen-on port 53 { } ”
Adicione allow-transfers para o seu servidor de DNS secundário(slave).
E a allow-query é referente à quais clientes o servidor vai responder às querys.
Feito isso agora é necessário linkar outro arquivo de configuração que vai ser referente à rede local, adicione no fim do arquivo a seguinte linha:
include "/etc/named/named.conf.local";
OK, agora configurando o arquivo local:
vim /etc/named/named.conf.local
Nesse arquivo é onde será “declarado” as zonas e linkado os arquivos das zonas, existem duas zonas para um dominio, a zona em si e a zona reversa que realiza a tradução do ipv4 para os hosts do dominio.
Segue um exemplo abaixo de como ficaria a configuração das zonas:
zone "diesec.killall.die" {
type master;
file "/etc/named/zones/db.diesec.killall.die"; # Zone File Path
};
zone "0.0.10.in-addr.arpa"{
type master;
file "/etc/named/zones/db.0.0.10" ; #10.0.0.0/26 subnet && Zone FIle Path
};
Repare que na reverse zone ela tem a declaração da subnet, que no caso é 10.0.0.0/26, segundo a RFC 2317 que trata o tipo de situação quando a zona é uma Classless, você precisa definir o máximo possível, coloque ao contrário antes de in-addr.arpa.
Supondo que sua rede seja 192.168.10.0/24, você pode definir assim, por exemplo 10.168.192.in-addr.arpa
Criando a Zona:
sudo chmod 755 /etc/named
sudo mkdir /etc/named/zones
sudo vim /etc/named/zones/db.diesec.killall.die
Exemplo de configuração de zona :
$TTL 604800 ; Tempo de vida do cache
@ IN SOA ns1.diesec.killall.die. admin.diesec.killall.die. (
2018010701 ; Serial
604800 ; Refresh -> Intervalo de atualização.
86400 ; Retry -> Intervalo para novas tentativas
2419200 ; Expire -> Expiração da zona.
604800 ) ; Negative cache TTL -> Tempo de Cache
;
; Name Servers - NS Records
IN NS ns1.diesec.killall.die.
IN NS ns2.diesec.killall.die.
; Name Servers - Records
ns1.diesec.killall.die. IN A 10.0.0.5
ns2.diesec.killall.die. IN A 10.0.0.11
IN MX 10 mail
; 10.0.0.0/26 - Records
logcenter IN A 10.0.0.6
mail IN A 10.0.0.10
docker.diesec.killall.die. IN A 10.0.0.12
prime.diesec.killall.die. IN A 10.0.0.10
secgen01.diesec.killall.die. IN A 10.0.0.3
Se atente a utilização de pontos no final dos dominios, quando se utiliza o ponto você diz que começa ali, quando você não usa ponto, ele acopla aquilo como um host, logo, se eu deixasse sem ponto, por exemplo:
secgen01.diesec.killall.die IN A 10.0.0.3
Ele iria reconhecer como secgen01.diesec.killall.die.diesec.killall.die, então seria errado, você poderia declarar assim:
secgen01 IN A 10.0.0.3
Então ele iria reconhecer de forma correta: secgen01.diesec.killall.die
Existem outros valores de registros DNS, no caso eu só usei o “IN A” e “IN NS” porém existem outros, segue abaixo:
- A -> Nome para IPv4
- AAAA -> Nome para IPv6
- CNAME -> Nome Canonico.
- PTR -> DNS Reverso
- NS -> Name Server
- MX -> Mail Exchange
- TXT -> Dever de casa.
Exemplo de configuração da Zona Reversa:
$TTL 604800
@ IN SOA ns1.diesec.killall.die. admin.diesec.killall.die. (
2018010701 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ; Negative Cache TTL
)
; Name Servers - NS Records
IN NS ns1.diesec.killall.die.
IN NS ns2.diesec.killall.die.
; PTR Records
5 IN PTR ns1.diesec.killall.die.
11 IN PTR ns2.diesec.killall.die.
6 IN PTR logcenter.diesec.killall.die.
12 IN PTR docker.diesec.killall.die.
10 IN PTR prime.diesec.killall.die.
3 IN PTR secgen01.diesec.killall.die.
Caso um registro não tenha informado o host no começo da linha, por exemplo:
IN MX 5 mail
No exemplo acima não existe um nome no registro, logo é utilizado o nome de origem, conhecido como @ que nesse caso é o próprio servidor DNS, que também é um servidor de email. Agora temos o número "5" também no registro do MX, é utilizado para definir prioridade pois um dominio pode ter vários servidores de MX, então quanto menor o número maior a prioridade.
Para realizar verificações de sintaxe nos arquivos de zona utilize o seguinte comando:
$ sudo named-checkconf
Para realizer verificações nos arquivos das zonas utilize o seguinte comando:
$ sudo named-checkzone diesec.killall.die /etc/named/zones/db.diesec.killall.die
Se tudo estiver ok, vamos iniciar o serviço:
$ sudo systemctl start named
$ sudo systemctl enable named
$ sudo systemctl status named
● named.service - Berkeley Internet Name Domain (DNS)
Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; vendor preset: disabled)
Active: active (running) since Sex 2018-01-12 22:04:36 -02; 26min ago
Process: 836 ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS (code=exited, status=0/SUCCESS)
Process: 775 ExecStartPre=/bin/bash -c if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi (code=exited, status=0/SUCCESS)
Main PID: 863 (named)
CGroup: /system.slice/named.service
└─863 /usr/sbin/named -u named -c /etc/named.conf
Jan 12 22:04:36 masterslave-dns.novalocal named[863]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: loa...erial 0
Jan 12 22:04:36 masterslave-dns.novalocal named[863]: zone localhost/IN: loaded serial 0
Jan 12 22:04:36 masterslave-dns.novalocal named[863]: zone diesec.killall.die/IN: loaded serial 2018010701
Jan 12 22:04:36 masterslave-dns.novalocal named[863]: zone localhost.localdomain/IN: loaded serial 0
Jan 12 22:04:36 masterslave-dns.novalocal named[863]: all zones loaded
Jan 12 22:04:36 masterslave-dns.novalocal named[863]: running
Jan 12 22:04:36 masterslave-dns.novalocal named[863]: zone 0.0.10.in-addr.arpa/IN: sending notifies (serial 2018010701)
Jan 12 22:04:36 masterslave-dns.novalocal named[863]: zone diesec.killall.die/IN: sending notifies (serial 2018010701)
Jan 12 22:04:36 masterslave-dns.novalocal systemd[1]: Started Berkeley Internet Name Domain (DNS).
Jan 12 22:04:46 masterslave-dns.novalocal named[863]: managed-keys-zone: Unable to fetch DNSKEY set '.': timed out
Hint: Some lines were ellipsized, use -l to show in full.
Antes de implementarmos o servidor DNS secundário vamos realizar algumas querys para testar os registros:
[root@cobaia-one centos]# yum install dnsutils
[root@cobaia-one centos]# dig @10.0.0.5 logcenter.diesec.killall.die
; <> DiG 9.9.4-RedHat-9.9.4-51.el7_4.1 <> @10.0.0.5 logcenter.diesec.killall.die
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER< Realizando uma query reversa, procurando qual é o nome do endereço 10.0.0.6
; <> DiG 9.9.4-RedHat-9.9.4-51.el7_4.1 <> @10.0.0.5 -x 10.0.0.6
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53725
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;6.0.0.10.in-addr.arpa. IN PTR
;; ANSWER SECTION:
6.0.0.10.in-addr.arpa. 604800 IN PTR logcenter.diesec.killall.die.
;; AUTHORITY SECTION:
0.0.10.in-addr.arpa. 604800 IN NS ns2.diesec.killall.die.
0.0.10.in-addr.arpa. 604800 IN NS ns1.diesec.killall.die.
;; ADDITIONAL SECTION:
ns1.diesec.killall.die. 604800 IN A 10.0.0.5
ns2.diesec.killall.die. 604800 IN A 10.0.0.11
;; Query time: 1 msec
;; SERVER: 10.0.0.5#53(10.0.0.5)
;; WHEN: Sáb Jan 13 10:49:41 UTC 2018
;; MSG SIZE rcvd: 160
Caso não retorne nada, verifique se no arquivo /etc/named.conf está com o endereço do cliente autorizado dentro da ACL "trusted".
Agora vamos pro servidor secundário:
Slave
Edite o arquivo /etc/named.conf
# sudo vi /etc/named.conf
E então adicione a acl "trusted" depois do bloco da "options":
acl "trusted"{
10.0.0.5;
10.0.0.11;
10.0.0.6;
};
De volta no options, remova as entradas referentes à ipv6, caso você não saiba o protocolo sempre dá preferência pra ivp4, então deixar ipv6 habilitado quando não se está utilizando é perda de "tempo" e arrisco falar "performance".
options {
listen-on port 53 { 127.0.0.1; ; };
# listen-on-v6 port 53 { ::1; };
E adicione a allow-query para a acl trusted assim:
allow-query { trusted; }; # allows queries from "trusted" clients
E por ultimo nesse arquivo, adicione o include que linka no arquivo que declara as zonas:
include "/etc/named/named.conf.local";
Agora é necessário criar o arquivo named.conf.local:
$ sudo chmod 755 /etc/named
$ sudo vim /etc/named/named.conf.local
Segue exemplo de configuração do named.conf.local
zone "diesec.killall.die" {
type slave;
file "slaves/db.diesec.killall.die";
masters { 10.0.0.5; } ;
};
zone "0.0.10.in-addr.arpa"{
type slave;
file "slaves/db.0.0.10" ;
masters { 10.0.0.5; };
};
Repare que as duas zonas foram criadas do tipo slave e o campo masters aponta para o servidor ns1.
Feito isso, não é necessário configurar as zonas em si pois isso é um slave, ele vai puxar(Através de uma transfêrencia de zona) as zonas do master e vai gerar um arquivo binário com as zonas do master. Vamos verificar se está tudo ok com a sintaxe:
$ sudo named-checkconf
Se não aprensentar erros, vamos habilitar o serviço e inicializar:
$ sudo systemctl enable named
$ sudo systemctl start named
Nesse ponto ocorrerá uma transferência de zona da master para a slave, então a slave passará a ter todos os registros da master.
Para manter as zonas sincronizadas é necessário sempre que uma alteração for feita no master, alterar o número serial no master, então o slave vai identificar que o serial dele é menor que o do mestre e então vai fazer uma transferência de zona. Existe um outro mecanismo chamado de Notify e notify-also que quando o master detecta uma alteração, ele notifica os servidores slave, por default ela já vem habilitado.
$TTL 604800
@ IN SOA ns1.diesec.killall.die. admin.diesec.killall.die. (
2018010701 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative cache TTL
;
Por exemplo, o serial acima é 2018010701, é algo que eu adoto é YYYYMMDDXX ou seja, ano, mês, dia e alteração no dia, logo, a primeira alteração no dia seria 01, a segunda 02, então ficaria pra primeira alteração 2018011301 já a segunda 2018011302 e no dia seguinte 2018011401 e assim vai. Esses valores acima são respectivamente, serial, tempo de verificação de atualizações, em caso de erro vai esperar 86400 segundos até uma nova tentativa, caso o valor sem atualizar passe de 2419200 a zona deixará de existir e por ultimo é o tempo de vida do cache. Esses valores estão definidos em segundo porém poderiam ser utilizados o sufixo H(hora), D(Dia) e W(semanas).
É necessário alterar o serial para que os slaves reconheçam que ocorreu alteração e então sincronizem. Agora é necessário dar um reload no serviço, utlizando o utilitário rndc , segue exemplo:
# rndc reload domain.tld
Outra forma é disparar um signal HUP para o processo da seguinte forma:
# kill -HUP `pidof named`
Cache-Only
Existem outros dois tipos(segundo o livro do Luciano A. Siqueira 4ºedt) que seriam os servidores DNS cache-only e Forwarders(redirecionamento).
Para dar o deploy nesses outros dois tipos irei subir um debian 9.3 versão cloud, estou te falando isso pois é diferente as configurações entre um centos e um Debian. Eu particularmente gostei mais do centOS, soa mais organizado, mas continuando.
Cache-Only
Então novamente de forma resumida um servidor de cache-only é responsável de realizar as requisições e armazenar a answer em cache então as próximas requisições para aquele endereço já estarão lá no cache.
Instalando os pacotes:
apt-get update && apt-get upgrade -y && apt-get install bind9 dnsutils -y
Agora vamos configurar o arquivo /etc/bind/named.conf.options. Esse arquivo é carregado a partir do arquivo /etc/bind/named.conf
Exemplo de configuração:
acl trusted {
127.0.0.1;
localnets;
10.0.0.0/26;
};
options {
directory "/var/cache/bind";
listen-on port 53 { 127.0.0.1; 10.0.0.7; };
dnssec-validation auto;
auth-nxdomain no; # conform to RFC1035
recursion yes;
allow-query { trusted ; };
};
Só explicando a utilização da acl trusted, definir quais hosts podem realizar querys é importante para evitar que seu servidor DNS seja utilizado para DNS Amplification attack. Caso vocẽ prefira vídeos, segue abaixo:
Agora se você não sabe inglẽs não hà nada que eu possa fazer.
Outras formas de limitar o acesso seria utilizando o allow-recursion e allow-query-cache e estou com preguiça de copiar traduzindo o texto então vou simplesmente copiar a explicação abaixo:
We explicitly turned recursion on, and then configured the allow-query parameter to use our ACL specification. We could have used a different parameter, like allow-recursion to reference our ACL group. If present and recursion is on, allow-recursion will dictate the list of clients that can use recursive services.
However, if allow-recursion is not set, then Bind falls back on the allow-query-cache list, then the allow-query list, and finally a default of localnets and localhost only. Since we are configuring a caching only server (it has no authoritative zones of its own and doesn't forward requests), the allow-query list will always apply only to recursion. We are using it because it is the most general way of specifying the ACL.
Aqui uma PoC, em um servidor qualquer eu disparei a query DNS para meu servidor de cache-only
[root@masterslave-dns zones]# dig @10.0.0.7 www.google.com
; <> DiG 9.9.4-RedHat-9.9.4-51.el7_4.1 <> @10.0.0.7 www.google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18166
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 5
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.google.com. IN A
;; ANSWER SECTION:
www.google.com. 300 IN A 216.58.202.100
;; AUTHORITY SECTION:
google.com. 158499 IN NS ns4.google.com.
google.com. 158499 IN NS ns2.google.com.
google.com. 158499 IN NS ns3.google.com.
google.com. 158499 IN NS ns1.google.com.
;; ADDITIONAL SECTION:
ns1.google.com. 158499 IN A 216.239.32.10
ns2.google.com. 158499 IN A 216.239.34.10
ns3.google.com. 158499 IN A 216.239.36.10
ns4.google.com. 158499 IN A 216.239.38.10
;; Query time: 1038 msec
;; SERVER: 10.0.0.7#53(10.0.0.7)
;; WHEN: Sáb Jan 20 13:05:39 -02 2018
;; MSG SIZE rcvd: 195
E aqui é um sniffer de rede que detecta o servidor de cache-only fazendo a requisição.
root@OpenStack:/home/operador# tcpdump -i br-ex host 172.24.4.3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br-ex, link-type EN10MB (Ethernet), capture size 262144 bytes
13:05:38.164605 IP 172.24.4.3.60207 > ns4.google.com.domain: 5399 [1au] A? www.google.com. (43)
13:05:38.327054 IP OpenStack.44974 > 172.24.4.3.hostmon: Flags [S], seq 3364213474, win 29200, options [mss 1460,sackOK,TS val 2262705088 ecr 0,nop,wscale 7], length 0
13:05:38.327127 IP 172.24.4.3 > OpenStack: ICMP time exceeded in-transit, length 68
13:05:38.327385 IP OpenStack.44976 > 172.24.4.3.hostmon: Flags [S], seq 4173326526, win 29200, options [mss 1460,sackOK,TS val 2262705088 ecr 0,nop,wscale 7], length 0
13:05:38.327421 IP 172.24.4.3 > OpenStack: ICMP time exceeded in-transit, length 68
13:05:38.332978 IP ns4.google.com.domain > 172.24.4.3.60207: 5399*- 1/0/0 A 216.58.202.100 (48)
13:05:38.335121 IP 172.24.4.3.44638 > f.gtld-servers.net.domain: 12181 [1au] DS? google.com. (39)
13:05:38.892578 IP f.gtld-servers.net.domain > 172.24.4.3.60669: Flags [S.], seq 953231069, ack 3894322860, win 1460, options [mss 1440], length 0
13:05:38.892969 IP 172.24.4.3.60669 > f.gtld-servers.net.domain: Flags [.], ack 1, win 28200, length 0
13:05:38.893154 IP 172.24.4.3.60669 > f.gtld-servers.net.domain: Flags [P.], seq 1:42, ack 1, win 28200, length 4161544 [1au] DS? google.com. (39)
13:05:39.194369 IP f.gtld-servers.net.domain > 172.24.4.3.60669: Flags [.], ack 42, win 14000, length 0
13:05:39.197393 IP f.gtld-servers.net.domain > 172.24.4.3.60669: Flags [P.], seq 1:763, ack 42, win 14000, length 76261544*- 0/6/1 (760)
13:05:39.197617 IP 172.24.4.3.60669 > f.gtld-servers.net.domain: Flags [.], ack 763, win 29718, length 0
13:05:39.197990 IP 172.24.4.3.60669 > f.gtld-servers.net.domain: Flags [F.], seq 42, ack 763, win 29718, length 0
13:05:39.492845 IP f.gtld-servers.net.domain > 172.24.4.3.60669: Flags [F.], seq 763, ack 43, win 14000, length 0
13:05:39.493289 IP 172.24.4.3.60669 > f.gtld-servers.net.domain: Flags [.], ack 764, win 29718, length 0
13:05:43.549067 ARP, Request who-has 172.24.4.3 tell OpenStack, length 28
13:05:43.549130 ARP, Reply 172.24.4.3 is-at fa:16:3e:31:bc:5e (oui Unknown), length 28
^C
O meu sniffer está na saída da rede, então se eu disparar novamente a mesma query, nenhum tráfego sai da rede, a consulta finaliza no cache do servidor cache-only.
Estranho ele ter usado TCP, que eu saiba TCP era só utilizado em transferências de zonas e ali era para ter sido apenas um query recursiva normal, porém foi utilizado TCP, hmm, eu não ligo o suficiente para não tentar desvencer esse mistério.
Forward
Um servidor de redirecionamento trabalha de forma semelhante à do cache-only, ele vai redirecionar todas as requisições para servidores pré configurados nos arquivos de configuração. Acredito que a maioria dos servidores de redirecionamento também são de cache quero dizer, faz sentido se for, já que você ta redirecionando as querys, porque não armazenar as respostas num cache? Tipo, o tráfego já ta passando por você mesmo.
Então vou pegar o servidor de cache-only e configurar ele em Forwarding DNS Server, resumidamente é só adicionar um bloco forwarders{} dentro do campo options definindo os servidores destino do redirecionamento e definir como forward only, então voltando no arquivo /etc/named/named.conf.local
acl trusted {
127.0.0.1;
localnets;
10.0.0.0/26;
};
options {
directory "/var/cache/bind";
forwarders {
10.0.0.5; #MasterSlave aka DNS primário
10.0.0.7; #SlaveOne aka DNS Secundário
};
forward only;
dnssec-validation auto;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
recursion yes;
allow-query { trusted ; };
};
Então basicamente vamos encaminhar todas as requisições para o DNS master/slave, vamos fazer uma PoC com os bagulho do tcpdump pra ver o que vai rolar. Vou ativar um sniffer na saída da rede e outro dois nos respectivos servidores DNS, vamos ver o que rola.
root@OpenStack:/home/operador# tcpdump -i br-ex host 172.24.4.3 -n and ! port 22 # Saída da rede pegando os pacotes do cache server, só pra verificar se ele vai sair da rede.
[root@masterslave-dns zones]# tcpdump -i any host 10.0.0.7 # Servidor DNS primŕaio snifando pacote do servidor cache only pra ver se chega a query DNS.
[root@dns-slave centos]# tcpdump -i any host 10.0.0.7 # Servidor DNS SLAve
[root@cobaia-one centos]# dig @10.0.0.7 diesec.sytes.net # Cliente DNS
Segue amostra de tráfego capturado:
16:21:25.217845 IP 10.0.0.8.51450 > 10.0.0.7.53: 54197+ [1au] A? thehackernews.com. (46)
16:21:25.218385 IP 10.0.0.7.39733 > 10.0.0.11.53: 25118+% [1au] A? thehackernews.com. (46)
16:21:26.418705 IP 10.0.0.7.48541 > 10.0.0.5.53: 41352+% [1au] A? thehackernews.com. (46)
16:21:27.167040 IP 10.0.0.11.53 > 10.0.0.7.39733: 25118 2/2/5 A 104.24.30.49, A 104.24.31.49 (219)
16:21:27.167077 IP 10.0.0.7 > 10.0.0.11: ICMP 10.0.0.7 udp port 39733 unreachable, length 255
16:21:27.551394 IP 10.0.0.5.53 > 10.0.0.7.48541: 41352 2/2/5 A 104.24.31.49, A 104.24.30.49 (219)
16:21:27.551984 IP 10.0.0.7.58278 > 10.0.0.11.53: 21963+% [1au] DS? thehackernews.com. (46)
Todo tráfego da query foi executado pelos servidores no campo forwarders
Configurando o RNDC para conectar remoto.
O programa rndc(Remote Name Daemon Control) pode ser utilizado para controlar o daemon named local assim como remotamente. Para isso, é necessário o arquivo rndc.key, qual contem a chave de credencial e informações de acesso.
Caso o arquivo rndc.key não esteja presente, utilize o utilitário rndc-confgen, segue algumas opções do comando:
Usage:
rndc-confgen [-a] [-b bits] [-c keyfile] [-k keyname] [-p port] [-r randomfile] [-s addr] [-t chrootdir] [-u user]
-a: generate just the key clause and write it to keyfile (/etc/bind/rndc.key)
-A alg: algorithm (default hmac-md5)
-b bits: from 1 through 512, default 256; total length of the secret
-c keyfile: specify an alternate key file (requires -a)
-k keyname: the name as it will be used in named.conf and rndc.conf
-p port: the port named will listen on and rndc will connect to
-r randomfile: source of random data (use "keyboard" for key timing)
-s addr: the address to which rndc should connect
-t chrootdir: write a keyfile in chrootdir as well (requires -a)
-u user: set the keyfile owner to "user" (requires -a)
Então, vamos gerar um arquivo rndc.key para conectar em um servidor remoto:
root@est-samba:/etc/bind# rndc-confgen -s 10.0.0.14 -p 953
# Start of rndc.conf
key "rndc-key" {
algorithm hmac-md5;
secret "jAmTH4TpwuaZjxWGzV+MZg==";
};
options {
default-key "rndc-key";
default-server 10.0.0.14;
default-port 953;
};
# End of rndc.conf
# Use with the following in named.conf, adjusting the allow list as needed:
# key "rndc-key" {
# algorithm hmac-md5;
# secret "jAmTH4TpwuaZjxWGzV+MZg==";
# };
#
# controls {
# inet 10.0.0.14 port 953
# allow { 10.0.0.14; } keys { "rndc-key"; };
# };
# End of named.conf
Como você pode ver ele dispara o output pra stdout, ele também já gerou a parte do código para ser adicionado no named.conf. Vamos então salvar a parte do rndc.key no servidor remoto e adicionar a parte do named.conf no nosso servidor que será conectado.
Posteriormente à isso, no servidor remoto, você pode simplesmente controlar o named usando o rndc da seguinte forma:
~$ rndc -s 10.0.0.14 -p 953 -k /etc/bind/rndc.key stop
A Stub name server
A stub zone is like a slave zone, except that it replicates only the NS records of a master zone instead of the entire zone. In other words, the DNS server hosting the stub zone is only a source of information on the authoritative name servers. This server must have network access to the remote DNS server in order to copy the authoritative name server information.
The purpose of stub zones is two fold:
- Keep delegated zone information current. By updating a stub zone for one of its child zones regularly, the DNS server that hosts the stub zone will maintain a current list of authoritative DNS servers for the child zone.
- Improve name resolution. Stub zones make it possible for a DNS server to perform name resolution using the stub zone’s list of name servers, without having to use forwarding or root hints.
Creating subdomains:
A melhor forma de se criar um subdominio é delegar o subdominio à um arquivo de zona separado, essa forma fica mais organizado, evitando falhas humanas e é atribuido um próprio SOA e registros de NS ao subdominio. Vamos ir com um exemplo então, vamos supor que o dominio diesec.killall.die pode delegar autoridade pra um outro dominio, que vamos chamar de backdoor.diesec.killall.die.
Primeiro vamos criar uma nova zona, a zona backdoor.diesec.killall.die:
zone "backdoor.diesec.killall.die" {
type master;
file "/etc/bind/db.backdoor.diesec.killall.die";
};
Agora vamos adicionar o seguinte registro no arquivo db.diesec.killall.die:
backdoor.diesec.killall.die. IN NS ns3.backdoor.diesec.killall.die.
Então pra finalizar, vamos configurar o arquivo da zona da nossa subzona aka sub dominio, db.backdoor.diesec.killall.die:
$TTL 2d ; default TTL = 2 days
@ IN SOA ns3.backdoor.diesec.killall.die. hostmaster.backdoor.diesec.killall.die. (
2018060903 ; serial number
2h ; refresh = 2 hours
15M ; update retry = 15 minutes
3W12h ; expiry = 3 weeks + 12 hours
2h20M ; minimum = 2 hours + 20 minutes
)
; NS
IN NS ns3.backdoor.diesec.killall.die.
ns3 IN A 10.0.0.14
; HOST
teste IN A 10.0.0.55
Alguns testes confirmando a operação das configurações:
root@dns-master:/etc/bind# dig -t ns backdoor.diesec.killall.die @localhost +short
ns3.backdoor.diesec.killall.die.
root@dns-master:/etc/bind# dig @localhost teste.backdoor.diesec.killall.die +short
10.0.0.55
Operacional!
Named-Compilezone
A partir da versão 9.9, arquivos de zonas escravas são por padrão armazenadas no formato raw. A conversão entre o formato de texto e o formato raw pode ser feito com o comando named-compilezone. Por exemplo, para converter o arquivo de zona do formato raw para texto:
[root@dns-slave slaves]# named-compilezone -f raw -F text -o output diesec.killall.die. diesec.killall.die.db
zone diesec.killall.die/IN: backdoor.diesec.killall.die/NS 'ns3.backdoor.diesec.killall.die' has no REQUIRED GLUE address records (A or AAAA)
zone diesec.killall.die/IN: backdoor.diesec.killall.die/NS 'ns3.backdoor.diesec.killall.die' (out of zone) has no addresses records (A or AAAA)
zone diesec.killall.die/IN: loaded serial 2018061005 (DNSSEC signed)
dump zone to output...done
OK
[root@dns-slave slaves]# cat output
diesec.killall.die. 604800 IN SOA ns1.diesec.killall.die. god.diesec.killall.die. 2018061005 604800 86400 2419200 604800
diesec.killall.die. 604800 IN RRSIG SOA 3 3 604800 20180713043346 20180613043346 747 diesec.killall.die. CGN+unkAbrZF8N2ncQyVNvv0R4B9nIXTf2++wUUyUE96WGZqOH2npiA=
diesec.killall.die. 604800 IN NS ns1.diesec.killall.die.
diesec.killall.die. 604800 IN NS ns2.diesec.killall.die.
diesec.killall.die. 604800 IN RRSIG NS 3 3 604800 20180713043346 20180613043346 747 diesec.killall.die. CBQwXIdVr9dghMdZpwGDt8YFmiyoJALDvBAZWspd/p3KEwqmYrSrL5A=
diesec.killall.die. 604800 IN A 10.0.0.14
diesec.killall.die. 604800 IN RRSIG A 3 3 604800 20180713043346 20180613043346 747 diesec.killall.die. CEdpjPkQnBrJBUrrObUsot8hJM8bBzPmp+zUHT9qiXvt1tholMJZUXk=
diesec.killall.die. 604800 IN NSEC backdoor.diesec.killall.die. A NS SOA RRSIG NSEC DNSKEY
diesec.killall.die. 604800 IN RRSIG NSEC 3 3 604800 20180713043346 20180613043346 747 diesec.killall.die. CHhlGYvNhanCRkC7
---- Saída Omitida. ----
A sintaxe do comando é bem simples, o -f define o tipo do arquivo de entrada, -F para o tipo de arquivo de saída, -o a saída, o nome da zona e o arquivo onde está o raw.
Para realizar o procedimento inverso, basta fazer o seguinte:
[root@dns-slave slaves]# named-compilezone -f text -F raw -o output.raw diesec.killall.die output
zone diesec.killall.die/IN: backdoor.diesec.killall.die/NS 'ns3.backdoor.diesec.killall.die' has no REQUIRED GLUE address records (A or AAAA)
zone diesec.killall.die/IN: backdoor.diesec.killall.die/NS 'ns3.backdoor.diesec.killall.die' (out of zone) has no addresses records (A or AAAA)
zone diesec.killall.die/IN: loaded serial 2018061005 (DNSSEC signed)
dump zone to output.raw...done
OK
Para alterar o armazenamento default como text, basta inserir a seguinte linha na declaração da zona:
masterfile-format text;
Tools
Bom, durante esse paper nós utilizamos algumas ferramentas para interagir com os servidores DNS, vou listar algumas ferramentas abaixo:
- dig
- host
- nslookup
- DNSwalk
As duas primerias já foram utilizadas nesse paper, irei abordar um pouco sobre o nslookup e o DNSWalk.
NSLOOKUP
Esse programa está deprecated e pode ser obtido pelo pacote bind-utils, é melhor utilizar o dig ou o host, mass, a lpic2 202 aborda, então vamos lá, ele é utilizado basicamente de forma interativa, porém pode ser utilizado de forma não interativa, vamos dar uma olhada na forma não interativa primeiro:
Simplesmente digitando o host que deseja descobrir o endereço:
[root@dns-slave slaves]# nslookup thehackernews.com
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name: thehackernews.com
Address: 104.24.31.49
Name: thehackernews.com
Address: 104.24.30.49
Repare que as primeiras linhas são referentes à qual o servidor que será realizado a query.
É possível definir para qual servidor DNS a query será realizada, utilizando - [ Server Address/Name ].
[root@dns-slave slaves]# nslookup thehackernews.com - 1.1.1.1
Server: 1.1.1.1
Address: 1.1.1.1#53
Non-authoritative answer:
Name: thehackernews.com
Address: 104.24.30.49
Name: thehackernews.com
Address: 104.24.31.49
No modo interativo, você digita nslookup sem nenhum argumento e cai dentro da console, então é possível alterar o modo de consulta do comando nslookup graças ao argumento set:
- set type=mx: permite recolher informações relativas aos servidores do serviço de mensagens de um domínio;
- set type=ns: permite reunir informações relativas ao servidor de nomes associado ao domínio;
- set type=a: permite colher informações relativas a um hóspede da rede. É o modo de interrogação por padrão;
- set type=soa: permite exibir as informações do campo SOA (Start Of Authority);
- set type=cname: permite mostrar as informações relativas ao pseudônimo;
- set type=hinfo: permite, quando estes dados são informados, exibir as informações relativas ao hardware e ao sistema operacional do hóspede.
Então realizando uma query atrás dos MX:
[root@dns-slave slaves]# nslookup
> set type=mx
> thehackernews.com
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
thehackernews.com mail exchanger = 5 alt2.aspmx.l.google.com.
thehackernews.com mail exchanger = 5 alt1.aspmx.l.google.com.
thehackernews.com mail exchanger = 100 mx3.mailhostbox.com.
thehackernews.com mail exchanger = 10 aspmx2.googlemail.com.
thehackernews.com mail exchanger = 10 aspmx3.googlemail.com.
thehackernews.com mail exchanger = 1 aspmx.l.google.com.
Authoritative answers can be found from:
DNSWALK
O DNSwalk é um DNS debbuger, use com cautela, uma vez que ele tenta realizar transferẽncia de zona enquanto checa bases dns para verificar consistencia e precisão. O pacote que provê esse programa é dnswalk, vamos aos exemplos:
root@dns-master:/etc/bind# dnswalk diesec.killall.die.
Checking diesec.killall.die.
Getting zone transfer of diesec.killall.die. from ns1.diesec.killall.die...failed
FAIL: Zone transfer of diesec.killall.die. from ns1.diesec.killall.die failed: REFUSED
Getting zone transfer of diesec.killall.die. from ns2.diesec.killall.die...failed
FAIL: Zone transfer of diesec.killall.die. from ns2.diesec.killall.die failed: REFUSED
BAD: All zone transfer attempts of diesec.killall.die. failed!
2 failures, 0 warnings, 1 errors.
Não esqueça de colocar o ponto no final do dominio, ele é meio fresco e reclama. No exemplo anterior, as transferências de zonas falharam, porquê security is a bitch.
Segurança em Servidores DNS
Primeiro de tudo é necessário enjaular o daemon, fazendo com que o serviço opere com menos privilégios. Você pode alterar o arquivo /etc/init.d/bind9 e alterar a variável OPTIONS:
# for a chrooted server: "-u bind -t /var/lib/named"
# Don't modify this line, change or create /etc/default/bind9.
OPTIONS=""
Adicione um usuário não privilegiado, de preferência um criado por vocẽ com um nome adequando e um respectivo grupo, ficando assim:
# for a chrooted server: "-u bind "
# Don't modify this line, change or create /etc/default/bind9.
OPTIONS="-u named -g named"
Agora falando sobre criptografia em servidores DNS estamos falando de DNSSEC, uma forma de confirmar que a resposta da query é de fato legitima é verificando a integridade atráves de chaves assimétricas. Porém é possível também definir chaves de acesso de outros hosts.
Vamos dar uma olhada em como configurar uma chave para um servidor slave:
Configurando chave para acesso de hosts.
root@dns-master:/etc/bind/keys/host# dnssec-keygen -a HMAC-MD5 -b 512 -n HOST ns4.diesec.killall.die
Vai gerar dois arquivos,
Kns4.diesec.killall.die.+157+48316.key
Kns4.diesec.killall.die.+157+48316.private
root@dns-master:/etc/bind/keys/host# cat Kns4.diesec.killall.die.+157+48316.private
Private-key-format: v1.3
Algorithm: 157 (HMAC_MD5)
Key: U6NcqLs3LEB2/RO6D5kIQ1M/kV4QjWU4mQCl0o95CoN55PyGpHSDzpf2wAtUhQmaucrpI1x5R6j3OhAUhhwgSQ==
Bits: AAA=
Created: 20180613051142
Publish: 20180613051142
Activate: 20180613051142
root@dns-master:/etc/bind/keys/host# ls -l
Arquivo named.conf:
key key1.diesec.killall.die. {
algorithm "hmac-md5";
secret "U6NcqLs3LEB2/RO6D5kIQ1M/kV4QjWU4mQCl0o95CoN55PyGpHSDzpf2wAtUhQmaucrpI1x5R6j3OhAUhhwgSQ==";
};
server 10.0.0.11 {
keys key1.diesec.killall.die. ;
};
É necessário alterar a propriedade do allow-transfer:
allow-transfer{ slaves; key key1.diesec.killall.die.; };
Agora no slave que vai utilizar a chave, o procedimento é semelhante:
key key1.diesec.killall.die.{
algorithm "hmac-md5";
secret "U6NcqLs3LEB2/RO6D5kIQ1M/kV4QjWU4mQCl0o95CoN55PyGpHSDzpf2wAtUhQmaucrpI1x5R6j3OhAUhhwgSQ==";
};
server 10.0.0.14{
keys key1.diesec.killall.die;
};
Agora é só criar a zona:
zone "diesec.killall.die"{
type slave;
file "/var/named/slaves/diesec.killall.die.db";
masters{10.0.0.14;};
};
E reiniciar o serviço. Posteriormente reiniciar o serviço, repare que a transferência ocorre normalmente:
root@est-samba:/etc/bind# systemctl status bind9
● bind9.service - BIND Domain Name Server
Loaded: loaded (/lib/systemd/system/bind9.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2018-06-13 05:20:09 UTC; 1min 40s ago
Docs: man:named(8)
Process: 3092 ExecStop=/usr/sbin/rndc stop (code=exited, status=0/SUCCESS)
Main PID: 3097 (named)
Tasks: 4 (limit: 4915)
CGroup: /system.slice/bind9.service
└─3097 /usr/sbin/named -f -u bind
jun 13 05:20:09 est-samba named[3097]: zone 255.in-addr.arpa/IN: loaded serial 1
jun 13 05:20:09 est-samba named[3097]: zone localhost/IN: loaded serial 2
jun 13 05:20:09 est-samba named[3097]: all zones loaded
jun 13 05:20:09 est-samba named[3097]: running
jun 13 05:20:09 est-samba named[3097]: zone diesec.killall.die/IN: Transfer started.
jun 13 05:20:09 est-samba named[3097]: transfer of 'diesec.killall.die/IN' from 10.0.0.14#53: connected using 10.0.0.11#57631
jun 13 05:20:09 est-samba named[3097]: zone diesec.killall.die/IN: transferred serial 2018061005: TSIG 'key1.diesec.killall.die'
jun 13 05:20:09 est-samba named[3097]: transfer of 'diesec.killall.die/IN' from 10.0.0.14#53: Transfer status: success
jun 13 05:20:09 est-samba named[3097]: transfer of 'diesec.killall.die/IN' from 10.0.0.14#53: Transfer completed: 1 messages, 12 records, 403 bytes, 0
jun 13 05:20:09 est-samba named[3097]: zone diesec.killall.die/IN: sending notifies (serial 2018061005)
Então é isso, TSIG significa Transaction SIGnature, e utilizou a chave definida.
Assinando a zona
O ambiente que nós vamos configurar agora é criptografar o arquivo de zona, possibilitando assim os registros RRSIG:
No Arquivo /etc/named.conf, habilitar:
dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;
Gerando as chaves:
cd /var/named/
[root@masterslave-dns named]# dnssec-keygen -a DSA -b 1024 -r /dev/urandom -n ZONE diesec.killall.die
----Saida Omitida----
[root@masterslave-dns named]# dnssec-keygen -a DSA -f KSK -b 1024 -r /dev/urandom -n ZONE diesec.killall.die
Generating key pair......................+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++* ...+............+..+.+..................+......+.....+....+.....................................................+..+.............+.........+...+.........+......+............+.....................................................+........+................+..............+...........+................................+..........+........+...+....+..+....+...............+.....+.......+..+.........+...+..+....+.......................+..+.......+..+.........+...+..................+.+.......+.....+...............+.............+..+....+..............+.....+...................+..........+.........+.+......+...........+....+......................+.......+........+.........+...+..............+..............+.+...+.+........+.........+....+...+.+..+..........................+..........+.+............+..........+.......+.....................+.+.....+...............+.................+.......+.+......+.+......+.........................+.....+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
Kdiesec.killall.die.+003+45065
-a -> Criptografia utilizada
-b -> Fonte de dados aleatórios.
-n -> O tipo de dono da chave(Zone).
È interessante usar alguma tool que gera entropia no sistema, por exemplo à haveged.
Vai ser gerado então 4 chaves, duas privadas e duas públicas, as chaves públicas(.key) devem ser linkadas no arquivo da zona.
-rw-r--r--. 1 root root 815 Jan 20 15:03 Kdiesec.killall.die.+003+45609.key
-rw-------. 1 root root 761 Jan 20 15:03 Kdiesec.killall.die.+003+45609.private
Adicionar os arquivo .key no arquivo da zona:
vim /etc/named/zones/db.diesec.kiallall.die +
$include "/var/named/Kdiesec.killall.die.+003+45609.key";
$include "/var/named/Kdiesec.killall.die.+003+45065.key";
Assinando a zona:
[root@masterslave-dns named]# dnssec-signzone -r /dev/urandom -o diesec.killall.die -t /etc/named/zones/db.diesec.kiallall.die
Verifying the zone using the following algorithms: DSA.
Zone fully signed:
Algorithm: DSA: KSKs: 1 active, 0 stand-by, 0 revoked
ZSKs: 1 active, 0 stand-by, 0 revoked
/etc/named/zones/db.diesec.kiallall.die.signed
Signatures generated: 17
Signatures retained: 0
Signatures dropped: 0
Signatures successfully verified: 0
Signatures unsuccessfully verified: 0
Signing time in seconds: 0.009
Signatures per second: 1849.836
Runtime in seconds: 0.047
Será criado um arquivo .signed no diretório onde está à zona, então é necessário alterar no arquivo de declaração da zona o novo arquivo de zona.
zone "diesec.killall.die" {
type master;
#file "/etc/named/zones/db.diesec.kiallall.die"; # Zone File Path
file "/etc/named/zones/db.diesec.kiallall.die.signed"; # Zone File Path
};
zone "0.0.10.in-addr.arpa"{
type master;
file "/etc/named/zones/db.0.0.10" ; #10.0.0.0/26 subnet, i hope
};
[root@masterslave-dns zones]# rndc reload
server reload successful
Verificando a zona:
# dig DNSKEY diesec.killall.die. @10.0.0.5 +multiline
; <> DiG 9.9.4-RedHat-9.9.4-51.el7_4.1 <> DNSKEY diesec.killall.die. @10.0.0.5 +multiline
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51278
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;diesec.killall.die. IN DNSKEY
;; ANSWER SECTION:
diesec.killall.die. 604800 IN DNSKEY 257 3 3 (
CL6mqsDmNpWfcMl3doep7AYAfxybmejv5TL3MRaCCeRC
tHmBotuRmAmeq38VsXw1Vt1tjeGU1V2k2OT0VDPASYrA
qRZ9/EI0b2kwDdr6mHoorXeJtjV4O2F1LjZLKO4fojn6
KOiv9qDx9HMVsU3KamY/oIH3hqjvKre6/qYc4xKYEFD9
vPF2VanMsHxBBmyJ9ZAy1eNQaafTRMiVdNDVoODiUHyA
SqJHVf5x9MXkUjWfpl6oLeN3vUFIOHdI0j1kBgDZzvHd
9AFe6Qa5l2IVVzGyY5Aw/DCSFLsbe3J6VvhGMdWqSh/d
7mIhCyATb5oAMGy5vKdiikDhV6lZrDcmHCm+EKlb/C3w
iLJzvLQAOLyF/MhTlWvwd5Z6lmwHjd68MPj5XuRNrvXQ
OegUKF9kEHYCaObbBRDLFWQSUrotvutCsCcTXTWjQ1QM
L15GoYtI2H6W3ww8rboC8WerfPifQm3MvYDvDOzddVGo
+OFsNX1ZgOrNY2tBjH2MO5wqpLQIe0eG1pu7f12C2qXl
kmrx4MFQIYw+
) ; KSK; alg = DSA; key id = 45065
diesec.killall.die. 604800 IN DNSKEY 256 3 3 (
CPpMmf52jMIBpTpSNmPUGC7r7Lvhl4hLVWfNJIPWPzkt
kLxQ5whCmcmBdQNX27HdOuHRoM/3KRLbWEYuauPjdXZN
e2cS5Fj0giCfWRy8Oe0G0M9brgsX6HJhCz2NQQDMnMKx
JQCyFWlPcjZWZi0trPqxkfeXnna0JxYLzyMFzKdov/zo
0f1dUPIf+kinz668mQfso898RUl69/4awoi4KGIXGeWF
dGSxpESH33AqvXK50hoNv7UmoBSNFhmXNT+Zi/R17ufy
xwal5giibT2nNcogfkMzMT6E0d1Qcr78R37BqvOMtxmK
n11eHAQjSaGIXLT2nMOEb4pG9IUrUYW1RgDQUbPILj2Z
vUBf/4oXh9xD0fTO1lJCnGvazbre5yWT4jqOOI0Ztyhq
sScIOAsE6hLB4JjlzcbbheVnrC4F5kuRWtV2rAUTXnP9
C4pxwkqILN1sjC7tQ17gxCuEaxYb4tkd0SjjbRF3aq/p
KTBU0+4NkbjdLYscsqwPFz40Oicd0o+CgtibuCvapmHF
1F6XJ5i3+XxH
) ; ZSK; alg = DSA; key id = 45609
;; Query time: 0 msec
;; SERVER: 10.0.0.5#53(10.0.0.5)
;; WHEN: Sáb Jan 20 16:24:14 -02 2018
;; MSG SIZE rcvd: 889
Outras medidas de segurança:
-> Ocultar a versão do BIND
options {
// ...
version "hidden";
};
-> Limitando acesso.
As ACL(Access Control List) devem ser implementadas limitando o acesso apenas para hosts confiáveis.
acl "trusted" {
localhost;
192.168.1.0/24;
};
-> Limitando querys normais:
Através da diretiva allow-query
-> Limitando transferência de zonas:
A diretiva allow-transfer deve ser usada para limitar a transferência de zonas apenas para os seus servidores slaves. Essa diretiva pode ser definida tanto no campo global options { } ou dentro da zona, porém a definição dentro da zona sobreescreve a global. É importante bloquear também a transferência de zona dos servidores slaves.
Chroot
Você pode isolar o processo em um diretório, onde o processo ficará isolado dentro de um "novo" diretório raiz, sem acesso ao diretório raiz do sistema em si. Segue abaixo um breve tutorial de como realizar isso:
1 - Pare o serviço:
rndc stop
2 - Crie os diretórios:
mkdir -p /var/lib/named/etc
mkdir -p /var/lib/named/dev
mkdir -p /var/lib/named/var/cache/bind
mkdir -p /var/lib/named/var/run/bind/run
3 - Mova o diretório e crie um link simbolico:
mv /etc/bind /var/lib/named/etc/
ln -s /var/lib/named/etc/bind /etc/bind
4 - Crie arquivos e altere permissões
mknod /var/lib/named/dev/null c 1 3
mknod /var/lib/named/dev/random c 1 8
chmod 666 /var/lib/named/dev/null
chmod 666 /var/lib/named/dev/random
chown -R nobody:nogroup /var/lib/named/var/*
chown -R nobody:nogroup /var/lib/named/etc/bind
5 - Altere a configuração para rodar em chroot no arquivo /etc/default/bind
OPTIONS="-u bind -t /var/lib/named"
6 - Inicie o serviço:
/etc/init.d/bind9 start
The Logging Statement
Uma diferença entre o Bind 8 e o Bind 9 é que o bind 8 inicia o sistema de log já de inicio do programa, já o bind9 apenas depois que todos os arquivos de configuração foram iniciados. Enquanto está iniciando, o servidor encaminha todas as mensagens de log a respeito de erros de sintaxe para a configuração dos channels default, esses erros podem ser redirecionados para a saida padrão se a opção -g for definida durante a inicialização.
Vamos focar na diferença entre categories e channels.
- Categories -> É uma definição de saída, um channel nullo, por exemplo não encaminha log algum
- Category -> É o tipo de data
Uma categoria por exemplo é a security, um exemplo abaixo de redirecionamento dessa categoria para o default_syslog:
logging {
category security { default_syslog; };
// ...
};
Para desabilitar alguns tipos de logs, basta definir um channel null:
logging {
category lame-servers { null; };
category cname { null; };
};
No exemplo acima, todas as mensagems do tipo lame-servers e cname vão ser descartadas.
Fontes:
https://pt.wikipedia.org/wiki/Dom%C3%ADnio_de_topo
https://www.digitalocean.com/community/tutorial_series/an-introduction-to-managing-dns
https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-a-private-network-dns-server-on-centos-7
Classless IN-ADDR.ARPA Delegation
https://www.verisign.com/en_US/website-presence/online/how-dns-works/index.xhtml
http://kb.odin.com/en/120888
https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-a-caching-or-forwarding-dns-server-on-ubuntu-14-04
https://www.digitalocean.com/community/tutorials/how-to-setup-dnssec-on-an-authoritative-bind-dns-server--2
ftp://ftp.registro.br/pub/doc/configuracao_dnssec_dominio.pdf
https://kb.isc.org/article/AA-00608/0/Converting-Zone-Files-Between-Text-and-Raw-Formats.html
http://man7.org/linux/man-pages/man2/mknod.2.html
