return true;
});
- luaCtx.registerFunction<void (DNSQuestion::*)(const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>&, std::optional<uint16_t>)>("spoof", [](DNSQuestion& dnsQuestion, const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>& response, std::optional<uint16_t> typeForAny) {
+ luaCtx.registerFunction<void (DNSQuestion::*)(const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>&, std::optional<uint16_t>, std::optional<uint32_t>)>("spoof", [](DNSQuestion& dnsQuestion, const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>& response, std::optional<uint16_t> typeForAny, std::optional<uint32_t> ttl) {
dnsdist::ResponseConfig responseConfig;
+ responseConfig.ttl = ttl.value_or(60);
if (response.type() == typeid(LuaArray<ComboAddress>)) {
std::vector<ComboAddress> data;
auto responses = boost::get<LuaArray<ComboAddress>>(response);
:param string tail: The new data
:returns: true if the operation succeeded, false otherwise
- .. method:: spoof(ip|ips|raw|raws [, typeForAny])
+ .. method:: spoof(ip|ips|raw|raws [, typeForAny[, ttl]])
.. versionchanged:: 1.9.0
Optional parameter ``typeForAny`` added.
+ .. versionchanged:: 2.2.0
+ Optional parameter ``ttl`` added.
+
Forge a response with the specified record data as raw bytes. If you specify list of raws (it is assumed they match the query type), all will get spoofed in.
:param ComboAddress ip: The `ComboAddress` to be spoofed, e.g. `newCA("192.0.2.1")`.
:param string raw: The raw string to be spoofed, e.g. `"\\192\\000\\002\\001"`.
:param table raws: The raw strings to be spoofed, e.g. `{ "\\192\\000\\002\\001", "\\192\\000\\002\\002" }`.
:param int typeForAny: The type to use for raw responses when the requested type is ``ANY``, as using ``ANY`` for the type of the response record would not make sense.
+ :param int ttl: The TTL to set for the spoofed response, with a default value of 60.
.. method:: suspend(asyncID, queryID, timeoutMS) -> bool
self.checkMessageNoEDNS(expectedResponse, receivedResponse)
self.assertEqual(receivedResponse.answer[0].ttl, 60)
+ def testSpoofLuaTtl(self):
+ """
+ Spoofing: With a TTL
+ """
+ name = "lua-ttl.spoofing.tests.powerdns.com."
+ query = dns.message.make_query(name, "A", "IN")
+ query.flags &= ~dns.flags.RD
+ expectedResponse = dns.message.make_response(query)
+ expectedResponse.flags &= ~dns.flags.AA
+ rrset = dns.rrset.from_text(name, 300, dns.rdataclass.IN, dns.rdatatype.A, "192.0.2.1")
+ expectedResponse.answer.append(rrset)
+
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (_, receivedResponse) = sender(query, response=None, useQueue=False)
+ self.assertTrue(receivedResponse)
+ self.assertEqual(expectedResponse, receivedResponse)
+ self.assertEqual(receivedResponse.answer[0].ttl, 300)
+
class TestSpoofingViaLuaConfig(DNSDistTest, SpoofingTests):
_config_template = """
+ function spoofWithTTL(dq)
+ if(dq.qtype==DNSQType.A)
+ then
+ dq:spoof({ newCA("192.0.2.1") }, nil, 300)
+ return DNSAction.HeaderModify
+ else
+ return DNSAction.None
+ end
+ end
+
addAction(SuffixMatchNodeRule("spoofaction.spoofing.tests.powerdns.com."), SpoofAction({"192.0.2.1", "2001:DB8::1"}))
addAction(SuffixMatchNodeRule("spoofaction-aa.spoofing.tests.powerdns.com."), SpoofAction({"192.0.2.1", "2001:DB8::1"}, {aa=true}))
addAction(SuffixMatchNodeRule("spoofaction-ad.spoofing.tests.powerdns.com."), SpoofAction({"192.0.2.1", "2001:DB8::1"}, {ad=true}))
addAction(AndRule{SuffixMatchNodeRule("multiraw.spoofing.tests.powerdns.com"), QTypeRule(DNSQType.A)}, SpoofRawAction({"\\192\\000\\002\\001", "\\192\\000\\002\\002"}))
-- rfc8482
addAction(AndRule{SuffixMatchNodeRule("raw-any.spoofing.tests.powerdns.com"), QTypeRule(DNSQType.ANY)}, SpoofRawAction("\\007rfc\\056\\052\\056\\050\\000", { typeForAny=DNSQType.HINFO }))
+ addAction(SuffixMatchNodeRule("lua-ttl.spoofing.tests.powerdns.com."), LuaAction(spoofWithTTL))
newServer{address="127.0.0.1:%d"}
"""
- '\\007rfc\\056\\052\\056\\050\\000'
vars:
ttl: 60
+ - selector:
+ type: "QNameSuffix"
+ suffixes:
+ - "lua-ttl.spoofing.tests.powerdns.com."
+ action:
+ type: "Lua"
+ function_code: |
+ return function(dq)
+ if(dq.qtype==DNSQType.A)
+ then
+ dq:spoof({ newCA("192.0.2.1") }, nil, 300)
+ return DNSAction.HeaderModify
+ else
+ return DNSAction.None
+ end
+ end
"""
_yaml_config_params = ["_testServerPort"]
_config_params = []