]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Add support for TLV values
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 27 Feb 2020 13:40:30 +0000 (14:40 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 17 Mar 2020 13:12:55 +0000 (14:12 +0100)
pdns/lua-recursor4.cc
pdns/lua-recursor4.hh
pdns/pdns_recursor.cc

index 36239b0e14a779b788e7bbd0b6c19cab3fcef7be..e8b413f2ebd9b75388738efd6e6ffbd1d8a78d16 100644 (file)
@@ -183,6 +183,19 @@ boost::optional<Netmask>  RecursorLua4::DNSQuestion::getEDNSSubnet() const
   return boost::optional<Netmask>();
 }
 
+std::vector<std::pair<uint8_t, string>> RecursorLua4::DNSQuestion::getProxyProtocolValues() const
+{
+  std::vector<std::pair<uint8_t, string>> result;
+  if (proxyProtocolValues) {
+    result.reserve(proxyProtocolValues->size());
+
+    for (const auto& value: *proxyProtocolValues) {
+      result.push_back({ value.type, value.content });
+    }
+  }
+
+  return result;
+}
 
 vector<pair<int, DNSRecord> > RecursorLua4::DNSQuestion::getRecords() const
 {
@@ -291,6 +304,7 @@ void RecursorLua4::postPrepareContext()
   d_lw->registerFunction("getEDNSOptions", &DNSQuestion::getEDNSOptions);
   d_lw->registerFunction("getEDNSOption", &DNSQuestion::getEDNSOption);
   d_lw->registerFunction("getEDNSSubnet", &DNSQuestion::getEDNSSubnet);
+  d_lw->registerFunction("getProxyProtocolValues", &DNSQuestion::getProxyProtocolValues);
   d_lw->registerFunction("getEDNSFlags", &DNSQuestion::getEDNSFlags);
   d_lw->registerFunction("getEDNSFlag", &DNSQuestion::getEDNSFlag);
   d_lw->registerMember("name", &DNSRecord::d_name);
index 4515136a4a650aaec0abecd1de75484d384a1671..8e3e082bd7d65f227f797e1474664604cbb8ba1e 100644 (file)
@@ -33,6 +33,8 @@
 #include "ednsoptions.hh"
 #include "validate.hh"
 #include "lua-base4.hh"
+#include "proxy-protocol.hh"
+
 #include <unordered_map>
 
 #include "lua-recursor4-ffi.hh"
@@ -74,6 +76,7 @@ public:
     vector<DNSRecord>* currentRecords{nullptr};
     DNSFilterEngine::Policy* appliedPolicy{nullptr};
     std::vector<std::string>* policyTags{nullptr};
+    const std::vector<ProxyProtocolValue>* proxyProtocolValues{nullptr};
     std::unordered_map<std::string,bool>* discardedPolicies{nullptr};
     std::string requestorId;
     std::string deviceId;
@@ -91,6 +94,7 @@ public:
     vector<pair<uint16_t, string> > getEDNSOptions() const;
     boost::optional<string> getEDNSOption(uint16_t code) const;
     boost::optional<Netmask> getEDNSSubnet() const;
+    std::vector<std::pair<uint8_t, string>> getProxyProtocolValues() const;
     vector<string> getEDNSFlags() const;
     bool getEDNSFlag(string flag) const;
     void setRecords(const vector<pair<int,DNSRecord> >& records);
index 24e9e82b1c3a50ccd443e61f8d99164846076ff5..bed4ea90b6d06f77618fa3e7b073361a920de574 100644 (file)
@@ -1287,6 +1287,7 @@ static void startDoResolve(void *p)
     dq.deviceId = dc->d_deviceId;
     dq.deviceName = dc->d_deviceName;
 #endif
+    dq.proxyProtocolValues = &dc->d_proxyProtocolValues;
 
     if(ednsExtRCode != 0) {
       goto sendit;
@@ -2049,6 +2050,18 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
         t_fdm->removeReadFD(fd);
         return;
       }
+
+      /* check the real source */
+      if (t_allowFrom && !t_allowFrom->match(&conn->d_source)) {
+        if (!g_quiet) {
+          g_log<<Logger::Error<<"["<<MT->getTid()<<"] dropping TCP query from "<<conn->d_source.toString()<<", address not matched by allow-from"<<endl;
+        }
+
+        ++g_stats.unauthorizedTCP;
+        t_fdm->removeReadFD(fd);
+        return;
+      }
+
       conn->data.resize(2);
       conn->state = TCPConnection::BYTE0;
     }
@@ -2280,11 +2293,14 @@ static void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t& )
       return;
     }
 
-    if(t_remotes)
+    if(t_remotes) {
       t_remotes->push_back(addr);
-    if(t_allowFrom && !t_allowFrom->match(&addr)) {
+    }
+
+    bool fromProxyProtocolSource = expectProxyProtocol(addr);
+    if(t_allowFrom && !t_allowFrom->match(&addr) && !fromProxyProtocolSource) {
       if(!g_quiet)
-        g_log<<Logger::Error<<"["<<MT->getTid()<<"] dropping TCP query from "<<addr.toString()<<", address not matched by allow-from"<<endl;
+        g_log<<Logger::Error<<"["<<MT->getTid()<<"] dropping TCP query from "<<addr.toString()<<", address neither matched by allow-from nor proxy-protocol-from"<<endl;
 
       g_stats.unauthorizedTCP++;
       try {
@@ -2295,6 +2311,7 @@ static void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t& )
       }
       return;
     }
+
     if(g_maxTCPPerClient && t_tcpClientCounts->count(addr) && (*t_tcpClientCounts)[addr] >= g_maxTCPPerClient) {
       g_stats.tcpClientOverflow++;
       try {
@@ -2314,7 +2331,7 @@ static void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t& )
     socklen_t len = tc->d_destination.getSocklen();
     getsockname(tc->getFD(), reinterpret_cast<sockaddr*>(&tc->d_destination), &len); // if this fails, we're ok with it
 
-    if (expectProxyProtocol(addr)) {
+    if (fromProxyProtocolSource) {
       tc->proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize;
       tc->data.resize(tc->proxyProtocolNeed);
       tc->state = TCPConnection::PROXYPROTOCOLHEADER;
@@ -2641,7 +2658,7 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
         t_remotes->push_back(fromaddr);
       }
 
-      if(t_allowFrom && !t_allowFrom->match(&fromaddr)) {
+      if(t_allowFrom && !t_allowFrom->match(&source)) {
         if(!g_quiet) {
           g_log<<Logger::Error<<"["<<MT->getTid()<<"] dropping UDP query from "<<fromaddr.toString()<<", address not matched by allow-from"<<endl;
         }
@@ -4169,7 +4186,7 @@ static int serviceMain(int argc, char*argv[])
   g_XPFAcl.toMasks(::arg()["xpf-allow-from"]);
   g_xpfRRCode = ::arg().asNum("xpf-rr-code");
 
-  g_proxyProtocolACL.toMasks(::arg()["proxy-protocol-allow-from"]);
+  g_proxyProtocolACL.toMasks(::arg()["proxy-protocol-from"]);
   g_proxyProtocolMaximumSize = ::arg().asNum("proxy-protocol-maximum-size");
 
   g_networkTimeoutMsec = ::arg().asNum("network-timeout");