BIND 9

The BIND 9 DNS Server is commonly used on Unix-like operating systems. It can act as both an authoritative name server and a recursive resolver.

In addition to collecting BIND 9 logs, consider implementing File Integrity Monitoring or DNS audit Logging for the BIND 9 configuration files.

Configuring BIND 9 logging

BIND 9 can be configured to log events to file or via syslog. Log messages are organized into categories and log destinations are configured as channels. The special default category can be used to specify the default for any categories that have not been explicitly configured. For full details about BIND 9 configuration, see the corresponding BIND 9 Administrator Reference Manual.

Example 1. Logging all categories via syslog

This configuration logs all messages, of info severity or greater, to the local syslog daemon. The queries category is specified explicitly, because query logging is otherwise disabled by default. The print-* options enable the inclusion of various metadata in the log messages—this metadata can later be parsed by NXLog.

named.conf
logging {

  # Add a Syslog channel, with info severity
  channel my_syslog {
    syslog daemon;
    severity info;

    # Enable all metadata
    print-time yes;
    print-category yes;
    print-severity yes;
  };

  # Set the default destination for all categories
  category default { my_syslog; };

  # Enable query logging by setting this category explicitly
  category queries { my_syslog; };
};
Log format
<syslog-header> <date> <time> <category>: <severity>: <message>
Log sample
<30>Apr 29 22:30:15 debian named[16373]: 29-Apr-2019 22:30:15.371 general: info: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
<30>Apr 29 22:30:15 debian named[16373]: 29-Apr-2019 22:30:15.372 resolver: info: resolver priming query complete
<30>Apr 29 22:30:20 debian named[16373]: 29-Apr-2019 22:30:20.770 queries: info: client @0x7f9b6810ed50 10.80.0.1#44663 (google.com): query: google.com IN A +E(0) (10.80.1.88)
Example 2. Logging to file

BIND can be configured to write log messages to a file. This configuration also shows how a particular category can be disabled.

named.conf
logging {

  # Add a file channel with info severity
  channel my_file {
    file "/var/log/bind.log" versions 3 size 100m;
    severity info;
    print-time yes;
    print-category yes;
    print-severity yes;
  };

  category default { my_file; };
  category queries { my_file; };

  # Disable a category by setting its destination to null
  category lame-servers { null; };
};

The resulting log format is the same as in the previous example, but without the syslog header.

Log sample
01-May-2019 00:26:56.579 general: info: managed-keys-zone: Key 20326 for zone . acceptance timer complete: key now trusted
01-May-2019 00:26:56.617 resolver: info: resolver priming query complete
01-May-2019 00:27:48.084 queries: info: client @0x7f82bc11d4e0 10.80.0.1#53995 (google.com): query: google.com IN A +E(0) (10.80.1.88)

Parsing BIND 9 logs

BIND 9 uses a single basic logging format across the logging categories. This allows log data to be parsed reliably, and further parsing can be configured as required for each individual category. Therefore, parsing of BIND 9 logs can be implemented in these three steps:

  1. the syslog headers with xm_syslog (if logging via syslog),

  2. the BIND metadata (from the print-* options) with a regular expression, and

  3. any category-specific syntax (such as for the queries category below)—additional parsing can be implemented, if required, for any other category that uses a consistent format.

The following examples have been tested with BIND 9.10 and 9.11.
Example 3. Collecting BIND 9 logs via syslog

This configuration uses the im_uds module to accept local syslog messages. BIND 9 should be configured to log messages via syslog as shown in Logging all categories via syslog above.

nxlog.conf
<Extension _syslog>
    Module  xm_syslog
</Extension>

<Input syslog>
    Module  im_uds
    UDS     /dev/log
    <Exec>
        # 1. Parse Syslog header
        parse_syslog_bsd();

        # 2. Parse BIND 9 metadata
        if $Message =~ /(?x)^(?<EventTime>\S+\s\S+)\s(?<Category>\S+):\s
                             (?<BINDSeverity>[^:]+):\s(?<Message>.+)$/i
        {
            $EventTime = parsedate($EventTime);

            # 3. Parse messages from the queries category
            if $Category == "queries"
            {
                $Message =~ /(?x)^client\s((?<ClientID>\S+)\s)?(?<Client>\S+)\s
                                 \((?<OriginalQuery>\S+)\):\squery:\s
                                 (?<QueryName>\S+)\s(?<QueryClass>\S+)\s
                                 (?<QueryType>\S+)\s(?<QueryFlags>\S+)\s
                                 \((?<LocalAddress>\S+)\)$/;
            }

            # Parse messages from another category
            #else if $Category == "resolver"
            #{
            #   $Message =~ ...
            #}
        }
    </Exec>
</Input>
Event sample
{
  "EventReceivedTime": "2019-04-29T22:30:20.856069+01:00",
  "SourceModuleName": "syslog",
  "SourceModuleType": "im_uds",
  "SyslogFacilityValue": 3,
  "SyslogFacility": "DAEMON",
  "SyslogSeverityValue": 6,
  "SyslogSeverity": "INFO",
  "SeverityValue": 2,
  "Severity": "INFO",
  "Hostname": "debian",
  "EventTime": "2019-04-29T22:30:20.770000+01:00",
  "SourceName": "named",
  "ProcessID": "16373",
  "Message": "client @0x7f9b6810ed50 10.80.0.1#44663 (google.com): query: google.com IN A +E(0) (10.80.1.88)",
  "BINDSeverity": "info",
  "Category": "queries",
  "Client": "10.80.0.1#44663",
  "ClientID": "@0x7f9b6810ed50",
  "LocalAddress": "10.80.1.88",
  "OriginalQuery": "google.com",
  "QueryClass": "IN",
  "QueryFlags": "+E(0)",
  "QueryName": "google.com",
  "QueryType": "A"
}
Example 4. Collecting BIND 9 logs from file

This configuration uses the im_file module to read messages from the BIND 9 log file. BIND 9 should be configured as shown in Logging to file above. The parsing here is very similar to the previous example, but without syslog header parsing.

nxlog.conf
<Input file>
    Module  im_file
    File    '/var/log/bind.log'
    <Exec>
        if $raw_event =~ /(?x)^(?<EventTime>\S+\s\S+)\s(?<Category>\S+):\s
                               (?<Severity>[^:]+):\s(?<Message>.+)$/i
        {
            $EventTime = parsedate($EventTime);
            if $Category == "queries"
            {
                $Message =~ /(?x)^client\s((?<ClientID>\S+)\s)?(?<Client>\S+)\s
                                 \((?<OriginalQuery>\S+)\):\squery:\s
                                 (?<QueryName>\S+)\s(?<QueryClass>\S+)\s
                                 (?<QueryType>\S+)\s(?<QueryFlags>\S+)\s
                                 \((?<LocalAddress>\S+)\)$/;
            }
        }
    </Exec>
</Input>

DNS audit logging

Different to File Integrity Monitoring which provides monitoring based on checking for changes to the cryptographic checksums, DNS audit logging provides some additional details. Apply the following rules to watch BIND 9 configuration files. The im_linuxaudit module can also be applied to audit other assets on Linux. See Linux Audit System.

Example 5. Configuring DNS audit logging on configuration files

This configuration uses the im_linuxaudit module to watch the the BIND 9 configuration file /etc/bind/named.conf for modifications and tags the events with conf-change-bind. Read more about Audit rules.

nxlog.conf
<Input audit>
    Module         im_linuxaudit
    FlowControl    FALSE
    <Rules>
        # Delete all rules (This rule has no affect; it is performed
        # automatically by im_linuxaudit)
        -D

        # Watch /etc/bind/named.conf for modifications and tag 'conf-change-bind'
        -w /etc/bind/named.conf -p wa -k conf-change-bind

        # Generate a log entry when the system time is changed
        -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k system_time

        # Lock Audit rules until reboot
        -e 2
    </Rules>
</Input>
Event sample of BIND 9 configuration change
{
  "type": "CONFIG_CHANGE",
  "time": "2020-02-21T01:30:36.027000+01:00",
  "seq": 31,
  "auid": 4294967295,
  "ses": "4294967295",
  "subj": "=unconfined",
  "op": 0,
  "key": "conf-change-bind",
  "list": "4",
  "res": "1",
  "EventReceivedTime": "2020-02-21T01:30:36.034819+01:00",
  "SourceModuleName": "audit",
  "SourceModuleType": "im_linuxaudit"
}
Event sample of audit trail
{
  "type": "SYSCALL",
  "time": "2020-02-21T02:20:32.365000+01:00",
  "seq": 165,
  "arch": "c000003e",
  "syscall": "257",
  "success": "yes",
  "exit": 3,
  "a0": "ffffff9c",
  "a1": "563b82d382a0",
  "a2": "441",
  "a3": "1b6",
  "items": 2,
  "ppid": 1739,
  "pid": 1740,
  "auid": 1000,
  "uid": 0,
  "gid": 0,
  "euid": 0,
  "suid": 0,
  "fsuid": 0,
  "egid": 0,
  "sgid": 0,
  "fsgid": 0,
  "tty": "pts2",
  "ses": "2",
  "comm": "nano",
  "exe": "/bin/nano",
  "subj": "=unconfined",
  "key": "conf-change-bind",
  "EventReceivedTime": "2020-02-21T02:20:32.373192+01:00",
  "SourceModuleName": "audit",
  "SourceModuleType": "im_linuxaudit"
}
Disclaimer

While we endeavor to keep the information in this topic up to date and correct, NXLog makes no representations or warranties of any kind, express or implied about the completeness, accuracy, reliability, suitability, or availability of the content represented here.

Last revision: 01 February 2021