Network monitoring : log DNS queries with bind

Mar 30, 2022 by Thibault Debatty | 35577 views

Monitoring Sysadmin

https://cylab.be/blog/209/network-monitoring-log-dns-queries-with-bind

Recording the DNS queries perform by devices on your network is a simple and efficient way of monitoring your network. In this blog post we show how to configure the bind DNS server to log these…

Prerequisites

For this blog post, we assume that you already have a bind server installed and configured on your network. Also, all devices on your network should be configured to use this DNS server…

For this blog post I used a Ubuntu 20.04 server.

Bind configuration

To enable query logging in bind, add the following snippet at the end of /etc/bind/named.conf.options:

logging {
        channel default_log {
                file "/var/log/bind/default.log";
                print-time yes;
                print-category yes;
                print-severity yes;
                severity info;
        };

        category default { default_log; };
        category queries { default_log; };
};

As you can guess from this snippet, bind allows to define different logging channels. A logging channel can be a log file or a syslog facility.

Then, different categories of events can be mapped to one or more channel. This allows a very fine logging granularity.

In this example we send the default and queries events to our default log file. The complete list of categories can be found in the documentation of bind: https://bind9.readthedocs.io/en/latest/reference.html#the-category-phrase

Now you should create the directory where the log files will be written:

sudo mkdir /var/log/bind
sudo chown bind /var/log/bind

Finally, you can restart bind:

sudo service bind9 restart

The file /var/log/bind/default.log will start to fill with lines like

24-Mar-2022 15:52:00.178 queries: info: client @0x7f34380446a0 
    10.155.105.100#54387 (www.akamai.com): query: www.akamai.com IN A + 

In this example:

  • @0x7f3438044 is a unique client identifier;
  • 10.155.105.100 is the IP of the client;
  • 54387 is the source port;
  • www.akamai.com IN A is the received query.

The query itself may be followed by a series of characters to indicate additional information:

  • + : Recursion Desired flag was set (like in the example above);
  • S : the query was signed;
  • E : EDNS was in use, with EDNS version number;
  • T : TCP was used;
  • D : DO (DNSSEC Ok) was set;
  • C : CD (Checking Disabled) was set;
  • V : a valid DNS Server COOKIE was received;
  • K : a DNS COOKIE option without a valid Server COOKIE.

Analysis

With this logging in place, you may start analyzing what happens on your network.

Top queries

For example, to list the most often queried domain names:

grep queries /var/log/bind/default.log  | cut -d " " -f 10 | sort 
    | uniq -c | sort -n

This will produce a list like

     14 2.tlu.dl.delivery.mp.microsoft.com
     14 feeds.feedburner.com
     21 ctldl.windowsupdate.com
     23 grafana.com
     24 marketplace.opennebula.systems
     40 settings-win.data.microsoft.com
     46 www.akamai.com
     51 safebrowsing.googleapis.com
     58 connectivity-check.ubuntu.com
     67 v10.events.data.microsoft.com

Top queries, grouped by level-3 domain

As you might have noticed from the list above, some domains have a long list of sub-sub-sub domains (like 2.tlu.dl.delivery.mp.microsoft.com). It might be more interesting to group them all according to the level-3 domain (mp.microsoft.com):

grep queries /var/log/bind/default.log | cut -d " " -f 10 | rev 
    | cut -d "." -f "1-3" | rev  | sort | uniq -c | sort -n

This time, the list looks like this, and queries for data.microsoft.com are really showing up:

     17 archive.ubuntu.com
     21 ctldl.windowsupdate.com
     25 grafana.com
     26 marketplace.opennebula.systems
     49 www.akamai.com
     62 safebrowsing.googleapis.com
     63 connectivity-check.ubuntu.com
     96 mp.microsoft.com
    116 data.microsoft.com

We could also group by level-2 domains to summarize even more…

Most active devices

Finally, we can list the devices that sent the most queries:

grep queries /var/log/bind/default.log | cut -d " " -f 7 | cut -d "#" -f 1 
    | sort | uniq -c | sort -n
     92 10.155.142.9
     94 10.155.141.247
     94 10.155.142.0
    100 10.155.0.6
    101 127.0.0.1
    106 10.155.0.3
    117 10.155.138.61
    136 10.155.116.150
    139 10.155.0.2
    139 10.155.1.4
    515 10.155.105.100

On this subnet, I would like to have a look at 10.155.105.100

Logrotate

You can use logrotate to create a new log file each week. Create the file /etc/logrotate.d/bind with the following content:

/var/log/bind/*.log {
  weekly
  rotate 53
  compress
  create 0644 bind bind
  missingok
  notifempty
  sharedscripts
  postrotate
    # reload bind, to write in the new log file
    /usr/sbin/rndc reconfig > /dev/null 2>/dev/null || true
  endscript
}

This blog post is licensed under CC BY-SA 4.0

This website uses cookies. More information about the use of cookies is available in the cookies policy.
Accept