How to log all DNS requests made through OpenWRT router?

I have an OpenWRT router that is running dnsmasq. I want to create a file that has each domain that has been requested through the router. My output should looks something like this:

google.com
cnn.com
wikipedia.com
news.google.com
gmail.com

Ideally there wouldn't be any duplicates. I could probably setup a cron job that would remove duplicates if necessary. Right now I'm trying to figure out a good way to log them. I looked at the options for dnsmasq. I found the following options:

 -q, --log-queries                       Log DNS queries.
 -8, --log-facility=<facilty>|<file>     Log to this syslog facility or file. (defaults to DAEMON)
--log-dhcp                          Extra logging for DHCP.
--log-async[=<integer>]             Enable async. logging; optionally set queue length.

On OpenWRT these settings seem to be buried in the /etc/init.d/dnsmasq file. I tried setting them without any luck. :-( Is there an easier way to accomplish my goal?

Ah! With a little hackery I was able to get it to write to a log file. However, it doesn't have the data I need to create this list. Maybe dnsmasq can't do what I want it to?


You can edit the config file:

vi /etc/dnsmasq.conf

    # /etc/dnsmasq.conf
    log-dhcp
    log-queries
    log-facility=/tmp/dnsmasq.log

Or edit another config file:

vi /etc/config/dhcp

    config dnsmasq
        ...
        option logdhcp '1'
        option logqueries '1'
        option logfacility '/tmp/dnsmasq.log'

Then restart service:

/etc/init.d/dnsmasq restart

Log file can be parsed in real-time with tail+awk:

$ vi dnsmasq.awk

    #!/usr/bin/awk -f

    BEGIN {
      OFS = ",";
    }

    $5 == "query[A]" {
      time = mktime( \
        sprintf("%04d %02d %02d %s\n", \
          strftime("%Y", systime()), \
          (match("JanFebMarAprMayJunJulAugSepOctNovDec",$1)+2)/3, \
          $2, \
          gensub(":", " ", "g", $3) \
        ) \
      );
      query = $6;
      host = $8;
      print time, host, query;
    }

$ chmod +x dnsmasq.awk

$ tail -f /tmp/dnsmasq.log | ./dnsmasq.awk

1468999090,192.168.1.100,google.com
1468999092,192.168.1.101,youtube.com
1468999095,192.168.1.102,facebook.com
1468999097,192.168.1.100,qa.sockets.stackexchange.com

More advanced method is sending log via filebeat to ELK in realtime.


You can install tcpdump and sniff the packet going to the port 53

tcpdump -i eth0 -l -vvv dst host 192.168.1.100 and dst port 53 >> dump.log

This file will grow really fast and your router will run out of memory very quickly. Using a usb stick to save the log will prevent this.


In /etc/config/dhcp add:

config dnsmasq
    [...]
    option logqueries '1'

and restart dnsmasq.

Logs will be written to the systemlog, view with logread -f in a terminal or via LuCi.


Given that you are using a router, if you want to write logs onto the internal flash memory a lot, this will lower the lifespan of the flash memory potentially bricking it.

If you do not mind having your logs appearing on a 3rd party service, may I suggest using OpenDNS to achieve your purpose instead?

Conceptually

  1. As soon as your router changes WAN IP, it needs to notify OpenDNS of your new IP.
  2. Your router needs to be configured to use OpenDNS servers for DNS lookups.
  3. Your network's DNS lookup history will show up on OpenDNS Dashboard albeit after some hours of delay. Here, you can see the number of times a domain has been queried ordered by top most and also a graph that tells you lookups per hour.

Details

Quote from a tutorial I wrote

OpenDNS DNS-O-Matic setup

Firstly, we need an account on DNS-O-Matic and OpenDNS to maintain logs.

  1. Signup for a DNS-O-Matic (www.dnsomatic.com) account. Use a password without special characters. As far as I remember, this caused issues with configuration on OpenWRT. You can compensate the loss of password strength by increasing length.
  2. Using the same login credentials, signin at OpenDNS Dashboard (dashboard.opendns.com)
  3. Under Settings, label your network with a name. I call it ‘Home’
  4. Settings for: <Your network label>, select this
  5. Click on Stats and Logs
  6. Enable stats and logs
  7. Go back to DNS-O-Matic
  8. Add a service, OpenDNS
  9. Select your home network

OpenWRT configuration

We need to configure OpenWRT to update OpenDNS via DNS-O-Matic service upon change of public IP address, i.e. due to reboot of router, WAN link dropped and reconnected, etc.

Note: These steps are for OpenWRT Chaos Calmer.

Important: Depending on available space on your router, you may have to resort to using non-SSL options.

  1. Navigate to System > Software
  2. Update lists
  3. If you want to use SSL, install ca-certificates and wget
  4. If you do not want to or unable to use SSL, install wget-nossl
  5. Install ddns-scripts and luci-app-ddns
  6. Navigate to Service > Dynamic DNS
  7. Add a new entry and call it dnsomatic
  8. Select -custom- DDNS Service provider
  9. Set Custom update-url to http://[USERNAME]:[PASSWORD]@updates.dnsomatic.com/nic/update?hostname=all.dnsomatic.com&myip=[IP]&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG without substituting anything
  10. Set hostname to dnsomatic.com
  11. Enter your username and password
  12. Check ‘Use HTTP Secure’ if you are using the SSL option
  13. The [IP] part of the URL will be substituted as defined by ‘IP address source ‘and ‘Network’ fields under ‘Advanced Settings’.
  14. Save & Apply