Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate Dnstap and DNS agents #11

Closed
m3047 opened this issue Jan 22, 2024 · 5 comments
Closed

Separate Dnstap and DNS agents #11

m3047 opened this issue Jan 22, 2024 · 5 comments
Labels
announcement Major updates, advance warning of things possibly breaking enhancement New feature or request

Comments

@m3047
Copy link
Owner

m3047 commented Jan 22, 2024

The present implementation lacks flexibility and only supports 1:1 telemetry capture.

The current dns_agent combines two functionalities:

  • Reads Dnstap protocol telemetry from a unix socket.
  • Writes filtered data to a Redis database.

The Dnstap protocol as architected is not network-aware; the BIND implementation is capable only writing to either the unix socket or to (rotating) files.

It is desirable to support many-to-one, one-to-many, and many-to-many capture modalities for redundancy and failover, as well as for additional uses. For instance, work is underway to alter Rear View RPZ to that it can optionally ingest telemetry data via UDP datagrams transmitted in the format envisioned here.

The anticipated future architecture is:

  • A Dnstap agent which reads from the unix socket, filters relevant information, and sends UDP datagrams.
  • A DNS agent which receives UDP datagrams, filters relevant information from them, and updates the Redis database.

This issue exists to inform the community of the anticipated change and to solicit feedback.

UDP as the transmission modality

UDP datagrams are anticipated as the transmission modality, with each datagram encapsulating one observable event.

An observable event is defined as a (potential) CNAME chain ending in a single IP address; if the underlying Dnstap event resolves the (single) CNAME chain to multiple addresses, then one observable event is generated for each address.

UDP is chosen because it supports not only one-to-one and many-to-one, but also one-to-many and many-to-many (multicast addresses). Additionally, UDP is connectionless and so recovery / tolerance for network or receiver outages is much simpler to build as well as understand.

UDP has an absolute 64K byte limit on datagram size; on the other hand the efficient datagram size is determined by path MTU and can be considerably smaller (the typical ethernet MTU is 1500 bytes). Datagrams larger than the path MTU are dealt with via fragmentation, which increases the possibility of data loss and requires packet reassembly at the receiving end.

Note that the maximum size of a DNS query or response tracks the UDP absolute limit on datagram size.

Content of the telemetry data

Dnstap telemetry can capture different versions of a DNS query or response (stub resolver to caching resolver or caching resolver to authoritative, request or response) as well as additional metadata. Since a single DNS message itself can theoretically reach the absolute limit on datagram size, curation of data is required in order to reliably use UDP as a transport.

The datagram content is envisioned as a JSON dictionary with three keys:

  • id a monotonically increasing serial number for the datagram, reset to zero on restart of the Dnstap agent
  • address the address or "end" of the CNAME chain; both IPv4 and IPv6 are supported
  • chain a list containing the reversed CNAME chain
  • client the address from which the query was sent

Given the DNS data:

www.example.com.    IN CNAME server.example.com.
server.example.com. IN A     10.0.0.1

a sample (and prettified) datagram payload might look like this:

{   "id": 1,
    "address": "10.0.0.1",
    "chain": ["server.example.com.", "www.example.com."],
    "client": "10.43.11.48"
}
@m3047 m3047 added enhancement New feature or request announcement Major updates, advance warning of things possibly breaking labels Jan 22, 2024
@m3047 m3047 pinned this issue Jan 22, 2024
@m3047
Copy link
Owner Author

m3047 commented Jan 29, 2024

For generalization purposes added two additional fields:

  • qtype The query type, either "A" or "AAAA".
  • status A status code string, either "NOERROR" or "NXDOMAIN".

@m3047
Copy link
Owner Author

m3047 commented Feb 11, 2024

Smoketest code is on the fwm branch. It's not even soaked yet, consider this an "early preview".

Multicast support

IPv4 multicast is nominally supported by the code. I welcome feedback, I make no promises as to if or how issues will be resolved.

dnstap2json.py changes

This is a diamond in the rough, people use it on its own. I am now using it as the basis for the Dnstap Agent. There are a few of changes of note:

  • JSONMapper.map_fields() is now a generator function, allowing it to create multiple output events from a single input event.
  • multicast support (yes, I mentioned that already)
  • extra guardrails around command line args and config options

BREAKING CHANGE: dns_agent is now dnstap_agent and dns_agent (two agents)

You now have to deploy two agents instead of one, and they need to communicate with each other using UDP datagrams (unicast or multicast).

If you don't want to be caught off guard or need time to plan for this, now would be a good time to fork the repo and use that fork for your build. When you've completed your upgrade you can abandon the fork.

@m3047
Copy link
Owner Author

m3047 commented Feb 12, 2024

I've got this in production now, feeding both the ShoDoHFlo Redis agent (dns_agent.py) and RearView RPZ (love me some multicast!).

Feel free to go ahead and try out the fwm branch.

@m3047
Copy link
Owner Author

m3047 commented Feb 12, 2024

So far so good. I'll let it soak until Monday February 19 before merging into master.

@m3047
Copy link
Owner Author

m3047 commented Feb 19, 2024

This has been merged to master at 6ce0036.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
announcement Major updates, advance warning of things possibly breaking enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant