The way DNS was (and is) run was not very secure. Running the latest recommended version of BIND is the very least you should do. If you're running any version of BIND 4 or a version of BIND 8 that's not current, you're open to numerous weaknesses in the code. The most threatening thing in old versions of BIND is how easy it is to feed it bogus information, known as spoofing or poisoning. It would then spread this bad information on to its clients. If you consider how important DNS information is for many (most?) of the security mechanisms used in UNIX, this is quite chilling. Spoofing or poisoning is still possible, but it's much harder now, and by configuring DNS restrictively, it can be made even more difficult. As BIND 9 is completed and DNS-SEC is deployed across the Internet, things will get even better. However, add to this that BIND has had (and we might still find new) remote root exploits, and the scenario is pretty grim for security.
Spoofing DNSSpoofing BIND used to be as easy as sending it a properly formed answer package it would store the information, regardless of whether it had asked for the information. If you run an old BIND 4, you are likely still vulnerable to this attack, which has been widely known for years. It is still possible to spoof BIND 8, but it's much more difficult.. The basic method is to set up a nameserver to issue query replies with an extra, poison, record in them (this can involve creative zone files or source code hacking). The trick then is to get other nameservers to query it, and when the poisoned answer arrives with the extra record, the record is stored in the nameserver's cache. Thereafter, until the cached answer expires, any queries to that server are resolved based on the bogus information in the cache, quite possibly spreading the poison further in the process.
Most BIND installations will act as recursive resolvers for anyone asking. This makes getting a given installation to retrieve bogus information from other nameservers quite easy. Another scenario in which a DNS server will retrieve information that might be poisoned is when it attempts to retrieve glue information for NS records it is about to put in a query answer. Both, however, can be turned off in named.conf:: options { … recursion no; fetch-clue no; … } This is fine if your nameserver does not act as a recursive resolver for anyone, but it probably needs to perform recursion for your own machines the ones using it as their local nameserver. So, instead of disabling recursion altogether, you might want to restrict it to your own networks instead. The penguin.bv nameserver needs to act as a recursive resolver for the Penguin network, which is 192.168.55.0/255.255.255.0 (also written as 192.168.55.0/24 because the network address is 24 bits). Penguin AS has one other network 192.168.56.0/255.255.255.128, alias 192.168.56.0/25. And the nameserver should also act as a nameserver to itself, 127.0.0.1. Here is the example: options { … allow-recursion { 192.168.55.0/24; 192.168.56.0/25; 127.0.0.1; }; … }; You can be still more restrictive, though. If your nameserver is not acting as an authoritative server for zones, you don't want it to answer queries from strange computers at all. You, again, want only the internal networks inside Penguin AS to be capable of querying the server: options { … allow-query { 192.168.55.0/24; 192.168.56.0/25; 127.0.0.1; }; … }; ACLsEnumerating all those networks multiple times throughout the config file is tedious and error prone. Therefore, BIND offers named Access Control Lists (ACLs), which you can define and then use in permissions and denials. An ACL statement can include any number of network addresses and single addresses you want. Rewriting the previous allow-recursion and allow-query statements, this is the new configuration: acl penguinets { 192.168.55.0/24; 192.168.56.0/25; 127.0.0.1; // Use "localhost" instead }; options { … allow-recursion { penguinets; }; allow-query { penguinets; }; … }; Four predefined ACLs exist: any, which matches anything; none, which matches nothing; localhost, which matches all the addresses of all the interfaces on your BIND server; and localnets, which is the networks directly attached to those interfaces. You should probably use localhost instead of 127.0.0.1, so I loose one point for the previous ACL I wrote. As is usual for these things, the ACL is processed one element at a time until a match is made. ACLs or ACL components can be negated by prefixing an exclamation mark (!). These restrictions stop whomever the nameserver wants to answer queries from. But, the Penguin nameserver is authoritative for a number of zones, and its job is to answer queries about all those zones. So, it must answer queries about the penguin.bv zone as well as all the other zones it holds. That is configured like this: zone "penguin.bv" { type master; file "pz/penguin.bv"; allow-query { any; }; }; The allow-query option must be repeated for every zone for which the server is authoritative, if you restrict allow-query in the way shown in the previous code. This, and continued enhancements to the logic of BIND, is the best we can do for now. Your BIND should really be configured like this in any case. Restricting access to DNS servers is one of the subjects of AUS-CERT advisory AL-1999.004; it deals with DoS attacks leveraging DNS servers. The advisory is available at ftp:// ftp.auscert.org.au/pub/auscert/advisory/AL-1999.004.dns dos The advisory makes for good reading, and describes ACLs very well; I highly recommend it.
acl "bogon" { 0.0.0.0/8; // Null address 1.0.0.0/8; // IANA reserved, popular fakes 2.0.0.0/8; 192.0.2.0/24; // Test address 224.0.0.0/3; // Multicast addresses // These might be used internally in your organization, // remove them if so. 10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16; }; options { … blackhole {bogon; }; … }; BlackholingNow you have secured your nameserver the best you and I know how, but as long as your server is acting as an authoritative DNS server, it still must answer queries from anyone. This cannot be avoided; it is the function of DNS. But, sometimes, when someone (due to misconfiguration, ill will, or intent, abuses your nameserver), you might want to bar them form contacting it entirely. It probably would be better to bar them by installing appropriate rules on a firewall, but you can do almost the same with the blackhole option. Incorporating the blackhole suggestion from the AUS-CERT advisory discussed earlier, the code becomes the following: acl "bogon" { … // From the AUS-CERT advisory }; acl rougenets { 10.0.128.0/255.255.255.0; }; options { … blackhole { rougenets; bogon; }; … }; But, of course, many attack techniques do not require the attacker to use his or her own return address on the query packets. Any source address can be used, forcing you to blackhole networks that are not attacking you, or even networks you can't blackhole because they are dependent on you, or you on them, for DNS service. When this is the situation, the only solution is to track down the real attacker and stop the attack. Or wait it out. Bad ServersAs the AlterNIC episode clearly shows, DNS depends on DNS servers to be good and serve good data. In the case of the AlterNIC episode, a fixed version of BIND that would not accept that kind of bad data was out in short order. However, the possibility of someone setting up a bad server and succeeding in a poisoning scheme still exists. Another possibility is an ineptly setup nameserver that is spreading bad information. If you use the following syntax, your BIND will simply stop talking to the server: server 10.156.82.33 { bogus yes; }; Listing a server as bogus is not quite the same as blackholing it. If you blackhole it, your nameserver will not answer queries from the server. If you bogus list it, as in the previous code, your server will stop asking it, but it will not deny it answers. |