A recente vulnerabilidade no protocolo DNS causou uma grande quantidade de estudos sobre o assunto recentemente. No meu trabalho não foi diferente e de certo modo ainda pior.

Depois de analisar com cuidado o atual cenário do DNS por lá e trabalhar alguns dias para aplicar todas as correções, cheguei à conclusão que arrumar a atual configuração seria apenas empurrar com a barriga um problema maior e por isso minha idéia foi implantar um novo par de DNS recursivos para substituir o atual.

O número de usuários locais não é muito grande – cerca de 5000 – mas pelo que fui informado são todos heavy-users e já houve vezes em que o servidor DNS abriu o bico.

O desafio então foi encontrar uma solução que conseguisse atender bem os usuários sem exigir muito hardware, já que serão necessários dois novos servidores para o serviço.

Os candidatos

Depois de uma olhada aqui, adotei os seguintes critérios: Deveria ser Open Source, com possibilidade de rodar no Linux ou no Solaris e eu já deveria, pelo menos, ter ouvido falar.

Os 4 escolhidos foram:

O Teste

Para executar o teste adotei a seguinte estratégia (do grego, estrategie):

  1. Criar uma lista com 1000 FQDNs
  2. Resolver contra o servidor cada um destes FQDNs sequencialmente (serial) pela primeira vez (sem cache)
  3. Resolver contra o servidor cada um destes FQDNs sequencialmente (serial) pela segunda vez (com cache)
  4. Resolver contra o servidor cada um destes FQDNs ao mesmo tempo (paralelo) uma vez (com cache criado pelas interações anteriores)

As Ferramentas

comentei aqui antes que sou um péssimo programador, então é provável que você olhe para os scripts que criei para estes testes e ache uma piada. Criticas construtivas são bem-vindas. Do contrário, vai encher o saco da mãe.

Para gerar a lista de domínios fui na unha fazendo o seguinte:

Fiz isso em muitas URLs (principalmente blogs e entradas da Wikipedia) até que o output do comando abaixo fosse próximo de 1000:

A lista final de FQDNs está neste arquivo aqui.

Em seguida, utilizei este script para o primeiro e segundo teste – resolução serial. Como podem observar, preservei o resultado tanto do STDOUT como STDERR para referência futura.

Para o teste em paralelo, ao invés de bash tive que apelar para Python e o script utilizado foi este outro.

O servidor

Como podem imaginar, uma universidade não tem 96 blade servers top de linha parados num data-center para eu poder brincar, como era no antigo emprego, então tive que me virar com alguma coisa muito mais simples:

Caixa:

  • Pentium 4 3.2GHz
  • 3GB RAM
  • 144GB RAID5 SATA
  • VMWare ESXi 3.5

Instância VMware:

  • Pentium 4 3.2GHz
  • 512MB RAM
  • 8GB HD
  • Ubuntu Server 8.04

** É importante ressaltar que apesar de ser uma instância VMWare, a caixa que roda o host é nova e não tem mais nada instalado, de forma que a performance do host não influenciou o desempenho do guest. **

Todos os 4 DNS foram testados com a configuração mais simples possível, instalando à partir do repositório oficial do Ubuntu, sem nenhum tweak adicional, exceto pelo djbDNS que, por causa da licença, precisa ser compilado do fonte. Para isso utilizei este tutorial aqui.

O Resultado

O resultado não foi o que eu esperava. Sinceramente tinha quase que certeza que a disputa ia ser cabeça à cabeça entre o djbDNS e o MaraDNS, mas os resultados reais estão abaixo:

<td style="border: 1px solid #000000;" colspan="4" width="549" align="center" valign="middle" bgcolor="#666666">
  <strong><span style="color: #ffffff; font-size: small;">SERIAL</span></strong>
</td>
<td style="border: 1px solid #000000;" colspan="2" align="center" valign="middle">
  <strong><span style="color: #4c4c4c;">Sem Cache</span></strong>
</td>

<td style="border: 1px solid #000000;" colspan="2" align="center" valign="middle">
  <strong><span style="color: #4c4c4c;">Com Cache</span></strong>
</td>
<td style="border: 1px solid #000000;" align="center" valign="middle" bgcolor="#666666">
  <strong><span style="color: #ffffff;">Tempo de execução</span></strong>
</td>

<td style="border: 1px solid #000000;" align="center" valign="middle" bgcolor="#0066cc">
  <strong><span style="color: #ffffff;">Erros</span></strong>
</td>

<td style="border: 1px solid #000000;" align="center" valign="middle" bgcolor="#666666">
  <strong><span style="color: #ffffff;">Tempo de execução</span></strong>
</td>

<td style="border: 1px solid #000000;" align="center" valign="middle" bgcolor="#0066cc">
  <strong><span style="color: #ffffff;">Erros</span></strong>
</td>
<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:09:55</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;">2</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:09:10</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;">2</span>
</td>
<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:07:49</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;"></span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:01:07</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;"></span>
</td>
<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:09:47</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;">6</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:02:11</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;">6</span>
</td>
<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:07:08</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;"></span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:01:54</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;">3</span>
</td>
<td style="border: 1px solid #000000;" colspan="3" width="411" align="center" valign="middle" bgcolor="#666666">
  <strong><span style="color: #ffffff; font-size: small;">PARALELO</span></strong>
</td>
<td style="border: 1px solid #000000;" colspan="3" align="center" valign="middle">
  <strong><span style="color: #4c4c4c;">With Cache</span></strong>
</td>
<td style="border: 1px solid #000000;" align="center" valign="middle" bgcolor="#666666">
  <strong><span style="color: #ffffff;">Execution Time</span></strong>
</td>

<td style="border: 1px solid #000000;" align="center" valign="middle" bgcolor="#0066cc">
  <strong><span style="color: #ffffff;">Errors</span></strong>
</td>

<td style="border: 1px solid #000000;" align="center" valign="middle" bgcolor="#666666">
  <strong><span style="color: #ffffff;">Pico de uso da CPU </span></strong>
</td>
<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:00:27</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;">29</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">10.00%</span>
</td>
<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:00:11</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;">1</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">2.00%</span>
</td>
<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:00:22</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;">6</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">11.00%</span>
</td>
<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">00:00:13</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#0066cc">
  <span style="color: #ffffff;">5</span>
</td>

<td style="border: 1px solid #000000;" align="right" bgcolor="#666666">
  <span style="color: #ffffff;">30.00%</span>
</td>
  • Erros são connection time outs que recebi do servidor.
  • Picos de CPU não foram significativos no teste serial

Eu não esperava que o resultado fosse mostrar o PowerDNS como a melhor ferramenta, mas foi isso que os testes mostraram. Depois de ver isso pesquisei um pouco e descobri que grandes instalações, como register.com, tucows.com e mediawiki utilizam este sistema.

Já mandei o resultado da pesquisa para o resto da equipe e espero implementar o PowerDNS em breve.