README.rst 3 KB
Newer Older
1 2 3 4 5
.. _mod-block:

Query blocking
--------------

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
This module can block queries (and subrequests) 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.

There are two policies implemented:

* ``pattern``
  - applies action if QNAME matches `regular expression <http://lua-users.org/wiki/PatternsTutorial>`_
* ``suffix``
  - 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:

* ``PASS`` - let the query pass through
* ``DENY`` - return NXDOMAIN answer
* ``DROP`` - terminate query resolution, returns SERVFAIL to requestor
23

24 25
.. 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".

26 27 28
Example configuration
^^^^^^^^^^^^^^^^^^^^^

29 30 31 32 33
.. code-block:: lua

	-- Load default block rules
	modules = { 'block' }
	-- Whitelist 'www[0-9].badboy.cz'
34
	block:add(block.pattern(block.PASS, '\4www[0-9]\6badboy\2cz'))
35
	-- Block all names below badboy.cz
36
	block:add(block.suffix(block.DENY, {'\6badboy\2cz'}))
37
	-- Custom rule
38 39 40
	block:add(function (req, query)
		if query:qname():find('%d.%d.%d.224\7in-addr\4arpa') then
			return block.DENY
41 42
		end
	end)
43
	-- Disallow ANY queries
44 45
	block:add(function (req, query)
		if query.type == kres.type.ANY then
46 47 48
			return block.DROP
		end
	end)
49 50 51 52 53 54 55 56 57 58

Properties
^^^^^^^^^^

.. envvar:: block.PASS (number)
.. envvar:: block.DENY (number)
.. envvar:: block.DROP (number)

.. function:: block:add(rule)

59
  :param rule: added rule, i.e. ``block.pattern(block.DENY, '[0-9]+\2cz')``
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
  :param pattern: regular expression
  
  Policy to block queries based on the QNAME regex matching.

.. function:: block.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)

  :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.

78 79 80 81 82 83 84
.. function:: block.suffix_common(action, suffix_table[, common_suffix])

  :param action: action if the pattern matches QNAME
  :param suffix_table: table of valid suffixes
  :param common_suffix: common suffix of entries in suffix_table
  
  Like suffix match, but you can also provide a common suffix of all matches for faster processing (nil otherwise).
85
  This function is faster for small suffix tables (in the order of "hundreds").
86

87 88 89
.. _`Aho-Corasick`: https://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm
.. _`@jgrahamc`: https://github.com/jgrahamc/aho-corasick-lua