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.
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.
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; };
};
<syslog-header> <date> <time> <category>: <severity>: <message>
<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)
BIND 9 can be configured to write log messages to a file. This configuration also shows how a particular category can be disabled.
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.
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:
-
the syslog headers with xm_syslog (if logging via syslog),
-
the BIND metadata (from the
print-*
options) with a regular expression, and -
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.
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.
<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>
{
"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"
}
This configuration uses the im_file module to read messages from the BIND 9 log file. BIND 9 should be configured as shown in BIND 9 logging to file above. The parsing here is very similar to the previous example, but without syslog header parsing.
<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.
This configuration uses the im_linuxaudit module to watch the BIND 9 configuration file /etc/bind/named.conf
for modifications.
The events are tagged with conf-change-bind
.
Read more about Audit rules.
<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>
{
"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"
}
{
"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"
}