]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
datamodel: policy: added Lua template
authorAleš <ales.mrazek@nic.cz>
Wed, 15 Dec 2021 18:11:14 +0000 (19:11 +0100)
committerAleš Mrázek <ales.mrazek@nic.cz>
Fri, 8 Apr 2022 14:17:53 +0000 (16:17 +0200)
- new jinja2 macros

manager/knot_resolver_manager/datamodel/policy_schema.py
manager/knot_resolver_manager/datamodel/templates/config.lua.j2
manager/knot_resolver_manager/datamodel/templates/macros/common_macros.lua.j2
manager/knot_resolver_manager/datamodel/templates/macros/policy_macros.lua.j2
manager/knot_resolver_manager/datamodel/templates/policy.lua.j2 [new file with mode: 0644]

index 87f74e2b6fc45891e137212091593bda864c8c44..a159e450b6c11aea09068fa42d8e71e54ad32307 100644 (file)
@@ -1,13 +1,12 @@
 from typing import List, Optional
 
 from knot_resolver_manager.datamodel.network_schema import AddressRenumberingSchema
-from knot_resolver_manager.datamodel.types import ActionEnum, DomainName, IPAddressPort, QTypeEnum, TimeUnit
+from knot_resolver_manager.datamodel.types import ActionEnum, IPAddressPort, QTypeEnum, TimeUnit
 from knot_resolver_manager.datamodel.view_schema import FlagsEnum
 from knot_resolver_manager.utils import SchemaNode
 
 
 class FilterSchema(SchemaNode):
-    domain: Optional[List[DomainName]] = None
     suffix: Optional[List[str]] = None
     pattern: Optional[List[str]] = None
     qtype: Optional[List[QTypeEnum]] = None
index 29af22378aa3361656f2a45b9f435d11a4237516..a8ef7d7b136204ba086140ae5b3a4bcc5d6499bb 100644 (file)
@@ -18,6 +18,9 @@
 -- VIEWS section
 {% include "views.lua.j2" %}
 
+-- POLICY section
+{% include "policy.lua.j2" %}
+
 -- RPZ section
 {% include "rpz.lua.j2" %}
 
index 31f9f176de2e7b6096eec6fd558e49c9833f5927..af8a5d76f0fef823d6dabf6dd35dd97edc363f6b 100644 (file)
@@ -24,6 +24,19 @@ kres.str2ip('{{ item|string }}'),
 {%- endif -%}
 {%- endmacro %}
 
+{# Return qtype or table of qtype #}
+{% macro qtype_table(table) -%}
+{%- if table is string -%}
+kres.type.{{ table|string }}
+{%- else-%}
+{
+{%- for item in table -%}
+kres.type.{{ item|string }},
+{%- endfor -%}
+}
+{%- endif -%}
+{%- endmacro %}
+
 {# Return server address or table of server addresses #}
 {% macro servers_table(servers) -%}
 {%- if servers is string -%}
@@ -77,4 +90,4 @@ pin_sha256=
 },
 {%- endif -%}
 {%- endif -%}
-{%- endmacro %}
\ No newline at end of file
+{%- endmacro %}
index c52c831da5202de15529e18b368e15afc2176340..9e11ea51c13a9187521fd95ecf193405e58fa5cc 100644 (file)
@@ -1,13 +1,17 @@
-{% from 'macros/common_macros.lua.j2' import string_table, str2ip_table, servers_table, tls_servers_table %}
+{% from 'macros/common_macros.lua.j2' import string_table, str2ip_table, qtype_table, servers_table, tls_servers_table %}
+
+
+{# Add policy #}
 
 {% macro policy_add(rule, postrule=false) -%}
 {%- if postrule -%}
 policy.add({{ rule }}, true)
-{% else %}
+{%- else -%}
 policy.add({{ rule }})
-{% endif %}
+{%- endif -%}
 {%- endmacro %}
 
+
 {# Flags #}
 
 {% macro policy_flags(flags) -%}
@@ -18,6 +22,7 @@ policy.FLAGS({
 })
 {%- endmacro %}
 
+
 {# Filters #}
 
 {% macro policy_all(action) -%}
@@ -28,6 +33,10 @@ policy.all({{ action }})
 policy.suffix({{ action }}, {{ suffix_table }})
 {%- endmacro %}
 
+{% macro policy_suffix_common(action, suffix_table, common_suffix) -%}
+policy.suffix_common({{ action }}, {{ suffix_table }}, {{ common_suffix }})
+{%- endmacro %}
+
 {% macro policy_pattern(action, pattern) -%}
 policy.pattern({{ action }}, {{ pattern }})
 {%- endmacro %}
@@ -36,6 +45,54 @@ policy.pattern({{ action }}, {{ pattern }})
 policy.rpz({{ action|string }}, '{{ path|string }}', {{ 'true' if watch else 'false' }})
 {%- endmacro %}
 
+
+{# Custom filters #}
+
+{% macro declare_policy_qtype_custom_filter() -%}
+function policy_qtype(action, qtype)
+
+    local function has_value (tab, val)
+        for index, value in ipairs(tab) do
+            if value == val then
+                return true
+            end
+        end
+
+        return false
+    end
+
+    return function (state, query)
+        if query.stype == qtype then
+            return action
+        elseif has_value(qtype, query.stype) then
+            return action
+        else
+            return nil
+        end
+    end
+end
+{%- endmacro %}
+
+{% macro policy_qtype_custom_filter(action, qtype) -%}
+policy_qtype({{ action }}, {{ qtype }})
+{%- endmacro %}
+
+
+{# Auto Filter #}
+
+{% macro policy_auto_filter(action, filter=none) -%}
+{%- if filter.suffix -%}
+{{ policy_suffix(action, policy_todname(filter.suffix)) }}
+{%- elif filter.pattern -%}
+{{ policy_pattern(action, filter.pattern) }}
+{%- elif filter.qtype -%}
+{{ policy_qtype_custom_filter(action, qtype_table(filter.qtype)) }}
+{%- else -%}
+{{ policy_all(action) }}
+{%- endif %}
+{%- endmacro %}
+
+
 {# Non-chain actions #}
 
 {% macro policy_pass() -%}
@@ -58,6 +115,16 @@ policy.DROP
 policy.REFUSE
 {%- endmacro %}
 
+{% macro policy_tc() -%}
+policy.TC
+{%- endmacro %}
+
+{% macro policy_reroute(reroute) -%}
+policy.REROUTE({
+{# TODO: completion of this action #}
+})
+{%- endmacro %}
+
 {% macro policy_answer(answer) -%}
 policy.ANSWER({ [kres.type.{{ answer.query_type }}] = { rdata=
 {%- if answer.query_type == 'A' -%}
@@ -74,20 +141,38 @@ ttl={{ answer.ttl.seconds()|int }},
 } }, nodata={{ 'true' if answer.nodata else 'false' }} )
 {%- endmacro %}
 
-{% macro policy_action(policy) -%}
-{%- if policy.action == 'pass' -%}
-{{ policy_pass()|string }}
-{%- elif policy.action == 'deny' -%}
-{%- if policy.message -%}
-{{ policy_deny_msg(policy.message)|string }}
-{%- else -%}
-{{ policy_deny()|string }}
-{%- endif -%}
-{# TODO: do same for other actions #}
+
+{# Chain actions #}
+
+{% macro policy_mirror(mirror) -%}
+policy.MIRROR(
+{% if mirror is string %}
+'{{ mirror }}'
+{% else %}
+{
+{%- for addr in mirror -%}
+'{{ addr }}',
+{%- endfor -%}
+}
 {%- endif -%}
+)
 {%- endmacro %}
 
-{# Chain actions #}
+{% macro policy_debug_always() -%}
+policy.DEBUG_ALWAYS
+{%- endmacro %}
+
+{% macro policy_debug_cache_miss() -%}
+policy.DEBUG_CACHE_MISS
+{%- endmacro %}
+
+{% macro policy_qtrace() -%}
+policy.QTRACE
+{%- endmacro %}
+
+{% macro policy_reqtrace() -%}
+policy.REQTRACE
+{%- endmacro %}
 
 {% macro policy_stub(servers) -%}
 policy.STUB({{ servers_table(servers) }})
@@ -101,7 +186,43 @@ policy.FORWARD({{ servers_table(servers) }})
 policy.TLS_FORWARD({{ tls_servers_table(servers) }})
 {%- endmacro %}
 
-{# other #}
+
+{# Auto Action #}
+
+{% macro policy_auto_action(rule) -%}
+{%- if rule.action == 'pass' -%}
+{{ policy_pass()|string }}
+{%- elif rule.action == 'deny' -%}
+{%- if rule.message -%}
+{{ policy_deny_msg(rule.message)|string }}
+{%- else -%}
+{{ policy_deny()|string }}
+{%- endif -%}
+{%- elif rule.action == 'drop' -%}
+{{ policy_drop() }}
+{%- elif rule.action == 'refuse' -%}
+{{ policy_refuse() }}
+{%- elif rule.action == 'tc' -%}
+{{ policy_tc() }}
+{%- elif rule.action == 'reroute' -%}
+{{ policy_reroute(rule.reroute) }}
+{%- elif rule.action == 'answer' -%}
+{{ policy_answer(rule.answer) }}
+{%- elif rule.action == 'mirror' -%}
+{{ policy_mirror(rule.mirror) }}
+{%- elif rule.action == 'debug-always' -%}
+{{ policy_debug_always() }}
+{%- elif rule.action == 'debug-cache-miss' -%}
+{{ policy_sebug_cache_miss() }}
+{%- elif rule.action == 'qtrace' -%}
+{{ policy_qtrace() }}
+{%- elif rule.action == 'reqtrace' -%}
+{{ policy_reqtrace() }}
+{%- endif -%}
+{%- endmacro %}
+
+
+{# Other #}
 
 {% macro policy_todname(names) -%}
 policy.todnames({
diff --git a/manager/knot_resolver_manager/datamodel/templates/policy.lua.j2 b/manager/knot_resolver_manager/datamodel/templates/policy.lua.j2
new file mode 100644 (file)
index 0000000..688e0fe
--- /dev/null
@@ -0,0 +1,64 @@
+{% from 'macros/policy_macros.lua.j2' import declare_policy_qtype_custom_filter, policy_flags, policy_add, policy_auto_filter, policy_auto_action %}
+{% from 'macros/view_macros.lua.j2' import view_tsig, view_addr %}
+
+{% if cfg.policy -%}
+
+-- query type based custom policy filter
+{{ declare_policy_qtype_custom_filter() }}
+
+{% for id, rule in cfg.policy.items() %}
+-- policy rule: {{ id }}
+{% if rule.views -%}
+{# views set for rule #}
+{% for view_id in rule.views -%}
+{%- set view = cfg.views[view_id] -%}
+
+{# merge options from view and forward-zone #}
+{%- set options = none -%}
+{% if rule.options and view.options -%}
+{% set options = rule.options|list + view.options|list %}
+{% elif rule.options %}
+{% set options = rule.options|list %}
+{% elif view.options %}
+{% set options = view.options|list %}
+{%- endif %}
+
+{# view tsig #}
+{% if view.tsig -%}
+{% for tsig in view.tsig -%}
+
+{% if options -%}
+{{ view_tsig(tsig|string, policy_auto_filter(policy_flags(options|list), rule.filter)) }}
+{%- endif %}
+
+{{ view_tsig(tsig|string, policy_auto_filter(policy_auto_action(rule), rule.filter)) }}
+
+{% endfor %}
+{% endif -%}
+
+{# view addr #}
+{% if view.subnets -%}
+{% for addr in view.subnets -%}
+
+{% if options -%}
+{{ view_addr(addr|string, policy_auto_filter(policy_flags(options|list), rule.filter)) }}
+{%- endif %}
+
+{{ view_addr(addr|string, policy_auto_filter(policy_auto_action(rule), rule.filter)) }}
+
+{% endfor %}
+{% endif %}
+
+{%- endfor -%}
+{%- else -%}
+{# no views set for policy rule #}
+
+{% if rule.options -%}
+{{ policy_add(policy_auto_filter(policy_flags(rule.options|list), rule.filter)) }}
+{%- endif %}
+
+{{ policy_add(policy_auto_filter(policy_auto_action(rule), rule.filter)) }}
+
+{% endif %}
+{% endfor %}
+{% endif %}
\ No newline at end of file