DNS rebinding: prevention?

Mordechai T. Abzug morty+bind at frakir.org
Wed Aug 8 09:24:47 UTC 2007


On Wed, Aug 08, 2007 at 11:39:39AM +1000, Mark Andrews wrote:

> 	There is a big difference in controlling queries vs controlling
> 	what is put into the cache.

Why?  You are actually controlling queries in both cases.  The only
difference is at what stage of the query process we are looking.

The normal model for recursive queries is:

(1) process client recursive query

(2) Check permissions

(3) If the query can be answered from cache or from local
    authoritative zones, answer it

(4) Otherwise, go out and find out the external information on behalf
    of the client

(5) 

(6) insert external response into cache

(7) respond to client

What I am proposing is to fill in step 5 with a check of the response.
It's that simple.

> 	allow-cache {
> 		      // allow internal from internal
> 		      { { range; }; { range; } };
> 		      // disallow internal from external
> 		      { { range; }; { none; }; };
> 		      // allow everything else from anywhere
> 		      { { any; };  { any; }; };
> 		    };

That adds a whole lot of unnecessary complexity, and it doesn't even
begin to deal with CNAMEs.  Remember, we don't need to enumerate what
to protect, because we (should) already have authoritative DNS zones
that contain the stuff to protect.  So the config mechanism should be
as simple as:

acl externals_that_legitimately_point_to_me {
        10.0.0.45; // or whatever
        172.16.1.1; // or whatever
};

options {
        // disable others pointing to my zones by default
	   allow-external-pointing-to-this { none; }; 

        // other options elided
};

view "default" {
        zone "1.168.192.in-addr.arpa" {
                type master;
                allow-transfer { can_axfr; };
                allow-query { any; };
                file "zone/192.168.1";
                // no externals can legimiately point at this domain, 
                // so no allow-external-pointing-to-this required here
        };
        zone "2.168.192.in-addr.arpa" {
                type master;
                allow-transfer { can_axfr; };
                allow-query { any; };
                file "zone/192.168.2";

                // there are some external zones hosted at a couple of
                // known IPs that have A records to this zone.  Let's
                // allow them to do so, using an ACL defined earlier
                allow-external-pointing-to-this { 
                             externals_that_legitimately_point_to_me; 
                };
        };
        zone "example.com" {
                type master;
                allow-transfer { can_axfr; };
                allow-query { any; };
                file "zone/example.com";
                // no externals can legimiately point at this domain, 
                // so no allow-external-pointing-to-this required here
        };
        zone "example2.com" {
                type master;
                allow-transfer { can_axfr; };
                allow-query { any; };
                file "zone/example2.com";

                // there are some external zones hosted at a couple of
                // known IPs that have CNAMEs to this zone.  Let's allow them
                // to do so, using an ACL defined earlier
                allow-external-pointing-to-this { 
                             externals_that_legitimately_point_to_me; 
                };
        };
        zone "friend.com" {
                type slave;
                file "zone/friend.com";
                allow-query { any; };
                masters { 4.7.57.48 ; };

                // this isn't really my zone, it's a secondary for
                // a friend's company, so I don't have any
                // expectations about other entities pointing at it,
                // and there are no security implications to allowing this
                // from my own company's perspective
                allow-external-pointing-to-this { any; }; 

                // Note that I probably shouldn't even have this zone
                // here at all.  It should be in a separate nameserver or
                // view that is used for the DNS hierarchy, rather than
                // as part of my caching config.
        };
        // etc
};

Note that we only needed one new syntactic element:
allow-external-pointing-to-this, which takes a BIND ACL.  Also note
that if we are really going to do this properly, it makes sense to
fully illustrate the caching DNS component vs. the hierarchical DNS
component; I included both above in a single config, which is not
really correct.

> 	However named really has no way to know if the source address of
> 	the packet is valid.  So what we want is the destination address
> 	of the packet as well which isn't available in basic socket API.

<snip>

Why is the destination address of the packet coming into play?  That
doesn't matter at all.  And the validity of source addresses is no
worse of a problem than it is for DNS in general.

The basic mechanism here is simple: a DNS response from anywhere
should not contain internal DNS names or internal DNS IPs in the DNS
response portion of the packet.  In the general case (i.e. no
exception mechanism), it doesn't matter what the source IP or
destination IP of the response is -- so long as it didn't come from my
authoritative information, then it came from *somewhere* outside, and
I don't want to cache it or pass it on to clients.  It's that easy.

In the event that an exception mechanism is configured -- either by
server IP/netmask or by TSIG -- then recognizing the source is no
worse than the general problem of DNS spoofing.  If TSIG is
configured, then DNS spoofing is not a problem at all; if TSIG is not
configured, then DNS spoofing is no more of a problem than it is for
any non-DNSSEC query.  This is why DNSSEC was invented.

IMHO, spoofing is actually less of a problem than in the general case,
since unlike the normal case where the spoofer can easily determine
what the correct nameserver should be and try to spoof its IP, here
the spoofer must guess an IP that would be in an exception ACL, which
may or may not exist, and requires knowing offhand of the existence of
third-party records pointing at the domain.

> 	IPv6 supports retrieving the destination address in the advanced
> 	API.

Again, I fail to see what the packet destination address has to do
with anything.  Please explain this.

> 	Next people will want to add in namespaces.

[snip]

As per my previous post and as per the above, the simplest way to
handle namespaces is to to just use the existing "zone" statement
already present and basic to DNS.

> 	Then they will want to use nameserver names rather than addresses.

There are already named ACLs in bind which do a fine job with this.

> 	Now we have to cope with glue from the parents.

I originally thought this as well, and included "known glue records"
as a necessary exception in my original post.  Then I gave it more
thought, and realized that you don't need to worry about glue, for a
very simple reason -- a DNS server doesn't walk the hierarchy for its
own zones because it's authoritative for them.  So one does not need
to worry about delegations to one's own zones.

- Morty



More information about the bind-users mailing list