DNS:可以进行“查询重写”吗?

DNS:可以进行“查询重写”吗?

我想“将外部主机名映射到我的域地址空间”。我需要一次性完成这件事。

例如,如果我定义以下 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

相关内容