From e1c8a4bba5c721029a055c4ad82616d8eff5fd75 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 24 Jun 2016 15:25:01 +0200 Subject: [PATCH] rec: Add support for protobuf requestor's anonymization --- pdns/iputils.hh | 25 ++++++++++++++++++++++++- pdns/pdns_recursor.cc | 18 ++++++++++++------ pdns/rec-lua-conf.cc | 8 +++++++- pdns/rec-lua-conf.hh | 2 ++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/pdns/iputils.hh b/pdns/iputils.hh index d93507359..1cc3798ba 100644 --- a/pdns/iputils.hh +++ b/pdns/iputils.hh @@ -306,7 +306,7 @@ public: { d_network = network; - if(bits == 0xff) + if(bits > 128) bits = (network.sin4.sin_family == AF_INET) ? 32 : 128; d_bits = bits; @@ -398,6 +398,29 @@ public: { return d_network; } + const ComboAddress getMaskedNetwork() const + { + ComboAddress result(d_network); + if(isIpv4()) { + result.sin4.sin_addr.s_addr = htonl(ntohl(result.sin4.sin_addr.s_addr) & d_mask); + } + else if(isIpv6()) { + size_t idx; + uint8_t bytes=d_bits/8; + uint8_t *us=(uint8_t*) &result.sin6.sin6_addr.s6_addr; + uint8_t bits= d_bits % 8; + uint8_t mask= (uint8_t) ~(0xFF>>bits); + + if (bytes < sizeof(result.sin6.sin6_addr.s6_addr)) { + us[bytes] &= mask; + } + + for(idx = bytes + 1; idx < sizeof(result.sin6.sin6_addr.s6_addr); ++idx) { + us[idx] = 0; + } + } + return result; + } int getBits() const { return d_bits; diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 9ebf695c4..bcd706ad2 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -610,9 +610,11 @@ catch(...) } #ifdef HAVE_PROTOBUF -static void protobufLogQuery(const std::shared_ptr& logger, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const Netmask& ednssubnet, bool tcp, uint16_t id, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::string appliedPolicy, const std::vector& policyTags) +static void protobufLogQuery(const std::shared_ptr& logger, uint8_t maskV4, uint8_t maskV6, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const Netmask& ednssubnet, bool tcp, uint16_t id, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::string appliedPolicy, const std::vector& policyTags) { - RecProtoBufMessage message(DNSProtoBufMessage::Query, uniqueId, &remote, &local, qname, qtype, qclass, id, tcp, len); + Netmask requestorNM(remote, remote.sin4.sin_family == AF_INET ? maskV4 : maskV6); + const ComboAddress& requestor = requestorNM.getMaskedNetwork(); + RecProtoBufMessage message(DNSProtoBufMessage::Query, uniqueId, &requestor, &local, qname, qtype, qclass, id, tcp, len); message.setEDNSSubnet(ednssubnet); if (!appliedPolicy.empty()) { @@ -660,7 +662,9 @@ void startDoResolve(void *p) RecProtoBufMessage pbMessage(RecProtoBufMessage::Response); #ifdef HAVE_PROTOBUF if (luaconfsLocal->protobufServer) { - pbMessage.update(dc->d_uuid, &dc->d_remote, &dc->d_local, dc->d_tcp, dc->d_mdp.d_header.id); + Netmask requestorNM(dc->d_remote, dc->d_remote.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); + const ComboAddress& requestor = requestorNM.getMaskedNetwork(); + pbMessage.update(dc->d_uuid, &requestor, &dc->d_local, dc->d_tcp, dc->d_mdp.d_header.id); pbMessage.setEDNSSubnet(dc->d_ednssubnet); pbMessage.setQuestion(dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); } @@ -1215,7 +1219,7 @@ void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) getQNameAndSubnet(std::string(conn->data, conn->qlen), &qname, &qtype, &qclass, &ednssubnet); dc->d_ednssubnet = ednssubnet; - protobufLogQuery(luaconfsLocal->protobufServer, dc->d_uuid, dest, conn->d_remote, ednssubnet, true, dh->id, conn->qlen, qname, qtype, qclass, std::string(), std::vector()); + protobufLogQuery(luaconfsLocal->protobufServer, luaconfsLocal->protobufMaskV4, luaconfsLocal->protobufMaskV6, dc->d_uuid, dest, conn->d_remote, ednssubnet, true, dh->id, conn->qlen, qname, qtype, qclass, std::string(), std::vector()); } catch(std::exception& e) { if(g_logCommonErrors) @@ -1357,7 +1361,7 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr RecProtoBufMessage pbMessage(DNSProtoBufMessage::DNSProtoBufMessageType::Response); #ifdef HAVE_PROTOBUF if(luaconfsLocal->protobufServer) { - protobufLogQuery(luaconfsLocal->protobufServer, uniqueId, fromaddr, destaddr, ednssubnet, false, dh->id, question.size(), qname, qtype, qclass, std::string(), policyTags); + protobufLogQuery(luaconfsLocal->protobufServer, luaconfsLocal->protobufMaskV4, luaconfsLocal->protobufMaskV6, uniqueId, fromaddr, destaddr, ednssubnet, false, dh->id, question.size(), qname, qtype, qclass, std::string(), policyTags); } #endif /* HAVE_PROTOBUF */ @@ -1365,7 +1369,9 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr if (cacheHit) { #ifdef HAVE_PROTOBUF if(luaconfsLocal->protobufServer) { - pbMessage.update(uniqueId, &fromaddr, &destaddr, false, dh->id); + Netmask requestorNM(fromaddr, fromaddr.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); + const ComboAddress& requestor = requestorNM.getMaskedNetwork(); + pbMessage.update(uniqueId, &requestor, &destaddr, false, dh->id); pbMessage.setEDNSSubnet(ednssubnet); protobufLogResponse(luaconfsLocal->protobufServer, pbMessage); } diff --git a/pdns/rec-lua-conf.cc b/pdns/rec-lua-conf.cc index cf1a5aa98..0c1474ed5 100644 --- a/pdns/rec-lua-conf.cc +++ b/pdns/rec-lua-conf.cc @@ -240,11 +240,17 @@ void loadRecursorLuaConfig(const std::string& fname) }); #if HAVE_PROTOBUF - Lua.writeFunction("protobufServer", [&lci](const string& server_, const boost::optional timeout, const boost::optional maxQueuedEntries, const boost::optional reconnectWaitTime) { + Lua.writeFunction("protobufServer", [&lci](const string& server_, const boost::optional timeout, const boost::optional maxQueuedEntries, const boost::optional reconnectWaitTime, const boost::optional maskV4, boost::optional maskV6) { try { ComboAddress server(server_); if (!lci.protobufServer) { lci.protobufServer = std::make_shared(server, timeout ? *timeout : 2, maxQueuedEntries ? *maxQueuedEntries : 100, reconnectWaitTime ? *reconnectWaitTime : 1); + if (maskV4) { + lci.protobufMaskV4 = *maskV4; + } + if (maskV6) { + lci.protobufMaskV6 = *maskV6; + } } else { theL()<toString()< dsAnchors; map negAnchors; std::shared_ptr protobufServer{nullptr}; + uint8_t protobufMaskV4{32}; + uint8_t protobufMaskV6{128}; }; extern GlobalStateHolder g_luaconfs; -- 2.40.0