DNS: ¿Es posible hacer "reescritura de consultas"?

0

Me gustaría "asignar nombres de host externos a mi espacio de direcciones de dominio". Necesito hacer esto de una vez.

Por ejemplo si defino los siguientes mapeos 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

Lo que me gustaría que sucediera es que el cliente DNS pregunte:   'resolver HOST1.delegated1.my.example.com' y para que mi servidor DNS devuelva las direcciones IP resultantes.

Preferiría realmente obtener el resultado del servidor DNS ascendente apropiado para averiguar cuál es la IP real para HOST1.dominio1.com y devolver el resultado al cliente (con TTL y todo).

Además, si la respuesta es un CNAME, tengo que resolverlo "localmente" y solo devolver el resultado final (IP o lista de IP) al cliente. No debería devolver el CNAME, lo que daría lugar a que se emita otra consulta de DNS.

En otras palabras, necesito devolver una IP (o varias IP), no devolver otro nombre que el cliente deba resolver. Necesito la resolución para pasar por mí.

¿Alguna idea sobre cómo lograr esto? ¿Hay alguna forma de configurar Bind o DNSMasq para hacer algo como esto?

Las razones de estos requisitos son un poco más complicadas, pero esto es a lo que se reduce. Esencialmente el cliente DNS es desconocido. Normalmente, un servidor o una estación de trabajo Linux o Windows, que consultará a otro servidor DNS. Ese servidor se configurará para señalarme la resolución de cualquier cosa debajo de "mi" subdominio. En este ejemplo, cualquier cosa que termine con .my.example.com. y necesito ser capaz de resolver ese nombre. En realidad, como dije, debería ser algo así como un CNAME que debería resolver (no el cliente). La razón es porque el cliente no puede resolver nombres fuera de example.com. O para ser exactos, los servidores DNS "principales" que los clientes están configurados para consultar están aislados y no tienen conectividad a servidores DNS externos para consultar HOST1.domain1.com. Además, quiero restringir qué nombres o dominios se pueden resolver. Espero que esto aclare el uso previsto.

user1259398
fuente
¿Por qué no quieres usar CNAME RR, que son prácticamente diseñado ¿para esto? (Asignando un nombre de RR a otro.) Por favor editar su pregunta para incluir una justificación (Además, es posible que desee cambiar el término de "asignación de subdominios" a "reescritura de consultas", que probablemente esté más cerca de lo que está buscando. El título me causó cierta confusión.)
a CVn
Gracias. Cambié el tema como sugeriste. Si te refieres a por qué no usar un registro CNAME regular, el requisito es que toda la resolución suceda de una sola vez. A mi entender (y me corrijo si estoy equivocado) cuando un cliente emite una consulta DNS para HOST1.delegated1.my.example.com si esto se define como un CNAME, el servidor DNS volverá como respuesta HOST1.domain1.com (en lugar de la dirección IP) y el cliente tendría que emitir una segunda consulta preguntando cuál es la IP de HOST1.domain1.com. ¿Correcto? Esta es la parte que debo evitar. El cliente debe obtener la respuesta en un intento.
user1259398
Eso depende de su resolutor y de la relación entre el cliente y el resolutor. Le sugiero encarecidamente que cambie la pregunta para que sea más o menos lo que estaba en su comentario en este momento: establezca el objetivo final deseado (y tal vez proporcione alguna explicación de por qué es necesario), en lugar de centrarse en una posible solución que puede Puede que no sea el más apropiado. Ver ¿Cuál es el problema XY? para más sobre esto.
a CVn

Respuestas:

0

Para responder a mi propia pregunta: Es posible usar scripts PowerDNS. Es bastante simple.

Publicando aquí una versión desinfectada del 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

Además, aquí está el script de shell para configurar esto

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