diff --git a/doc/modules.rst b/doc/modules.rst index 2bfcc3eeac14c672cf0781b2d6744eb70dd0150c..2a1e4cfd89d73ed1018fa0ae227d5d750e7d9623 100644 --- a/doc/modules.rst +++ b/doc/modules.rst @@ -10,6 +10,7 @@ Implemented modules :local: .. include:: ../modules/hints/README.rst +.. include:: ../modules/block/README.rst .. include:: ../modules/stats/README.rst .. include:: ../modules/cachectl/README.rst .. include:: ../modules/graphite/README.rst diff --git a/modules/block/README.rst b/modules/block/README.rst new file mode 100644 index 0000000000000000000000000000000000000000..9e52d11f8ec03f1112d3888382ffa389b5f14351 --- /dev/null +++ b/modules/block/README.rst @@ -0,0 +1,11 @@ +.. _mod-block: + +Query blocking +-------------- + +This module can block queries (and subqueries) based on user-defined policies. +By default, it blocks queries to reverse lookups in private subnets as per :rfc:`1918`,:rfc:`5735` and :rfc:`5737`. + +Example configuration +^^^^^^^^^^^^^^^^^^^^^ + diff --git a/modules/block/block.lua b/modules/block/block.lua new file mode 100644 index 0000000000000000000000000000000000000000..002ebc5b2de520616777f8fddf4e12e45a6b5ddb --- /dev/null +++ b/modules/block/block.lua @@ -0,0 +1,102 @@ +local block = { + -- Policies + PASS = 1, DENY = 2, DROP = 3, + -- Special values + ANY = 0, + -- Private, local, broadcast, test and special zones + private_zones = { + -- RFC1918 + '10.in-addr.arpa.', + '16.172.in-addr.arpa.', + '17.172.in-addr.arpa.', + '18.172.in-addr.arpa.', + '19.172.in-addr.arpa.', + '20.172.in-addr.arpa.', + '21.172.in-addr.arpa.', + '22.172.in-addr.arpa.', + '23.172.in-addr.arpa.', + '24.172.in-addr.arpa.', + '25.172.in-addr.arpa.', + '26.172.in-addr.arpa.', + '27.172.in-addr.arpa.', + '28.172.in-addr.arpa.', + '29.172.in-addr.arpa.', + '30.172.in-addr.arpa.', + '31.172.in-addr.arpa.', + '168.192.in-addr.arpa.', + -- RFC5735, RFC5737 + '0.in-addr.arpa.', + '127.in-addr.arpa.', + '254.169.in-addr.arpa.', + '2.0.192.in-addr.arpa.', + '100.51.198.in-addr.arpa.', + '113.0.203.in-addr.arpa.', + '255.255.255.255.in-addr.arpa.', + -- IPv6 local, example + '0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.', + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.', + 'd.f.ip6.arpa.', + '8.e.f.ip6.arpa.', + '9.e.f.ip6.arpa.', + 'a.e.f.ip6.arpa.', + 'b.e.f.ip6.arpa.', + '8.b.d.0.1.0.0.2.ip6.arpa', + } +} + +-- @function Block requests which QNAME matches given zone list +function block.in_zone(zone_list) + return function(pkt, qry) + local qname = pkt:qname() + for _,zone in pairs(zone_list) do + if qname:sub(-zone:len()) == zone then + return block.DENY + end + end + return nil + end +end + +-- @function Evaluate packet in given rules to determine block action +function block.evaluate(block, pkt, qry) + for _,rule in pairs(block.rules) do + local action = rule(pkt, qry) + if action then + return action + end + end + return block.PASS +end + +-- @function Block layer implementation +block.layer = { + produce = function(state, data, pkt) + -- Only when a query isn't already answered + if state ~= kres.CONSUME then + return state + end + -- @todo Interpret QUERY (as it has final name) + -- Interpret packet in Lua and evaluate + local pkt = kres.packet(pkt) + local action = block:evaluate(pkt, nil) + if action == block.DENY then + pkt:flag(kres.wire.QR) + pkt:flag(kres.wire.AA) + pkt:flag(kres.wire.CD) + pkt:rcode(kres.rcode.NXDOMAIN) + -- @todo add SOA record + return kres.DONE + elseif action == block.DROP then + return kres.FAIL + else + return state + end + + + end +} + +-- @var Default rules +block.rules = { block.in_zone(block.private_zones) } + +return block diff --git a/modules/block/block.mk b/modules/block/block.mk new file mode 100644 index 0000000000000000000000000000000000000000..fba7b340fefe3fcb38c88d09d36ab32070bd4315 --- /dev/null +++ b/modules/block/block.mk @@ -0,0 +1,2 @@ +block_SOURCES := block.lua +$(call make_lua_module,block) diff --git a/modules/modules.mk b/modules/modules.mk index 41bbb8c90fabd3901ce38ced548c5f16c943439c..1717714590fca54672094a6ee07cce5aae36e9a0 100644 --- a/modules/modules.mk +++ b/modules/modules.mk @@ -15,7 +15,8 @@ endif # List of Lua modules ifeq ($(HAS_lua),yes) modules_TARGETS += ketcd \ - graphite + graphite \ + block endif # List of Golang modules