From: Peter van Dijk Date: Fri, 19 Mar 2021 14:47:54 +0000 (+0100) Subject: sdig, pdnsutil: add dnsdist spoofAction string generators X-Git-Tag: rec-4.5.0-beta1~7^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F10200%2Fhead;p=thirdparty%2Fpdns.git sdig, pdnsutil: add dnsdist spoofAction string generators --- diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 575c4bde9f..f6c1acd404 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -515,6 +515,7 @@ dsrecord dst DTS Dufberg +dumpluaraw dumresp dynblock dynblocklist diff --git a/docs/manpages/pdnsutil.1.rst b/docs/manpages/pdnsutil.1.rst index 4b263de2fb..27d062e8d6 100644 --- a/docs/manpages/pdnsutil.1.rst +++ b/docs/manpages/pdnsutil.1.rst @@ -242,6 +242,8 @@ test-schema *ZONE* Test database schema, this creates the zone *ZONE* unset-presigned *ZONE* Disables presigned operation for *ZONE*. +raw-lua-from-content *TYPE* *CONTENT* + Display record contents in a form suitable for dnsdist's `SpoofRawAction`. DEBUGGING TOOLS --------------- diff --git a/docs/manpages/sdig.1.rst b/docs/manpages/sdig.1.rst index 612a06ece1..9c6fad35f9 100644 --- a/docs/manpages/sdig.1.rst +++ b/docs/manpages/sdig.1.rst @@ -37,6 +37,8 @@ recurse Set the RD bit in the question. showflags Show the NSEC3 flags in the response (they are hidden by default). +dumpluaraw + Display record contents in a form suitable for dnsdist's `SpoofRawAction`. tcp Use TCP instead of UDP to send the query. dot diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index 6749e45361..77c148a15e 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -1393,6 +1393,19 @@ The following actions exist. :func:`DNSName:toDNSString` is convenient for converting names to wire format for passing to ``SpoofRawAction``. + ``sdig dumpluaraw`` and ``pdnsutil raw-lua-from-content`` from PowerDNS can generate raw answers for you: + + .. code-block:: Shell + + $ pdnsutil raw-lua-from-content SRV '0 0 65535 srv.powerdns.com.' + "\000\000\000\000\255\255\003srv\008powerdns\003com\000" + $ sdig 127.0.0.1 53 open-xchange.com MX recurse dumpluaraw + Reply to question for qname='open-xchange.com.', qtype=MX + Rcode: 0 (No Error), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0 + 0 open-xchange.com. IN MX "\000c\004mx\049\049\012open\045xchange\003com\000" + 0 open-xchange.com. IN MX "\000\010\003mx\049\012open\045xchange\003com\000" + 0 open-xchange.com. IN MX "\000\020\003mx\050\012open\045xchange\003com\000" + :param string rawAnswer: The raw record data :param {string} rawAnswers: A table of raw record data to spoof :param table options: A table with key: value pairs with options. diff --git a/pdns/misc.cc b/pdns/misc.cc index 5a02ed31b3..21179f67fb 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -1610,3 +1610,26 @@ std::string getCarbonHostName() return hostname; } + +std::string makeLuaString(const std::string& in) +{ + ostringstream str; + + str<<'"'; + + char item[5]; + for (unsigned char n : in) { + if (islower(n) || isupper(n)) { + item[0] = n; + item[1] = 0; + } + else { + snprintf(item, sizeof(item), "\\%03d", n); + } + str << item; + } + + str<<'"'; + + return str.str(); +} diff --git a/pdns/misc.hh b/pdns/misc.hh index 83ca2178dd..193750446c 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -624,3 +624,5 @@ DNSName reverseNameFromIP(const ComboAddress& ip); std::string getCarbonHostName(); size_t parseRFC1035CharString(const std::string &in, std::string &val); // from ragel + +std::string makeLuaString(const std::string& in); diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 0ca3449b46..0660951281 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -24,6 +24,7 @@ #include "signingpipe.hh" #include "dns_random.hh" #include "ipcipher.hh" +#include "misc.hh" #include #include #include //termios, TCSANOW, ECHO, ICANON @@ -2298,6 +2299,7 @@ try cout<<"unset-publish-cdnskey ZONE Disable sending CDNSKEY responses for ZONE"<serialize(DNSName(), true))<& packet, const string& q, const string& t pw.getHeader()->id = htons(qid); } -static void printReply(const string& reply, bool showflags, bool hidesoadetails) +static void printReply(const string& reply, bool showflags, bool hidesoadetails, bool dumpluaraw) { MOADNSParser mdp(false, reply); if (!s_expectedIDs.count(ntohs(mdp.d_header.id))) { @@ -134,6 +135,10 @@ static void printReply(const string& reply, bool showflags, bool hidesoadetails) cout << i->first.d_place - 1 << "\t" << i->first.d_name.toString() << "\t" << nameForClass(i->first.d_class, i->first.d_type) << "\t" << DNSRecordContent::NumberToType(i->first.d_type); + if (dumpluaraw) { + cout<<"\t"<< makeLuaString(i->first.d_content->serialize(DNSName(), true))<first.d_class == QClass::IN) { if (i->first.d_type == QType::RRSIG) { string zoneRep = i->first.d_content->getZoneRepresentation(); @@ -222,6 +227,7 @@ try { string subjectName; string caStore; string tlsProvider = "openssl"; + bool dumpluaraw = false; for (int i = 1; i < argc; i++) { if ((string)argv[i] == "--help") { @@ -318,6 +324,9 @@ try { ComboAddress dest(argv[++i]); proxyheader = makeProxyHeader(ptcp, src, dest, {}); } + else if (strcmp(argv[i], "dumpluaraw") == 0) { + dumpluaraw = true; + } else { cerr << argv[i] << ": unknown argument" << endl; exit(EXIT_FAILURE); @@ -377,7 +386,7 @@ try { string question(packet.begin(), packet.end()); // FIXME: how do we use proxyheader here? reply = mc.postURL(argv[1], question, mch, timeout, fastOpen); - printReply(reply, showflags, hidesoadetails); + printReply(reply, showflags, hidesoadetails, dumpluaraw); #else throw PDNSException("please link sdig against libcurl for DoH support"); #endif @@ -399,7 +408,7 @@ try { reply = reply.substr(2); } - printReply(reply, showflags, hidesoadetails); + printReply(reply, showflags, hidesoadetails, dumpluaraw); } else if (tcp) { std::shared_ptr tlsCtx{nullptr}; if (dot) { @@ -447,7 +456,7 @@ try { if (handler.read(&reply[0], len, timeout) != len) { throw PDNSException("tcp read failed"); } - printReply(reply, showflags, hidesoadetails); + printReply(reply, showflags, hidesoadetails, dumpluaraw); } } else // udp { @@ -465,7 +474,7 @@ try { if (!result) throw std::runtime_error("Timeout waiting for data"); sock.recvFrom(reply, dest); - printReply(reply, showflags, hidesoadetails); + printReply(reply, showflags, hidesoadetails, dumpluaraw); } } catch (std::exception& e) {