From: Remi Gacogne Date: Mon, 20 Feb 2017 08:07:43 +0000 (+0100) Subject: rec: Use the RPZ zone's TTL and add a new `maxTTL` setting X-Git-Tag: rec-4.1.0-alpha1~201^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8f61890146076eee87ba18da652a4041147f7501;p=thirdparty%2Fpdns.git rec: Use the RPZ zone's TTL and add a new `maxTTL` setting --- diff --git a/docs/markdown/recursor/settings.md b/docs/markdown/recursor/settings.md index 99ab17631e..46aff0043a 100644 --- a/docs/markdown/recursor/settings.md +++ b/docs/markdown/recursor/settings.md @@ -504,9 +504,10 @@ In this example, 'policy.rpz' denotes the name of the zone to query for. Settings for `rpzFile` and `rpzMaster` can contain: -* defpol = Policy.Custom, Policy.Drop, Policy.NXDOMAIN, Policy.NODATA, Policy.Truncate, Policy.NoAction +* defpol = Default policy: Policy.Custom, Policy.Drop, Policy.NXDOMAIN, Policy.NODATA, Policy.Truncate, Policy.NoAction * defcontent = CNAME field to return in case of defpol=Policy.Custom -* defttl = the TTL of the CNAME field to be synthesized. The default is to use the zone's TTL +* defttl = the TTL of the CNAME field to be synthesized for the default policy. The default is to use the zone's TTL +* maxTTL = the maximum TTL value of the synthesized records, overriding a higher value from `defttl` or the zone. Default is unlimited * policyName = the name logged as 'appliedPolicy' in protobuf messages when this policy is applied * zoneSizeHint = an indication of the number of expected entries in the zone, speeding up the loading of huge zones by reserving space in advance diff --git a/pdns/filterpo.hh b/pdns/filterpo.hh index 018cb7d77f..fb9ee4c1c4 100644 --- a/pdns/filterpo.hh +++ b/pdns/filterpo.hh @@ -77,7 +77,7 @@ public: PolicyKind d_kind; std::shared_ptr d_custom; std::shared_ptr d_name; - int d_ttl; + int32_t d_ttl; }; DNSFilterEngine(); diff --git a/pdns/rec-lua-conf.cc b/pdns/rec-lua-conf.cc index f06575bd57..1f90d94f3e 100644 --- a/pdns/rec-lua-conf.cc +++ b/pdns/rec-lua-conf.cc @@ -60,6 +60,37 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly) } #else +static void parseRPZParameters(const std::unordered_map >& have, std::string& polName, boost::optional& defpol, uint32_t& maxTTL, size_t& zoneSizeHint) +{ + if(have.count("policyName")) { + polName = boost::get(constGet(have, "policyName")); + } + if(have.count("defpol")) { + defpol=DNSFilterEngine::Policy(); + defpol->d_kind = (DNSFilterEngine::PolicyKind)boost::get(constGet(have, "defpol")); + defpol->d_name = std::make_shared(polName); + if(defpol->d_kind == DNSFilterEngine::PolicyKind::Custom) { + defpol->d_custom= + shared_ptr( + DNSRecordContent::mastermake(QType::CNAME, 1, + boost::get(constGet(have,"defcontent")) + ) + ); + + if(have.count("defttl")) + defpol->d_ttl = static_cast(boost::get(constGet(have, "defttl"))); + else + defpol->d_ttl = -1; // get it from the zone + } + } + if(have.count("maxTTL")) { + maxTTL = boost::get(constGet(have, "maxTTL")); + } + if(have.count("zoneSizeHint")) { + zoneSizeHint = static_cast(boost::get(constGet(have, "zoneSizeHint"))); + } +} + void loadRecursorLuaConfig(const std::string& fname, bool checkOnly) { LuaConfigItems lci; @@ -89,41 +120,23 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly) }; Lua.writeVariable("Policy", pmap); - Lua.writeFunction("rpzFile", [&lci](const string& filename, const boost::optional>>& options) { + Lua.writeFunction("rpzFile", [&lci](const string& filename, const boost::optional>>& options) { try { boost::optional defpol; std::string polName("rpzFile"); const size_t zoneIdx = lci.dfe.size(); + uint32_t maxTTL = std::numeric_limits::max(); if(options) { auto& have = *options; - if(have.count("policyName")) { - polName = boost::get(constGet(have, "policyName")); - } - if(have.count("defpol")) { - defpol=DNSFilterEngine::Policy(); - defpol->d_kind = (DNSFilterEngine::PolicyKind)boost::get(constGet(have, "defpol")); - defpol->d_name = std::make_shared(polName); - if(defpol->d_kind == DNSFilterEngine::PolicyKind::Custom) { - defpol->d_custom= - shared_ptr( - DNSRecordContent::mastermake(QType::CNAME, 1, - boost::get(constGet(have,"defcontent")) - ) - ); - - if(have.count("defttl")) - defpol->d_ttl = boost::get(constGet(have, "defttl")); - else - defpol->d_ttl = -1; // get it from the zone - } - } - if(have.count("zoneSizeHint")) { - lci.dfe.reserve(zoneIdx, static_cast(boost::get(constGet(have, "zoneSizeHint")))); + size_t zoneSizeHint = 0; + parseRPZParameters(have, polName, defpol, maxTTL, zoneSizeHint); + if (zoneSizeHint > 0) { + lci.dfe.reserve(zoneIdx, zoneSizeHint); } } theL()<>>& options) { + Lua.writeFunction("rpzMaster", [&lci, checkOnly](const string& master_, const string& zone_, const boost::optional>>& options) { try { boost::optional defpol; TSIGTriplet tt; - int refresh=0; - std::string polName; + uint32_t refresh=0; + std::string polName(zone_); size_t maxReceivedXFRMBytes = 0; + uint32_t maxTTL = std::numeric_limits::max(); ComboAddress localAddress; const size_t zoneIdx = lci.dfe.size(); if(options) { auto& have = *options; - polName = zone_; - if(have.count("policyName")) - polName = boost::get(constGet(have, "policyName")); - if(have.count("defpol")) { - // cout<<"Set a default policy"<d_kind = (DNSFilterEngine::PolicyKind)boost::get(constGet(have, "defpol")); - defpol->d_name = std::make_shared(polName); - if(defpol->d_kind == DNSFilterEngine::PolicyKind::Custom) { - // cout<<"Setting a custom field even!"<d_custom= - shared_ptr( - DNSRecordContent::mastermake(QType::CNAME, 1, - boost::get(constGet(have,"defcontent")) - ) - ); - if(have.count("defttl")) - defpol->d_ttl = boost::get(constGet(have, "defttl")); - else - defpol->d_ttl = -1; // get it from the zone - } - } - if(have.count("zoneSizeHint")) { - lci.dfe.reserve(zoneIdx, static_cast(boost::get(constGet(have, "zoneSizeHint")))); + size_t zoneSizeHint = 0; + parseRPZParameters(have, polName, defpol, maxTTL, zoneSizeHint); + if (zoneSizeHint > 0) { + lci.dfe.reserve(zoneIdx, zoneSizeHint); } if(have.count("tsigname")) { tt.name=DNSName(toLower(boost::get(constGet(have, "tsigname")))); @@ -175,10 +169,10 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly) throw std::runtime_error("TSIG secret is not valid Base-64 encoded"); } if(have.count("refresh")) { - refresh = boost::get(constGet(have,"refresh")); + refresh = boost::get(constGet(have,"refresh")); } if(have.count("maxReceivedMBytes")) { - maxReceivedXFRMBytes = static_cast(boost::get(constGet(have,"maxReceivedMBytes"))); + maxReceivedXFRMBytes = static_cast(boost::get(constGet(have,"maxReceivedMBytes"))); } if(have.count("localAddress")) { localAddress = ComboAddress(boost::get(constGet(have,"localAddress"))); @@ -192,10 +186,10 @@ void loadRecursorLuaConfig(const std::string& fname, bool checkOnly) lci.dfe.setPolicyName(zoneIdx, polName); if (!checkOnly) { - auto sr=loadRPZFromServer(master, zone, lci.dfe, defpol, zoneIdx, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress); + auto sr=loadRPZFromServer(master, zone, lci.dfe, defpol, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes * 1024 * 1024, localAddress); if(refresh) sr->d_st.refresh=refresh; - std::thread t(RPZIXFRTracker, master, zone, defpol, zoneIdx, tt, sr, maxReceivedXFRMBytes * 1024 * 1024, localAddress); + std::thread t(RPZIXFRTracker, master, zone, defpol, maxTTL, zoneIdx, tt, sr, maxReceivedXFRMBytes * 1024 * 1024, localAddress); t.detach(); } } diff --git a/pdns/reczones.cc b/pdns/reczones.cc index 7d9a4f5653..d319c4663f 100644 --- a/pdns/reczones.cc +++ b/pdns/reczones.cc @@ -310,9 +310,9 @@ string reloadAuthAndForwards() } -void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, boost::optional defpol, size_t polZone, const TSIGTriplet& tt, shared_ptr oursr, size_t maxReceivedBytes, const ComboAddress& localAddress) +void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, boost::optional defpol, uint32_t maxTTL, size_t polZone, const TSIGTriplet& tt, shared_ptr oursr, size_t maxReceivedBytes, const ComboAddress& localAddress) { - int refresh = oursr->d_st.refresh; + uint32_t refresh = oursr->d_st.refresh; for(;;) { DNSRecord dr; dr.d_content=oursr; @@ -359,7 +359,7 @@ void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, boost::opti else { totremove++; L< defpol, size_t place) +void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, bool addOrRemove, boost::optional defpol, uint32_t maxTTL, size_t place) { static const DNSName drop("rpz-drop."), truncate("rpz-tcp-only."), noaction("rpz-passthru."); static const DNSName rpzClientIP("rpz-client-ip"), rpzIP("rpz-ip"), @@ -115,8 +115,11 @@ void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, bool addOrR } } - if(pol.d_ttl < 0) - pol.d_ttl = dr.d_ttl; + if (!defpol || defpol->d_ttl < 0) { + pol.d_ttl = static_cast(std::min(maxTTL, dr.d_ttl)); + } else { + pol.d_ttl = static_cast(std::min(maxTTL, static_cast(pol.d_ttl))); + } // now to DO something with that @@ -157,7 +160,7 @@ void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, bool addOrR } } -shared_ptr loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, boost::optional defpol, size_t place, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress) +shared_ptr loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, boost::optional defpol, uint32_t maxTTL, size_t place, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress) { L< loadRPZFromServer(const ComboAddress& master, const continue; } - RPZRecordToPolicy(dr, target, true, defpol, place); + RPZRecordToPolicy(dr, target, true, defpol, maxTTL, place); nrecords++; } if(last != time(0)) { @@ -198,7 +201,7 @@ shared_ptr loadRPZFromServer(const ComboAddress& master, const } // this function is silent - you do the logging -int loadRPZFromFile(const std::string& fname, DNSFilterEngine& target, boost::optional defpol, size_t place) +int loadRPZFromFile(const std::string& fname, DNSFilterEngine& target, boost::optional defpol, uint32_t maxTTL, size_t place) { ZoneParserTNG zpt(fname); DNSResourceRecord drr; @@ -216,7 +219,7 @@ int loadRPZFromFile(const std::string& fname, DNSFilterEngine& target, boost::op } else { dr.d_name=dr.d_name.makeRelative(domain); - RPZRecordToPolicy(dr, target, true, defpol, place); + RPZRecordToPolicy(dr, target, true, defpol, maxTTL, place); } } catch(PDNSException& pe) { diff --git a/pdns/rpzloader.hh b/pdns/rpzloader.hh index eebbeb2d57..6026361bb9 100644 --- a/pdns/rpzloader.hh +++ b/pdns/rpzloader.hh @@ -24,7 +24,7 @@ #include #include "dnsrecords.hh" -int loadRPZFromFile(const std::string& fname, DNSFilterEngine& target, boost::optional defpol, size_t place); -std::shared_ptr loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, boost::optional defpol, size_t place, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress); -void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, bool addOrRemove, boost::optional defpol, size_t place); -void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, boost::optional defpol, size_t polZone, const TSIGTriplet &tt, shared_ptr oursr, size_t maxReceivedBytes, const ComboAddress& localAddress); +int loadRPZFromFile(const std::string& fname, DNSFilterEngine& target, boost::optional defpol, uint32_t maxTTL, size_t place); +std::shared_ptr loadRPZFromServer(const ComboAddress& master, const DNSName& zone, DNSFilterEngine& target, boost::optional defpol, uint32_t maxTTL, size_t place, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress); +void RPZRecordToPolicy(const DNSRecord& dr, DNSFilterEngine& target, bool addOrRemove, boost::optional defpol, uint32_t maxTTL, size_t place); +void RPZIXFRTracker(const ComboAddress& master, const DNSName& zone, boost::optional defpol, uint32_t maxTTL, size_t polZone, const TSIGTriplet &tt, shared_ptr oursr, size_t maxReceivedBytes, const ComboAddress& localAddress);