Я хотел бы "сопоставить имена внешних хостов с адресным пространством моего домена". Мне нужно сделать это за один раз.

Например, если я определю следующие отображения 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 ответ1

0

Чтобы ответить на мой собственный вопрос: это возможно с помощью сценариев 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

Кроме того, вот сценарий оболочки, чтобы настроить это

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .