BIND DNS Server Security, Configuration and Performance Tips menu barHome   Site Map   Support   Contact Us   Website & Servers 
  DNS Topics:   Main Page - DNS Tips,


BIND DNS Server Security, Configuration and Performance Tips



The BIND DNS Server is a Popular, free, Open Source, Multi-platform DNS Server.  It is full featured, highly
configurable and is updated and supported by the ISC.

Our goal here is to provide help with the more popular topics including security and performance and also
provide a deeper but easy to understand guide for the more complex and confusing configurations, issues,
and resolutions.

Use the links at the top and on the right pane to navigate through the articles and topics.

In this first instalment of this series we will look into Security, Configuration and Performance tips including
a section on configuring secure access for the rndc remote management tool.




Configuring specific listen IP addresses and ports on a BIND DNS Server


The ISC BIND DNS server by default will listen on port #53 of all detected Network Interfaces.
If you have a multi-Homed system with more than one network interface and you have multiple instances of named(.exe)
running or don't want BIND to listen on all interfaces. Maybe you have a need to configure different listen port numbers.
You can configure exactly what you want using the listen-on [port] { xxx.xxx.xxx.xxx; } statement.

In your named.conf options section use the syntax listen-on { xxx.xxx.xxx.xxx; }; statement to specify the IP address.

To configure multiple IP addressess: listen-on { 192.168.1.1; 192.168.3.1; };

To configure a non-standard port: listen-on port 5335 ( 192.168.1.1; 192.168.3.1; );

Users of ISC BIND version 9 can configure a different non-standard port per IP Address as follows:

Use this statement in your named.conf - 

The above statement will configure BIND to listen on the following addresses and ports 
Interface 192.168.1.1:5335   Server is listening on port 5335
Interface 192.168.3.1:1053   Server is listening on port 1053
Interface 192.168.2.1:53       Server is listening on default port 53

Now that we have discussed configuring the inbound listen ports, We will move on to configuring the outbound source port.


Firewall issues and setting specific outbound source ports on a BIND DNS Server


Normally BIND uses a dynamic high number source port (1024 and up) for outbound queries. This may cause issues
with some firewall configurations. If port 53 is the only open port for inbound as well as outbound queries, those
high level source port queries will be blocked. * Check your firewalls configuration documentation, your
network support group, or use a sniffer to verify that this is the case. To get around this restriction you can use
the query-source statement in your options configuration.

 { query-source address 192.168.1.1 port 53; };
 
This will cause all queries to be sent by interface 192.168.1.1:53 (std port 53). That should get those packets on their
way without any more fuss from the firewall.

Note: You can specify multiple IP addresses if desired using the same format shown above for the listen-on statement.



Zone File configuration when DNS is behind a firewall NAT


If you have a DNS Server behind a firewall and NAT (or PAT) is enabled, where your "Public" IP Address is different
than your "Private" IP Address, you need to configure the NAT'ted IP address in your zone files and not the inside
or Private IP Address for your internet serving DNS.

This is because the "Query Response" sent back to the requester is contained in the data portion of the packet
and as such will not be changed by the router or router\firewall.

In a nutshell, the requesting systems in the public domain needs to know the public IP address to use as the
destination from their point of view.

For internal use you can configure an Intranet DNS server whose zone files reflect your internal address structure.
Point your internal clients to this DNS and you can benefit from it's caching capability and also have no issues
addressing any web, mail and FTP servers that also reside inside the firewall.

For security purposes make this Intranet server inaccessible by the internet and use the allow-query restrictions as
defined at the end of the next section.


Enhancing Security: Limiting DNS Server access with ACL's, blackhole, and allow-query


When you configure you server you may start with a configuration that lets it provide all services to all requesters.
While this is very generous, you may be leaving yourself open to those with malicious intent. Let's look at ways we
can enhance the security of your DNS Server without compromising functionality. 


The blackhole {addr_match_list;}; statement provides a way to completely ignore all queries from a host or network.
The blackhole statement can be used with an IP address or in conjunction with an access control list or more properly
in BIND syntax, the "address match list". Here is an example.

acl blacklist { 192.168.100.68; 172.16.0.0/12; };
blackhole { blacklist; };

This has the effect if ignoring all queries from the 192.168.100.68 host and the 172.16 network.

Note that when a query is performed by a black-holed site, the event is not logged. If you want to refuse requests
and then log the event, you may want to use the negated allow-query. Details are provided further down the page.

Now that you know how to handle the bad guys, here is a use that is more proactive. In spoof attacks, private rfc1918,
non-routeable or illegal addresses are often used. In addition to your blacklist, create another access control list called
spoofbuster that includes the following addresses



Put this new list together with your previous black-hole statement.

acl blacklist { 192.168.100.68; 172.16.0.0/12; }; black-hole { blacklist; spoofbuster; };

Note: If your DNS Server provides name resolution for your internal networks and they use the private RFC1918 space,
be sure you don't include those IP ranges in your spoofbuster access control list! If you use split or stealth DNS, you
may want to place the blackhole statement within the proper zone section or clause instead of the global options section.
For this situation you may want to consider having separate DNS servers for name resolution for your internal networks
and clients which usually provides better performance, security and manageability. 

Also note that this is not a DNSBL or DNSRBL that is commonly used for blocking Email spam. That type of black-hole
usage is typically configured in a zone file using reverse IP notation. Here is a wikipedia link for more information about
DNS Black-hole List or DNSBL's used for spam blocking.

The allow-query {addr_match_list;}; statement can be used to limit the responses to queries from specific hosts.
Of course responding to queries is what a DNS server lives for but, just in case you want to provide a "polite"
way of blacklisting a particular host and refusing their queries, consider the following.

allow-query { !192.168.100.68; any; };

This statement will allow queries from all hosts except 192.168.100.68. The bang or exclamation mark preceding the
IP Address specifies negation. Please note the position of the negated IP Address in the address match list. The list
is processed from left to right until a match is found. If the "any;" entry was positioned first, all IP Addresses will match
"any" so anything after "any;" would not change the result even those entries were negated with a "!".

Query refusals of this type will be logged to the security category.

You may want to use this allow-query negation type of "Blacklisting" as a way to minimize any DoS attack from a
suspicious host as a prior step to black-holing them. Note that a "Request Refused" response will be generated and
may serve as a warning to the host performing the query. If you don't want that host notified but ignored instead,
use the black hole directive discussed above.



Configuring an Intranet server to respond to only internal requests


If you have an Intranet DNS server you probably do not want it to respond external queries. You can use the allow-query
statement to limit responses to only internal requests from two subnets as follows.

acl internalnets { 192.168.200.32/28; 192.168.200.64/28; };
allow-query { internalnets; }; 

If you want to allow queries from the entire 192.168 network you can use this format.
allow-query { 192.168.0.0/16; };

To limit recursive queries to the internal networks as well we can use the allow-recursion statement. 

allow-recursion { internalnets; };  or
allow-recursion { 192.168.0.0/16; };



Enhancing Security: Limiting DNS Slave Server updates with allow-notify


Slave DNS Server only:
The allow-notify {addr_match_list;}; statement identifies to a slave the IP addresses of servers whose notify is
accepted. Since this allows another server to update this servers zone data this should be set to none if it is not
required or the chance exists that the host address can be spoofed.

Use this statement in the options section of your named.conf

allow-notify { none; };

!! Note that if this is set to none then any slaves must be manually synced with the master DNS servers zone data!


The control statement and securing the BIND Control Channel


The control channel provides the mechanism to manage your BIND DNS Server from another programs or applications
like ndc or rndc.

Because of the power given to it, the control channel needs to be secured. This is configured with the control statement. 

First, if you are not using the control channel it should be disabled. Use the following command in the top level of
named.conf. Top Level means not within any other section or statement (like options) or clause (like zone):

controls {};

If you use the control channel to manage your server, There a couple of steps you can take to enhance security.

First, the control statement in BIND 9 contains up to three statements or clauses- inet, allow, and keys.

The listen for the control port is set using the inet statement. The allow (address_match_list} statement determines
from which IP Address commands will be accepted. If you do not need to control your DNS server remotely
then set this to the localhost\loopback address as follows.

controls {inet 127.0.0.1 allow (127.0.0.1; } };

This will set up the control channel to listen on localhost using the default port 953. If you want to specify a
different port you can add that after the IP Address as follows.

controls {inet 127.0.0.1 port 1953 allow (127.0.0.1; } );

This will set up the control channel to listen on localhost port 1953. Both examples above will assume there is a file
containing the keys named rndc.key which is usually in the default /etc directory(folder). It would be wise to keep this
rndc.key file's access privileges locked down to be only accessible by the named(.exe) user id.

If you want to specify the key itself in this named.conf file you can do that by the keys statement or clause.
!! Note that it may be less secure to include the actual key here in case named.conf becomes compromised!
The Keys statement references key-ID(s) to determine the key data. These Key IDs need to be configured in the top
level of named.conf prior to the controls statement. We will discuss the creation of key-id's later in this section.
let's assume for the sake of discussion that you already created a key called myrndc-key. Set up your controls
statement as follows.

controls { inet 192.168.2.200 port 1953
                allow { 127.0.0.1; 192.168.2.202; }
                keys { "myrndc-key"; }; };
This will set up a listen for the control channel on the network interface that uses the address 192.168.2.200 using
port 1953. It allows access from the localhost\loopback address 127.0.0.1 and host 192.168.2.202 using a key defined
under the key-id name of "myrndc-key".
Please note that this last statement is an example for this article only. You will need to change the specifics of
the above to match your own configuration needs.

We have now covered the controls statement and various control channel configurations. 
    

Using BIND's KEY statement to strengthen security


To go beyond relatively simple security measures of file permissions and access control lists we step up to generating
random lists of characters and symbols called hashes to provide unique, hard to decipher keys that are used by both a
requesting client and a server to provide more secure communications and determine access privileges. In the context
of this article we will now discuss the key statement used by BIND in conjunction with TSIG and the control channel.
It is the latter we will be focusing on here.

The purpose of the key statement is to relate a secret key to a key-id. As we discussed in a previous section, the
key-id(s) are used in the keys clause of the control statement. That is the means to which the two are tied together.
Here is the syntax:

key "key-id" { algorithm "algorithm-type;
               secret "hash list of characters and symbols"; };

The key-id is a name you want to use in referring to this "secret" hash.
The algorithm-type is the type of algorithm used in creating the hash. Currently under BIND 9.3 only hmac-md5 is valid.

Here is an example of a key statement used to support the control channel controls statement: 

key "myrndc-key" { algorithm hmac-md5;
                  secret "x6e5r88iof6ycxdzvb77ity9=="; };
                  
You will have to generate your own secret hash and substitute it for the "x6e5r88iof6ycxdzvb77ity9==" shown.
BIND provides the command line utility rndc-confgen to make this easy.

To create a secret for the above example, issue the following command from the \etc directory:
rndc-confgen -k myrndc-key -a. This will produce a rndc.key file. Open that file in a text editor and copy the
secret key to this key statement on your named.conf file.

As with any change to named.conf you need to reload the DNS server for this change to take effect. Before you use
rndc you will need to insure the key-id and it's secret in rndc.conf match what is in your named.conf file.


That completes setting up the basic implementation of the key statement.
While this configuration works, you need to understand that if your named.conf file gets compromised, someone may
be able to discover your key since it is shown here in plain text.


A more secure way to accomplish the same task is to keep the entire key statement in a separate file and call it into
your configuration using the include statement.

Here's how:
Create a plain text file and copy in the entire key statement. You need to put this file in the directory specified by the
directory1 statement in your named.conf. FtSoD (For the Sake of Discussion) let's name it febmdfive.
Replace your key statement with:

include "febmdfive";

Reload your DNS Server and you are good to go! While this will not make it hacker proof, it does make it more difficult
to get your key.

In an attempt to further thwart hackers, you now have a number of options open to you. For instance, Make the include
file name something less obvious so it does not call attention to itself. Position the include statement in a different area,
But the same context, away from your controls statement in your named.conf.


That is about all I want to divulge here. No need to give away secrets to any wannabe hackers. If you have implemented
at least a few of my recommendations, your server is more secure than some. Now you have the tools.
If you are diligent and creative, I'm sure you can discover additional measures.

BTW - Here is one tip that all the hackers know about and hope you never use. Run a sniffer if you have the resources
and analyse the traffic. See my networking page for help in this area. Review your query logs and look for anything
suspicious. Get some tools that help you automate this analysis. Also peruse the forums that abound to stay aware of
the current risks and strategies to minimize them.

And of course, Check back here! We are always adding new articles, tips, tools and services. We are here to help!
Thanks.

That completes my discussion on the key statement and this section regarding my easily configurable steps to a
more secure DNS Server.  



Enhancing Performance: Limiting DNS Functions


To enhance performance, you probably want to narrow the scope of some services. The services you limit will vary
depending on the intended use of the server, Its hardware configuration, and even security policies. 

Typically you have allow-recursion option set dependent on the use of that particular server by using one of the
following statements:

recursion no;  or allow-recursion { none;};

recursion yes; or allow-recursion { all;};

Now let's narrow the scope using an access control list or acl.

Acl myinternalnets { 192.168.1.0/24; 192.168.2.0/24; }; 
Allow-recursion { myinternalnets; };

This has the effect of allowing the DNS Server to provide recursive name resolution for  only the hosts in the networks
specified in the "myinternalnets" acl (192.168.1.0 or 192.168.2.0 ).

Now, say you have a particular host or sub-network to which you don't want to provide recursive resolution.
We can take this a step further. Consider this:

Acl myinternalnets { 192.168.1.0/24; 192.168.2.0/24; }; 
Allow-recursion { !192.168.1.230; myinternalnets; };

The addition of the !192.168.1.230 has the effect of excluding recursive DNS resolution for that particular host without
affecting any other hosts on the 192.168.1.0 network. This can be used, for example, in a test lab environment where
you want the disallowed host\server to provide its own recursive name resolution.

When you limit the Recursive resolution function to your internal network, you have configured a Closed DNS. Having
a Closed DNS can significantly enhance performance since your server will not try recursively resolving names for
the entire internet community!

This configuration also enhances security as it protects you from one type of Denial of Service (DoS) Attack.


There are two other statements we can add to limit unnecessary network traffic and system resource usage.


1. If you do not need to process zone transfer requests, disallow all requests. The default is to allow all.
   Add this to your options section:
   
   allow-transfer{none;};
  
2. Notification is on (yes) by default. Turn this off (no) if there are no other servers require an automatic update
from this master. For example, No slave servers exist in your domain or they will be updated by another source. 
(This option is not applicable to a strict slave configuration)

   Add this to your options section:
   
   notify no;


That's about it for the easily configurable steps to a more efficient and better performing DNS Server. Enjoy!


Back to the top

If you found this page useful, consider linking to it.
Just copy (mark then ctrl-c) and past into your website.
This is how this link will look: BIND DNS configuration tips



Thanks!


Version 1.1   Copyright © 2007-2014 AITechSolutions.net. All rights reserved.   Terms of Use










Quick Links


Using BIND's listen-on statement

Firewalls and using BIND's
query-source statement


NAT and Zone File Configuration

Security: Limiting access

Securing the BIND Control Channel

Security: Using BIND's KEY statement

Performance: Limiting DNS Functions


Related Links

Link to the ISC BIND web site