View Comments
Tive que fazer uma interface de gerenciamento de DNS round-robin para fazer um "poor high-availability". Consiste em de um telefone celular ou de qualquer browser controlar os servidores que fazem parte de uma entrada round-robin do DNS. Utilizei python para fazer um CGI simples que faz uma consulta no servidor de DNS para ver quais servidores estão atualmente respondendo e a página abre com estes servidores pré-selecionados. Você seleciona os servidores que deverão ser utilizados para a entrada e da um atualizar e ele atualiza via dynamic update no BIND.
Primeiro, vamos configurar o bind para permitir dynamic update. Você precisa criar uma chave de host(que chamarei de pauba) utilizando o comando:
# dnssec-keygen -a HMAC-MD5 -b 512 -n host pauba
Este comando irá criar dois arquivos no diretório que você estiver:
Kpauba.um_monte_de_numero.key Kpauba.um_monte_de_numero.private
No arquivo .private, você precisa pegar a Key que ele gerou e acrescentar no named.conf(substituia sua key pelos XXXXXX== abaixo):
key "pauba" { algorithm hmac-md5; secret "XXXXXXXXXXXXXXXXXXXXXXXXXX=="; }; zone "suazona.com.br" { type master; allow-transfer { 1.2.3.4; }; notify yes; allow-update { key "pauba."; }; file "/var/lib/bind/db.suazona.com.br"; };
Com isto o bind vai permitir atualização dinâmica da zona de qualquer um utilizando a chave acima.
Agora vamos ao programa. Você vai precisar do dnspython, no ubuntu, aptitude install python-dnspython.
No host que você irá criar o programa, o apache precisa estar configurado para permitir ExecCGI e o ScriptAlias precisa estar configurado também.
O código está abaixo.
#!/usr/bin/env python import dns.query import dns.tsigkeyring import dns.update import dns.resolver import dns.rdataset import cgi import sys keyring = dns.tsigkeyring.from_text({ 'pauba.' : 'XXXXXXXXXXXXXXXXX==' }) # A entrada round-robin entrada = 'www' # O dominio dominio = '.suazona.com.br' # O servidor de DNS master com BIND configurado servidor_master = '4.3.2.1' class clsServers: name = "" address = "" checked = "" def __init__(self, name="", address="", checked=""): self.name = name self.address = address self.checked = checked servidores = [] servidores.append(clsServers('img1-us', '1.1.1.1')) servidores.append(clsServers('img2-us', '1.1.1.2')) servidores.append(clsServers('img1-br', '1.1.2.1')) servidores.append(clsServers('img2-br', '1.1.2.2')) servidores.append(clsServers('img1-ne', '1.1.3.1')) servidores.append(clsServers('img2-ne', '1.1.3.2')) servidores_no_ar=dns.resolver.query(entrada+dominio, 'A') for rdata in servidores_no_ar: for servidor in servidores: if (servidor.address == rdata.address): servidor.checked="checked" def generateHeader(): print "Content-type: text/html\n" print "<html>" print "<head><title>Atualizacao de DNS de Imagens</title></head>" print "</head>" print "<body>" def generateFooter(): print "</body>" print "</html>" def generateForm(): print "<h3>Selecione os Servidores</h3>" print "<form method='post' action='/cgi-bin/dnsupdate.py'>" for servidor in servidores: print "<input type='checkbox' name='" + servidor.name + "' value='" + servidor.address + "' " + servidor.checked + " />" + servidor.name + "<br/>" print "<br/>" print "<input type='submit' name='btnEnviar' value='Enviar'>" print "</form>" def main(): form = cgi.FieldStorage() if (form.has_key("btnEnviar")): generateHeader() update = dns.update.Update(dominio, keyring=keyring) update.delete(entrada) for key in form.keys(): if (key.find('img') == 0): update.add(entrada, 300, 'A', form.getvalue(key)) response = dns.query.tcp(update, servidor_master) generateFooter() else: generateHeader() generateForm() generateFooter() main()
E é isto. Dúvidas, críticas e sugestões, os comentários estão aí para isto.