]> granicus.if.org Git - pdns/commitdiff
rec: Add support for protobuf requestor's anonymization
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 24 Jun 2016 13:25:01 +0000 (15:25 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 28 Jun 2016 09:32:10 +0000 (11:32 +0200)
pdns/iputils.hh
pdns/pdns_recursor.cc
pdns/rec-lua-conf.cc
pdns/rec-lua-conf.hh

index d935073592433db405633df206a1448d1d277a10..1cc3798ba5db851bac765a584b4020a3e8c4c98e 100644 (file)
@@ -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;
index 9ebf695c4b7e564dff7598b80a87468ea1555e29..bcd706ad28d7fbb33bf97c6a8f6ea3aa3f1f6c32 100644 (file)
@@ -610,9 +610,11 @@ catch(...)
 }
 
 #ifdef HAVE_PROTOBUF
-static void protobufLogQuery(const std::shared_ptr<RemoteLogger>& 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<std::string>& policyTags)
+static void protobufLogQuery(const std::shared_ptr<RemoteLogger>& 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<std::string>& 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<std::string>());
+          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<std::string>());
         }
         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);
       }
index cf1a5aa982c3668b4bd0a1c6affeeb8d8e631c25..0c1474ed588c81da2b82a3387f7a06604f551c33 100644 (file)
@@ -240,11 +240,17 @@ void loadRecursorLuaConfig(const std::string& fname)
     });
 
 #if HAVE_PROTOBUF
-  Lua.writeFunction("protobufServer", [&lci](const string& server_, const boost::optional<uint16_t> timeout, const boost::optional<uint64_t> maxQueuedEntries, const boost::optional<uint8_t> reconnectWaitTime) {
+  Lua.writeFunction("protobufServer", [&lci](const string& server_, const boost::optional<uint16_t> timeout, const boost::optional<uint64_t> maxQueuedEntries, const boost::optional<uint8_t> reconnectWaitTime, const boost::optional<uint8_t> maskV4, boost::optional<uint8_t> maskV6) {
       try {
        ComboAddress server(server_);
         if (!lci.protobufServer) {
           lci.protobufServer = std::make_shared<RemoteLogger>(server, timeout ? *timeout : 2, maxQueuedEntries ? *maxQueuedEntries : 100, reconnectWaitTime ? *reconnectWaitTime : 1);
+          if (maskV4) {
+            lci.protobufMaskV4 = *maskV4;
+          }
+          if (maskV6) {
+            lci.protobufMaskV6 = *maskV6;
+          }
         }
         else {
           theL()<<Logger::Error<<"Only one protobuf server can be configured, we already have "<<lci.protobufServer->toString()<<endl;
index 57f1f9ed492d210127b55a8997ea2ae13768b9f7..a4207cbaeb9ce81b2530c143f0efe2813f876ec6 100644 (file)
@@ -13,6 +13,8 @@ public:
   map<DNSName,DSRecordContent> dsAnchors;
   map<DNSName,std::string> negAnchors;
   std::shared_ptr<RemoteLogger> protobufServer{nullptr};
+  uint8_t protobufMaskV4{32};
+  uint8_t protobufMaskV6{128};
 };
 
 extern GlobalStateHolder<LuaConfigItems> g_luaconfs;