From: Remi Gacogne Date: Wed, 5 Jul 2017 15:49:42 +0000 (+0200) Subject: dnsdist: Add support for returning several IPs to spoof from Lua X-Git-Tag: rec-4.1.0-alpha1~27^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F5496%2Fhead;p=thirdparty%2Fpdns.git dnsdist: Add support for returning several IPs to spoof from Lua --- diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index 237f4f0001..19597947ce 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -591,7 +591,7 @@ Valid return values for `LuaAction` functions are: * DNSAction.Nxdomain: return a response with a NXDomain rcode * DNSAction.Pool: use the specified pool to forward this query * DNSAction.Refused: return a response with a Refused rcode - * DNSAction.Spoof: spoof the response using the supplied IPv4 (A), IPv6 (AAAA) or string (CNAME) value + * DNSAction.Spoof: spoof the response using the supplied string (CNAME) value or a comma-separated list of IPv4 (A) or IPv6 (AAAA) * DNSAction.Truncate: return a response with TC=1 The same feature exists to hand off some responses for Lua inspection, using `addLuaResponseAction(x, func)`. diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 9a365662c2..d36512d922 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -809,16 +809,33 @@ catch(...) return 0; } -void spoofResponseFromString(DNSQuestion& dq, const string& spoofContent) +static void spoofResponseFromString(DNSQuestion& dq, const string& spoofContent) { string result; - try { - ComboAddress spoofAddr(spoofContent); - SpoofAction sa({spoofAddr}); - sa(&dq, &result); - } - catch(PDNSException &e) { - SpoofAction sa(spoofContent); // CNAME then + + std::vector addrs; + stringtok(addrs, spoofContent, " ,"); + + if (addrs.size() == 1) { + try { + ComboAddress spoofAddr(spoofContent); + SpoofAction sa({spoofAddr}); + sa(&dq, &result); + } + catch(const PDNSException &e) { + SpoofAction sa(spoofContent); // CNAME then + sa(&dq, &result); + } + } else { + std::vector cas; + for (const auto& addr : addrs) { + try { + cas.push_back(ComboAddress(addr)); + } + catch (...) { + } + } + SpoofAction sa(cas); sa(&dq, &result); } } diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 1b05cb47b6..eaf9394bb7 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -715,7 +715,6 @@ std::shared_ptr wrandom(const NumberedServerVector& servers, co std::shared_ptr whashed(const NumberedServerVector& servers, const DNSQuestion* dq); std::shared_ptr roundrobin(const NumberedServerVector& servers, const DNSQuestion* dq); int getEDNSZ(const char* packet, unsigned int len); -void spoofResponseFromString(DNSQuestion& dq, const string& spoofContent); uint16_t getEDNSOptionCode(const char * packet, size_t len); void dnsdistWebserverThread(int sock, const ComboAddress& local, const string& password, const string& apiKey, const boost::optional >&); bool getMsgLen32(int fd, uint32_t* len); diff --git a/regression-tests.dnsdist/test_Spoofing.py b/regression-tests.dnsdist/test_Spoofing.py index 7c271a0692..ad67dcae6d 100644 --- a/regression-tests.dnsdist/test_Spoofing.py +++ b/regression-tests.dnsdist/test_Spoofing.py @@ -270,7 +270,7 @@ class TestSpoofingLuaSpoof(DNSDistTest): function spoof1rule(dq) if(dq.qtype==1) -- A then - return DNSAction.Spoof, "192.0.2.1" + return DNSAction.Spoof, "192.0.2.1,192.0.2.2" elseif(dq.qtype == 28) -- AAAA then return DNSAction.Spoof, "2001:DB8::1" @@ -302,7 +302,7 @@ class TestSpoofingLuaSpoof(DNSDistTest): 60, dns.rdataclass.IN, dns.rdatatype.A, - '192.0.2.1') + '192.0.2.1', '192.0.2.2') expectedResponse.answer.append(rrset) (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)