我需要一个 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 服务器的一个良好起点。