Open PenelopeFudd opened 1 month ago
Hrm - maybe something like this (but with qtype/qclass in proper positions) - includes qclass, subnet and DO bit. Is there a 'nice' way to print query flags too?
I was half into this a few months ago but never got around to finishing it.
- fprintf(filePtr.get(), "%s %" PRId64 " %s ; rcode %" PRIu8 ", key %" PRIu32 ", length %" PRIu16 ", received over UDP %d, added %" PRId64 "\n", value.qname.toString().c_str(), static_cast<int64_t>(value.validity - now), QType(value.qtype).toString().c_str(), rcode, entry.first, value.len, value.receivedOverUDP ? 1 : 0, static_cast<int64_t>(value.added));
+ fprintf(filePtr.get(), "%s %" PRId64 " %s %s ; scope %s, rcode %" PRIu8 ", key %" PRIu32 ", length %" PRIu16 ", received over UDP %d, added %" PRId64 ", dnssec %d\n", value.qname.toString().c_str(), static_cast<int64_t>(value.validity - now), QType(value.qtype).toString().c_str(), QClass(value.qclass).toString().c_str(), value.subnet ? value.subnet.get().toString().c_str() : "", rcode, entry.first, value.len, value.receivedOverUDP ? 1 : 0, static_cast<int64_t>(value.added), value.dnssecOK ? 1 : 0);
; dnsdist's packet cache dump follows
;
google.com. 293 A IN ; scope 8.8.8.0/24, rcode 0, key 2426484888, length 66, received over UDP 1, added 1725937615, dnssec 0
google.com. 25 TXT CHAOS ; scope 1.2.4.0/24, rcode 2, key 4091352989, length 50, received over UDP 1, added 1725937587, dnssec 1
google.com. 17 TXT CHAOS ; scope ::/128, rcode 2, key 556335832, length 63, received over UDP 1, added 1725937579, dnssec 0
google.com. 298 A IN ; scope 8.8.8.0/24, rcode 0, key 3904309213, length 66, received over UDP 1, added 1725937620, dnssec 1
google.com. 22 TXT CHAOS ; scope 1.2.4.0/24, rcode 2, key 4244306876, length 50, received over UDP 1, added 1725937584, dnssec 0
google.com. 49 A IN ; scope , rcode 5, key 227726898, length 39, received over UDP 1, added 1725937611, dnssec 0
Actually, would it be possible to see the answers, and not just their lengths?
Unfortunately dnsdist doesn't know how to parse most of the DNS records, because it doesn't have to, and we would like to keep it that way to reduce the amount of complexity. We could display the content of the response without decoding the content of records, just their owner names, types, classes and lengths. We might also offer an option to dump the raw (hex?) content of records.
@phonedph1 looks like a nice improvement, would you like to PR it? :)
As long as I can see everything in the cache (in hex if nothing else), with some indication as to what parts are being used as the cache key and what the initial and current ttl are, that'd be nice.
If there was a way to dump the packets in a mocked-up pcap form (i.e. dummy source/destination), then parsing could be done with an external program (tcpdump/wireshark/etc).
sidenote: base64 would be shorter
If there was a way to dump the packets in a mocked-up pcap form (i.e. dummy source/destination), then parsing could be done with an external program (tcpdump/wireshark/etc).
sdig
from pdns-utils
can parse packets from stdin, so if we have hex or base64 full packets, that would be as simple as echo [base64 goes here] | openssl base64 -d | sdig stdin 0 . A
note to self: sdig says Reply to question for ..
even when I hand it a query packet.
Amazing.
; dnsdist's packet cache dump follows
;
powerdns.com. 292 IN A ; ecs 70.0.0.0/8, rcode 0, key 3175689385, length 254, received over UDP 1, added 1726003963, dnssecOK 1, base64response 94CBoAABAAMAAAABCHBvd2VyZG5zA2NvbQAAAQABwAwAAQABAAABLAAExzxnocAMAAEAAQAAASwABMc8Zz3ADAAuAAEAAAEsAKAAAQgCAAABLGbraYBmz7oAjLUIcG93ZXJkbnMDY29tAEYxPKnCR4OBvr28SQdRYoUy5WHBg1gYo5+WAHlbjyvPY8lIST23ueA6l5HG5xFicGUhF7CLoTZsSF7KigGogTbQMdQCnr8CaUMGSjhHa2DdTzLgS9lhaSYrII2aIyJMCzm6gnJhjpANhhm4Ijde10aya3fbYIBeVplVs1QRLKw/AAApAgAAAIAAAAkACAAFAAEIAEY=
powerdns.com. 55 IN A ; ecs empty, rcode 5, key 1913889586, length 41, received over UDP 1, added 1726003966, dnssecOK 0, base64response fcmBhQABAAAAAAABCHBvd2VyZG5zA2NvbQAAAQABAAApAgAAAAAAAAA=
$ echo 94CBoAABAAMAAAABCHBvd2VyZG5zA2NvbQAAAQABwAwAAQABAAABLAAExzxnocAMAAEAAQAAASwABMc8Zz3ADAAuAAEAAAEsAKAAAQgCAAABLGbraYBmz7oAjLUIcG93ZXJkbnMDY29tAEYxPKnCR4OBvr28SQdRYoUy5WHBg1gYo5+WAHlbjyvPY8lIST23ueA6l5HG5xFicGUhF7CLoTZsSF7KigGogTbQMdQCnr8CaUMGSjhHa2DdTzLgS9lhaSYrII2aIyJMCzm6gnJhjpANhhm4Ijde10aya3fbYIBeVplVs1QRLKw/AAApAgAAAIAAAAkACAAFAAEIAEY= | base64 -d | ./sdig stdin 0 . A
ID 63360 was not expected, this response was not meant for us!
Reply to question for qname='powerdns.com.', qtype=A
Rcode: 0 (No Error), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0
0 powerdns.com. 300 IN A 199.60.103.161
0 powerdns.com. 300 IN A 199.60.103.61
0 powerdns.com. 300 IN RRSIG A 8 2 300 [expiry] [inception] [keytag] powerdns.com. ...
2 . 32768 IN OPT AAgABQABCABG
EDNS Subnet response: 70.0.0.0/8, scope: 0.0.0.0/0, family = 2
index d6323d8b3..f5cb1399d 100644
--- a/pdns/dnsdistdist/dnsdist-cache.cc
+++ b/pdns/dnsdistdist/dnsdist-cache.cc
@@ -28,6 +28,7 @@
#include "dnsdist-ecs.hh"
#include "ednssubnet.hh"
#include "packetcache.hh"
+#include "base64.hh"
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters): too cumbersome to change at this point
DNSDistPacketCache::DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL, uint32_t minTTL, uint32_t tempFailureTTL, uint32_t maxNegativeTTL, uint32_t staleTTL, bool dontAge, uint32_t shards, bool deferrableInsertLock, bool parseECS) :
@@ -507,7 +508,8 @@ uint64_t DNSDistPacketCache::dump(int fileDesc)
rcode = dnsHeader.rcode;
}
- fprintf(filePtr.get(), "%s %" PRId64 " %s ; rcode %" PRIu8 ", key %" PRIu32 ", length %" PRIu16 ", received over UDP %d, added %" PRId64 "\n", value.qname.toString().c_str(), static_cast<int64_t>(value.validity - now), QType(value.qtype).toString().c_str(), rcode, entry.first, value.len, value.receivedOverUDP ? 1 : 0, static_cast<int64_t>(value.added));
+ std::string rawResponse = Base64Encode(value.value);
+ fprintf(filePtr.get(), "%s %" PRId64 " %s %s ; ecs %s, rcode %" PRIu8 ", key %" PRIu32 ", length %" PRIu16 ", received over UDP %d, added %" PRId64 ", dnssecOK %d, base64response %s\n", value.qname.toString().c_str(), static_cast<int64_t>(value.validity - now), QClass(value.qclass).toString().c_str(), QType(value.qtype).toString().c_str(), value.subnet ? value.subnet.get().toString().c_str() : "empty", rcode, entry.first, value.len, value.receivedOverUDP ? 1 : 0, static_cast<int64_t>(value.added), value.dnssecOK ? 1 : 0, rawResponse.c_str());
}
catch (...) {
fprintf(filePtr.get(), "; error printing '%s'\n", value.qname.empty() ? "EMPTY" : value.qname.toString().c_str());
Should we do anything about the "ID 63360 was not expected, this response was not meant for us!" message? Although for the life of me I can't think of what would make sense:
sdig
skip that warning for answers with an ID of zero?sdig
that says "don't print that warning, I don't care"| grep -v "not meant for us"
Should we do anything about the "ID 63360 was not expected, this response was not meant for us!" message?
that plus the thing I noted probably warrant a separate ticket about "improving sdig stdin
". Want to do those honours?
that plus the thing I noted probably warrant a separate ticket about "improving
sdig stdin
".
this directly became PR #14665. Let me know there if you can think of any other relevant improvements :)
Short description
With DNSDist, if you dump a cache to disk, it doesn't include all of the cached information. Specifically, it doesn't include ECS subnet information.
Environment
Steps to reproduce
dnsdist -k "$password" -c 127.0.0.1:1111 -C /dev/null <<< 'getPool("pdns"):getCache():dump("/tmp/dnsdist-dump")'
more /tmp/dnsdist-dump
Expected behaviour
Actual behaviour
Other information
Actually, would it be possible to see the answers, and not just their lengths?
Thanks!