]> granicus.if.org Git - pdns/commitdiff
dnsdist: Add IP 'encryption' options to RemoteLog{,Response}Action
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 30 Jan 2019 15:58:04 +0000 (16:58 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 25 Mar 2019 09:22:41 +0000 (10:22 +0100)
pdns/dnsdist-lua-actions.cc
pdns/dnsdistdist/docs/rules-actions.rst

index 55c7251e0aaca0866ec83c78e1ffc17cdf89c5bf..25d2dbbf01c32789e00a9652bae1c914bc0b336a 100644 (file)
@@ -19,6 +19,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+#include "config.h"
 #include "threadname.hh"
 #include "dnsdist.hh"
 #include "dnsdist-ecs.hh"
 #include "ednsoptions.hh"
 #include "fstrm_logger.hh"
 #include "remote_logger.hh"
-#include "boost/optional/optional_io.hpp"
+
+#include <boost/optional/optional_io.hpp>
+
+#ifdef HAVE_LIBCRYPTO
+#include "ipcipher.hh"
+#endif /* HAVE_LIBCRYPTO */
 
 class DropAction : public DNSAction
 {
@@ -771,7 +777,7 @@ private:
 class RemoteLogAction : public DNSAction, public boost::noncopyable
 {
 public:
-  RemoteLogAction(std::shared_ptr<RemoteLoggerInterface>& logger, boost::optional<std::function<void(const DNSQuestion&, DNSDistProtoBufMessage*)> > alterFunc, const std::string& serverID): d_logger(logger), d_alterFunc(alterFunc), d_serverID(serverID)
+  RemoteLogAction(std::shared_ptr<RemoteLoggerInterface>& logger, boost::optional<std::function<void(const DNSQuestion&, DNSDistProtoBufMessage*)> > alterFunc, const std::string& serverID, const std::string& ipEncryptKey): d_logger(logger), d_alterFunc(alterFunc), d_serverID(serverID), d_ipEncryptKey(ipEncryptKey)
   {
   }
   DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
@@ -786,6 +792,13 @@ public:
       message.setServerIdentity(d_serverID);
     }
 
+#if HAVE_LIBCRYPTO
+    if (!d_ipEncryptKey.empty())
+    {
+      message.setRequestor(encryptCA(*dq->remote, d_ipEncryptKey));
+    }
+#endif /* HAVE_LIBCRYPTO */
+
     if (d_alterFunc) {
       std::lock_guard<std::mutex> lock(g_luamutex);
       (*d_alterFunc)(*dq, &message);
@@ -805,6 +818,7 @@ private:
   std::shared_ptr<RemoteLoggerInterface> d_logger;
   boost::optional<std::function<void(const DNSQuestion&, DNSDistProtoBufMessage*)> > d_alterFunc;
   std::string d_serverID;
+  std::string d_ipEncryptKey;
 };
 
 class SNMPTrapAction : public DNSAction
@@ -891,7 +905,7 @@ private:
 class RemoteLogResponseAction : public DNSResponseAction, public boost::noncopyable
 {
 public:
-  RemoteLogResponseAction(std::shared_ptr<RemoteLoggerInterface>& logger, boost::optional<std::function<void(const DNSResponse&, DNSDistProtoBufMessage*)> > alterFunc, const std::string& serverID, bool includeCNAME): d_logger(logger), d_alterFunc(alterFunc), d_serverID(serverID), d_includeCNAME(includeCNAME)
+  RemoteLogResponseAction(std::shared_ptr<RemoteLoggerInterface>& logger, boost::optional<std::function<void(const DNSResponse&, DNSDistProtoBufMessage*)> > alterFunc, const std::string& serverID, const std::string& ipEncryptKey, bool includeCNAME): d_logger(logger), d_alterFunc(alterFunc), d_serverID(serverID), d_ipEncryptKey(ipEncryptKey), d_includeCNAME(includeCNAME)
   {
   }
   DNSResponseAction::Action operator()(DNSResponse* dr, string* ruleresult) const override
@@ -906,6 +920,13 @@ public:
       message.setServerIdentity(d_serverID);
     }
 
+#if HAVE_LIBCRYPTO
+    if (!d_ipEncryptKey.empty())
+    {
+      message.setRequestor(encryptCA(*dr->remote, d_ipEncryptKey));
+    }
+#endif /* HAVE_LIBCRYPTO */
+
     if (d_alterFunc) {
       std::lock_guard<std::mutex> lock(g_luamutex);
       (*d_alterFunc)(*dr, &message);
@@ -925,6 +946,7 @@ private:
   std::shared_ptr<RemoteLoggerInterface> d_logger;
   boost::optional<std::function<void(const DNSResponse&, DNSDistProtoBufMessage*)> > d_alterFunc;
   std::string d_serverID;
+  std::string d_ipEncryptKey;
   bool d_includeCNAME;
 };
 
@@ -1221,14 +1243,18 @@ void setupLuaActions()
       }
 
       std::string serverID;
+      std::string ipEncryptKey;
       if (vars) {
         if (vars->count("serverID")) {
           serverID = boost::get<std::string>((*vars)["serverID"]);
         }
+        if (vars->count("ipEncryptKey")) {
+          ipEncryptKey = boost::get<std::string>((*vars)["ipEncryptKey"]);
+        }
       }
 
 #ifdef HAVE_PROTOBUF
-      return std::shared_ptr<DNSAction>(new RemoteLogAction(logger, alterFunc, serverID));
+      return std::shared_ptr<DNSAction>(new RemoteLogAction(logger, alterFunc, serverID, ipEncryptKey));
 #else
       throw std::runtime_error("Protobuf support is required to use RemoteLogAction");
 #endif
@@ -1243,14 +1269,18 @@ void setupLuaActions()
       }
 
       std::string serverID;
+      std::string ipEncryptKey;
       if (vars) {
         if (vars->count("serverID")) {
           serverID = boost::get<std::string>((*vars)["serverID"]);
         }
+        if (vars->count("ipEncryptKey")) {
+          ipEncryptKey = boost::get<std::string>((*vars)["ipEncryptKey"]);
+        }
       }
 
 #ifdef HAVE_PROTOBUF
-      return std::shared_ptr<DNSResponseAction>(new RemoteLogResponseAction(logger, alterFunc, serverID, includeCNAME ? *includeCNAME : false));
+      return std::shared_ptr<DNSResponseAction>(new RemoteLogResponseAction(logger, alterFunc, serverID, ipEncryptKey, includeCNAME ? *includeCNAME : false));
 #else
       throw std::runtime_error("Protobuf support is required to use RemoteLogResponseAction");
 #endif
index 36d8b3a55b5702f60250d3f157c1136dcd9e2c42..b23b03f75991feb0bc0f69203e5204835f2e7444 100644 (file)
@@ -963,6 +963,9 @@ The following actions exist.
   .. versionchanged:: 1.3.0
     ``options`` optional parameter added.
 
+  .. versionchanged:: 1.3.4
+    ``ipEncryptKey`` optional key added to the options table.
+
   Send the content of this query to a remote logger via Protocol Buffer.
   ``alterFunction`` is a callback, receiving a :class:`DNSQuestion` and a :class:`DNSDistProtoBufMessage`, that can be used to modify the Protocol Buffer content, for example for anonymization purposes
 
@@ -973,12 +976,16 @@ The following actions exist.
   Options:
 
   * ``serverID=""``: str - Set the Server Identity field.
+  * ``ipEncryptKey=""``: str - A key, that can be generated via the :ref:`makeIPCipherKey` function, to encrypt the IP address of the requestor for anonymization purposes. The encryption is done using ipcrypt for IPv4 and a 128-bit AES ECB operation for IPv6.
 
 .. function:: RemoteLogResponseAction(remoteLogger[, alterFunction[, includeCNAME [, options]]])
 
   .. versionchanged:: 1.3.0
     ``options`` optional parameter added.
 
+  .. versionchanged:: 1.3.4
+    ``ipEncryptKey`` optional key added to the options table.
+
   Send the content of this response to a remote logger via Protocol Buffer.
   ``alterFunction`` is the same callback that receiving a :class:`DNSQuestion` and a :class:`DNSDistProtoBufMessage`, that can be used to modify the Protocol Buffer content, for example for anonymization purposes
   ``includeCNAME`` indicates whether CNAME records inside the response should be parsed and exported.
@@ -992,6 +999,7 @@ The following actions exist.
   Options:
 
   * ``serverID=""``: str - Set the Server Identity field.
+  * ``ipEncryptKey=""``: str - A key, that can be generated via the :ref:`makeIPCipherKey` function, to encrypt the IP address of the requestor for anonymization purposes. The encryption is done using ipcrypt for IPv4 and a 128-bit AES ECB operation for IPv6.
 
 .. function:: SetECSAction(v4 [, v6])