动态计算 A 记录

动态计算 A 记录

我需要一个 DNS 服务器,它基本上允许将主机名解析为任何 IP。例如,看起来像的主机名将A-B-C-D.myhost.example.com被解析为A.B.C.D。(当然,A 是 0-255 等等。对于无效的主机名,返回一些无用的东西是可以的)

我已经看到 bind9 有$GENERATE指令,但似乎无法嵌套它(并且 2^32 记录可能会破坏服务器或至少消耗大量内存)。

有什么软件可以做到这一点?(可能是支持正则表达式的东西?)

答案1

PowerDNS 支持多个后端,其中一个是管道后端,您可以使用它来处理查询并发送您的请求。如果您添加指令以使用管道(在此示例中,我假设您有一些区域文件,这就是我们使用launch后端的原因bind

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

然后,您可以使用 Python 脚本pdns-backend.py来处理查询并发送结果。类似下面的代码:

#!/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")

有了该 DNS 配置,您就可以将该区域处理为动态区域:

$ 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

也许这样的事情有点过度并且难以调试(示例 python 脚本没有进行任何错误检查)但它可能是拥有真正动态和可编程的 DNS 服务器的一个良好起点。

相关内容