LPI-2 202-450 Topico 207.3
Segurança em DNS
Índice
207.3 Segurança de DNS - Objetivos
Peso 2
O candidato deve ser capaz de configurar um servidor DNS para operar sob um usuário diferente do root e dentro de um ambente chroot. Este objetivo inclui realizar a troca segura de dados entre servidores DNS.
Conhecimentos-chave:
- Arquivo de configuração do BIND 9;
- Configuração do BIND para operar num ambiente chroot;
- Dividir a configuração do BIND usando redirecionamentos;
- Configurar e utilizar assinaturas de transação (TSIG);
- Assinar zonas com DNSSEC;
- Noção do registro DANE.
Lista parcial dos arquivos, termos e ferramentas utilizados:
/etc/named.conf
/etc/passwd
- DNSSEC
dnssec-keygen
dnssec-signzone
207.3 Segurança de DNS - Conteúdo
Quando se pensa em segurança de DNS, logo vem à mente a indisponibilidade do servidor e por consequência a incapacidade de resolver nomes em endereços de IP. Porém além dessa consequência óbvia um outro problema até mais grave seria acessar uma máquina que teria maliciosamente tomado o nome de uma máquina autêntica. Essa técnica é conhecida como DNS poisoning. Muito utilizada para roubar dados sensíveis como informações de cartão de crédito e mais.
Jaula de CHROOT
Outro dos riscos conhecidos a que os servidores DNS são expostos é a possibilidade de um invasor obter acesso ao servidor onde está rodando o serviço do BIND. Para evitar esse tipo de ataque o daemon do BIND pode rodar em um ambiente isolado onde só existam os componentes necessários à sua execução. Esse ambiente é denominado "jaula chroot".
Configurar o servidor BIND DNS para rodar em chroot jail pode ser bem complexo. Mas, com base na distro que escolhermos, muitas configurações podem ser feitas automaticamente.
Por exemplo, diferente do Debian, no CentOS por padrão todas as
configurações são colocadas no arquivo /etc/named.conf
.
Porém ao instalar o pacote bind-chroot
é criado todo o ambiente e
os links necessários para rodar o daemon do BIND em CHROOT.
Ele criará o diretório /var/named/chroot
e colocará os links para
"dev
, etc
, lib64
, usr
e var
" com os respectivo subdiretórios
necessários.
Por fim devemos editar o arquivo /etc/default/bind9
acrescentando
-t /var/named/chroot
ao final da linha OPTIONS
.
# run resolvconf? RESOLVCONF=no # startup options for the server OPTIONS="-u bind -t /var/named/chroot"
DNSSEC
O DNSSEC é um complemento do BIND.
O objetivo original do DNSSEC era proteger os clientes da Internet de dados DNS falsos, verificando as assinaturas digitais incorporadas nos dados. Se as assinaturas digitais nos dados corresponderem às armazenadas nos servidores DNS mestre, os dados poderão continuar para o computador cliente que está fazendo a solicitação.
O DNSSEC usa um sistema de chaves públicas e assinaturas digitais para verificar os dados. Essas chaves públicas também podem ser usadas por sistemas de segurança que criptografam dados à medida que são enviados pela Internet e depois os descriptografam quando recebidos pelo destinatário pretendido. No entanto, o DNSSEC não pode proteger a privacidade ou confidencialidade dos dados porque não inclui algoritmos de criptografia. Ele carrega apenas as chaves necessárias para autenticar os dados DNS como genuínos ou genuinamente indisponíveis.
Funcionamento do DNSSEC
Para entender como funciona o DNSSEC precisamos conhecer alguns itens: RRsets, ZSK, RRSIG, DNSKEY e KSK.
Resource Records sets (RRsets) ou Conjuto de Registro de Recursos
É um agrupamento de registros semelhantes que estejam abaixo de um "label". Como por exemplo zabbix.tools.infralinux.com.br, wiki.tools.infralinux.com.br, pass.tools.infralinux.com.br
No caso todos os nomes exemplificados acima ficam abaixo de "tools.infralinux.com.br", logo todos eles podem ser agrupados em um mesmo RRset.
Zone-signing key pair (ZSK) ou par de chaves de assinatura de zona
Cada zona no DNSSEC tem um par de chaves de assinatura de zona (ZSK). A parte privada da chave assina digitalmente cada RRset na zona, enquanto a parte pública verifica a assinatura.
Resource Records SIGnature RRSIG ou Assinatura de Registro de Recursos
Ao habilitar o DNSSEC, o administrador do DNS cria assinaturas digitais para cada RRset usando o ZSK privado e publica essas assinaturas digitais como um registro do tipo RRSIG no DNS.
Isso é como dizer: “Estes são meus registros DNS, eles vêm do meu servidor e devem ser parecidos com isto”.
Quando um resolvedor de DNSSEC solicita um tipo de registro específico (por exemplo, AAAA), o servidor de nomes também retorna o RRSIG correspondente. O resolvedor pode então obter o registro DNSKEY contendo o ZSK público do servidor de nomes. Juntos, o RRset, o RRSIG e o ZSK público podem validar a resposta.
Se confiarmos na chave de assinatura de zona no registro DNSKEY, podemos confiar em todos os registros na zona. Mas, e se a chave de assinatura de zona foi comprometida? HA HA HA, Precisamos de uma forma de validar o ZSK público. A solução é encontrar uma maneira de verificar o ZSK Público. Vamos usar o KSK!
Key Signing Keys (KSK)
Além de uma chave de assinatura de zona, os servidores de nomes DNSSEC também têm uma chave de assinatura de chave (KSK). O KSK valida o registro DNSKEY exatamente da mesma maneira que nosso ZSK protegeu o resto de nossos RRsets na seção anterior: Ele assina o ZSK público (que é armazenado em um registro DNSKEY), criando um RRSIG para o DNSKEY.
Assim como o ZSK público, o servidor de nomes publica o KSK público em outro registro DNSKEY. Tanto a KSK pública quanto a ZSK pública são assinadas pela KSK privada. Os resolvedores podem então usar o KSK público para validar o ZSK público.
Como funciona a validação de um registro dentro do DNSsec
A validação executada pelos resolvers é algo como:
- Solicite o RRset desejado, que também retorna o registro RRSIG correspondente.
- Solicite os registros DNSKEY contendo o ZSK público e o KSK público, que também retorna o RRSIG para o RRset DNSKEY.
- Verifique o RRSIG do RRset solicitado com o ZSK público.
- Verifique o RRSIG do DNSKEY RRset com o KSK público.
Colocando em prática o DNSSEC
Criando as chaves para assinar a zona
dnssec-keygen
O comando
dnssec-keygen
gera todos os tipos de chave para o DNSSEC. Esse comando conta com as seguintes opções:-a
define o algorítmo;-b
o tamanho da chave;-n
define o tipo da chave que pode serZONE
para o DNSSEC ouHOST
para o TSIG;-f
seta a flag no campo flag do registro KEY/DNSKEY. Somente existem duas flags possíveisKSK
eREVOKE
.
- Criando a KSK
dnssec-keygen -a RSASHA256 -b 512 -n ZONE -f KSK nova.com.br
- Criando a ZSK
dnssec-keygen -a RSASCHA256 -b 512 -n ZONE nova.com.br
Note que nesse segundo comando não utilizamos o
-f
(algo que aparentemente não faz diferença).Outra coisa, na documentação do Debian indica que ao criar a chave KSK deve-se utilizar um valor de 2048, porém na hora de criar a ZSK utiliza-se o tamanho de 1280, meio que a metade. Há até uma tabela com relacionamentos com top level domains.
Assinando a zona
dnssec-signzone
Análogo ao seu nome o comando
dnssec-signzone
é responsável por assinar a zona. Atenção para as opções:-o
zona e/ou arquivo da zona-S
procura automáticamente os arquivos de zona para assinar
- Assinando a zona
# dnssec-signzone -o nova.com.br -S db.nova.com.br Fetching ZSK 20463/RSASHA256 from key repository. Fetching KSK 13030/RSASHA256 from key repository. Verifying the zone using the following algorithms: RSASHA256. Zone fully signed: Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked ZSKs: 1 active, 0 stand-by, 0 revoked db.nova.com.br.signed
Como pode ser notado acima o comando identifica sozinho as chaves ZSK e KSK fazendo a assinatura da zona. Criando automaticamente o arquivo de zona assinado colocando a extensão
.signed
no final do nome do arquivo de zona "normal", ficandodb.nova.com.br.signed
.; File written on Sat Mar 20 22:06:35 2021 ; dnssec_signzone version 9.11.5-P4-5.1+deb10u3-Debian nova.com.br. 259200 IN SOA floid.nova.com.br. hostmaster.nova.com.br. ( 2007060401 ; serial 28800 ; refresh (8 hours) 7200 ; retry (2 hours) 2419200 ; expire (4 weeks) 86400 ; minimum (1 day) ) 259200 RRSIG SOA 8 3 259200 ( 20210420000635 20210321000635 20463 nova.com.br. oY/Z1KFoJ8b7OIYXXeS+KF2OYPSgE9X4Jh9/ rYSoTyBhM0YYRdnUPEa+JM9s+dcRbjdW95uv 5U9clrSrehe7gQ== ) 259200 NS floid.nova.com.br. 259200 RRSIG NS 8 3 259200 ( 20210420000635 20210321000635 20463 nova.com.br. n5z7o+gOQDPJWmXnb+DokbOPeRmmAMQLRjNt bjx7u/4UjbkDGARCMp902e9mc7sEpm89Sv6s lXwZTL3c03dw5A== ) 259200 MX 5 mail.nova.com.br. 259200 RRSIG MX 8 3 259200 ( 20210420000635 20210321000635 20463 nova.com.br. tspO0758AmKAGzZy1wlqZ+GB+oidxfw2KTrV QGNdJSb5d5/+KJ9oiwRiCc3EBWPMS5X1uFJG 7FF8sC3BVxDMUw== ) 86400 NSEC floid.nova.com.br. NS SOA MX RRSIG NSEC DNSKEY 86400 RRSIG NSEC 8 3 86400 ( 20210420000635 20210321000635 20463 nova.com.br. NNXoDYTMjnP+8U/64q6PkWOWZzw5mmLSUUhw SjecqKQ8S1g5mn3EBog9XbTEelPBUqMCvrR6 5SyTHigUc4pMNw== ) 259200 DNSKEY 256 3 8 ( AwEAAdUmy4klg9r2bUnbz9y/A9w6nahC8MlV 0qQ3z+uvjpvbsXwZtp8cflzh+db8H4x6+LP6 IvkMN7k0Qli+knsoQGE= ) ; ZSK; alg = RSASHA256 ; key id = 20463 259200 DNSKEY 257 3 8 ( AwEAAa+ypHJR/9fJCgrzsDNdHlyyEjvfNKK7 XUXkg6hYC53B4/QDV7LnRbfMQo1aGCO35GQi 8yWjQsWrIIAlgGpkRwE= ) ; KSK; alg = RSASHA256 ; key id = 13030 259200 RRSIG DNSKEY 8 3 259200 ( 20210420000635 20210321000635 13030 nova.com.br. L0DRVXnvNCKZ7Uud6F85JtiHix/nIGIuZRyz msjxJVDrxqsGdI/pSDuHTik9srmibNe92U8u AMleprUixjCArA== ) 259200 RRSIG DNSKEY 8 3 259200 ( 20210420000635 20210321000635 20463 nova.com.br. xZV/2qOLoDC7f/90aOm9e8q71Uan2EyPRLeG 9jhY3y4VfQ0WHmZJa0KVvu2X0LLIXpsT9iN1 IzND0Zebo2FcCQ== ) floid.nova.com.br. 259200 IN A 10.152.240.42 259200 RRSIG A 8 4 259200 ( 20210420000635 20210321000635 20463 nova.com.br. iIbd2ZZTujTHA2d2yd1ykGx4+6kkd8ay6UJ1 KZlemI7OVngvYJElf9WfHqt5T8lhq724ERO7 4+N42SOSMftr4w== ) 86400 NSEC mail.nova.com.br. A RRSIG NSEC 86400 RRSIG NSEC 8 4 86400 ( 20210420000635 20210321000635 20463 nova.com.br. hXaT71/fmwpgLYgLEgIuDOXASzBmXZwqHMg2 mMjor85lQUzzry/9ONi5BoVry8TGkMedSqu2 WBC31aBBkNfILg== ) mail.nova.com.br. 259200 IN A 10.152.240.40 259200 RRSIG A 8 4 259200 ( 20210420000635 20210321000635 20463 nova.com.br. jR6Yo1ElWBx/8foJPVaEFzicSu/BQBTZyQgO gZLIJZvMGzFaTkoEWpGrOItfafla7ryLUI4Y n1jxWFP9mzW2og== ) 86400 NSEC nova.com.br. A RRSIG NSEC 86400 RRSIG NSEC 8 4 86400 ( 20210420000635 20210321000635 20463 nova.com.br. tFAacO7PH9pbNKEh22HoxsWC8oAmoqnNMVyY jPvPra0dp610jwik02edIVxT2Az1QarNViXP it5GU0donZqZlw== )
Note que no arquivo de zona novo foram criadas entradas NSEC e RRSIG.
Primeiro ajusta-se o permissionamento dos arquivos de chave:
chgrp bind Knova.com.br.+*
chmod g=r,o= Knova.com.br.+*
Agora com a zona assinada precisam ser adicionadas as seguintes opções (seção
options
) da configuração do named (named.conf
no Centos ounamed.conf.options
no Debian).dnssec-enable yes; dnssec-validation yes; dns-seclookaside auto; <== não precisa mais
Edita-se o arquivo
named.conf
no CentOS ou onamed.conf.default-zones
no Debian:zone "nova.com.br" { inline-signing yes; auto-dnssec maintain; serial-update-method increment; key-directory "/var/cache/bind"; type master; file "db.nova.com.br.signed"; };
Faça as validações com os comandos
named-checkconf
enamed-checkzone
e dê um reload na zona com o comandorndc reload
.A partir desse ponto a zona irá entregar junto com as resoluções os respectivos RRSIG.
Porém o setup ainda não foi 100% finalizado. No momento que executamos o comando
dnssec-signzone
também foi criado um arquivo com o préambulodsset-
no nome, no nosso exemplo foi criado o aquivodsset-nova.com.br
. Este arquivo não precisa ser apresentado na configuração do DNS, porém seu conteúdo é muito importante ele contém o Registro DS (Delegation Signer ou assinatura de delegação em tradução nossa). No caso precisamos criar em nosso DNS autoritativo (aqui no Brasil geralmente o Registro.BR) junto com as entradas de delegação de NS o registro NS com os dados desse arquivo.Importante se você delegar um subdomínio a partir de seu domínio, este subdomínio para ser assinado precisará conter o registro DS relativo a ele.
Como o processo de assinatura de zonas é um processo manual, será necessário reexecutá-lo todas as vezes que os dados da zona forem alterados. Será necessário ajustar as chaves adicionando e removendo registros DNSKEY (e interagindo com o registro pai) nos momentos apropriados.
- Testando publicamente a validade da assinatura da zona
A Verisign labs mantém uma ferramenta de validação de DNSSEC muito prática de usar, ela está acessível no endereço:
https://dnssec-debugger.verisignlabs.com/
Onde apenas precisamos preencher a caixa de texto com o endereço a validar, ela nos apresentará toda a cadeia de assinatura desde o registro de recurso até a raíz.
Pode-se testar também diretamente seu endereço apenas colocando ele no final do endereço da ferramenta da seguinte forma:
https://dnssec-debugger.verisignlabs.com/lpi-2.infralinux.com.br
Transaction Signatures (TSIG) Assinatura de Transações
Assinaturas de transação (TSIG) é um mecanismo usado para proteger mensagens DNS e fornecer comunicação segura de servidor para servidor (geralmente entre o servidor mestre e escravo, mas também pode ser estendido para atualizações dinâmicas). O TSIG pode proteger os seguintes tipos de transações entre dois servidores DNS:
- Transferência de zona;
- Notificação (Notify);
- Dynamic updates;
- Consultas recursivas (Recursive query).
De uma forma mais simples, usamos TSIG para proteger a transferência de zona entre o servidor DNS mestre e escravo. O TSIG usa segredos compartilhados (TKEY) e uma função hash unilateral para autenticar mensagens DNS. TSIG é fácil e leve para resolvers e named.
Como já exposto anteriormente o comando
dnssec-keygen
gera as chaves para o DNSSEC mas também pode ser
utilizado para criar as chaves TKEY. Diferentes algoritmos
podem ser escolhidos.
Note que diferente dos outros comandos que executamos aqui nós
colocamos no argumento -n
a opção HOST
e ao invés de colocar
a zona em si colocamos ao final do comando um nome qualquer
para gerar a chave compartilhada TKEY.
# cd /var/named # dnssec-keygen -a HMAC-MD5 -b 128 -r /dev/uramdom -n HOST novakey
Quando o comando finalizar serão criados 2 arquivos (.key
e
.private
) no formato Knnnn.+aaa+iiii
. Os elementos significam:
- nnnn: Nome da chave;
- aaa: representação numérica do algoritmo;
- iiii: identificação da chave (ou impressão digital).
Como o TSIG utiliza chaves compartilhadas, só precisaremos de
um dos conteúdos desses arquivos, no caso utilizaremos Key:
yUnRjpQ4LgR3MBjud86Abg==
do arquivo de final .private
para
usar nos servidores master e slave. Assim criaremos o arquivo
de chave named.conf.tsig
.
key "novakey" { algorithm HMAC-MD5; secret "yUnRjpQ4LgR3MBjud86Abg=="; };
Agora devemos incluir o arquivo de chave na configuração do
named named.conf
inserindo a linha:
include "/etc/bind/named.conf.tsig";
Por fim podemos editar o arquivo named.conf.default-zones
permitindo a transferência de zonas mediante a chave
compartilhada:
allow-transfer { key "novakey"; };
Os servidores DNS que buscam dados no servidor onde o DNSSSEC foi utilizado poderão agora validar os dados por meio da chave compartilhada.
Feito os ajustes agora apenas precisamos fazer o reload do
rndc
.
Ajuste no servidor secundário (slave)
Após esse ajuste, se efetuarmos algum ajuste de zona incrementando o serial do servidor primário o secundário começará a apresentar mensagens de erro no log semelhantes a:
Transfer status: REFUSED
failed while receiving responses: REFUSED
Logo precisamos ajustar a transferência de zona com a chave compartilhada que criamos acima.
Assim copiamos o arquivo named.conf.tsig
que havíamos criado no
primário e referenciamos ele no named.conf
do servidor secundário.
server 10.152.240.42 { keys { "novakey" ; }; };
DANE
Também o DNS também pode ser utilizado para melhorar a segurança de outros serviços, como o HTTP. É possível inserir um registro no DNS atestando um vínculo extra entre o certificado e o domínio, que pode ser verificado pelo software cliente, como o browser. Para esse fim é utilizado o padrão DANE - DNS-based Authentication of Named Entities - que opera em conjunto com o DNSSEC.
O DANE precisa que os registros DNS sejam assinados com DNSSEC para que seu modelo de segurança funcione. Além disso, o DANE permite que um proprietário de domínio especifique qual CA tem permissão para emitir certificados para um recurso específico, o que resolve o problema de qualquer CA ser capaz de emitir certificados para qualquer domínio.
O registro TLSA
O registro de recurso TLSA DNS (RR) é usado para associar um certificado de servidor TLS ou chave pública ao nome de domínio onde o registro se encontra, formando assim uma "associação de certificado TLSA". Em conjunto com as assinaturas DNSSEC, isso permitirá maneiras melhores e mais seguras para os aplicativos autenticarem certificados. Aqui está um exemplo para o serviço HTTPS (porta 443, TCP) em www.example.com:
_443._tcp.www.example.com. IN TLSA ( 0 0 1 d2abde240d7cd3ee6b4b28c54df034b9 7983a1d16e8a410e4561cb106618e971 )
Restringir acesso
Você deverá restringir algumas das informações que são servidas pelo
BIND para clientes externos, assim não poderão ser usadas para obter
informações sobre sua empresa que não deseja dar. Isto inclui
adicionar as seguintes opções: allow-transfer
, allow-query
,
allow-recursion
e version
. Você pode limitar isto na seção global
(assim aplicando a todas as zonas que são servidas) ou por zona
.
Imagine que seu servidor (um servidor básico contendo múltiplos
endereços) está conectado à Internet e à sua rede interna (seu
endereço IP é 192.168.1.2
), você não vai querer oferecer qualquer
serviço para os computadores. Você poderá restringir o bind
incluindo o seguinte no /etc/bind/named.conf
:
options {
allow-query { 192.168.0/24; } ;
allow-transfer { none; } ;
allow-recursion { 192.168.1/24; } ;
listen-on { 192.168.1.2; } ;
forward { only; } ;
forwarders { A.B.C.D; } ;
};
A opção listen-on
faz o BIND ser executado somente na interface que
tem o endereço interno, mas, até mesmo se esta interface for a mesma
que te conecta a Internet (caso estiver usando NAT, por exemplo), as
requisições serão aceitas somente se estiverem vindo de suas
máquinas internas (devido a opção allow-query
. Se o sistema tiver
múltiplas interfaces e a opção
listen-on
não estiver presente, somente usuários internos poderão
fazer requisições, mas, como a porta está acessível para possíveis
invasores externos, eles podem tentar travar (ou tentar realizar
ataques de estouro de buffer) no servidor DNS.
Em algumas zonas pode ser interessante desabilitar completamente a
recursividade, nesses casos a diretiva allow-recurson
pode ser
substituída por recursion no
.
O registro version.bind
contém a versão do processo
do bind atualmente em execução. Esta informação é freqüentemente
usada por scaneadores automáticos e individualmente por pessoas
maliciosas que desejam determinar se o bind é vulnerável a um ataque
específico. Oferecendo informações falsas ou não fornecendo
informações ao registro version.bind
, diminui a probabilidade que o
servidor seja atacado baseado na versão publicada. Para fornecer sua
própria versão, use a diretiva version da seguinte forma:
options { ... várias opções aqui ... version "Não disponível."; };
Uso de ACLs
Com as ACL's (Access Control Lists ou listas de controle de acesso em tradução nossa) podemos criar listas de endereços IP's e designarmos nomes a essas listas, com o único objetivo de quando formos nos referenciar a endereços IP usarmos nomes em vez de números. Algumas acl's já existem e podem ser usadas:
any
- qualquer endereço;
none
- nenhum endereço;
localhosts
- apenas interfaces de loopback;
localnets
- as redes a qual as interfaces de rede onde o servidor Bind está instalado.
acl intranet { 192.168.2.0/24; 192.168.3.0/24; }; acl slaves { 200.4.5.6/32; 200.5.6.7/32; };
Aplicando as opções de segurança
Utilizando nosso arquivo named.conf
de exemplo poderíamos
incrementar a segurança dele da seguinte forma:
acl intranet { 192.168.2.0/24; 192.168.3.0/24; }; acl slaves { 200.4.5.6/32; 200.5.6.7/32; }; options { directory "/var/named"; version "Nao disponivel."; listen-on { 192.168.2.30; }; }; zone "." IN { type hint; file "root.hints"; allow-query { intranet; }; }; zone "gink.go" IN { type master; file "gink.go.zone"; allow-transfer { slaves} }; allow-recursion { intranet; }; }; zone "0.168.192.in-addr.arpa" IN { type master; file "db.192.168.0.in-addr.arpa"; allow-transfer { slaves} }; allow-recursion { intranet; }; allow-update { none; }; };