BIND - Berkeley Internet Name Domain

BIND - Berkeley Internet Name Domain - DNS on RHEL 4 or 5

The reference implementation of RFC's for DNS see http://www.isc.org/products/BIND  also see alternative http://www.unbound.net


Prerequisites: bind, bind-utils, bind-chroot, caching-nameserver, openssl


Location of daemons: /usr/sbin/named, /usr/sbin/rndc


Startup: /etc/init.d/named


Iptables support: tcp/udp 53 and 953 incoming - tcp/udp ephemeral ports outgoing


SELinux support is available as well as Applications specific security - fix contexts with restorecon -R /var/named/chroot

if selinux booleans are changed from default they must be persisted in /etc/selinux/targeted/booleans.local

    getsebool -a |grep named

Configuration Files:

  • /var/named/chroot/

  • /etc/named.conf

  • /var/named/*

  • /etc/rndc.key


Start by installing all of the prerequisite packages listed above:

   yum -y install openssl
   yum -y install bind bind-utils
   yum -y install bind-chroot
   yum -y install caching-nameserver  #for an initial config

Make absolutely certain to copy /var/named/chroot/etc/named.caching-nameserver.conf to /var/named/chroot/etc/named.conf and chown root:named and then edit /var/named/chroot/etc/named.conf as the primary config file.  Also verify that /etc/named.conf has the correct SELinux context.

Cache-only example named.conf

options {

listen-on port 53 { 127.0.0.1; };

allow-query { localhost; 10.1.4.0/24; };

listen-on-v6 port 53 { ::1; };

directory "/var/named";

dump-file "/var/named/data/cache_dump.db";

        statistics-file "/var/named/data/named_stats.txt";

        memstatistics-file "/var/named/data/named_mem_stats.txt";


// Those options should be used carefully because they disable port

// randomization

// query-source    port 53;

// query-source-v6 port 53;


allow-query-cache { localhost; };

  forwarders { 10.1.4.30; 10.1.4.40; };

forward only;

};

logging {

        channel default_debug {

                file "data/named.run";

                severity dynamic;

        };

};

view localhost_resolver {

match-clients   { localhost; 10.1.4.0/24; };

match-destinations { localhost; };

recursion yes;

include "/etc/named.rfc1912.zones";

};

Adding a master zone in /var/named/chroot/var/named/sysxperts.com.zone
$TTL 86400
@       IN SOA    ns1 webmaster (
                        43 ; serial (d. adams)
                        3H ; refresh
                        15M ; retry
                        1W ; expiry
                        1D ) ; minimum
@            IN NS         ns1
ns1          IN A           10.1.4.30
@            IN MX 10     mail.sysxperts.com

in /var/named/chroot/etc/named.conf update the view section

view localhost_resolver {

    match-clients   { localhost; 10.1.4.0/24; };

    match-destinations { localhost; };

    recursion yes;

    include "/etc/named.rfc1912.zones";

zone "sysxperts.com" IN {

    type master;

    file "sysxperts.com.zone";

    allow-update { none; };

    forwarders {};

};

};


Adding a reverse lookup zone in /var/named/chroot/var/named/10.1.4.zone
cp -a /var/named/chroot/var/named/named.local /var/named/chroot/var/named/10.1.4.zone and edit
$TTL 86400
@       IN      SOA     ns1.sysxperts.com. webmaster.sysxperts.com.  (
                                      1997022701 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400 )    ; Minimum
@        IN      NS      ns1.sysxperts.com.
40       IN      PTR     ns1.sysxperts.com.

in /var/named/chroot/etc/named.conf update the view section

view localhost_resolver {
    match-clients   { localhost; 10.1.4.0/24; };
    match-destinations { localhost; };
    recursion yes;
    include "/etc/named.rfc1912.zones";
zone "sysxperts.com" IN {
    type master;
    file "sysxperts.com.zone";
    allow-update { none; };
    forwarders {};
zone "4.1.10.in-addr.arpa" IN {
    type master;
    file "10.1.4.zone";
    allow-update { none; };
    forwarders {};

};
}; 

Test the configuration:

    service named configtest
    inspect /etc/sysconfig/named and look for ROOTDIR=/var/named/chroot
    also verify that ps -ef |grep named output includes a -t pointing to the chroot directory


Configure for autostart and start the service:

   chkconfig named on
   service named start


Configuring the Stub:

    edit /etc/resolv.conf so that it specifies only nameserver  127.0.0.1  (::1 for ipv6)
    add PEERDNS=no to every ifcfg-* file in /etc/sysconfig/network-scripts/  (Prevents DHCP from overwriting resolv.conf - VERY BAD THING FOR A NS)
    unpriviledged users can determine nameservers via /var/lib/dhclient/dhclient-eth0.leases

BIND ACLs assign a name to a match list, may be nested, and are generally preferred over the use of match lists.  


Example:

At the top of the /etc/named.conf enter some sample ACL entries as follows

acl "trusted"    { 10.1.1.21; };
acl "exec"         { 10.1.2.0/24; trusted; };
acl "it"               { 10.2.2.0/24; };
acl "thishost"   { 127.0.0.1; 10.1.3.55; };

built in ACL's

  • none -  no matches

  • any - All IPs match

  • localhost - Any IP of the nameserver

  • localnets - directly-connected networks


Enable BIND on only the desired interfaces

    listen-on port 53 { thishost; };  #see acl "thishost" above to see ip's that it maps to and note that loopback must be specified


Allow queries to members of acl

    allow-query { exec; it; };  #if not specified all queries are allowed


Best practices indicate that authoritative servers should be restricted to that purpose and caching-only servers should be setup to perform caching and external lookups.


allow-recursion (applies only to queries not in cache already) and allow-transfer (applies to zone transfers) work the same way as allow-query for their respective types - again, if not defined, named permits all.


Example /etc/named.conf with ACL:


// named.conf with ACL entries

acl "trusted"    { 10.1.1.21; };

acl "exec"         { 10.1.2.0/24; trusted; };

acl "it"               { 10.2.2.0/24; };

acl "thishost"   { 127.0.0.1; 10.1.3.55; };

acl "masters"   { 10.1.4.70; 10.1.4.71; };

acl "slaves"     { 10.1.3.56; 10.1.3.57; 10.1.3.58 };


options {

      # bind to local interface and loopback

      listen-on port 53 { thishost; };

      # for v6 uncomment the following

      # listen-on-v6  port 53 { ::1; };


      # enable self-queries

      allow-query  { localhost; trusted; exec; it; };

      allow-recursion { localhost; trusted; exec; it; };

      /* don't let anyone do zone transfers but slaves */

      allow-transfer { localhost; slaves; !trusted; !exec; !it; };


      # use a recursive upstream server

      forwarders { 10.2.0.254; };

      forward only;

};



Slave Zone:

zone "sysxperts.com" {
    type slave;
    masters { masters; };
    file "slaves/sysxperts.com.zone";
};

The zone line tells bind to act as authoritative nameserver for sysxperts.com and sysxperts.com is the origin as indicated in the zones SOA record domain field.  The type specifies that this server should be a slave for this zone. The masters specifies which servers to perform zone transfers against and the file option indicates where the zone files should be stored.  For a chroot environment files would be stored in /var/named/chroot/var/named/slaves/ in this case.

Always configure BIND to use the slaves directory for slave zones in /var/named/chroot/etc/named.conf; otherwise, SELinux will prevent zone transfers.  If you must change the path then be sure to use restorecon command to configure the appropriate SELinux context.

    semanage fcontext -l |grep slaves
    semanage fcontext -a -f "" -t named_cache_t '/path/to/slaves(/.*)?'
    restorecon -vR /path/to/   #note that I did not include slaves/ here
    service reload named  # automatically creates the sysxperts.com.zone file

Test slave zone transfer by going to /var/named/chroot/var/named/slaves and confirming the zone file was created after restarting named.
Also perform a non-recursive query with:
    host -r ns1.sysxperts.com localhost

Master Zone:

zone "sysxperts.com" {
    type master;
    file "sysxperts.com.zone";
};

The root user must write data to the master zone file.  After creating file ensure that it is owned by root:named.  Again, verify the SELinux context as done above for the slave zone.  Reload named after creating the sysxperts.com.zone master zone file.

Loopback zones should be defined and never be slave zones.

The simplest way to create a new zone file is to use one of the existing zone files created by the caching-nameserver package.

Adding $TTL 86400 as the first line in a zone file allows you to avoid entering the TTL value for every record.

Example of multi-line rdata entry:
       
$TTL 86400    
@ IN SOA    ns1.sysxperts.com.     webmaster    (
        97    ; serial (p. valentino)
        1H    ; refresh
        15M  ; retry
        1W   ; expire auth
        1D)   ; min. for negative answers

@            IN NS         ns1
ns1          IN A           10.1.4.30
@             IN MX  (
                        10    ; priority
                        mail1.sysxperts.com.) ; canonical mail server name

In the example above webmaster will be appended with the origin since it's not dot term
inated; therefore, the SOA contact will be webmaster@sysxperts.com.

Run service named configtest after editing to verify syntax (note that permissions and sanity checks are not performed by config testing tools).

You may also run named-checkconf and named-checkzone to check files that are not in the default locations.

    named-checkconf ~/bindconfig/named.conf #to check file in your home bindconfig directory
    named-checkconf -t /var/named/chroot  #to check file in chrooted location
    named-checkzone sysxperts.com /var/named/chroot/var/named/sysxperts.com.zone  #checks zone config for sysxperts.com
    service named configtest

Note the ports for named that must be allowed through firewall or iptables configurations
grep domain|/etc/services
domain 53/tcp # name-domain server
domain 53/udp
domaintime 9909/tcp # domaintime
domaintime 9909/udp # domaintime

in /etc/sysconfig/iptables add:

-A Firewall-INPUT -p udp -m udp --dport 53 -j ACCEPT

-A Firewall-INPUT -p tcp -m tcp --dport 53 -j ACCEPT


then restart iptables with service iptables restart in order to allow DNS traffic to flow

RNDC - Remote Name Daemon Control provides remote and local management for named and is configured by bind-chroot package.

  • Note rndc utilizes keys stored in /var/named/chroot/etc/rndc.key to match against rndc_hosts acl entries - if key does not match named will not stop or start.
  • rndc can also be called by a remote BIND or DHCP server to update the local configuration - matching keys must exist for all remote servers.

Enabling remote administration example:

Create separate TSIG key for each pair of servers and copy the keys to each remote machine.  Chown the keys to named on each remote machine as well.  The following example shows example of setup for hosts ns1 and ns2 where ns2 can remotely administer ns1.  Edit /var/named/chroot/etc/named.conf:

rndc-confgen -a -b 256 -t /var/named/chroot -k ns1_ns2key [-r keyboard]

acl  "localhosts" { 127.0.0.1; };
include "/etc/rndc.key"
include "/etc/ns1_ns2key.key";
controls {
    inet 127.0.0.1 allow { localhosts; } keys { rndckey; };
    inet 10.1.4.71 allow  { 10.1.4.70; } keys { ns1_ns2key; };
};


Troubleshooting:
  • Ensure that the name of the rndc key referenced in named.conf is the same as the name of the key in /etc/rndc.key. This should berndckey.
  • If using a chroot environment, make sure /etc/rndc.key is a soft link to/var/named/chroot/etc/rndc.key.
  • Check the permissions and ownership of the rndc.key file. Permissions should be 640 with owner:group of root:named
  • Make sure that port 953 is open between the servers at the firewall and iptables
  • Note that keys cannot be placed in acl or match lists or they will just be ignored.

Delegating Subdomains

Prior to a new delegation it is common to create a new NS record with a low TTL while continuing to use the existing nameserver.  Once the new server comes online the NS record is updated and the TTL is set to a normal higher value.
Let's say that sysxperts.com has spawned off a division that it wants to manage with a subdomain such as geekwads.sysxperts.com and they want to use ren.geekwads.sysxperts.com and stimpy.geekwads.sysxperts.com to be the authoritative slave servers for the geekwads.sysxperts.com domain.
First, they must setup a zone on each child server ren & stimpy to hold the subdomain data.
Second, the parent zone must be configured to delegate authority to ren & stimpy.  To do so, create an NS record for the subdomain that points to the new name servers.  For example, in sysxperts.com zone on ns1 & ns2.sysxperts.com:

geekwads.sysxperts.com.    IN NS    ren.geekwads.sysxperts.com.
geekwads.sysxperts.com.    IN NS    stimpy.geekwads.sysxperts.com.

And a glue record is also required so that the parent zone knows how to find ren & stimpy so again in sysxperts.com zone on ns1 & ns2.sysxperts.com:

ren.geekwads.sysxperts.com.    IN A    10.1.4.50
stimpy.geekwads.sysxperts.com.     IN A    10.1.4.60

Split DNS

Split DNS is simply presenting zone data differently based upon a view or mapping.  For example, presenting one set of zone data to internal clients and a different set to external clients.

view "internal" {
    match-clients {10.1.4.0/24; };
    recursion yes;
    zone "sysxperts.com" {
        type master;
        file "sysxperts-internal.zone";
    };
};

view "external" {
    match-clients { any; };
    recursion no;
    zone "sysxperts.com" {
        type master;
        file "sysxperts-external.zone";
    };
};





2 comments:

SG said...

Great information!

SG said...

Great information on bind!