DNS: É possível fazer “reescrita de consulta”?

0

Gostaria de "mapear nomes de host externos para o espaço de endereçamento do meu domínio". Eu preciso fazer isso de uma só vez.

Por exemplo, se eu definir os seguintes mapeamentos de 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

O que eu gostaria que acontecesse é que o cliente DNS perguntasse:   'resolver HOST1.delegated1.my.example.com' e para o meu servidor DNS retornar o (s) endereço (s) IP resultante (s).

Eu preferiria realmente obter o resultado do servidor DNS upstream apropriado para descobrir qual é o IP real para HOST1.domain1.com e retornar o resultado para o cliente (com TTL e todos ).

Além disso, se a resposta for um CNAME, tenho que resolvê-lo "localmente" e retornar apenas o resultado final (IP ou lista de IPs) para o cliente. Eu não deveria estar retornando o CNAME, o que resultaria em outra consulta DNS sendo emitida.

Em outras palavras, preciso retornar um IP (ou vários IPs), não retornar outro nome que o cliente precise resolver. Preciso que a resolução aconteça por mim.

Alguma idéia de como conseguir isso? Existe alguma maneira de configurar o Bind ou o DNSMasq para fazer algo assim?

As razões para esses requisitos são um pouco mais complicadas, mas é isso que se resume. Esentially o cliente DNS é desconhecido. Normalmente, um servidor ou estação de trabalho Linux ou Windows, que consultará outro servidor DNS. Esse servidor será configurado para apontar para a resolução de qualquer coisa sob o subdomínio "meu". Neste exemplo, qualquer coisa que termine com .my.example.com. e eu preciso ser capaz de resolver esse nome. Na realidade, como afirmado, deveria ser algo como um CNAME que eu deveria resolver (não o cliente). O motivo é porque o cliente não consegue resolver nomes fora de example.com. Ou, para ser exato, os servidores DNS "principais" que os clientes estão configurados para consultar são isolados e não têm conectividade com servidores DNS externos para consultar HOST1.domain1.com. Além disso, quero restringir quais nomes ou domínios são solucionáveis. Espero que isso esclarece o uso pretendido.

    
por user1259398 10.04.2015 / 15:52

1 resposta

0

Para responder à minha própria pergunta: É possível usar o script do PowerDNS. É bastante simples.

Publicando aqui uma versão higienizada do script 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

Além disso, aqui está o script de shell para configurar isso

#!/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
    
por 15.04.2015 / 14:28