Controlando DNS round-robin de um Blackberry/IPhone


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.

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Comments

Nenhum comentário ainda.

Deixe um comentário

(obrigatório)

(obrigatório)