]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
modules/block -> modules/policy
authorMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 10 Aug 2015 12:55:15 +0000 (14:55 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 10 Aug 2015 12:55:15 +0000 (14:55 +0200)
modules/block/block.mk [deleted file]
modules/modules.mk
modules/policy/README.rst [moved from modules/block/README.rst with 69% similarity]
modules/policy/aho-corasick.lua [moved from modules/block/aho-corasick.lua with 100% similarity]
modules/policy/policy.lua [moved from modules/block/block.lua with 66% similarity]
modules/policy/policy.mk [new file with mode: 0644]

diff --git a/modules/block/block.mk b/modules/block/block.mk
deleted file mode 100644 (file)
index e0acb7f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-block_SOURCES := block.lua aho-corasick.lua
-$(call make_lua_module,block)
index de98b7b9e951d8fef2e962aed59a84a8427c1a89..7c628ea27d971bef839edbae20c3625023b6cba6 100644 (file)
@@ -16,7 +16,7 @@ endif
 ifeq ($(HAS_lua),yes)
 modules_TARGETS += ketcd \
                    graphite \
-                   block \
+                   policy \
                    predict
 endif
 
similarity index 69%
rename from modules/block/README.rst
rename to modules/policy/README.rst
index 0802ba38a6fc14970dc77f14074bf45b879ab03b..a6eb146e592301b8ef7023559ff43727bea4e135 100644 (file)
@@ -1,11 +1,12 @@
-.. _mod-block:
+.. _mod-policy:
 
-Query blocking
+Query policies 
 --------------
 
-This module can block queries (and subrequests) based on user-defined policies.
+This module can block, rewrite, or alter queries 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`.
 You can however extend it to deflect `Slow drip DNS attacks <https://blog.secure64.com/?p=377>`_ for example, or gray-list resolution of misbehaving zones.
+It supports a subset of the ISC RPZ_ format.
 
 There are two policies implemented:
 
@@ -15,11 +16,12 @@ There are two policies implemented:
   - applies action if QNAME suffix matches given list of suffixes (useful for "is domain in zone" rules),
   uses `Aho-Corasick`_ string matching algorithm implemented by `@jgrahamc`_ (CloudFlare, Inc.) (BSD 3-clause)
 
-There are three action:
+There are several defined actions:
 
 * ``PASS`` - let the query pass through
 * ``DENY`` - return NXDOMAIN answer
 * ``DROP`` - terminate query resolution, returns SERVFAIL to requestor
+* ``TC`` - set TC=1 if the request came through UDP, forcing client to retry with TCP
 
 .. note:: The module (and ``kres``) treats domain names as wire, not textual representation. So each label in name is prefixed with its length, e.g. "example.com" equals to "\7example\3com".
 
@@ -28,54 +30,55 @@ Example configuration
 
 .. code-block:: lua
 
-       -- Load default block rules
-       modules = { 'block' }
+       -- Load default policies
+       modules = { 'policy' }
        -- Whitelist 'www[0-9].badboy.cz'
-       block:add(block.pattern(block.PASS, '\4www[0-9]\6badboy\2cz'))
+       policy:add(policy.pattern(policy.PASS, '\4www[0-9]\6badboy\2cz'))
        -- Block all names below badboy.cz
-       block:add(block.suffix(block.DENY, {'\6badboy\2cz'}))
+       policy:add(policy.suffix(policy.DENY, {'\6badboy\2cz'}))
        -- Custom rule
-       block:add(function (req, query)
+       policy:add(function (req, query)
                if query:qname():find('%d.%d.%d.224\7in-addr\4arpa') then
-                       return block.DENY
+                       return policy.DENY
                end
        end)
        -- Disallow ANY queries
-       block:add(function (req, query)
+       policy:add(function (req, query)
                if query.type == kres.type.ANY then
-                       return block.DROP
+                       return policy.DROP
                end
        end)
 
 Properties
 ^^^^^^^^^^
 
-.. envvar:: block.PASS (number)
-.. envvar:: block.DENY (number)
-.. envvar:: block.DROP (number)
+.. envvar:: policy.PASS (number)
+.. envvar:: policy.DENY (number)
+.. envvar:: policy.DROP (number)
+.. envvar:: policy.TC   (number)
 
-.. function:: block:add(rule)
+.. function:: policy:add(rule)
 
-  :param rule: added rule, i.e. ``block.pattern(block.DENY, '[0-9]+\2cz')``
+  :param rule: added rule, i.e. ``policy.pattern(policy.DENY, '[0-9]+\2cz')``
   :param pattern: regular expression
   
   Policy to block queries based on the QNAME regex matching.
 
-.. function:: block.pattern(action, pattern)
+.. function:: policy.pattern(action, pattern)
 
   :param action: action if the pattern matches QNAME
   :param pattern: regular expression
   
   Policy to block queries based on the QNAME regex matching.
 
-.. function:: block.suffix(action, suffix_table)
+.. function:: policy.suffix(action, suffix_table)
 
   :param action: action if the pattern matches QNAME
   :param suffix_table: table of valid suffixes
   
   Policy to block queries based on the QNAME suffix match.
 
-.. function:: block.suffix_common(action, suffix_table[, common_suffix])
+.. function:: policy.suffix_common(action, suffix_table[, common_suffix])
 
   :param action: action if the pattern matches QNAME
   :param suffix_table: table of valid suffixes
@@ -86,4 +89,4 @@ Properties
 
 .. _`Aho-Corasick`: https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm
 .. _`@jgrahamc`: https://github.com/jgrahamc/aho-corasick-lua
-
+.. _RPZ: https://dnsrpz.info/
similarity index 66%
rename from modules/block/block.lua
rename to modules/policy/policy.lua
index 399b1af4d12746c8092a873b3062ab6ebf62f0c6..b4b71231aa6cbaeb0c69ff732eb23c108fa4b900 100644 (file)
@@ -1,13 +1,13 @@
 local kres = require('kres')
-local block = {
+local policy = {
        -- Policies
-       PASS = 1, DENY = 2, DROP = 3,
+       PASS = 1, DENY = 2, DROP = 3, TC = 4,
        -- Special values
        ANY = 0,
 }
 
--- @function Block requests which QNAME matches given zone list (i.e. suffix match)
-function block.suffix(action, zone_list)
+-- @function Requests which QNAME matches given zone list (i.e. suffix match)
+function policy.suffix(action, zone_list)
        local AC = require('aho-corasick')
        local tree = AC.build(zone_list)
        return function(req, query)
@@ -20,7 +20,7 @@ function block.suffix(action, zone_list)
 end
 
 -- @function Check for common suffix first, then suffix match (specialized version of suffix match)
-function block.suffix_common(action, suffix_list, common_suffix)
+function policy.suffix_common(action, suffix_list, common_suffix)
        local common_len = string.len(common_suffix)
        local suffix_count = #suffix_list
        return function(req, query)
@@ -40,8 +40,8 @@ function block.suffix_common(action, suffix_list, common_suffix)
        end
 end
 
--- @function Block QNAME pattern
-function block.pattern(action, pattern)
+-- @function policy QNAME pattern
+function policy.pattern(action, pattern)
        return function(req, query)
                if string.find(query:name(), pattern) then
                        return action
@@ -50,44 +50,51 @@ function block.pattern(action, pattern)
        end
 end
 
--- @function Evaluate packet in given rules to determine block action
-function block.evaluate(block, req, query)
-       for i = 1, #block.rules do
-               local action = block.rules[i](req, query)
+-- @function Evaluate packet in given rules to determine policy action
+function policy.evaluate(policy, req, query)
+       for i = 1, #policy.rules do
+               local action = policy.rules[i](req, query)
                if action ~= nil then
                        return action
                end
        end
-       return block.PASS
+       return policy.PASS
 end
 
--- @function Block layer implementation
-block.layer = {
+-- @function policy layer implementation
+policy.layer = {
        begin = function(state, req)
                req = kres.request_t(req)
-               local action = block:evaluate(req, req:current())
-               if action == block.DENY then
+               local action = policy:evaluate(req, req:current())
+               if action == policy.DENY then
                        -- Write authority information
                        local answer = req.answer
                        answer:rcode(kres.rcode.NXDOMAIN)
                        answer:begin(kres.section.AUTHORITY)
-                       answer:put('\5block', 900, answer:qclass(), kres.type.SOA,
-                               '\5block\0\0\0\0\0\0\0\0\14\16\0\0\3\132\0\9\58\128\0\0\3\132')
+                       answer:put('\7blocked', 900, answer:qclass(), kres.type.SOA,
+                               '\7blocked\0\0\0\0\0\0\0\0\14\16\0\0\3\132\0\9\58\128\0\0\3\132')
                        return kres.DONE
-               elseif action == block.DROP then
+               elseif action == policy.DROP then
                        return kres.FAIL
+               elseif action == policy.TC then
+                       local answer = req.answer
+                       print(answer.max_size)
+                       if answer.max_size ~= 65535 then
+                               answer:tc(1) -- ^ Only UDP queries
+                               return kres.DONE
+                       end
                end
                return state
        end
 }
 
--- @function Add rule to block list
-function block.add(block, rule)
-       return table.insert(block.rules, rule)
+-- @function Add rule to policy list
+function policy.add(policy, rule)
+       return table.insert(policy.rules, rule)
 end
 
 -- @function Convert list of string names to domain names
-function block.to_domains(names)
+function policy.to_domains(names)
        for i, v in ipairs(names) do
                names[i] = v:gsub('([^.]*%.)', function (x)
                        return string.format('%s%s', string.char(x:len()-1), x:sub(1,-2))
@@ -133,9 +140,9 @@ local private_zones = {
        'b.e.f.ip6.arpa.',
        '8.b.d.0.1.0.0.2.ip6.arpa',
 }
-block.to_domains(private_zones)
+policy.to_domains(private_zones)
 
 -- @var Default rules
-block.rules = { block.suffix_common(block.DENY, private_zones, '\4arpa') }
+policy.rules = { policy.suffix_common(policy.DENY, private_zones, '\4arpa') }
 
-return block
+return policy
diff --git a/modules/policy/policy.mk b/modules/policy/policy.mk
new file mode 100644 (file)
index 0000000..f859ac9
--- /dev/null
@@ -0,0 +1,2 @@
+policy_SOURCES := policy.lua aho-corasick.lua
+$(call make_lua_module,policy)