BIND: Forcing authoritative nameserver answer with no data on non-recursive requests (Research purposes)

binddomain-name-systemnameserver

Edit: I've simplified target goal as suggested by Andrew B.

The goal is basically setting an authoritative name server to only give real answer on recursive requests, which means breaking the iterative procedure of dns resolving. Makes no sense for any real use but what I try here is for research purposes, specifically on identifying misbehaving open resolvers.

What I want is answering with no data to non-recursive dns requests even if we know otherwise (e.g. if we are the authoritative nameserver for the requested domain).
i.e.:

Case 1: REQUEST(RD=0) -> RESPONSE(rcode=NOERROR, All sections Empty, RA=1) 
Case 2: REQUEST(RD=1) -> RESPONSE(Real Answer, RA=1) 

My available resources are one Authoritative name server for specific domain and one dns resolver on separate machines. The behavior should be similar for any sub-domain of my controlled domain.


My current setup:

  • Machine-1 (M1 in short): BIND authoritative name server registered for research.lab.mydomain.com
  • Machine-2 (M2 in short): BIND resolver (open)

Both allow recursive calls (for research purposes).
Currently, 'A' queries for research.lab.mydomain.com sub-domains go to M1's nameserver and return NXDOMAIN results (there are no sub domains registered). M2 is currently not in use.

What I thought should be done

Make all queries of research.lab.mydomain.com subdomains go to the resolver instead of the name server. The resolver in turns queries the nameserver if recursion desired is set or return cached answers with no error otherwise. All queries from the outside world should go through the resolver.

What I tried

I though about changing M1 to be the resolver and M2 to be the nameserver, so research.lab.mydomain.com would still be registered to M1's address. So I moved the zone configuration from M1 to M2 and also set forwarding from M1 to M2 in named.conf.options.

named.conf.local in M1 is now empty and in M2 is now:

zone "research.lab.mydomain.com" {
        type master;
        file "/var/lib/bind/research.lab.mydomain.com.hosts";
}; 

The content of /var/lib/bind/research.lab.mydomain.com.hosts is a modified version of the one that was in M1 (substituted m1 with m2):

$ttl 38400
research.lab.mydomain.com.  IN  SOA m2.lab.mydomain.com. roee88.gmail.com. (
            1410888930
            10800
            3600
            604800
            38400 )
research.lab.mydomain.com.  IN  NS  m2.lab.sit.cased.de.
research.lab.mydomain.com.  IN  NS  ns1.research.lab.mydomain.com.
ns1.research.lab.mydomain.com.  IN  A   {IP ADDRESS OF M2}

Unfortunately that didn't work. queries received on m2 resulted in SERVFAIL responses.

Best Answer

Have you tried telling M1 that M2 is responsible for the subdomain by ip address rather than name, eg with

zone "research.lab.mydomain.com." {
        type forward;
        forward first;
        forwarders {
                a.b.c.d ;
        } ;
} ;

in M1's named.conf, where a.b.c.d is the IP address of M2?

Related Topic