Calcular registros A dinamicamente

1

Eu preciso de um servidor DNS que permita essencialmente resolver nomes de host para qualquer IP. Por exemplo, nomes de host parecidos com A-B-C-D.myhost.example.com serão resolvidos para A.B.C.D . (de cource, A é 0-255 e assim por diante. Não há problema em retornar algo inútil para nomes de host inválidos)

Eu vi que bind9 tem $GENERATE diretiva, mas parece ser impossível aninhá-lo (e 2 ^ 32 registros provavelmente quebrariam o servidor ou pelo menos consumiriam muita memória).

Existe algum software que possa fazer isso? (provavelmente algo com suporte a expressões regulares?)

    
por swat32.exe 03.08.2016 / 17:07

1 resposta

3

O PowerDNS suporta vários back-ends, um deles é um back-end de pipe que você pode usar para processar a consulta e enviar o que você solicita. Se você adicionar as diretivas para usar pipe (neste exemplo, suponho que você tenha alguns arquivos de zona, é por isso que o launch o bind backend.

launch=bind,pipe
pipe-command=/etc/pdns/pdns-backend-ip.py
pipe-regex=^.*\.host\.example\.com;.*$

Depois, você pode usar um script Python pdns-backend.py para processar as consultas e enviar os resultados. Algo parecido com o código abaixo:

#!/usr/bin/python -u

# Implementation of a Pipe Backend for PowerDNS
# https://doc.powerdns.com/md/authoritative/backend-pipe/

# We need Python unbuffered so we use -u
# Another ways to achieve it in 
# http://stackoverflow.com/questions/107705/disable-output-buffering

import sys

def build_answer(qname, qtype, answer, ttl=60):
        return("%s\tIN\t%s\t%d\t1\t%s" % (qname, qtype, ttl, answer))

def send_log(msg):
        sys.stdout.write("LOG\t%s\n" % msg)

def send_data(msg):
        sys.stdout.write("DATA\t%s\n" % msg)
        send_log("Sent %s" % msg)

# Check first line to ensure that we are properly initialized
line = sys.stdin.readline().rstrip()
if line != "HELO\t1":
        sys.stdout.write("FAIL\n")
        sys.exit(1)
sys.stdout.write("OK    Python backend is alive!\n")

# Process each line!
while True:
        raw_line = sys.stdin.readline()
        line = raw_line.rstrip()
        args = line.split("\t")
        if len(args) < 6:
                send_log("PowerDNS sent me unparseable line")
                sys.stdout.write("FAIL\n")
                continue
        rtype,qname,qclass,qtype,id,ip = args
        send_log("Received [[ %s ]]" % line)
        # PDNS will use the SOA to decide which backend to use. We have to answer only
        # when the query is as close as possible: 
        # i.e.: answer host.example.com not to example.com.
        if qtype == "SOA" and qname.endswith('host.example.com'):
            send_data(build_answer(qname, 'SOA', 'ns1.example.com ahu.example.com 2008080300 1800 3600 604800 3600'))
        if qtype in ("A", "ANY") and qname.endswith("host.example.com"):
                ip_requested = qname.split('.')[0]
                send_data(build_answer(qname, 'A', ip_requested.replace('-','.')))

        sys.stdout.write("END\n")

Tendo essa configuração de DNS, você pode processar essa zona como dinâmica:

$ host 11-22-33-44.host.example.com 127.0.0.1
Using domain server:
Name: 127.0.0.1
Address: 127.0.0.1#53
Aliases: 

11-22-33-44.host.example.com has address 11.22.33.44

Talvez algo como isso seja um exagero e difícil de depurar (o script python de amostra não faz nenhuma verificação de erros), mas pode ser um bom ponto de partida para ter um servidor DNS realmente dinâmico e programável.

    
por 03.08.2016 / 21:12