From: Pieter Lexis Date: Thu, 29 Sep 2016 16:22:39 +0000 (+0200) Subject: On RPZ customPolicy, follow the resulting CNAME X-Git-Tag: dnsdist-1.1.0-beta2~80^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=53508135801b58be5e04a0830f7fef9f620f8ccf;p=pdns On RPZ customPolicy, follow the resulting CNAME Closes #4188 --- diff --git a/docs/markdown/recursor/settings.md b/docs/markdown/recursor/settings.md index 1ce258c29..cb58b4dee 100644 --- a/docs/markdown/recursor/settings.md +++ b/docs/markdown/recursor/settings.md @@ -497,7 +497,7 @@ If no settings are included, the RPZ is taken literally with no overrides applie The policy action are: -* Policy.Custom will return a NoError, CNAME answer with the value specified with `defcontent` +* Policy.Custom will return a NoError, CNAME answer with the value specified with `defcontent`, when looking up the result of this CNAME, RPZ is not taken into account * Policy.Drop will simply cause the query to be dropped * Policy.NoAction will continue normal processing of the query * Policy.NODATA will return a NoError response with no value in the answer section diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index c719bfe64..ca1e51490 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -637,6 +637,32 @@ static void protobufLogResponse(const std::shared_ptr& logger, con } #endif +/** + * Chases the CNAME provided by the PolicyCustom RPZ policy. + * + * @param spoofed: The DNSRecord that was created by the policy, should already be added to ret + * @param qtype: The QType of the original query + * @param sr: A SyncRes + * @param res: An integer that will contain the RCODE of the lookup we do + * @param ret: A vector of DNSRecords where the result of the CNAME chase should be appended to + */ +void handleRPZCustom(const DNSRecord& spoofed, const QType& qtype, SyncRes& sr, int& res, vector& ret) +{ + if (spoofed.d_type == QType::CNAME) { + bool oldWantsRPZ = sr.d_wantsRPZ; + sr.d_wantsRPZ = false; + vector ans; + res = sr.beginResolve(DNSName(spoofed.d_content->getZoneRepresentation()), qtype, 1, ans); + for (const auto& rec : ans) { + if(rec.d_place == DNSResourceRecord::ANSWER) { + ret.push_back(rec); + } + } + // Reset the RPZ state of the SyncRes + sr.d_wantsRPZ = oldWantsRPZ; + } +} + void startDoResolve(void *p) { DNSComboWriter* dc=(DNSComboWriter *)p; @@ -781,6 +807,7 @@ void startDoResolve(void *p) spoofed.d_content = appliedPolicy.d_custom; spoofed.d_place = DNSResourceRecord::ANSWER; ret.push_back(spoofed); + handleRPZCustom(spoofed, QType(dc->d_mdp.d_qtype), sr, res, ret); goto haveAnswer; case DNSFilterEngine::PolicyKind::Truncate: if(!dc->d_tcp) { @@ -845,6 +872,7 @@ void startDoResolve(void *p) spoofed.d_content = appliedPolicy.d_custom; spoofed.d_place = DNSResourceRecord::ANSWER; ret.push_back(spoofed); + handleRPZCustom(spoofed, QType(dc->d_mdp.d_qtype), sr, res, ret); goto haveAnswer; } } @@ -909,6 +937,7 @@ void startDoResolve(void *p) spoofed.d_content = appliedPolicy.d_custom; spoofed.d_place = DNSResourceRecord::ANSWER; ret.push_back(spoofed); + handleRPZCustom(spoofed, QType(dc->d_mdp.d_qtype), sr, res, ret); goto haveAnswer; } } diff --git a/regression-tests.recursor/RPZ-Lua/expected_result b/regression-tests.recursor/RPZ-Lua/expected_result index 1cd6e7a32..0b23b6961 100644 --- a/regression-tests.recursor/RPZ-Lua/expected_result +++ b/regression-tests.recursor/RPZ-Lua/expected_result @@ -1,6 +1,7 @@ Reply to question for qname='www3.example.net.', qtype=A Rcode: 0 (No Error), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0 0 www3.example.net. IN CNAME 0 www2.example.net. +0 www2.example.net. IN A 10 192.0.2.2 Reply to question for qname='android.marvin.example.net.', qtype=A Rcode: 0 (No Error), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0 0 android.marvin.example.net. IN A 15 192.0.2.5 diff --git a/regression-tests.recursor/RPZ/expected_result b/regression-tests.recursor/RPZ/expected_result index 3039bf8d0..baf59124e 100644 --- a/regression-tests.recursor/RPZ/expected_result +++ b/regression-tests.recursor/RPZ/expected_result @@ -12,6 +12,7 @@ Rcode: 0 (No Error), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0 Reply to question for qname='www.example.net.', qtype=A Rcode: 0 (No Error), RD: 1, QR: 1, TC: 0, AA: 0, opcode: 0 0 www.example.net. IN CNAME 0 www2.example.net. +0 www2.example.net. IN A 15 192.0.2.2 ==> www4.example.net RPZ IP trigger action, dropped ==> trillian.example.net NXDOMAIN Reply to question for qname='trillian.example.net.', qtype=A