]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
datamodel: rpz: Lua configuration
authorAleš <ales.mrazek@nic.cz>
Tue, 7 Dec 2021 00:30:32 +0000 (01:30 +0100)
committerAleš Mrázek <ales.mrazek@nic.cz>
Fri, 8 Apr 2022 14:17:53 +0000 (16:17 +0200)
- templates: common macros
- templates: added a few more policy maros

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

index 0f53a31653e197d2e6750d25fcd57485dd599f94..a490ba075e96c05f07c988632c13c0851ab19bd3 100644 (file)
@@ -53,7 +53,7 @@ class KresConfig(SchemaNode):
         static_hints: StaticHintsSchema = StaticHintsSchema()
         views: Optional[Dict[str, ViewSchema]] = None
         policy: Optional[Dict[str, PolicySchema]] = None
-        rpz: Optional[Dict[DomainName, RPZSchema]] = None
+        rpz: Optional[Dict[str, RPZSchema]] = None
         stub_zones: Optional[Dict[DomainName, StubZoneSchema]] = None
         forward_zones: Optional[Dict[DomainName, ForwardZoneSchema]] = None
         cache: CacheSchema = CacheSchema()
@@ -70,7 +70,7 @@ class KresConfig(SchemaNode):
     static_hints: StaticHintsSchema
     views: Optional[Dict[str, ViewSchema]]
     policy: Optional[Dict[str, PolicySchema]]
-    rpz: Optional[Dict[DomainName, RPZSchema]]
+    rpz: Optional[Dict[str, RPZSchema]]
     stub_zones: Optional[Dict[DomainName, StubZoneSchema]]
     forward_zones: Optional[Dict[DomainName, ForwardZoneSchema]]
     cache: CacheSchema
@@ -90,4 +90,6 @@ class KresConfig(SchemaNode):
         return obj.dns64
 
     def render_lua(self) -> Text:
-        return _MAIN_TEMPLATE.render(cfg=self)
+        lua = _MAIN_TEMPLATE.render(cfg=self)
+        print(lua)
+        return lua
index c9bd059dd91a5e3443f46265a6169f5495c086db..af8a3138faacbcf67e13edc24d682518e91d0edc 100644 (file)
@@ -10,6 +10,6 @@ class RPZSchema(SchemaNode):
     action: ActionEnum
     file: AnyPath
     watch: bool = True
-    message: Optional[str] = None
-    views: Optional[str] = None
+    views: Optional[List[str]] = None
     options: Optional[List[FlagsEnum]] = None
+    message: Optional[str] = None
index f8dbcfd967aed65a65d55b267232288ab6af1049..29af22378aa3361656f2a45b9f435d11a4237516 100644 (file)
@@ -18,6 +18,9 @@
 -- VIEWS section
 {% include "views.lua.j2" %}
 
+-- RPZ section
+{% include "rpz.lua.j2" %}
+
 -- STUB-ZONES section
 {% include "stub_zones.lua.j2" %}
 
diff --git a/manager/knot_resolver_manager/datamodel/templates/macros/common_macros.lua.j2 b/manager/knot_resolver_manager/datamodel/templates/macros/common_macros.lua.j2
new file mode 100644 (file)
index 0000000..31f9f17
--- /dev/null
@@ -0,0 +1,80 @@
+{# Return string or table of strings #}
+{% macro string_table(table) -%}
+{%- if table is string -%}
+'{{ table|string }}'
+{%- else-%}
+{
+{%- for item in table -%}
+'{{ item|string }}',
+{%- endfor -%}
+}
+{%- endif -%}
+{%- endmacro %}
+
+{# Return str2ip or table of str2ip #}
+{% macro str2ip_table(table) -%}
+{%- if table is string -%}
+kres.str2ip('{{ table|string }}')
+{%- else-%}
+{
+{%- for item in table -%}
+kres.str2ip('{{ item|string }}'),
+{%- endfor -%}
+}
+{%- endif -%}
+{%- endmacro %}
+
+{# Return server address or table of server addresses #}
+{% macro servers_table(servers) -%}
+{%- if servers is string -%}
+'{{ servers|string }}'
+{%- else-%}
+{
+{%- for item in servers -%}
+{%- if item.address -%}
+'{{ item.address|string }}',
+{%- else -%}
+'{{ item|string }}',
+{%- endif -%}
+{%- endfor -%}
+}
+{%- endif -%}
+{%- endmacro %}
+
+{# Return server address or table of server addresses #}
+{% macro tls_servers_table(servers) -%}
+{%- if servers is string -%}
+'{{ servers|string }}', {{ tls_server_auth(servers) }}
+{%- else-%}
+{
+{%- for item in servers -%}
+{%- if item.address -%}
+{'{{ item.address|string }}', {{ tls_server_auth(item) }} },
+{%- else -%}
+'{{ item|string }}',
+{%- endif -%}
+{%- endfor -%}
+}
+{%- endif -%}
+{%- endmacro %}
+
+{% macro tls_server_auth(server) -%}
+{%- if server.hostname -%}
+hostname='{{ server.hostname|string }}',
+{%- endif -%}
+{%- if server.ca_file -%}
+ca_file='{{ server.ca_file|string }}',
+{%- endif -%}
+{%- if server.pin_sha256 -%}
+pin_sha256=
+{%- if server.pin_sha256 is string -%}
+'{{ server.pin_sha256|string }}',
+{%- else -%}
+{
+{%- for pin in server.pin_sha256 -%}
+'{{ pin|string }}',
+{%- endfor -%}
+},
+{%- endif -%}
+{%- endif -%}
+{%- endmacro %}
\ No newline at end of file
index 5e5044e3ef684e3e1bf709c23742d030fdd26f95..c52c831da5202de15529e18b368e15afc2176340 100644 (file)
-{% macro policy_add(rule) -%}
+{% from 'macros/common_macros.lua.j2' import string_table, str2ip_table, servers_table, tls_servers_table %}
+
+{% macro policy_add(rule, postrule=false) -%}
+{%- if postrule -%}
+policy.add({{ rule }}, true)
+{% else %}
 policy.add({{ rule }})
+{% endif %}
 {%- endmacro %}
 
+{# Flags #}
 
 {% macro policy_flags(flags) -%}
 policy.FLAGS({
-{%- for flag in flags -%}
+{%- for flag in flags|list -%}
 '{{ flag.upper().replace("-", "_") }}',
 {%- endfor -%}
 })
 {%- endmacro %}
 
+{# Filters #}
+
+{% macro policy_all(action) -%}
+policy.all({{ action }})
+{%- endmacro %}
 
 {% macro policy_suffix(action, suffix_table) -%}
 policy.suffix({{ action }}, {{ suffix_table }})
 {%- endmacro %}
 
+{% macro policy_pattern(action, pattern) -%}
+policy.pattern({{ action }}, {{ pattern }})
+{%- endmacro %}
 
-{% macro policy_stub(servers) -%}
-policy.STUB({
-{%- if servers is string %}
-'{{ addresses|string }}'
-{%- else -%}
-{%- for server in servers -%}
-{%- if server.address %}
-'{{ server.address|string }}',
-{%- else -%}
-'{{ server|string }}',
-{%- endif -%}
-{%- endfor -%}
-{%- endif -%}
-})
+{% macro policy_rpz(action, path, watch) -%}
+policy.rpz({{ action|string }}, '{{ path|string }}', {{ 'true' if watch else 'false' }})
 {%- endmacro %}
 
+{# Non-chain actions #}
 
-{% macro policy_forward(servers) -%}
-policy.FORWARD({
-{%- if servers is string %}
-'{{ addresses|string }}'
-{%- else -%}
-{%- for server in servers -%}
-{%- if server.address %}
-'{{ server.address|string }}',
-{%- else -%}
-'{{ server|string }}',
-{%- endif -%}
-{%- endfor -%}
-{%- endif -%}
-})
+{% macro policy_pass() -%}
+policy.PASS
 {%- endmacro %}
 
+{% macro policy_deny() -%}
+policy.DENY
+{%- endmacro %}
+
+{% macro policy_deny_msg(message) -%}
+policy.DENY_MSG('{{ message|string }}')
+{%- endmacro %}
+
+{% macro policy_drop() -%}
+policy.DROP
+{%- endmacro %}
 
-{% macro tls_auth(server) -%}
-{%- if server.hostname -%}
-hostname='{{ server.hostname|string }}',
+{% macro policy_refuse() -%}
+policy.REFUSE
+{%- endmacro %}
+
+{% macro policy_answer(answer) -%}
+policy.ANSWER({ [kres.type.{{ answer.query_type }}] = { rdata=
+{%- if answer.query_type == 'A' -%}
+{{ string_table(answer.rdata) }},
+{%- elif answer.query_type == 'AAAA' -%}
+{{ string_table(answer.rdata) }},
+{%- elif answer.query_type == 'TXT' -%}
+{{ str2ip_table(answer.rdata) }},
+{# TODO: do same for other types #}
 {%- endif -%}
-{%- if server.ca_file -%}
-ca_file='{{ server.ca_file|string }}',
+{% if answer.ttl %}
+ttl={{ answer.ttl.seconds()|int }},
 {%- endif -%}
-{%- if server.pin_sha256 -%}
-pin_sha256=
-{%- if server.pin_sha256 is string -%}
-'{{ server.pin_sha256|string }}',
+} }, 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 -%}
-{
-{%- for pin in server.pin_sha256 -%}
-'{{ pin|string }}',
-{%- endfor -%}
-},
+{{ policy_deny()|string }}
 {%- endif -%}
+{# TODO: do same for other actions #}
 {%- endif -%}
 {%- endmacro %}
 
+{# Chain actions #}
+
+{% macro policy_stub(servers) -%}
+policy.STUB({{ servers_table(servers) }})
+{%- endmacro %}
+
+{% macro policy_forward(servers) -%}
+policy.FORWARD({{ servers_table(servers) }})
+{%- endmacro %}
 
 {% macro policy_tls_forward(servers) -%}
-policy.TLS_FORWARD({
-{%- for server in servers -%}
-{'{{ server.address }}', {{ tls_auth(server) }} },
-{%- endfor -%}
-})
+policy.TLS_FORWARD({{ tls_servers_table(servers) }})
 {%- endmacro %}
 
+{# other #}
 
 {% macro policy_todname(names) -%}
 policy.todnames({
diff --git a/manager/knot_resolver_manager/datamodel/templates/rpz.lua.j2 b/manager/knot_resolver_manager/datamodel/templates/rpz.lua.j2
new file mode 100644 (file)
index 0000000..c5dd539
--- /dev/null
@@ -0,0 +1,58 @@
+{% from 'macros/policy_macros.lua.j2' import policy_flags, policy_add, policy_rpz, policy_action %}
+{% from 'macros/view_macros.lua.j2' import view_tsig, view_addr %}
+
+{% if cfg.rpz %}
+{% for id, rpz in cfg.rpz.items() %}
+-- rpz: {{ id }}
+{% if rpz.views -%}
+{# views set for rpz #}
+{% for view_id in rpz.views -%}
+{%- set view = cfg.views[view_id] -%}
+
+{# merge options from view and rpz #}
+{%- set options = none -%}
+{% if rpz.options and view.options -%}
+{% set options = rpz.options|list + view.options|list %}
+{% elif rpz.options %}
+{% set options = rpz.options|list %}
+{% elif view.options %}
+{% set options = view.options|list %}
+{%- endif %}
+
+{% if view.tsig -%}
+{% for tsig in view.tsig -%}
+
+{%- if options -%}
+{{ view_tsig(tsig|string,policy_rpz(policy_flags(rpz.options), rpz.file, rpz.watch)) }}
+{%- endif %}
+
+{{ view_tsig(tsig|string,policy_rpz(policy_action(rpz), rpz.file, rpz.watch )) }}
+
+{% endfor %}
+{%- endif -%}
+
+{% if view.subnets -%}
+{% for addr in view.subnets -%}
+
+{%- if options -%}
+{{ view_addr(addr|string,policy_rpz(policy_flags(rpz.options), rpz.file, rpz.watch)) }}
+{%- endif %}
+
+{{ view_addr(addr|string,policy_rpz(policy_action(rpz), rpz.file, rpz.watch )) }}
+
+{% endfor %}
+{% endif %}
+
+{% endfor %}
+{% else %}
+{# no views set for rpz #}
+
+{% if rpz.options -%}
+{{ policy_add(policy_rpz(policy_flags(rpz.options), rpz.file, rpz.watch)) }}
+{%- endif %}
+
+{{ policy_add(policy_rpz(policy_action(rpz), rpz.file, rpz.watch )) }}
+
+{% endif %}
+{% endfor %}
+{% endif %}
\ No newline at end of file