From: Remi Gacogne Date: Thu, 17 Aug 2017 10:56:30 +0000 (+0200) Subject: rec: Log the policy type (QName, Client IP, NS IP...) over protobuf X-Git-Tag: auth-4.1.0-rc1~9^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F5621%2Fhead;p=thirdparty%2Fpdns.git rec: Log the policy type (QName, Client IP, NS IP...) over protobuf --- diff --git a/contrib/ProtobufLogger.py b/contrib/ProtobufLogger.py index 5075e43f7d..c5e5d33cd6 100644 --- a/contrib/ProtobufLogger.py +++ b/contrib/ProtobufLogger.py @@ -66,6 +66,21 @@ class PDNSPBConnHandler(object): message.question.qType, message.question.qName)) + @staticmethod + def getAppliedPolicyTypeAsString(polType): + if polType == dnsmessage_pb2.PBDNSMessage.UNKNOWN: + return 'Unknown' + elif polType == dnsmessage_pb2.PBDNSMessage.QNAME: + return 'QName' + elif polType == dnsmessage_pb2.PBDNSMessage.CLIENTIP: + return 'Client IP' + elif polType == dnsmessage_pb2.PBDNSMessage.RESPONSEIP: + return 'Response IP' + elif polType == dnsmessage_pb2.PBDNSMessage.NSDNAME: + return 'NS DName' + elif polType == dnsmessage_pb2.PBDNSMessage.NSIP: + return 'NS IP' + def printResponse(self, message): if message.HasField('response'): response = message.response @@ -79,6 +94,8 @@ class PDNSPBConnHandler(object): policystr = '' if response.HasField('appliedPolicy') and response.appliedPolicy: policystr = ', Applied policy: ' + response.appliedPolicy + if response.HasField('appliedPolicyType'): + policystr = policystr + ' (' + self.getAppliedPolicyTypeAsString(response.appliedPolicyType) + ')' tagsstr = '' if response.tags: diff --git a/pdns/dnsmessage.proto b/pdns/dnsmessage.proto index d64de370c8..e53129f7e2 100644 --- a/pdns/dnsmessage.proto +++ b/pdns/dnsmessage.proto @@ -36,6 +36,14 @@ message PBDNSMessage { UDP = 1; // User Datagram Protocol (RFC 768) TCP = 2; // Transmission Control Protocol (RFC 793) } + enum PolicyType { + UNKNOWN = 1; // No policy applied, or unknown type + QNAME = 2; // Policy matched on the QName + CLIENTIP = 3; // Policy matched on the client IP + RESPONSEIP = 4; // Policy matched on one of the IPs contained in the answer + NSDNAME = 5; // Policy matched on the name of one nameserver involved + NSIP = 6; // Policy matched on the IP of one nameserver involved + } required Type type = 1; optional bytes messageId = 2; // UUID, shared by the query and the response optional bytes serverIdentity = 3; // UUID of the server emitting the protobuf message @@ -69,6 +77,7 @@ message PBDNSMessage { repeated string tags = 4; // Additional tags optional uint32 queryTimeSec = 5; // Time of the corresponding query reception (seconds since epoch) optional uint32 queryTimeUsec = 6; // Time of the corresponding query reception (additional micro-seconds) + optional PolicyType appliedPolicyType = 7; // Type of the filtering policy (RPZ or Lua) applied } optional DNSResponse response = 13; diff --git a/pdns/filterpo.cc b/pdns/filterpo.cc index 8ef02f4db6..c32054bbe4 100644 --- a/pdns/filterpo.cc +++ b/pdns/filterpo.cc @@ -156,30 +156,35 @@ void DNSFilterEngine::assureZones(size_t zone) void DNSFilterEngine::Zone::addClientTrigger(const Netmask& nm, Policy pol) { pol.d_name = d_name; + pol.d_type = PolicyType::ClientIP; d_qpolAddr.insert(nm).second=pol; } void DNSFilterEngine::Zone::addResponseTrigger(const Netmask& nm, Policy pol) { pol.d_name = d_name; + pol.d_type = PolicyType::ResponseIP; d_postpolAddr.insert(nm).second=pol; } void DNSFilterEngine::Zone::addQNameTrigger(const DNSName& n, Policy pol) { pol.d_name = d_name; + pol.d_type = PolicyType::QName; d_qpolName[n]=pol; } void DNSFilterEngine::Zone::addNSTrigger(const DNSName& n, Policy pol) { pol.d_name = d_name; + pol.d_type = PolicyType::NSDName; d_propolName[n]=pol; } void DNSFilterEngine::Zone::addNSIPTrigger(const Netmask& nm, Policy pol) { pol.d_name = d_name; + pol.d_type = PolicyType::NSIP; d_propolNSAddr.insert(nm).second = pol; } diff --git a/pdns/filterpo.hh b/pdns/filterpo.hh index e2ddd91853..da68956a26 100644 --- a/pdns/filterpo.hh +++ b/pdns/filterpo.hh @@ -65,9 +65,11 @@ class DNSFilterEngine { public: enum class PolicyKind { NoAction, Drop, NXDOMAIN, NODATA, Truncate, Custom}; + enum class PolicyType { None, QName, ClientIP, ResponseIP, NSDName, NSIP }; + struct Policy { - Policy(): d_kind(PolicyKind::NoAction), d_custom(nullptr), d_name(nullptr), d_ttl(0) + Policy(): d_custom(nullptr), d_name(nullptr), d_kind(PolicyKind::NoAction), d_type(PolicyType::None), d_ttl(0) { } bool operator==(const Policy& rhs) const @@ -75,9 +77,10 @@ public: return d_kind == rhs.d_kind; // XXX check d_custom too! } DNSRecord getCustomRecord(const DNSName& qname) const; - PolicyKind d_kind; std::shared_ptr d_custom; std::shared_ptr d_name; + PolicyKind d_kind; + PolicyType d_type; int32_t d_ttl; }; diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index afad36ca6d..a0ba2e98b7 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -1146,6 +1146,7 @@ static void startDoResolve(void *p) pbMessage.setResponseCode(pw.getHeader()->rcode); if (appliedPolicy.d_name) { pbMessage.setAppliedPolicy(*appliedPolicy.d_name); + pbMessage.setAppliedPolicyType(appliedPolicy.d_type); } pbMessage.setPolicyTags(dc->d_policyTags); pbMessage.setQueryTime(dc->d_now.tv_sec, dc->d_now.tv_usec); diff --git a/pdns/rec-protobuf.cc b/pdns/rec-protobuf.cc index b1f4909bf9..b0c2393731 100644 --- a/pdns/rec-protobuf.cc +++ b/pdns/rec-protobuf.cc @@ -61,6 +61,37 @@ void RecProtoBufMessage::setAppliedPolicy(const std::string& policy) #endif /* HAVE_PROTOBUF */ } +void RecProtoBufMessage::setAppliedPolicyType(const DNSFilterEngine::PolicyType& type) +{ +#ifdef HAVE_PROTOBUF + PBDNSMessage_DNSResponse* response = d_message.mutable_response(); + if (response) { + switch(type) { + case DNSFilterEngine::PolicyType::None: + response->set_appliedpolicytype(PBDNSMessage_PolicyType_UNKNOWN); + break; + case DNSFilterEngine::PolicyType::QName: + response->set_appliedpolicytype(PBDNSMessage_PolicyType_QNAME); + break; + case DNSFilterEngine::PolicyType::ClientIP: + response->set_appliedpolicytype(PBDNSMessage_PolicyType_CLIENTIP); + break; + case DNSFilterEngine::PolicyType::ResponseIP: + response->set_appliedpolicytype(PBDNSMessage_PolicyType_RESPONSEIP); + break; + case DNSFilterEngine::PolicyType::NSDName: + response->set_appliedpolicytype(PBDNSMessage_PolicyType_NSDNAME); + break; + case DNSFilterEngine::PolicyType::NSIP: + response->set_appliedpolicytype(PBDNSMessage_PolicyType_NSIP); + break; + default: + throw std::runtime_error("Unsupported protobuf policy type"); + } + } +#endif /* HAVE_PROTOBUF */ +} + void RecProtoBufMessage::setPolicyTags(const std::vector& policyTags) { #ifdef HAVE_PROTOBUF diff --git a/pdns/rec-protobuf.hh b/pdns/rec-protobuf.hh index da5d81a8f1..cebdbcb6af 100644 --- a/pdns/rec-protobuf.hh +++ b/pdns/rec-protobuf.hh @@ -22,7 +22,7 @@ #pragma once #include "protobuf.hh" - +#include "filterpo.hh" #include "dnsrecords.hh" class RecProtoBufMessage: public DNSProtoBufMessage @@ -45,6 +45,7 @@ public: void addRRs(const std::vector& records); void addRR(const DNSRecord& record); void setAppliedPolicy(const std::string& policy); + void setAppliedPolicyType(const DNSFilterEngine::PolicyType& policyType); void setPolicyTags(const std::vector& policyTags); std::string getAppliedPolicy() const; std::vector getPolicyTags() const;