class DNSAction
{
public:
- enum class Action : uint8_t { Drop, Nxdomain, Refused, Spoof, Allow, HeaderModify, Pool, Delay, Truncate, ServFail, None, NoOp, NoRecurse, SpoofRaw };
+ enum class Action : uint8_t { Drop, Nxdomain, Refused, Spoof, Allow, HeaderModify, Pool, Delay, Truncate, ServFail, None, NoOp, NoRecurse, SpoofRaw, SpoofPacket };
static std::string typeToString(const Action& action)
{
switch(action) {
return "Send Refused";
case Action::Spoof:
return "Spoof an answer";
+ case Action::SpoofPacket:
+ return "Spoof a raw answer from bytes";
case Action::SpoofRaw:
return "Spoof an answer from raw bytes";
case Action::Allow:
.. versionchanged:: 1.5.0
``DNSAction.SpoofRaw`` has been added.
+.. versionchanged:: 1.8.0
+ ``DNSAction.SpoofPacket`` has been added.
+
These constants represent an Action that can be returned from :func:`LuaAction` functions.
* ``DNSAction.Allow``: let the query pass, skipping other rules
* ``DNSAction.Refused``: return a response with a Refused rcode
* ``DNSAction.ServFail``: return a response with a ServFail rcode
* ``DNSAction.Spoof``: spoof the response using the supplied IPv4 (A), IPv6 (AAAA) or string (CNAME) value. TTL will be 60 seconds.
+ * ``DNSAction.SpoofPacket``: spoof the response using the supplied raw packet
* ``DNSAction.SpoofRaw``: spoof the response using the supplied raw value as record data (see also :meth:`DNSQuestion:spoof` and :func:`dnsdist_ffi_dnsquestion_spoof_raw` to spoof multiple values)
* ``DNSAction.Truncate``: truncate the response
* ``DNSAction.NoRecurse``: set rd=0 on the query
class TestSpoofingLuaSpoofPacket(DNSDistTest):
_config_template = """
- local ffi = require("ffi")
function spoofpacket(dq)
- -- REFUSED answer
- local rawResponse="\\000\\000\\129\\133\\000\\001\\000\\000\\000\\000\\000\\000\\014lua\\045raw\\045packet\\012ffi\\045spoofing\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001"
+ if dq.qtype == DNSQType.A then
+ return DNSAction.SpoofPacket, "\\000\\000\\129\\133\\000\\001\\000\\000\\000\\000\\000\\000\\014lua\\045raw\\045packet\\008spoofing\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001"
+ end
+ return DNSAction.None, ""
+ end
+
+ addAction("lua-raw-packet.spoofing.tests.powerdns.com.", LuaAction(spoofpacket))
+ local rawResponse="\\000\\000\\129\\133\\000\\001\\000\\000\\000\\000\\000\\000\\019rule\\045lua\\045raw\\045packet\\008spoofing\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001"
+ addAction(AndRule{QTypeRule(DNSQType.A), makeRule("rule-lua-raw-packet.spoofing.tests.powerdns.com.")}, SpoofPacketAction(rawResponse, string.len(rawResponse)))
+
+ local ffi = require("ffi")
+
+ function spoofpacketffi(dq)
local qtype = ffi.C.dnsdist_ffi_dnsquestion_get_qtype(dq)
- ffi.C.dnsdist_ffi_dnsquestion_spoof_packet(dq, rawResponse, string.len(rawResponse))
- return DNSAction.HeaderModify
+ if qtype == DNSQType.A then
+ -- REFUSED answer
+ local refusedResponse="\\000\\000\\129\\133\\000\\001\\000\\000\\000\\000\\000\\000\\014lua\\045raw\\045packet\\012ffi\\045spoofing\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001"
+
+ ffi.C.dnsdist_ffi_dnsquestion_spoof_packet(dq, refusedResponse, string.len(refusedResponse))
+ return DNSAction.HeaderModify
+ end
+ return DNSAction.None, ""
end
- addAction("lua-raw-packet.ffi-spoofing.tests.powerdns.com.", LuaFFIAction(spoofpacket))
- local otherResponse="\\000\\000\\129\\133\\000\\001\\000\\000\\000\\000\\000\\000\\014lua\\045raw\\045packet\\008spoofing\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001"
- addAction("lua-raw-packet.spoofing.tests.powerdns.com.", SpoofPacketAction(otherResponse, string.len(otherResponse)))
+ addAction("lua-raw-packet.ffi-spoofing.tests.powerdns.com.", LuaFFIAction(spoofpacketffi))
newServer{address="127.0.0.1:%s"}
"""
_verboseMode = True
- def testLuaFFISpoofPacket(self):
+ def testLuaSpoofPacket(self):
"""
Spoofing via Lua FFI: Spoof raw response via Lua FFI
"""
- name = 'lua-raw-packet.ffi-spoofing.tests.powerdns.com.'
+ for name in ('lua-raw-packet.spoofing.tests.powerdns.com.', 'rule-lua-raw-packet.spoofing.tests.powerdns.com.'):
- #
- query = dns.message.make_query(name, 'A', 'IN')
- expectedResponse = dns.message.make_response(query)
- expectedResponse.flags |= dns.flags.RA
- expectedResponse.set_rcode(dns.rcode.REFUSED)
+ query = dns.message.make_query(name, 'A', 'IN')
+ expectedResponse = dns.message.make_response(query)
+ expectedResponse.flags |= dns.flags.RA
+ expectedResponse.set_rcode(dns.rcode.REFUSED)
- for method in ("sendUDPQuery", "sendTCPQuery"):
- sender = getattr(self, method)
- (_, receivedResponse) = sender(query, response=None, useQueue=False)
- self.assertTrue(receivedResponse)
- self.assertEqual(expectedResponse, receivedResponse)
+ for method in ("sendUDPQuery", "sendTCPQuery"):
+ sender = getattr(self, method)
+ (_, receivedResponse) = sender(query, response=None, useQueue=False)
+ self.assertTrue(receivedResponse)
+ self.assertEqual(expectedResponse, receivedResponse)
- def testLuaSpoofPacket(self):
+ def testLuaFFISpoofPacket(self):
"""
- Spoofing via Lua : Spoof raw response via Lua
+ Spoofing via Lua FFI: Spoof raw response via Lua FFI
"""
- name = 'lua-raw-packet.spoofing.tests.powerdns.com.'
+ name = 'lua-raw-packet.ffi-spoofing.tests.powerdns.com.'
#
query = dns.message.make_query(name, 'A', 'IN')