Many DNS servers support dnstap. dnstap is a flexible, structured binary log format for DNS software. It uses Protocol Buffers to encode events that occur inside DNS software in an implementation-neutral format. Query and response activity can be forwarded from DNS servers supporting dnstap.
Vision receives DNS query and response logs from DNS servers supporting dnstap. It aggregates and stores this data while also optionally sending events and aggregated DNS data to an organizations SIEM. An organization can also use its SOAR and other systems to query the Vision API to access DNS activity history data.
Configuration of dnstap is unique for each DNS server. This document provides an example of how to enable dnstap for the ISC BIND 9 DNS server (BIND) running on CentOS 8.
These steps were tested using the following CentOS and BIND version:
$ sudo named -v
BIND 9.11.26-RedHat-9.11.26-6.el8 (Extended Support Version) <id:3ff8620>
$ sudo cat /etc/redhat-release
CentOS Linux release 8.1.1911 (Core)
The first challenge in enabling dnstap with BIND is whether dnstap support is available in the version of BIND being used and that it has been compiled in to the BIND software. ISC documents support as follows:
dnstap will be generally available in BIND 9.11 but is in certain editions of earlier versions, such as BIND 9.9.8-S5.
A good indication of whether the DNS server supports dnstap is by checking its library dependencies:
$ ldd /sbin/named | grep fstrm
libfstrm.so.0 => /lib64/libfstrm.so.0 (0x00007fd87012b000)
This library is used by dnstap to send data using the framestream protocol with messages encoded using the Protocol Buffers format. If the named
binary is linked against this library then dnsstap support should be available.
When enabling dnstap only a UNIX domain socket can be specified when configuring BIND to send data to another process, i.e. a TCP connection cannot be specified. However, OneDDI Sensors will accept connections using TCP only. This is an issue in general since processes wanting to receive dnstap messages are often located on different hosts and require the use of TCP connections.
When integrating BIND and Vision a bridge must created between the UNIX domain socket and an outbound TCP connection to a OneDDI Sensor. In this example the socat
program is used with a system service created to ensure it always runs and is restarted in case the connection is broken for whatever reason.
Each query and response message sent via dnstap has an associated message type (taken from https://github.com/dnstap/dnstap.pb/blob/master/dnstap.proto):
// There are eight types of "Message" defined that correspond to the
// four arrows in the following diagram, slightly modified from RFC 1035
// section 2:
// +---------+ +----------+ +--------+
// | | query | | query | |
// | Stub |-SQ--------CQ->| Recursive|-RQ----AQ->| Auth. |
// | Resolver| | Server | | Name |
// | |<-SR--------CR-| |<-RR----AR-| Server |
// +---------+ response | | response | |
// +----------+ +--------+
// Each arrow has two Type values each, one for each "end" of each arrow,
// because these are considered to be distinct events. Each end of each
// arrow on the diagram above has been marked with a two-letter Type
// mnemonic. Clockwise from upper left, these mnemonic values are:
//
// SQ: STUB_QUERY
// CQ: CLIENT_QUERY
// RQ: RESOLVER_QUERY
// AQ: AUTH_QUERY
// AR: AUTH_RESPONSE
// RR: RESOLVER_RESPONSE
// CR: CLIENT_RESPONSE
// SR: STUB_RESPONSE
During the development of dnstap support in Vision it was found that the message types used by dnstap can differ for each DNS server type. Administrators may sometimes need to configure additional dnstap message types for a DNS server type which are not required by others (for example Coredns only requires CLIENT_QUERY
and CLIENT_RESPONSE
).
For BIND, the AUTH_QUERY
and AUTH_RESPONSE
messages were found to be required. So in total the following message types will be used for BIND (these will be specified when creating the DNS server in Vision):
AUTH_QUERY
AUTH_RESPONSE
CLIENT_QUERY
CLIENT_RESPONSE
In this step we create a system service to listen for dnstap messages from BIND over a UNIX domain socket. The messages are then forwarded to a OneDDI sensor over a TCP connection.
Create the dnstap
user to system service will run as and the /var/run/bind
directory where the UNIX domain socket will be created:
$ sudo useradd dnstap
$ sudo mkdir /var/run/bind
$ sudo chown dnstap:dnstap /var/run/bind
Create the file /usr/lib/systemd/system/dnstap-socat.service
with the following contents (replacing oneddi-sensor.internal
withe hostname of a OneDDI Sensor):
[Unit]
After=network.target
Description=dnstap-socat
[Service]
ExecStart=socat UNIX-LISTEN:/var/run/bind/dnstap.sock,mode=777 TCP4-CONNECT:oneddi-sensor.internal:6000
SyslogIdentifier=dnstap-socat
Group=dnstap
Restart=always
Type=simple
User=dnstap
[Install]
WantedBy=multi-user.target
Use the following commands to create, enable and start the service:
$ sudo systemctl daemon-reload
$ sudo systemctl enable dnstap-socat
$ sudo systemctl start dnstap-socat
Verify it is then running:
$ ps -ef | grep socat
dnstap 32365 1 0 10:03 ? 00:00:00 /usr/bin/socat UNIX-LISTEN:/var/run/bind/dnstap.sock,mode=777 TCP4-CONNECT:192.168.68.167:6000
In this step the BIND DNS server is configured in Vision after which OneDDI Sensors will accept TCP connections from the UNIX domain socket bridge service created in step 1.
Navigate to the Vision / Network / DNS servers page in Vision.
Create a DNS server with the following data collection properties (using default property values if not specified):
dnstap
Once the DNS server is added, OneDDI Sensors will accept connections from the UNIX domain socket bridge service running on the DNS server.
To view inbound connection attempts from the DNS server, navigate to the Vision / Network / Sensors page and click “VIEW SENSOR” button for the sensor the DNS server is sending dnstap messages to. Under the “SENSOR LOG” panel search for dnstap
. The log will display failed and successful connections from the DNS server.
In this step BIND is configured to log dnstap messages to the UNIX domain socket through which the UNIX domain socket bridge is listening for data.
Edit the /etc/named.conf
BIND configuration file and place the following in the options
block:
options {
...
dnstap {client; auth; };
dnstap-output unix "/var/run/bind/dnstap.sock";
...
};
Restart the DNS server using the systemctl restart named
command.
Issue a query to the DNS server and verify the message appears in the “LATEST DNS QUERIES” table under the Vision / Live queries page.
If no DNS queries are seen in the live queries page refer to the Troubleshooting section.
If selinux is enabled the DNS server will likely be prevented by default from opening and writing to the UNIX domain socket it was configured with.
Check the /var/log/audit/audit.log
file for denied
messages, for example:
$ sudo grep denied /var/log/audit/audit.log | tail -1
type=AVC msg=audit(1712232548.327:385): avc: denied { connectto } for pid=3384 comm="isc-worker0003" path="/run/bind/dnstap.sock" scontext=system_u:system_r:named_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=0
If this is the case, use the following commands to create a selinux policy update and apply it to permit BIND to write to the UNIX domain socket:
$ sudo grep denied /var/log/audit/audit.log | tail -1 | audit2allow -a -M dnstap
$ sudo semodule -i dnstap.pp
For issues with socat and the TCP connection, the dnstap-socat service can be stopped and socat ran manually with debugging flags to understand what it is doing (don’t forget to start dnstap-socat again once troubleshooting is complete):
$ sudo systemctl stop dnstap-socat
$ sudo -u dnstap socat -d -d -d -d -d UNIX-LISTEN:/var/run/bind/dnstap.sock,mode=777 TCP4-CONNECT:oneddi-sensor.internal:6000
Connection attempts, UNIX domain socket activity and other message can be seen in the output.