我想“将外部主机名映射到我的域地址空间”。我需要一次性完成这件事。
例如,如果我定义以下 HOST 映射
HOST1.delegated1.my.example.com -> HOST1.domain1.com
HOST2.delegated2.my.example.com -> HOST2.domain2.com
HOST3.delegated2.my.example.com -> HOST3.domain2.com
我希望发生的是 DNS 客户端询问:“解析 HOST1.delegated1.my.example.com”,然后我的 DNS 服务器返回生成的 IP 地址。
我更愿意从适当的上游 DNS 服务器获取结果,以找出实际的 IP 地址HOST1.domain1.com并将结果(包括TTL和所有内容)返回给客户端。
此外,如果响应是 CNAME,我必须“本地”解析它并仅将最终结果(IP 或 IP 列表)返回给客户端。我不应该返回 CNAME,这会导致发出另一个 DNS 查询。
换句话说,我需要返回一个 IP(或多个 IP),而不是返回客户端需要解析的另一个名称。我需要由我来解析。
关于如何实现这一点有什么想法吗? 有没有办法配置 Bind 或 DNSMasq 来执行这样的操作?
提出这些要求的原因有点复杂,但归根结底就是如此。本质上 DNS 客户端是未知的。通常是 Linux 或 Windows 服务器或工作站,它们将查询另一个 DNS 服务器。该服务器将配置为指向我,以解析“我的”子域下的任何内容。在此示例中,任何以 .my.example.com 结尾的内容。我需要能够解析该名称。实际上,正如所述,这应该是我应该解析的 CNAME 之类的东西(而不是客户端)。原因是客户端无法解析 example.com 之外的名称。或者确切地说,客户端配置为查询的“主”DNS 服务器是孤立的,并且没有连接到外部 DNS 服务器来查询 HOST1.domain1.com。此外,我想限制哪些名称或域是可解析的。希望这能澄清预期用途。
答案1
回答我自己的问题:使用 PowerDNS 脚本是可能的。这相当简单。
在这里发布 Lua 脚本的净化版本
-- File: pdns-preresolve.lua
-- Description: This is a Lua script that pdns-recursor will invoke on each DNS resolution
-- References::
-- Lua
-- Programming in Lua - http://www.lua.org/pil/contents.html
-- PowerDNS:
-- docs - http://doc.powerdns.com/md/recursor/scripting/#cname-chain-resolution
-- examples - https://wiki.powerdns.com/trac/browser/trunk/pdns/pdns/powerdns-example-script.lua
-- Mapping rules:
-- delegated1.my.example.com -> domain1.com
-- delegated2.my.example.com -> domain2.com
function preresolve ( remoteip, domain, qtype )
print ("prequery handler called for: ", remoteip, getlocaladdress(), domain, qtype)
pdnslog("preresolve:: query "..qtype.." "..domain.." from "..remoteip.." on "..getlocaladdress());
-- "hard code" the IPs of our 2 NS servers here, so we do not have to setup the regular pdns daemon
-- currently this IGNORES the qtype. It probably should not
if domain == "ns1.my.example.com." then
return 0, {{qtype=pdns.A, content="10.1.1.1", ttl=21600}}
end
if domain == "ns2.my.example.com." then
return 0, {{qtype=pdns.A, content="10.1.1.2", ttl=21600}}
end
-- print("DISABLE the cache")
-- I am not really sure we need this. We might possibly cache some queries. I had some issues initially with getting failures to resolve, but were caused by pdns-recursor config issues
setvariable()
-- we also might want to drop any other types of DNS requests that match our made up domain
-- or implement the "replacement" only for 'A' records
-- for example 'host' with no options automatically queries AAAA (28) and MX (15) type records
-- see http://en.wikipedia.org/wiki/List_of_DNS_record_types
local myCname
local section
section = ""
if domain:match("delegated1") then
myCname,subs = string.gsub(domain, "\.delegated1\.my\.example\.com", ".domain1.com")
section = "delegated1"
elseif domain:match("delegated2") then
myCname,subs = string.gsub(domain, "\.delegated2\.my\.example\.com", ".domain2.com")
section = "delegated2"
else
pdnslog("Doing nothing for:" .. domain);
return -1;
end
if subs == 1 then
pdnslog("myCname = " .. myCname);
return "followCNAMERecords", 0, {{qtype=pdns.CNAME, content=myCname, ttl=60}}
else
pdnslog("No match in section [" .. section .. "] for: " .. domain);
end
-- we do not know how to resolve, let it continue recursing
return -1;
end
另外,下面是用于设置的 shell 脚本
#!/bin/bash
# File: configure-pdns-recursor.sh
# Description: Configure the pdns-recursor on CentOS 6.x
# Initial version. Not very well tested in terms of this shell script. It is more of a record of the commands I executed manually
sudo yum install pdns-recursor lua -y
# ...
# Package lua-5.1.4-4.1.el6.x86_64 already installed and latest version
# Package pdns-recursor.x86_64 0:3.7.1-1.el6 will be installed
# ...
# Installing : pdns-recursor-3.7.1-1.el6.x86_64
# ...
# make sure the daemon will be started automatically on boot
sudo chkconfig pdns-recursor on
# change syslog configuration
if [[ ! -e /etc/rsyslog.conf.orig ]]; then
echo "Replacing /etc/rsyslog.conf"
sudo cp -p /etc/rsyslog.conf /etc/rsyslog.conf.orig
# stop logging to /var/log/messages
sudo sed -i 's/^\*\.info;mail.none;authpriv.none;cron.none[ ]/\*\.info;mail.none;authpriv.none;cron.none;local0.none /' /etc/rsyslog.conf
# configure log files for PDNS
echo 'local0.* -/var/log/pdns.log' | sudo tee /etc/rsyslog.d/pdns.conf
sudo service rsyslog restart
fi
cd /etc/pdns-recursor/
# move the default config. Has many comments/explanations
sudo mv recursor.conf recursor.conf.default
# preserve the couple of settings from the original that we need
grep -v '^#' recursor.conf.default | grep -v '^$' | sudo tee recursor.conf
SCRIPT=/usr/local/bin/pdns-preresolve.lua
LOCALBIND=8.8.8.8
# determine the IP of this server
IP=$(ifconfig eth0 | grep 'inet addr' | awk '{print $2}' | sed 's/^addr://')
# complete the setup
echo "
local-address=127.0.0.1,${IP}
lua-dns-script=${SCRIPT}
logging-facility=0
forward-zones-recurse=.=${LOCALBIND}
##forward-zones-recurse=amazonaws.com=${LOCALBIND}, powerdns.org=${LOCALBIND}" | sudo tee -a recursor.conf
# create the script before you start the daemon
sudo touch "${SCRIPT}"
# change the ownership to the user running this script, so we can edit it easily
SELF=$(id -un)
sudo chown $SELF "${SCRIPT}"
echo "MUST populate the actual content"
#vi "${SCRIPT}"
# start the daemon
sudo service pdns-recursor start
MYGRP=$(id -gn)
sudo chgrp $MYGRP /var/log/pdns*
sudo chmod g+r /var/log/pdns*
echo "make sure it is listening"
netstat -nau | grep 53; netstat -nat | grep LISTEN | grep 53
echo " or filter by the proc name"
sudo netstat -natpu | grep pdns
echo " if it is not running it probably failed to start"
echo " check the logs - /var/log/pdns.log "
echo "tail -f /var/log/pdns.log"
exit 0
# to test you could do something like
TARGET="HOST1.delegated1.my.example.com"
dig -t A $TARGET @localhost | grep -v '^;' | grep -v '^$'
for LOOP in $(seq 1000); do echo "Looop $LOOP"; dig -t A $TARGET @localhost | grep -v '^;' | grep -v '^$'; done > /tmp/test.run