Get info on who asked DNS Question

Hey guys,

First of all, great project!! Ever since I've found out about ELK Stack I've been hooked up!

I would like to monitor DNS traffic using packetbeat, I've set everything up and it works, but it doesn't seem like packetbeat is showing the client who requested the IP for domain name and i would like to have that info as well.

Setup is like this:
1st Server hosting ELK Stack 6.x version (installed from yum repo)
2nd Server PDNS Recursor with packetbeat installed. (packetbeat also installed from yum repo), sending logs to logstash on 1st server.

When client that has an IP lets say 10.1.2.3 asks pdns recursor server for an IP for let's say example.com, i get logs in Kibana about query for example.com but i don't see who asked for it (10.1.2.3)
Is there a way that i can achieve this?

Thanks in advance, looking forward to hear back from you guys.

Packetbeat reports this information. The client_ip is the IP address of the host that sent the DNS request the ip is the address of the host that responded.

Perhaps you are monitoring the wrong interface or something similar that causes you to only be looking at the queries made by the recursive resolver on behalf of the client. BTW if the resolver supports sending it then you will be see the EDNS client subnet reported by Packetbeat (IIRC dns.opt.subnet is the field) for the requests made by the recursive resolver.

That's odd.

Is client_ip supposed to be in fields.yml of packetbeat as well or it goes without saying? Because i can only find client_ip in dhcp4, not in DNS unfortunately, and i definitely do not have that field in logs.
And I've set packetbeat to listen on 'any' devices, so it should capture on pretty much all interfaces, right ?

client_ip should be contained in the fields.yml and should be in the packetbeat index template in ES. It's one of the common fields used in Packetbeat. As an example here is a DNS transaction I captured.

{
  "@timestamp": "2018-12-12T05:19:36.591Z",
  "bytes_in": 32,
  "type": "dns",
  "transport": "udp",
  "proc": "",
  "beat": {
    "name": "raspberrypi",
    "hostname": "raspberrypi",
    "version": "6.5.2"
  },
  "client_server": "",
  "query": "class IN, type A, mesu.apple.com.",
  "client_proc": "",
  "client_ip": "10.0.0.2",
  "port": 53,
  "source": {
    "hostname": "x.local.mydomain.com"
  },
  "resource": "mesu.apple.com.",
  "bytes_out": 505,
  "client_port": 53405,
  "ip": "10.0.0.1",
  "method": "QUERY",
  "host": {
    "os": {
      "codename": "stretch",
      "platform": "raspbian",
      "version": "9 (stretch)",
      "family": ""
    },
    "id": "xx",
    "name": "raspberrypi",
    "containerized": false,
    "architecture": "armv7l"
  },
  "status": "OK",
  "responsetime": 42,
  "server": "",
  "dns": {
    "response_code": "NOERROR",
    "answers": [
      {
        "class": "IN",
        "ttl": "1163",
        "data": "mesu-cdn.apple.com.akadns.net.",
        "name": "mesu.apple.com.",
        "type": "CNAME"
      },
      {
        "data": "mesu.g.aaplimg.com.",
        "name": "mesu-cdn.apple.com.akadns.net.",
        "type": "CNAME",
        "class": "IN",
        "ttl": "1844"
      },
      {
        "data": "17.253.15.207",
        "name": "mesu.g.aaplimg.com.",
        "type": "A",
        "class": "IN",
        "ttl": "14"
      },
      {
        "name": "mesu.g.aaplimg.com.",
        "type": "A",
        "class": "IN",
        "ttl": "14",
        "data": "17.253.97.202"
      }
    ],
    "authorities_count": 13,
    "flags": {
      "checking_disabled": false,
      "authoritative": false,
      "truncated_response": false,
      "recursion_desired": true,
      "recursion_available": true,
      "authentic_data": false
    },
    "question": {
      "etld_plus_one": "apple.com.",
      "name": "mesu.apple.com.",
      "type": "A",
      "class": "IN"
    },
    "additionals_count": 7,
    "id": 13550,
    "op_code": "QUERY",
    "answers_count": 4,
    "authorities": [
      {
        "type": "NS",
        "class": "IN",
        "ttl": "33982",
        "data": "i.gtld-servers.net.",
        "name": "com."
      },
      {
        "class": "IN",
        "ttl": "33982",
        "data": "m.gtld-servers.net.",
        "name": "com.",
        "type": "NS"
      },
      {
        "name": "com.",
        "type": "NS",
        "class": "IN",
        "ttl": "33982",
        "data": "d.gtld-servers.net."
      },
      {
        "class": "IN",
        "ttl": "33982",
        "data": "b.gtld-servers.net.",
        "name": "com.",
        "type": "NS"
      },
      {
        "data": "f.gtld-servers.net.",
        "name": "com.",
        "type": "NS",
        "class": "IN",
        "ttl": "33982"
      },
      {
        "name": "com.",
        "type": "NS",
        "class": "IN",
        "ttl": "33982",
        "data": "e.gtld-servers.net."
      },
      {
        "data": "j.gtld-servers.net.",
        "name": "com.",
        "type": "NS",
        "class": "IN",
        "ttl": "33982"
      },
      {
        "ttl": "33982",
        "data": "g.gtld-servers.net.",
        "name": "com.",
        "type": "NS",
        "class": "IN"
      },
      {
        "data": "a.gtld-servers.net.",
        "name": "com.",
        "type": "NS",
        "class": "IN",
        "ttl": "33982"
      },
      {
        "class": "IN",
        "ttl": "33982",
        "data": "l.gtld-servers.net.",
        "name": "com.",
        "type": "NS"
      },
      {
        "name": "com.",
        "type": "NS",
        "class": "IN",
        "ttl": "33982",
        "data": "k.gtld-servers.net."
      },
      {
        "type": "NS",
        "class": "IN",
        "ttl": "33982",
        "data": "h.gtld-servers.net.",
        "name": "com."
      },
      {
        "type": "NS",
        "class": "IN",
        "ttl": "33982",
        "data": "c.gtld-servers.net.",
        "name": "com."
      }
    ]
  },
  "destination": {
    "hostname": "dns.local.mydomain.com"
  }
}

This is where it gets weird. client_ip on my end is the IP of DNS resolved.

{
  "_index": "packetbeat-6.5.2-2018.12.11",
  "_type": "doc",
  "_id": "oqm9nWcB6xVFHW-GgIsa",
  "_version": 1,
  "_score": null,
  "_source": {
    "dns": {
      "flags": {
        "authentic_data": false,
        "recursion_desired": true,
        "truncated_response": false,
        "checking_disabled": false,
        "authoritative": false,
        "recursion_available": true
      },
      "op_code": "QUERY",
      "answers": [
        {
          "class": "IN",
          "ttl": "300",
          "data": "10.0.0.52",
          "type": "A",
          "name": "production2.example.com."
        }
      ],
      "question": {
        "class": "IN",
        "type": "A",
        "name": "production2.example.com.",
        "etld_plus_one": "example.com."
      },
      "id": 32373,
      "response_code": "NOERROR",
      "authorities_count": 0,
      "answers_count": 1,
      "additionals_count": 0
    },
    "client_port": 58028,
    "@timestamp": "2018-12-11T14:48:20.309Z",
    "host": {
      "id": "34e85f430ad34f37b748d3dd9d94d09e",
      "architecture": "x86_64",
      "os": {
        "platform": "centos",
        "version": "7 (Core)",
        "codename": "Core",
        "family": "redhat"
      },
      "name": "pdns1-v2.example.com",
      "containerized": true
    },
    "notes": "Response: received without an associated Query",
    "@version": "1",
    "server": "",
    "beat": {
      "version": "6.5.2",
      "hostname": "pdns1-v2.example.com",
      "name": "pdns1-v2.example.com"
    },
    "client_ip": "10.0.0.52",
    "method": "QUERY",
    "resource": "production2.example.com.",
    "bytes_out": 56,
    "client_proc": "",
    "query": "class IN, type A, production2.example.com.",
    "client_server": "",
    "transport": "udp",
    "ip": "10.0.0.19",
    "type": "dns",
    "tags": [
      "beats_input_raw_event"
    ],
    "port": 53,
    "status": "Error",
    "proc": ""
  },
  "fields": {
    "@timestamp": [
      "2018-12-11T14:48:20.309Z"
    ]
  },
  "highlight": {
    "beat.name": [
      "@kibana-highlighted-field@pdns1-v2.example.com@/kibana-highlighted-field@"
    ],
    "beat.hostname": [
      "@kibana-highlighted-field@pdns1-v2.example.com@/kibana-highlighted-field@"
    ],
    "host.name": [
      "@kibana-highlighted-field@pdns1-v2.example.com@/kibana-highlighted-field@"
    ],
    "type": [
      "@kibana-highlighted-field@dns@/kibana-highlighted-field@"
    ]
  },
  "sort": [
    1544539700309
  ]
}

The status and notes fields indicate that something is wrong. The message indicates that packetbeat did not see the request packet or failed to correlate the request packet with the response. Do all of your events have status: Error? Do they all have the same notes value?

Didn't realize that, that was some generic query anyway, don't know how it got there. Here's one query that i initiated via dig.

{
  "_index": "packetbeat-6.5.3-2018.12.12",
  "_type": "doc",
  "_id": "FSh1o2cBK-SVseiVWR5F",
  "_version": 1,
  "_score": null,
  "_source": {
    "@timestamp": "2018-12-12T17:27:13.539Z",
    "method": "QUERY",
    "transport": "udp",
    "ip": "173.245.59.109",
    "bytes_in": 44,
    "responsetime": 15,
    "dns": {
      "authorities_count": 0,
      "opt": {
        "do": true,
        "version": "0",
        "udp_size": 512,
        "ext_rcode": "Unknown 15"
      },
      "op_code": "QUERY",
      "answers": [
        {
          "ttl": "300",
          "data": "104.31.3.154",
          "name": "kgb-hosting.com.",
          "type": "A",
          "class": "IN"
        },
        {
          "ttl": "300",
          "data": "104.31.2.154",
          "name": "kgb-hosting.com.",
          "type": "A",
          "class": "IN"
        }
      ],
      "flags": {
        "authoritative": true,
        "truncated_response": false,
        "recursion_desired": false,
        "recursion_available": false,
        "authentic_data": false,
        "checking_disabled": false
      },
      "response_code": "NOERROR",
      "question": {
        "name": "kgb-hosting.com.",
        "type": "A",
        "class": "IN",
        "etld_plus_one": "kgb-hosting.com."
      },
      "answers_count": 2,
      "additionals_count": 0,
      "id": 17057
    },
    "type": "dns",
    "port": 53,
    "beat": {
      "name": "pdns1-v2.example.com",
      "hostname": "pdns1-v2.example.com",
      "version": "6.5.3"
    },
    "host": {
      "containerized": true,
      "name": "pdns1-v2.example.com",
      "architecture": "x86_64",
      "os": {
        "codename": "Core",
        "platform": "centos",
        "version": "7 (Core)",
        "family": "redhat"
      },
      "id": "c21c2cb18e4346aaa2c8408fcc81d52b"
    },
    "direction": "out",
    "bytes_out": 76,
    "resource": "kgb-hosting.com.",
    "client_proc": "",
    "client_ip": "77.105.32.5",
    "client_port": 43588,
    "client_server": "",
    "status": "OK",
    "query": "class IN, type A, kgb-hosting.com.",
    "proc": "",
    "server": ""
  },
  "fields": {
    "@timestamp": [
      "2018-12-12T17:27:13.539Z"
    ]
  },
  "highlight": {
    "port": [
      "@kibana-highlighted-field@53@/kibana-highlighted-field@"
    ]
  },
  "sort": [
    1544635633539
  ]
}

In this case, client_ip is an IP address of DNS server that solved the query.
I've tried couple of more, no gain. Still the same. Don't really know how to get around this one.

OK, gotta add.

Don't know why, but whenever i use dig providing the IP of DNS server that i want to query (the one that has packetbeat on it) i don't get valid results. But i just tried setting the IP of that DNS in /etc/resolf.conf, basically forcing my laptop to query that DNS, i get valid results ! :slight_smile: So that's pretty much what i needed !

One again, awesome project ! Great work !

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.