From 3cd2d8629270daed30bd40ba1a93e3fa221022f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Mr=C3=A1zek?= <ales.mrazek@nic.cz>
Date: Mon, 24 Feb 2025 15:14:11 +0100
Subject: [PATCH] datamodel: forward: server: added 'insecure' config

---
 doc/_static/config.schema.json                   |  8 +++++++-
 python/knot_resolver/datamodel/forward_schema.py | 16 +++++++++++++++-
 .../templates/macros/forward_macros.lua.j2       | 13 +++++++++----
 .../datamodel/templates/test_forward_macros.py   |  2 +-
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/doc/_static/config.schema.json b/doc/_static/config.schema.json
index 754403734..dec117015 100644
--- a/doc/_static/config.schema.json
+++ b/doc/_static/config.schema.json
@@ -1097,11 +1097,17 @@
                                 "type": "boolean",
                                 "description": "Enable/disable DNSSEC.",
                                 "default": true
+                            },
+                            "insecure": {
+                                "type": "boolean",
+                                "description": "Allow insecure TLS configuration.",
+                                "default": false
                             }
                         },
                         "default": {
                             "authoritative": false,
-                            "dnssec": true
+                            "dnssec": true,
+                            "insecure": false
                         }
                     }
                 }
diff --git a/python/knot_resolver/datamodel/forward_schema.py b/python/knot_resolver/datamodel/forward_schema.py
index 6b693e6be..978bb5c3a 100644
--- a/python/knot_resolver/datamodel/forward_schema.py
+++ b/python/knot_resolver/datamodel/forward_schema.py
@@ -24,7 +24,7 @@ class ForwardServerSchema(ConfigSchema):
 
     def _validate(self) -> None:
         if self.pin_sha256 and (self.hostname or self.ca_file):
-            raise ValueError("'pin-sha256' cannot be configurad together with 'hostname' or 'ca-file'")
+            raise ValueError("'pin-sha256' cannot be configured together with 'hostname' or 'ca-file'")
 
 
 class ForwardOptionsSchema(ConfigSchema):
@@ -34,10 +34,13 @@ class ForwardOptionsSchema(ConfigSchema):
     ---
     authoritative: The forwarding target is an authoritative server.
     dnssec: Enable/disable DNSSEC.
+    insecure: Allow insecure TLS configuration.
+
     """
 
     authoritative: bool = False
     dnssec: bool = True
+    insecure: bool = False
 
 
 class ForwardSchema(ConfigSchema):
@@ -74,3 +77,14 @@ class ForwardSchema(ConfigSchema):
 
         if self.options.authoritative and is_transport_tls(self.servers):
             raise ValueError("Forwarding to authoritative servers using TLS protocol is not supported.")
+
+        if not self.options.insecure:
+            for server in self.servers:
+                if (
+                    isinstance(server, ForwardServerSchema)
+                    and server.transport == "tls"
+                    and not (server.pin_sha256 or server.hostname or server.ca_file)
+                ):
+                    raise ValueError(
+                        "no way to authenticate server (hostname, ca-file or pin-sha256) and 'insecure' is not set"
+                    )
diff --git a/python/knot_resolver/datamodel/templates/macros/forward_macros.lua.j2 b/python/knot_resolver/datamodel/templates/macros/forward_macros.lua.j2
index 1f3549b16..ce4143e2f 100644
--- a/python/knot_resolver/datamodel/templates/macros/forward_macros.lua.j2
+++ b/python/knot_resolver/datamodel/templates/macros/forward_macros.lua.j2
@@ -4,7 +4,7 @@
 {dnssec={{ boolean(options.dnssec) }},auth={{ boolean(options.authoritative) }}}
 {%- endmacro %}
 
-{% macro forward_server(server) -%}
+{% macro forward_server(server, options) -%}
 {%- if server.address is defined and server.address-%}
 {%- for addr in server.address -%}
 {'{{ addr }}',
@@ -13,6 +13,11 @@ tls=true,
 {%- else -%}
 tls=false,
 {%- endif -%}
+{%- if options.insecure -%}
+insecure=true,
+{%- else -%}
+insecure=false,
+{%- endif -%}
 {%- if server.hostname -%}
 hostname='{{ server.hostname }}',
 {%- endif -%}
@@ -29,14 +34,14 @@ ca_file='{{ server.ca_file }}',
 {%- endif -%}
 {%- endmacro %}
 
-{% macro forward_servers(servers) -%}
+{% macro forward_servers(servers, options) -%}
 {
 {%- for server in servers -%}
-{{ forward_server(server) }}
+{{ forward_server(server, options) }}
 {%- endfor -%}
 }
 {%- endmacro %}
 
 {% macro policy_rule_forward_add(subtree,options,servers) -%}
-policy.rule_forward_add('{{ subtree }}',{{ forward_options(options) }},{{ forward_servers(servers) }})
+policy.rule_forward_add('{{ subtree }}',{{ forward_options(options) }},{{ forward_servers(servers, options) }})
 {%- endmacro %}
diff --git a/tests/manager/datamodel/templates/test_forward_macros.py b/tests/manager/datamodel/templates/test_forward_macros.py
index 0ed2ec9b9..6447aabc2 100644
--- a/tests/manager/datamodel/templates/test_forward_macros.py
+++ b/tests/manager/datamodel/templates/test_forward_macros.py
@@ -17,7 +17,7 @@ def test_policy_rule_forward_add():
             },
         }
     )
-    result = "policy.rule_forward_add('.',{dnssec=true,auth=false},{{'2001:148f:fffe::1',tls=false,hostname='odvr.nic.cz',},{'185.43.135.1',tls=false,hostname='odvr.nic.cz',},})"
+    result = "policy.rule_forward_add('.',{dnssec=true,auth=false},{{'2001:148f:fffe::1',tls=false,insecure=false,hostname='odvr.nic.cz',},{'185.43.135.1',tls=false,insecure=false,hostname='odvr.nic.cz',},})"
 
     tmpl = template_from_str(tmpl_str)
     assert tmpl.render(rule=rule) == result
-- 
GitLab