Debian: Bind

BIND 9 has evolved to be a very flexible, full-featured DNS system. Whatever your application is, BIND 9 probably has the required features. As the first, oldest, and most commonly deployed solution, there are more network engineers who are already familiar with BIND 9 than with any other system.

Step 1: Install Packages

This installation expects apache to be already running

# sudo apt install bind9 bind9-utilsCode language: PHP (php)

Step 2: Configure BIND9 Basics

Change bind default settings and make sure bind always starts with proper user /etc/default/bind9

# run resolvconf?
RESOLVCONF=no

# startup options for the server
OPTIONS="-u bind"
Code language: PHP (php)

BIND9 has a specific file containing various of its generic options /etc/bind/named.conf which loads all the other configurations

// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local

// BIND9 : Transfer Keys
include "/etc/bind/tsig.keys";

// BIND9 : RNDC Key Controls
include "/etc/bind/rndc.key";

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.root-hints";
include "/etc/bind/named.conf.log";

controls {
      inet 127.0.0.1 port 953
      allow { 127.0.0.1; } keys { "rndc-key"; };
};

statistics-channels {
  inet 127.0.0.1 port 8053 allow { 127.0.0.1; };
};Code language: PHP (php)

BIND9 has a specific file containing various of its generic options /etc/bind/named.conf.options which loads all the other configurations

// BIND9: ACL Configuration
acl "trusted" {
    localhost;
    192.168.0.0/16;
    localnets;
};

// BIND9 : Options
options {

    // Zone Directory
    directory "/var/cache/bind";

    // GeoIP Directory
    geoip-directory "/var/lib/GeoIP";

    // conform to RFC1035
    auth-nxdomain no;

    // listen on IPv6 defined addresses only
    listen-on-v6 { <external-ipv6-ip>; };

    // Listen on IPv4 defined addresses only
    listen-on { 127.0.0.1; <external-ipv4-ip>; };

    // Do not make public version of BIND
    version none;

    // DNS sec
    dnssec-validation auto;  // Automatically manages root trust anchor
    managed-keys-directory "/var/cache/bind/keys";

    allow-query { any; };
    allow-query-cache { trusted; };
    allow-recursion { trusted; };

    minimal-responses yes;

    // pid file
    pid-file "/var/run/named/named.pid";

    // This statement defines the file-name to which data will be
    // written when the command rndc stats is issued.
    statistics-file "/var/log/named/named.stats";

    // This statement defines whether zone statistics will be maintained.
    zone-statistics yes;

    // By default DNS uses UDP port 53 for queries but is defined to allow both TCP and UDP.
    // The tcp-clients allows the user to define the maximum number of TCP connections to be supported.
    // The BIND 9 default is 100.
    tcp-clients 50;

    rate-limit {
        ipv4-prefix-length 32;
        window 10;
        responses-per-second 25;
        errors-per-second 5;
        nxdomains-per-second 5;
        slip 2;
        exempt-clients { trusted; };
    };
};Code language: PHP (php)

BIND9 has a specific file containing various of its generic logging options /etc/bind/named.conf.log :

// This is the logging configuration file for the BIND DNS server named.

logging {

    channel transfers {
            file "/var/log/named/transfers" versions 3 size 10M;
            print-time yes;
            severity info;
    };

    channel update_debug {
        file "/var/log/named/update_debug.log" versions 3 size 100k;
        severity debug;
        print-severity  yes;
        print-time      yes;
    };

    channel security_info {
        file "/var/log/named/security_info.log" versions 1 size 100k;
        severity info;
        print-severity  yes;
        print-time      yes;
    };

    channel bind_log {
        file "/var/log/named/bind.log" versions 3 size 1m;
        severity info;
        print-category  yes;
        print-severity  yes;
        print-time      yes;
    };

    // Fail2Ban configuration
    channel security_file {
        file "/var/log/named/security.log" versions 3 size 1m;
        severity dynamic;
        print-time yes;
    };

    category security {
        security_file;
    };

    channel slog {
        syslog security;
        severity info;
    };

    channel dnssec_log {
        file "/var/log/named/dnssec.log" versions 3 size 1m;
        severity info;
        print-time yes;
    };

    category dnssec { dnssec_log; };

    category xfer-out { transfers; slog; };
    category xfer-in { transfers; slog; };


    category default { bind_log; };
    category lame-servers { null; };
    category update { update_debug; };
    category update-security { update_debug; };
    category security { security_info; };

};Code language: PHP (php)

Step 3: TSIG: Local Control

The purpose of this signature is to authenticate transactions with BIND

# rndc-confgen > /etc/bind/rndc.conf
# chown root:bind  /etc/bind/rndc.conf
# chmod 640  /etc/bind/rndc.confCode language: PHP (php)

Copy the key section of /etc/bind/rndc.conf to /etc/bind/rndc.key file, change its permissions:

# chown root:bind /etc/bind/rndc.key
# chmod 640 /etc/bind/rndc.keyCode language: PHP (php)

Add the following into the primary bind configuration file /etc/bind/named.conf

include "/etc/rndc.key";

controls {
        inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; };
};Code language: PHP (php)

Step 4: TSIG: Secondary Zones

This post is not specifcally meant for setting up DNS zones as there are sufficient sites dedicated on that, however there are some things to take into account, for example making sure that secondary bind servers use secure keys to transfer zones.

Make sure that the zone file (exmaple) contains a definition of keys /etc/bind/named.conf.local on the Primary Server

zone "mydomain.org" in {
        type master;
        file "/var/cache/bind/mydomain.org.db";
        allow-transfer { <secondary-server-ip>; };
        also-notify { <secondary-server-ip>; };
        also-notify { <secondary-bind-server-ip>; };
};Code language: HTML, XML (xml)

Also properly configured on the secondary servers /etc/bind/named.conf.local

zone "mydomain.org" in {
    type slave;
    file "/var/cache/bind/mydomain.org.db";
    masters { <primary-server-ip>; };
    allow-notify { <primary-server-ip>; };
};Code language: HTML, XML (xml)

On the primary server generate a relationship key

# dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST -r /dev/urandom host1-host2Code language: PHP (php)

the key is in the file ‘host1-host2.+163+00000.private’ . Nothing directly uses this file, but the base-64 encoded string following “Key:” can be extracted from the file and used as a shared secret. Use this key and define it in the keyfile used for transfers /etc/bind/tskig.keys

// Transfer Keys
key "tsig-key" {
    algorithm HMAC-SHA512;
    secret "<key generated with dnssec-keygen command>";
};
Code language: JavaScript (javascript)