Passive DNS monitoring

Another source of DNS events can be found at the network level by capturing network packets being sent to a DNS Server. Packet analyzers typically set their network adapters into promiscuous mode which allows them to capture packets destined for other hosts. This enables network monitoring to occur on another host remote to the DNS Server. However, depending on the network architecture, it may be necessary to reconfigure the network to explicitly route packets to the passive DNS monitoring host as well.

The packet capture module im_pcap provides capabilities for monitoring all common network protocols, including network traffic that is specific to DNS clients and servers.

Configuring packet capture for passive DNS monitoring

Out of the many network protocols available with the im_pcap module, those of interest with regard to DNS monitoring are dns, ipv4, ipv6, udp, and tcp (if the DNS Server is configured for queries over TCP). Up to 14 fields can be specified for dns type packet capture. Depending on the DNS query, a DNS packet can have more than 14 fields via the extended field name pattern, $dns.additional.*, needed to store the various additional attributes of DNS traffic.

Combining packet capture protocols for obtaining necessary fields

Since none of the DNS packet fields track the network source or destination of communication between the DNS Server and its clients, it is advisable to include other protocol types for tracking this essential information. For this reason ipv4 and ipv6 are protocols of interest; they can provide correlation to the DNS events based on event times.

Example 1. A passive DNS monitoring example

This configuration uses the im_pcap module to capture DNS, IPv4, IPv6, TCP, and UDP packets which are then formatted to JSON while writing to a local file. Each protocol and its fields are defined within its own Protocol block.

The Dev directive in this example uses the enp0s3 network device/adapter for capturing network traffic. The device name indicates it is on a Linux or UNIX-like system. On Windows systems you will need to follow the device name format required by the WinPcap library: DeviceNPF_{<GUID>}. For more details, see Dev directive in the NXLog Reference Manual.

nxlog.conf
<Extension _json>
    Module  xm_json
</Extension>

<Input pcap>
    Module  im_pcap
    Dev     enp0s3
    <Protocol>
        Type    dns
        Field   dns.opcode
        Field   dns.id
        Field   dns.flags.authoritative
        Field   dns.flags.recursion_available
        Field   dns.flags.recursion_desired
        Field   dns.flags.authentic_data
        Field   dns.flags.checking_disabled
        Field   dns.flags.truncated_response
        Field   dns.response
        Field   dns.response.code
        Field   dns.query
        Field   dns.additional
        Field   dns.answer
        Field   dns.authority
    </Protocol>
    <Protocol>
        Type    ipv4
        Field   ipv4.src
        Field   ipv4.dst
        Field   ipv4.fragment
    </Protocol>
    <Protocol>
        Type    ipv6
        Field   ipv6.src
        Field   ipv6.dst
        Field   ipv6.options
    </Protocol>
    <Protocol>
        Type    tcp
        Field   tcp.src_port
        Field   tcp.dst_port
        Field   tcp.flag
    </Protocol>
    <Protocol>
        Type    udp
        Field   udp.src_port
        Field   udp.dst_port
    </Protocol>
</Input>

<Output file>
    Module  om_file
    File    "tmp/passive_dns.json"
    Exec    to_json();
</Output>
Samples of DNS and IPV4 packets
{
  "dns.additional.count": "0",
  "dns.answer.3.class": "IN",
  "dns.answer.3.name": "ns2.example.com",
  "dns.answer.3.ttl": "86400",
  "dns.answer.3.type": "A",
  "dns.answer.class": "IN",
  "dns.answer.count": "2",
  "dns.answer.name": "www.example.com",
  "dns.answer.ttl": "86400",
  "dns.answer.type": "CNAME",
  "dns.authority.class": "IN",
  "dns.authority.count": "1",
  "dns.authority.name": "example.com",
  "dns.authority.type": "NS",
  "dns.flags.authentic_data": "false",
  "dns.flags.authoritative": "true",
  "dns.flags.checking_disabled": "false",
  "dns.flags.recursion_available": "true",
  "dns.flags.recursion_desired": "true",
  "dns.flags.truncated_response": "false",
  "dns.id": "18321",
  "dns.opcode": "Query",
  "dns.query.class": "IN",
  "dns.query.count": "1",
  "dns.query.name": "www.example.com",
  "dns.response.code": "NOERROR",
  "ipv4.dst": "192.168.1.7",
  "ipv4.src": "192.168.1.24",
  "udp.dst_port": "36486",
  "udp.src_port": "53",
  "EventTime": "2020-05-18T12:15:34.033655-05:00",
  "EventReceivedTime": "2020-05-18T12:15:34.301402-05:00",
  "SourceModuleName": "pcap",
  "SourceModuleType": "im_pcap"
}
{
  "dns.additional.count": "0",
  "dns.answer.count": "0",
  "dns.authority.count": "0",
  "dns.flags.authentic_data": "false",
  "dns.flags.authoritative": "false",
  "dns.flags.checking_disabled": "false",
  "dns.flags.recursion_available": "false",
  "dns.flags.recursion_desired": "false",
  "dns.flags.truncated_response": "false",
  "dns.id": "0",
  "dns.opcode": "Query",
  "dns.query.class": "IN",
  "dns.query.count": "1",
  "dns.query.name": "wpad.local",
  "dns.response.code": "NOERROR",
  "ipv6.dst": "ff02::fb",
  "ipv6.src": "fe80::3c3c:c860:df55:fd89",
  "udp.dst_port": "5353",
  "udp.src_port": "5353",
  "EventTime": "2020-05-18T12:22:48.291661-05:00",
  "EventReceivedTime": "2020-05-18T12:22:48.487235-05:00",
  "SourceModuleName": "pcap",
  "SourceModuleType": "im_pcap"
}
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: 14 March 2021