logoCert_sugestao2.png

DNSSEC: adicionando mais segurança no Sistema de Nomes de Domínio

Introdução

DNSSEC é uma extensão do protocolo DNS para implementar mecanismos de segurança ao protocolo DNS. Através do uso de DNSSEC um servidor de nomes que consulta por um registro qualquer, poderá verificar a autenticidade e integridade das informações recebidas.

Para implementar essas funcionalidades, o DNSSEC faz uso da criptografia de chave pública (ou criptografia assimétrica) e introduz um novo conjunto de Resource Records (RRs) com funções específicas: assinar outros RRs (RRSIG), divulgar a chave pública que valida as assinaturas digitais de um determinado domínio (DNSKEY), garantir a não existência de outros registros (NSEC) e garantir a continuidade do "canal de segurança" na delegação de zonas (DS).

O PoP-BA já possui DNSSEC habilitado em todas as zonas para as quais é autoritativo. Juntamente com a implantação do DNSSEC estamos gerando documentação para que possamos incentivar seu uso por nossos clientes.

Nas sessões seguintes serão abordados alguns aspectos conceituais do DNSSEC, a política adotada pelo PoP-BA para gerenciamento das chaves criptográficas, detalhes da implantação no ambiente do PoP-BA e alguns documentos gerados para referência futura.

Sobre o DNSSEC

O DNSSEC soluciona alguns problemas encontrados na atual tecnologia DNS. Falsas informações DNS criam oportunidades para roubo de informações de terceiros ou alteração de dados em diversos tipos de transações como, por exemplo, compras eletrônicas. No protocolo DNS, um ataque onde a informação é corrompida é extremamente difícil de ser detectado e, na prática, impossível de ser prevenido. O objetivo da extensão DNSSEC é assegurar o conteúdo do DNS e impedir estes ataques validando os dados e garantindo a origem das informações.

DNSSEC introduz segurança no nível estrutural através de uma hierarquia de assinaturas criptográficas adicionadas à registros DNS. Assinatura criptográfica é uma técnica utilizada para validar a origem de uma mensagem e, em alguns casos, garantir que o conteúdo não foi alterado. Dessa forma o cliente consegue validar uma resposta DNS, invés de simplesmente confiar em sua veracidade.

O protocolo DNSSEC é descrito em três RFCs (RFC4033, RFC4034 e RFC4035), juntamente com outras RFCs que tratam de detalhes específicos de operação, resource records, etc. Para mais informações, veja as referências ao final do texto.

Assim como outras técnicas de segurança, como SPF no contexto de segurança no serviço de e-mails, DNSSEC precisa ser implementado na sua infra-estrutura e você precisa checar pela validade nas zonas que também implementam DNSSEC.

Vejamos a seguir o funcionamento básico do DNSSEC.

Uso de criptografia assimétrica para verificar autenticidade e integridade dos dados

Como já mencionamos, o DNSSEC utiliza-se da tecnologia de chaves assimétricas (chaves públicas e privadas) na sua implementação, assim o primeiro passo é gerar as chaves para assinar os registros da sua zona. A chave pública é armazenada no registro DNSKEY e disponibilizada para que outras pessoas possam validar os dados recebidos (isso é herdado do conceito de assinatura digital). Um exemplo ilustrativo da utilização do DNSKEY é o seguinte (dados fictícios):
pop-ba.rnp.br.      IN   DNSKEY   257 3 5 zWDdbb6c4e23ffd4286360712948696129824bc3ff20
pop-ba.rnp.br.      IN   DNSKEY   256 3 5 QGd060ca2fc88f11b73a877e2cfe7e6e7fb788cb7df4

Perceba que nesse caso estamos utilizando duas chaves (dois registros DNSKEY): uma dessas chaves será utilizada para assinar os registros da zona (.. DNSKEY 256...), também conhecida como Zone Signing Key (ZSK), e a outra será utilizada para assinar apenas os registros DNSKEY (... DNSKEY 257 ...), também conhecida como Key Signing Key (KSK). Por que essas duas chaves? Bom, vamos ver isso com mais calma.

O uso de chaves públicas e privadas implica na distribuição da chave pública para que os usuários possam validar as informações recebidas. Nesse sentido fica claro que devemos usar um meio seguro para distribuir as chaves públicas. O DNSSEC prevê duas formas para resolver esse problema da distribuição da chave pública: i) enviar a chave para cada cliente que deseja validar seus dados ou ii) adicionar um hash da chave pública na zona imediatamente acima da sua. Veremos essa questão com mais calma em seguida, mas o importante é notar que a chave pública será distribuída pela Internet de alguma forma.

Por outro lado, chaves públicas e privadas têm uma validade. A validade quase sempre é apresentada no formato "não antes" e "não depois" e é importante pois quanto mais informações criptografadas com uma determinada chave um atacante tiver acesso, mais fácil será quebrar o algoritmo. Isso sugere que teremos que trocar nossas chaves do DNSSEC com alguma frequência. Ainda, teremos que divulgar essa chave para toda a Internet, substituindo a anterior. Ou seja, quanto mais frenquentemente fizermos a troca da chave, mais trabalho teremos para atualizar todas as suas cópias. Nesse caso, seria interessante se tivéssemos uma chave cujo uso fosse menor para distribuir para os clientes, dessa forma o período de validade dela seria maior. Dessa necessidade surge a KSK. Como a KSK assina poucos registros, podemos definir uma validade maior para ela (e pedir para que os clientes a troquem com menos frequência). Já a ZSK, que assina todos os outros registros da zona, precisará ser trocada com uma frequência maior, porém seu impacto não é tão grande para os clientes: não é necessário nenhuma mudança na configuração do servidor, como é o caso da KSK.

É importante que fique claro que se a KSK foi alterada e o cliente não foi informado, todas as consultas para aquele domínio retornaram um erro SERVFAIL.

Outro ponto que merece destaque é que essa questão de distribuição de chaves é menos crítica quando a zona acima da que se está assinando já possui DNSSEC implantando, conforme veremos mais à frente.

Assinatura dos registros e garantia de não existência

Nesse ponto já temos nossas chaves públicas e privadas e precisamos assinar os dados da zona (os RRs). Na verdade, geralmente o software do DNS (o bind9, por exemplo) faz isso com alguns comandos. Mas vamos ver como esse processo funciona de forma geral.

Usaremos a chave privada (armazenada de forma segura no servidor e não divulgada) para assinar grupos de RRs (RRsets) da zona. Essa assinatura gera um novo registro, RRSIG, para cada grupo de RR assinado. O valor do RRSIG é a assinatura digital do RRset equivalente: hash do RRset cifrado com a chave privada. Um grupo de RRs é composto por RR que tem o mesmo nome, o mesmo tipo, mas diferem no valor (server2.pop-ba.rnp.br   IN   A no exemplo abaixo).

Por exemplo, suponha que deseja-se assinar os seguintes registros:
server1.pop-ba.rnp.br     IN    A        192.168.10.2
server2.pop-ba.rnp.br     IN    A        10.1.0.30
                          IN    A        10.1.0.40

Após a geração da chave e assinatura da zona, teremos algo parecido com o seguinte (os dados a seguir são usados somente como exemplo e estamos omitindo uma serie de detalhes):
server1.pop-ba.rnp.br     IN    A        192.168.10.2
server1.pop-ba.rnp.br     IN    RSIG   A    5eZlH2hCUP8MzTY8OjxfveAueLD863oYXN82Kl/X4JjCxI
server2.pop-ba.rnp.br     IN    A        10.1.0.30
                          IN    A        10.1.0.40
server2.pop-ba.rnp.br     IN    RSIG   A    LDJTlGVd5ss2iX5UB+gXQg4Co1A3o54tykd8Hat3wVsRrB

O processo de assinatura dos registros é feita off-line, ou seja, o administrador da zona deve fazê-lo antes de publicar a zona.

Quando um cliente (geralmente o servidor recursivo) recebe a resposta de uma consulta com DNSSEC habilitado, ele recebe duas informações: RRSet (registros consultados) + RRSIG (assinatura do RRSet). No processo de checagem o cliente calculará o hash do RRSet recebido, usará a chave pública da zona para decifrar o RRSIG e fará uma comparação entre o hash gerado por ele e o hash enviado pelo servidor (RRSIG decifrado). Caso sejam iguais, então a resposta é valida; caso contrário os dados foram alterados e teremos uma resposta do tipo SERVFAIL.

Porém, uma vez que a assinatura não é gerada em tempo real, como um servidor poderá assinar a resposta a uma consulta para o qual ele não conhece (ou seja, fornecer uma resposta NXDOMAIN)? Em outras palavras, o servidor precisa fornecer uma resposta autenticada a uma requisição, porém ele não possui os dados para assiná-los previamente (novamente, a assinatura é feita off-line).

Isso é resolvido com o registro NSEC (Next SECure). Esse registro armazena informações sobre o próximo nome na zona, que agora passa a ser ordenada. A grosso modo, cada registro mantem um apontador, através de seu NSEC, para o próximo registro; o último "aponta" para o primeiro. Vamos a um exemplo (serão omitidos uma série de detalhes da definição da zona. O objetivo é somente demonstrar o funcionamento do NSEC):

Suponha que sua zona contém as seguintes informações:
a.pop-ba.rnp.br
d.pop-ba.rnp.br
e.pop-ba.rnp.br

Após assinar a zona DNSSEC, temos:
a.pop-ba.rnp.br
a.pop-ba.rnp.br NSEC d.pop-ba.rnp.br

d.pop-ba.rnp.br
d.pop-ba.rnp.br NSEC e.pop-ba.rnp.br

e.pop-ba.rnp.br
e.pop-ba.rnp.br NSEC a.pop-ba.rnp.br

Assim, caso um cliente consulte por b.pop-ba.rnp.br ele receberá como resposta um registro com o nome a.pop-ba.rnp.br com o NSEC apontando para d.pop-ba.rnp.br, assinado, e o cliente poderá verificar que não existe de fato aquele nome. Isso é chamado de garantia de não existência.

Todo o processo detalhado acima, de reordenação da zona, geração dos registros NSEC e assinatura dos registros, é feito automaticamente pelo software DNS utilizado. No caso do bind, utiliza-se o comando dnssec-signzone para executar o processo acima. Mais informações podem ser obtidas no Procedimento de atualização da zona em servidores DNSSEC-habilitados.

Canal de confiança na hierarquia DNS

Como já mencionamos, teremos que divulgar a chave pública para que os clientes possam validar as informações. O recomendado é que se tenha duas chaves, a ZSK e a KSK, conforme já discutimos, e a chave que é divulgada é a KSK. Cada cliente precisará obter a KSK para validar os dados da zona em questão, assim faz-se necessário uma forma segura de transporte das chaves.

A primeira solução é ter uma cópia local da chave, obtida de forma segura (e-mail assinado, servidor FTP autenticado, HTTPS, etc.). Porém isso é ruim do ponto de vista de atualização da chave: cada cliente teria estar atento às atualizações de chave e atualizar sua cópia local com a nova versão. Isso, na prática, é muito difícil ser implementado. Assim pensou-se em uma forma de utilizar algo semelhante ao processo de delegação de zonas (dados distribuídos com "apontadores" para os próximos servidores de nomes na hierarquia) adaptado para as necessidades do DNSSEC. Daí surge o registro Delegation Signer (DS).

A ideia é armazenar um hash da KSK de uma zona em sua zona pai e deixar a tarefa de ancorar a chave diretamente no cliente (servidor recursivo) somente quando não tivermos como fazer isso com a zona pai. Ou seja, se todos os domínios aplicarem esse processo, apenas precisaremos ancorar as chaves da zona raiz no cliente. Veja a figura abaixo com exemplo dessa relação entre os domínios nl e nlnetlabs.nl.


O processo de validação continua o mesmo. Por exemplo, ao consultar por pop-ba.rnp.br ao servidor da rnp.br, o último responderá com um DS (hash da DNSKEY de pop-ba.rnp.br) assinada com sua chave privada. O cliente então decifra essa assinatura com a chave pública de rnp.br e guardar essa informação para validação futura, digamos Valor1. O cliente então solicita o DNSKEY de pop-ba.rnp.br para o servidor autoritativo daquela zona, aplica a função hash sobre esse DNSKEY e obtém o Valor2. Ora, se Valor1 é igual à Valor2 então a resposta é válida e a Cadeia de Confiança é continuada. Caso contrário, SERVFAIL e uma nova requisição terá que ser feita.

É fácil notar que, nesse esquema, se a raiz tiver DNSSEC habilitado, apenas precisaremos ancorar as chaves do domínio raiz. O processo de assinatura da raiz já foi iniciado e falta pouco para ser finalizado (provavelmente, nesse momento o leitor pode verificar se isso já não ocorreu). A figura abaixo ilustra essa situação:

Em qualquer caso, temos o que chamamos de ilhas de confiança. Ou seja, algumas zonas implementam DNSSEC e delegam uma sub-zona para um servidor que também implementa DNSSEC, mas outras não; algumas zonas não tem sua zona parent com DNSSEC implementado; outras situações. Dessa forma, temos uma situação parecida com o exibido na figura abaixo.

Uma terceira alternativa, é usar a verificação por validação à frente no DNSSEC (DNSSEC Lookaside Validation - DLV). Nesse esquema, um servidor armazena as chaves públicas de todos os outros domínios que estão no início de uma cadeia de confiança. Na figura acima, por exemplo, o DLV teria a DNSKEY das zonas nlnetlabs.nl, 193.in-addr.arpa e 194.in-addr.arpa. Um servidor DLV bastante utilizado é o DLV do ISC. Mais informações: https://dlv.isc.org/about/using.

Manutenção de zona segura

Como já mencionamos, ao assinar uma zona, introduzimos um elemento de tempo às assinaturas dos registros. Esse elemento não é presente em zonas não assinadas e requer uma manutenção periódica da zona. Veremos a seguir algumas implicações de reassinar uma zona além de outros aspectos da manutenção de zonas seguras, em especial o procedimento de troca de chaves (rollover).

Reassinar uma zona envolve simplesmente re-executar o utilitário dnssec-signzone sobre o arquivo de zona original. Arquivos de zona seguras precisam ser re-assinadas por um dos três motivos seguintes:
  1. Na mudança de um registro da zona: anteriormente uma mudança em um registro da zona implicava unicamente na alteração do Serial Number do registro SOA. Com DNSSEC, além de alterar o registro SOA precisaremos re-assinar o arquivo de zona.
  2. Quando uma assinatura expira: Conforme já discutido, ao assinar uma zona, é adicionado um elemento de tempo para indicar a validade do registro. Dessa forma, ao terminar a validade de um registro ele precisará ser re-assinado. O tempo de validade padrão é 30 dias, porém isso pode ser modificado.
  3. Quando alguma das chaves ZSK ou KSK necessita ser alterada: esse procedimento, chamado de rollover, pode ser necessário pela política de chaves da instituição ou por comprometimento de alguma das chaves privadas.

Os dois primeiros processos usam os registros DNSKEY existentes na zona e não tem impacto em servidores de nomes externos. Já o último, envolvendo o rollover de chaves, tem importantes implicações em servidores de nome externos que i) tem um registro DS apontando para a KSK (a zona parent), ii) configurou uma ancora de segurança que se referencia à KSK atual (parâmetro trusted-keys no bind9) ou iii) mantém um cache do registro DNSKEY para a ZSK ou KSK da zona.

A motivação para troca de chaves com certa frequência vem da natureza da criptografia assimétrica, destacando-se os seguintes pontos:
  • Sobre um período de tempo, pode ser possível que um atacante acumule dados criptografados e em texto claro de forma a viabilizar um estudo sobre a chave utilizada;
  • Ataques de força bruta geralmente gastam um certo período de tempo, de forma que se a chave é modificada nesse período o atacante terá que reiniciar o ataque;
  • Se a chave for comprometida sem o conhecimento da equipe de administradores, o atacante estará limitado à explorar essa vulnerabilidade somente durante o período de validade da chave.

Não obstante, o procedimento de troca de chaves traz alguns impactos específicos por tipo de chave (ZSK ou KSK). Alguns desses impactos necessitam de medidas por entidades externas. Elas são as seguintes:
  • Atualizar o registro DS na zona parent (somente para KSK): É necessário entrar em contato com o administrador da zona parent e solicitar que o mesmo substitua o registro DS antigo por um novo, hash da nova KSK. Isso pode levar tempo para ser realizado e esse tempo deve ser considerado quando do planejamento do rollover de chaves.
  • Atualizar as âncoras de confiança nos servidores de nome que a adicionaram (somente para KSK): Caso o administrador de um outro servidor recursivo tenha adicionado a DNSKEY de sua KSK diretamente na configuração dele, essa configuração precisará ser atualizada para a nova chave. Vale lembrar que se a configuração não for atualizada, comum de acontecer quando utiliza-se atualização manual, então os dados da zona serão rejeitados como bogus para qualquer consulta realizada naquela zona, tornando-a indisponível para aquele servidor. Existem processos de atualização automática das chaves, conforme descrito na RFC 5011. A atualização automática de chaves no bind9 está disponível a partir da versão 9.7 e é configurada pelo parâmetro managed-keys.
  • Atualizar cache dos registros RRSIG e DNSKEY nos servidores de nomes (tanto para KSK quanto ZSK): Pode acontecer de a assinatura de um registro ser obtida em um momento diferente do registro DNSKEY, usado para validar aquela assinatura. Por isso, o cache desses registros pode expirar em momentos diferentes, mesmo que tenham o TTL iguais. Ainda, caso a zona seja re-assinada com uma nova chave (KSK ou ZSK) é possível que tenhamos registros assinados com a chave antiga, porém somente a chave nova no cache, ou o contrário. Nesses casos, consultas pelos registros envolvidos ocasionaram uma resposta de falha.

Pelos motivos listados acima, fica claro que não poderá existir um momento único no tempo em que uma zona terá sua chave trocada, seja essa chave a KSK ou ZSK. Felizmente a especificação do DNSSEC permite a utilização de múltiplas chaves na zona (múltiplos DNSKEY) e obriga a utilização de todos eles na validação de uma resposta. Isso permite uma zona operar com ambas as chaves, antiga e nova, durante o período de troca, até que todos os caches tenham expirados e as configurações necessárias tenham sido efetuadas.

A troca de chaves planejada (quando alguma das chaves ZSK ou KSK necessita ser alterada - ver acima) vai depender da política de chaves DNSSEC da instituição. No caso do POP-BA, a ZSK é trocada a cada três meses e a KSK tem validade de 2 anos. Não existem valores ideais para essa política, essa definição vai depender da zona em que se está implantando DNSSEC. Para mais detalhes veja a política de publicação e administração de chaves DNSSEC do POP-BA.

Existem dois métodos utilizados na troca de chaves: Pre-publish e double-signing. No pre-publish a ideia é adicionar a nova chave à zona antes do término da validade da chave anterior (tempo definido na política de chaves da instituição). Assim, os servidores de cache já terão essa nova chave armazenada quando novos registros forem assinados com ela. No double-signing, cada conjunto de registro de recurso (RRset) será assinado duas vezes, uma com a chave nova e outra com a chave antiga. Geralmente utiliza-se o método pre-publish para a troca da ZSK, enquanto double-signing é usado para troca de chave KSK. Recomenda-se a leitura de Métodos de troca de chaves no DNSSEC para entender melhor como cada método funciona e porque da utilização de método específico por tipo de chave a ser substituída. Ainda, o procedimento para substituição manual planejada de chaves DNSSEC é detalhado em Procedimento para troca de chaves DNSSEC.

Implantando DNSSEC

Conforme já discutimos, a implantação do DNSSEC envolve assinar sua zona e adicionar as chaves DNSSEC e habilitar a checagem DNSSEC no servidor recursivo. A primeira etapa é importante para que os outros servidores recursivos possam validar as informações de sua zona, enquanto que o segundo permite que seu recursivo forneça respostas validadas às requisições dos clientes (resolvers).

No link abaixo disponibilizamos um tutorial de como implantar DNSSEC em sua zona, envolvendo o processo de geração das chaves, assinatura dos registros e publicação da chave (seja através de ancoras da chave KSK ou da delegação de zonas com o DS). No tutorial a configuração é feita utilizando-se o bind9.

Já a implantação da checagem DNSSEC no servidor recursivo é detalhada do documento abaixo. Nesse tutorial aborda-se a configuração do bind9.

Ferramentas de teste

Uma vez que a configuração do DNSSEC tenha sido concluída, é momento de testar o servidor recursivo a fim de verificar se a configuração está funcional. Como ferramenta de teste, recomenda-se o uso do utilitário dig com a opção +dnssec para verificar a validade das consultas, ou com a opção +sigchase para verificar o processo de validação do canal de assinaturas DNSSEC. Detalhes e exemplos de utilização do dig para testar o funcionamento do DNSSEC podem ser vistos em Testando DNSSEC com o DIG.

Uma outra opção é utilizar o plugin DNSSEC Validator para Firefox. Esse plugin foi desenvolvido pelo pessoal do NIC da República Checa e verifica as respostas do servidor recursivo, adicionando uma chave à barra de endereços do Firefox dependendo do resultado da validação da resposta:
  • Chave verde: resposta válida;
  • Chave laranja: a resposta possui o RRSIG porém não foi possível validá-la. Pode significar que a zona é assinada com DNSSEC porém o servidor recursivo que você está usando não possui DNSSEC habilitado ou é autoritativo para aquela zona;
  • Chave vermelha: validação falhou, verifique!
  • Sem chave: a zona em questão não possui suporte à DNSSEC.

Para instalar esse plugin no seu Firefox, acesse DNSSEC Validator :: Add-ons for Firefox. Para mais detalhes sobre o plugin, veja a apresentação sobre esse plugin do pessoal do NIC.cz no 60o encontro do RIPE e a página do plugin.

Documentos relacionados

Referências

Organizações & Web sites

RFCs (http://www.ietf.org/IETF)
  • RFC 3833 A Threat Analysis of the Domain Name System
  • RFC 4033 DNS Security Introduction and Requirements (DNSSEC-bis)
  • RFC 4034 Resource Records for the DNS Security Extensions (DNSSEC-bis)
  • RFC 4035 Protocol Modifications for the DNS Security Extensions (DNSSEC-bis)
  • RFC 4398 Storing Certificates in the Domain Name System (DNS)
  • RFC 4641 DNSSEC Operational Practices
  • RFC 5155 DNS Security (DNSSEC) Hashed Authenticated Denial of Existence