pdns-protobuf-receiver icon indicating copy to clipboard operation
pdns-protobuf-receiver copied to clipboard

Feature/support all pb fields [WIP]

Open ExaneServerTeam opened this issue 4 years ago • 7 comments

Hello,

This PR is a major rework on the Protobuf Parsing. The Published Json is quite changed.

It supports:

  • Almost all fields (originalRequestorSubnet is missing / No use & test case on my side)
  • Decodes of RRs & rdata
  • Split functions for Common/Query/Response/RRs data

My entended use is to provide required info for our SIEM with RPZ support on the DNS side (PDNS-Recursor)

ExaneServerTeam avatar Jan 05 '21 11:01 ExaneServerTeam

The Published Json is quite changed.

How compatible is it to the old format, for consumers?

Almost all fields (originalRequestorSubnet is missing / No use & test case on my side)

This field is important to many users, can you add it anyway? :)

Habbie avatar Jan 05 '21 12:01 Habbie

The Published Json is quite changed.

How compatible is it to the old format, for consumers?

I'll try to raise a diff or something. BRB on the subject.

Almost all fields (originalRequestorSubnet is missing / No use & test case on my side)

This field is important to many users, can you add it anyway? :)

PR updated with the support of originalRequestorSubnet. It is based on Protobuf.py implementation in PDNS source tree.

ExaneServerTeam avatar Jan 05 '21 15:01 ExaneServerTeam

JSON Produced by this PR

The main difference I see from current layout:

  • Query related data have been moved to query dict
  • return_code has moved to response dict
{
    "dns_message": "CLIENT_RESPONSE",
    "message_id": "f344c6f134c14351b87588d3e63bc8bf",
    "socket_family": "IPv4",
    "socket_protocol": "UDP",
    "from_address": "10.0.0.1",
    "to_address": "10.0.80.2",
    "bytes": 247,
    "dns_id": 34516,
    "from_port": 54462,
    "to_port": 53,
    "response": {
        "return_code": "NOERROR",
        "rrs": [
            {
                "name": "a767.dscg3.akamai.net.",
                "type": "A",
                "class": "IN",
                "ttl": 18,
                "rdata": {
                    "address": "92.122.122.152"
                },
                "udr": false
            },
            {
                "name": "a767.dscg3.akamai.net.",
                "type": "A",
                "class": "IN",
                "ttl": 18,
                "rdata": {
                    "address": "92.122.122.147"
                },
                "udr": false
            }
        ]
    },
    "query_time": "2021-01-05T15:32:16.574470+00:00",
    "response_time": "2021-01-05T15:32:16.575857+00:00",
    "latency": 0.001387,
    "query": {
        "name": "ctldl.windowsupdate.com.",
        "type": "A",
        "class": "IN"
    }
}

Reference JSON / Current one

{
    "dns_message": "AUTH_QUERY",
    "socket_family": "IPv6",
    "socket protocol": "UDP",
    "from_address": "0.0.0.0",
    "to_address": "184.26.161.130",
    "query_time": "2020-05-29 13:46:23.322",
    "response_time": "1970-01-01 01:00:00.000",
    "latency": 0,
    "query_type": "A",
    "query_name": "a13-130.akagtm.org.",
    "return_code": "NOERROR",
    "bytes": 4
}

ExaneServerTeam avatar Jan 05 '21 15:01 ExaneServerTeam

Hello, this version works a lot better. The previous had plenty of error while parsing rdata (Sorry my dev env required some firewall opening at my company to be operational).

It has been tested so far on:

  • A
  • AAAA
  • CNAME
  • TXT
  • MX
  • NS
  • PTR
  • SRV

Not done: 'SPF': Almost impossible to test (Deprecated) cf: https://tools.ietf.org/html/rfc7208#page-11

ExaneServerTeam avatar Jan 08 '21 13:01 ExaneServerTeam

@Habbie @dmachard Any thought or remarks ?

I have this version run for the past days and it works fine on my side with ~400 clients so far.

ExaneServerTeam avatar Jan 21 '21 12:01 ExaneServerTeam

FWIW I've a similar requirement and have implemented this code. I'm pushing to the receiver from DNSDist and had to remove the lines:

        "appliedPolicyTrigger": "applied_policy_trigger",  # 8
        "appliedPolicyHit": "applied_policy_hit",  # 9

As I was getting:

May 05 15:28:06 pdnsr_host pdns_protobuf_receiver[2852]: 2021-05-05 15:28:06,897 Task exception was never retrieved
May 05 15:28:06 pdnsr_host pdns_protobuf_receiver[2852]: future: <Task finished coro=<cb_onpayload() done, defined at /usr/local/lib/python3.6/dist-packages/pdns_protobuf_receiver/receiver.py:278> exception=ValueError('Protocol message DNSResponse has no field appliedPolicyHit.',)>
May 05 15:28:06 pdnsr_host pdns_protobuf_receiver[2852]: Traceback (most recent call last):
May 05 15:28:06 pdnsr_host pdns_protobuf_receiver[2852]:   File "/usr/local/lib/python3.6/dist-packages/pdns_protobuf_receiver/receiver.py", line 308, in cb_onpayload
May 05 15:28:06 pdnsr_host pdns_protobuf_receiver[2852]:     parse_pb_msg_response(dns_pb2, dns_msg)
May 05 15:28:06 pdnsr_host pdns_protobuf_receiver[2852]:   File "/usr/local/lib/python3.6/dist-packages/pdns_protobuf_receiver/receiver.py", line 203, in parse_pb_msg_response
May 05 15:28:06 pdnsr_host pdns_protobuf_receiver[2852]:     elif dns_pb2.response.HasField(key):
May 05 15:28:06 pdnsr_host pdns_protobuf_receiver[2852]: ValueError: Protocol message DNSResponse has no field appliedPolicyHit.

and

May 05 15:26:32 pdnsr_host pdns_protobuf_receiver[1785]: 2021-05-05 15:26:32,257 Task exception was never retrieved
May 05 15:26:32 pdnsr_host pdns_protobuf_receiver[1785]: future: <Task finished coro=<cb_onpayload() done, defined at /usr/local/lib/python3.6/dist-packages/pdns_protobuf_receiver/receiver.py:279> exception=ValueError('Protocol message DNSResponse has no field appliedPolicyTrigger.',)>
May 05 15:26:32 pdnsr_host pdns_protobuf_receiver[1785]: Traceback (most recent call last):
May 05 15:26:32 pdnsr_host pdns_protobuf_receiver[1785]:   File "/usr/local/lib/python3.6/dist-packages/pdns_protobuf_receiver/receiver.py", line 309, in cb_onpayload
May 05 15:26:32 pdnsr_host pdns_protobuf_receiver[1785]:     parse_pb_msg_rrs(dns_pb2, dns_msg)
May 05 15:26:32 pdnsr_host pdns_protobuf_receiver[1785]:   File "/usr/local/lib/python3.6/dist-packages/pdns_protobuf_receiver/receiver.py", line 204, in parse_pb_msg_response
May 05 15:26:32 pdnsr_host pdns_protobuf_receiver[1785]:     if isinstance(val, str):
May 05 15:26:32 pdnsr_host pdns_protobuf_receiver[1785]: ValueError: Protocol message DNSResponse has no field appliedPolicyTrigger.

Other than that though it seems to be a step forward definitely. I'm seeing response.rrs.rdata.address fields as expected which is definitely useful for us.

lwhitworth avatar May 05 '21 14:05 lwhitworth

@lwhitworth Hello I have been late on this. Looks like the PDNS Recursor PB messages are not in line with current dnsdist (1.5.1 at least) release. The last commit should fix the issue. Could you give it a try ?

ExaneServerTeam avatar May 20 '21 09:05 ExaneServerTeam