From: Aleš Date: Tue, 7 Dec 2021 00:30:32 +0000 (+0100) Subject: datamodel: rpz: Lua configuration X-Git-Tag: v6.0.0a1~69^2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad9334868e511d57ef626cb7839eecc38e0f3085;p=thirdparty%2Fknot-resolver.git datamodel: rpz: Lua configuration - templates: common macros - templates: added a few more policy maros --- diff --git a/manager/knot_resolver_manager/datamodel/config_schema.py b/manager/knot_resolver_manager/datamodel/config_schema.py index 0f53a3165..a490ba075 100644 --- a/manager/knot_resolver_manager/datamodel/config_schema.py +++ b/manager/knot_resolver_manager/datamodel/config_schema.py @@ -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 diff --git a/manager/knot_resolver_manager/datamodel/rpz_schema.py b/manager/knot_resolver_manager/datamodel/rpz_schema.py index c9bd059dd..af8a3138f 100644 --- a/manager/knot_resolver_manager/datamodel/rpz_schema.py +++ b/manager/knot_resolver_manager/datamodel/rpz_schema.py @@ -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 diff --git a/manager/knot_resolver_manager/datamodel/templates/config.lua.j2 b/manager/knot_resolver_manager/datamodel/templates/config.lua.j2 index f8dbcfd96..29af22378 100644 --- a/manager/knot_resolver_manager/datamodel/templates/config.lua.j2 +++ b/manager/knot_resolver_manager/datamodel/templates/config.lua.j2 @@ -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 index 000000000..31f9f176d --- /dev/null +++ b/manager/knot_resolver_manager/datamodel/templates/macros/common_macros.lua.j2 @@ -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 diff --git a/manager/knot_resolver_manager/datamodel/templates/macros/policy_macros.lua.j2 b/manager/knot_resolver_manager/datamodel/templates/macros/policy_macros.lua.j2 index 5e5044e3e..c52c831da 100644 --- a/manager/knot_resolver_manager/datamodel/templates/macros/policy_macros.lua.j2 +++ b/manager/knot_resolver_manager/datamodel/templates/macros/policy_macros.lua.j2 @@ -1,86 +1,107 @@ -{% 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 index 000000000..c5dd539e4 --- /dev/null +++ b/manager/knot_resolver_manager/datamodel/templates/rpz.lua.j2 @@ -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