]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
datamodel: stabilize dnssec schema
authorAleš Mrázek <ales.mrazek@nic.cz>
Fri, 28 Mar 2025 14:07:03 +0000 (15:07 +0100)
committerAleš Mrázek <ales.mrazek@nic.cz>
Tue, 5 Aug 2025 09:13:12 +0000 (11:13 +0200)
NEWS
doc/_static/config.schema.json
doc/user/config-dnssec.rst
python/knot_resolver/datamodel/config_schema.py
python/knot_resolver/datamodel/dnssec_schema.py
python/knot_resolver/datamodel/templates/dnssec.lua.j2
tests/manager/datamodel/test_config_schema.py

diff --git a/NEWS b/NEWS
index 5c1473994b1e6d6959c66a7c66c29b436a7ad6c8..ac83edbf14d15a3b75378f0ed59f9a08074963b2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,11 +9,18 @@ Incompatible changes
 --------------------
 - Removed options from declarative configuration model (YAML).  
   These are mostly experimental and debugging/testing options that are not useful for general users (remain in Lua):
+  - /dnssec/refresh-time
+  - /dnssec/hold-down-time
+  - /dnssec/time-skew-detection
   - /logging/debugging
   - /max-workers
   - /network/tls/auto-discovery
   - /webmgmt
 - Renamed/moved options in the declarative configuration model (YAML).
+  - /dnssec: true|false -> /dnssec/enabled: true|false
+  - /dnssec/keep-removed -> /dnssec/trust-anchors-keep-removed
+  - /dnssec/trust-anchor-sentinel -> /dnssec/sentinel
+  - /dnssec/trust-anchor-signal-query -> /dnssec/signal-query 
   - /network/tls/files-watchdog -> /network/tls/watchdog
 
 
index cfef3cb8ae5ac5286042e0379c5e2ef1b7835473..3d0c0cfdfa869c6c7031bc60ae4cb17397a43d67 100644 (file)
             }
         },
         "dnssec": {
-            "anyOf": [
-                {
-                    "type": "boolean"
+            "description": "DNSSEC configuration.",
+            "type": "object",
+            "properties": {
+                "enabled": {
+                    "type": "boolean",
+                    "description": "Enable/disable DNSSEC.",
+                    "default": true
                 },
-                {
-                    "description": "DNSSEC configuration.",
-                    "type": "object",
-                    "properties": {
-                        "trust-anchor-sentinel": {
-                            "type": "boolean",
-                            "description": "Allows users of DNSSEC validating resolver to detect which root keys are configured in resolver's chain of trust. (RFC 8509)",
-                            "default": true
-                        },
-                        "trust-anchor-signal-query": {
-                            "type": "boolean",
-                            "description": "Signaling Trust Anchor Knowledge in DNSSEC Using Key Tag Query, according to (RFC 8145#section-5).",
-                            "default": true
-                        },
-                        "time-skew-detection": {
-                            "type": "boolean",
-                            "description": "Detection of difference between local system time and expiration time bounds in DNSSEC signatures for '. NS' records.",
-                            "default": true
-                        },
-                        "keep-removed": {
-                            "type": "integer",
-                            "minimum": 0,
-                            "description": "How many removed keys should be held in history (and key file) before being purged.",
-                            "default": 0
-                        },
-                        "refresh-time": {
-                            "type": [
-                                "string",
-                                "null"
-                            ],
-                            "pattern": "^(\\d+)(us|ms|s|m|h|d)$",
-                            "description": "Force trust-anchors to be updated every defined time periodically instead of relying on (RFC 5011) logic and TTLs. Intended only for testing purposes.",
-                            "default": null
-                        },
-                        "hold-down-time": {
-                            "type": "string",
-                            "pattern": "^(\\d+)(us|ms|s|m|h|d)$",
-                            "description": "Modify hold-down timer (RFC 5011). Intended only for testing purposes.",
-                            "default": "30d"
-                        },
-                        "trust-anchors": {
-                            "type": [
-                                "array",
-                                "null"
-                            ],
-                            "items": {
-                                "type": "string"
-                            },
-                            "description": "List of trust-anchors in DS/DNSKEY records format.",
-                            "default": null
-                        },
-                        "negative-trust-anchors": {
-                            "type": [
-                                "array",
-                                "null"
-                            ],
-                            "items": {
+                "sentinel": {
+                    "type": "boolean",
+                    "description": "Allows users of DNSSEC validating resolver to detect which root keys are configured in resolver's chain of trust. (RFC 8509)",
+                    "default": true
+                },
+                "signal-query": {
+                    "type": "boolean",
+                    "description": "Signaling Trust Anchor Knowledge in DNSSEC Using Key Tag Query, according to (RFC 8145#section-5).",
+                    "default": true
+                },
+                "trust-anchors-keep-removed": {
+                    "type": "integer",
+                    "minimum": 0,
+                    "description": "How many removed keys should be held in history (and key file) before being purged.",
+                    "default": 0
+                },
+                "trust-anchors": {
+                    "type": [
+                        "array",
+                        "null"
+                    ],
+                    "items": {
+                        "type": "string"
+                    },
+                    "description": "Trust-anchors configuration.",
+                    "default": null
+                },
+                "trust-anchors-files": {
+                    "type": [
+                        "array",
+                        "null"
+                    ],
+                    "items": {
+                        "description": "Trust-anchor zonefile configuration.",
+                        "type": "object",
+                        "properties": {
+                            "file": {
                                 "type": "string",
-                                "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$"
-                            },
-                            "description": "List of domain names representing negative trust-anchors. (RFC 7646)",
-                            "default": null
-                        },
-                        "trust-anchors-files": {
-                            "type": [
-                                "array",
-                                "null"
-                            ],
-                            "items": {
-                                "description": "Trust-anchor zonefile configuration.",
-                                "type": "object",
-                                "properties": {
-                                    "file": {
-                                        "type": "string",
-                                        "description": "Path to the zonefile that stores trust-anchors."
-                                    },
-                                    "read-only": {
-                                        "type": "boolean",
-                                        "description": "Blocks zonefile updates according to RFC 5011.",
-                                        "default": false
-                                    }
-                                }
+                                "description": "Path to the zonefile that stores trust-anchors."
                             },
-                            "description": "List of zonefiles where trust-anchors are stored.",
-                            "default": null
+                            "read-only": {
+                                "type": "boolean",
+                                "description": "Blocks zonefile updates according to RFC 5011.",
+                                "default": false
+                            }
                         }
-                    }
+                    },
+                    "description": "List of zone-files where trust-anchors are stored.",
+                    "default": null
+                },
+                "negative-trust-anchors": {
+                    "type": [
+                        "array",
+                        "null"
+                    ],
+                    "items": {
+                        "type": "string",
+                        "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$"
+                    },
+                    "description": "List of domain names representing negative trust-anchors. (RFC 7646)",
+                    "default": null
                 }
-            ],
-            "description": "Disable DNSSEC, enable with defaults or set new configuration.",
-            "default": true
+            },
+            "default": {
+                "enabled": true,
+                "sentinel": true,
+                "signal_query": true,
+                "trust_anchors_keep_removed": 0,
+                "trust_anchors": null,
+                "trust_anchors_files": null,
+                "negative_trust_anchors": null
+            }
         },
         "dns64": {
             "anyOf": [
index d22ee4f2b9b7dc0f02e80a2c5e21a20665fc7c22..f3cd45f60f713644fa05b97e842bad9ee86baf5b 100644 (file)
@@ -20,7 +20,8 @@ system by doing so, add the following snippet to your configuration file.
 .. code-block:: yaml
 
    # turns off DNSSEC validation
-   dnssec: false
+   dnssec:
+     enabled: false
 
 The resolver supports DNSSEC including :rfc:`5011` automated DNSSEC TA updates
 and :rfc:`7646` negative trust anchors.  Depending on your distribution, DNSSEC
@@ -30,11 +31,17 @@ policy, or automatically maintained by the resolver itself.
 In practice this means that you can forget about it and your favorite Linux
 distribution will take care of it for you.
 
-Following :option:`dnssec <dnssec: false|<options>>` section allow to modify DNSSEC configuration *if you really have to*:
+Following :option:`dnssec <dnssec: <options>>` section allows to modify DNSSEC configuration *if you really have to*:
 
-.. option:: dnssec: false|<options>
+.. option:: dnssec: <options>
 
-   DNSSEC configuration options. If ``false``, DNSSEC is disabled.
+   DNSSEC configuration options.
+
+   .. option:: enabled: true|false
+
+      :default: true
+
+      If ``false``, DNSSEC is disabled.
 
    .. option:: trust-anchors-files: <list>
 
@@ -63,19 +70,7 @@ Following :option:`dnssec <dnssec: false|<options>>` section allow to modify DNS
              - file: root.key
                read-only: false
 
-   .. option:: hold-down-time: <time ms|s|m|h|d>
-
-      :default: 30d (30 days)
-
-      Modify :rfc:`5011` hold-down timer to given value. Intended only for testing purposes.
-
-   .. option:: refresh-time: <time ms|s|m|h|d>
-
-      Modify RFC5011 refresh timer to given value (not set by default), this will force trust anchors
-      to be updated every N seconds periodically instead of relying on RFC5011 logic and TTLs.
-      Intended only for testing purposes.
-
-   .. option:: keep-removed: <int>
+   .. option:: trust-anchors-keep-removed: <int>
 
       :default: 0
 
index 0b9096915eb03c93abb9c2af4904a4d21a9c7c84..65c90babcac9194aee1483ea701ecf3f9618ab5f 100644 (file)
@@ -100,7 +100,7 @@ class KresConfig(ConfigSchema):
         local_data: Local data for forward records (A/AAAA) and reverse records (PTR).
         forward: List of Forward Zones and its configuration.
         cache: DNS resolver cache configuration.
-        dnssec: Disable DNSSEC, enable with defaults or set new configuration.
+        dnssec: DNSSEC configuration.
         dns64: Disable DNS64 (RFC 6147), enable with defaults or set new configuration.
         logging: Logging and debugging configuration.
         monitoring: Metrics exposisition configuration (Prometheus, Graphite)
@@ -121,7 +121,7 @@ class KresConfig(ConfigSchema):
         local_data: LocalDataSchema = LocalDataSchema()
         forward: Optional[List[ForwardSchema]] = None
         cache: CacheSchema = lazy_default(CacheSchema, {})
-        dnssec: Union[bool, DnssecSchema] = True
+        dnssec: DnssecSchema = DnssecSchema()
         dns64: Union[bool, Dns64Schema] = False
         logging: LoggingSchema = LoggingSchema()
         monitoring: MonitoringSchema = MonitoringSchema()
@@ -142,7 +142,7 @@ class KresConfig(ConfigSchema):
     local_data: LocalDataSchema
     forward: Optional[List[ForwardSchema]]
     cache: CacheSchema
-    dnssec: Union[Literal[False], DnssecSchema]
+    dnssec: DnssecSchema
     dns64: Union[Literal[False], Dns64Schema]
     logging: LoggingSchema
     monitoring: MonitoringSchema
@@ -166,11 +166,6 @@ class KresConfig(ConfigSchema):
             )
         return obj.workers
 
-    def _dnssec(self, obj: Raw) -> Any:
-        if obj.dnssec is True:
-            return DnssecSchema()
-        return obj.dnssec
-
     def _dns64(self, obj: Raw) -> Any:
         if obj.dns64 is True:
             return Dns64Schema()
index 6f51d5eb6d65b8f7722fa057c2f502739166ccd3..3f051a68b41ca569cad1db1291d53bca3d2095a3 100644 (file)
@@ -1,6 +1,6 @@
 from typing import List, Optional
 
-from knot_resolver.datamodel.types import DomainName, EscapedStr, IntNonNegative, ReadableFile, TimeUnit
+from knot_resolver.datamodel.types import DomainName, EscapedStr, IntNonNegative, ReadableFile
 from knot_resolver.utils.modeling import ConfigSchema
 
 
@@ -23,23 +23,20 @@ class DnssecSchema(ConfigSchema):
     DNSSEC configuration.
 
     ---
-    trust_anchor_sentinel: Allows users of DNSSEC validating resolver to detect which root keys are configured in resolver's chain of trust. (RFC 8509)
-    trust_anchor_signal_query: Signaling Trust Anchor Knowledge in DNSSEC Using Key Tag Query, according to (RFC 8145#section-5).
-    time_skew_detection: Detection of difference between local system time and expiration time bounds in DNSSEC signatures for '. NS' records.
-    keep_removed: How many removed keys should be held in history (and key file) before being purged.
-    refresh_time: Force trust-anchors to be updated every defined time periodically instead of relying on (RFC 5011) logic and TTLs. Intended only for testing purposes.
-    hold_down_time: Modify hold-down timer (RFC 5011). Intended only for testing purposes.
+    enabled: Enable/disable DNSSEC.
+    sentinel: Allows users of DNSSEC validating resolver to detect which root keys are configured in resolver's chain of trust. (RFC 8509)
+    signal_query: Signaling Trust Anchor Knowledge in DNSSEC Using Key Tag Query, according to (RFC 8145#section-5).
+    trust_anchors_keep_removed: How many removed keys should be held in history (and key file) before being purged.
     trust_anchors: List of trust-anchors in DS/DNSKEY records format.
+    trust_anchors_files: List of zone-files where trust-anchors are stored.
+    trust_anchors: Trust-anchors configuration.
     negative_trust_anchors: List of domain names representing negative trust-anchors. (RFC 7646)
-    trust_anchors_files: List of zonefiles where trust-anchors are stored.
     """
 
-    trust_anchor_sentinel: bool = True
-    trust_anchor_signal_query: bool = True
-    time_skew_detection: bool = True
-    keep_removed: IntNonNegative = IntNonNegative(0)
-    refresh_time: Optional[TimeUnit] = None
-    hold_down_time: TimeUnit = TimeUnit("30d")
+    enabled: bool = True
+    sentinel: bool = True
+    signal_query: bool = True
+    trust_anchors_keep_removed: IntNonNegative = IntNonNegative(0)
     trust_anchors: Optional[List[EscapedStr]] = None
-    negative_trust_anchors: Optional[List[DomainName]] = None
     trust_anchors_files: Optional[List[TrustAnchorFileSchema]] = None
+    negative_trust_anchors: Optional[List[DomainName]] = None
index d0ad6ddbabc9beed2031a67e60b317eff7998308..30f98dbea588a524f1378044c57dce82fd188feb 100644 (file)
@@ -1,41 +1,23 @@
 {% from 'macros/common_macros.lua.j2' import boolean %}
 
-{% if not cfg.dnssec %}
--- disable dnssec
-trust_anchors.remove('.')
-{% else %}
+{% if cfg.dnssec.enabled %}
 
-
--- options.trust-anchor-sentinel
-{% if cfg.dnssec.trust_anchor_sentinel %}
+-- dnssec.sentinel
+{% if cfg.dnssec.sentinel %}
 modules.load('ta_sentinel')
 {% else %}
 modules.unload('ta_sentinel')
 {% endif %}
 
--- options.trust-anchor-signal-query
-{% if cfg.dnssec.trust_anchor_signal_query %}
+-- dnssec.signal-query
+{% if cfg.dnssec.signal_query %}
 modules.load('ta_signal_query')
 {% else %}
 modules.unload('ta_signal_query')
 {% endif %}
 
--- options.time-skew-detection
-{% if cfg.dnssec.time_skew_detection %}
-modules.load('detect_time_skew')
-{% else %}
-modules.unload('detect_time_skew')
-{% endif %}
-
-{% if cfg.dnssec.keep_removed %}
--- dnssec.keep-removed
-trust_anchors.keep_removed = {{ cfg.dnssec.keep_removed }}
-{% endif %}
-
-{% if cfg.dnssec.refresh_time %}
--- dnssec.refresh-time
-trust_anchors.refresh_time = {{ cfg.dnssec.refresh_time.seconds()|string  }}
-{% endif %}
+-- dnssec.trust-anchors-keep-removed
+trust_anchors.keep_removed = {{ cfg.dnssec.trust_anchors_keep_removed }}
 
 {% if cfg.dnssec.trust_anchors %}
 -- dnssec.trust-anchors
@@ -60,5 +42,9 @@ trust_anchors.add_file('{{ taf.file }}', {{ boolean(taf.read_only) }})
 {% endfor %}
 {% endif %}
 
+{% else %}
+
+-- Disable DNSSEC
+trust_anchors.remove('.')
 
-{% endif %}{# cfg.dnssec #}
+{% endif %}
index 9ec2b31b281784bdaf8b2b4546a2c2a9522db743..2a6180e8e9a51b7ad5a3b1cda97c88fc8b072891 100644 (file)
@@ -54,24 +54,22 @@ def test_config_defaults():
 
 
 def test_dnssec_false():
-    config = KresConfig({"dnssec": False})
+    config = KresConfig({"dnssec": {"enabled": False}})
 
-    assert config.dnssec == False
+    assert config.dnssec.enabled == False
 
 
 def test_dnssec_default_true():
     config = KresConfig()
 
     # DNSSEC defaults
-    assert config.dnssec.trust_anchor_sentinel == True
-    assert config.dnssec.trust_anchor_signal_query == True
-    assert config.dnssec.time_skew_detection == True
-    assert config.dnssec.refresh_time == None
+    assert config.dnssec.enabled == True
+    assert config.dnssec.sentinel == True
+    assert config.dnssec.signal_query == True
+    assert int(config.dnssec.trust_anchors_keep_removed) == 0
     assert config.dnssec.trust_anchors == None
-    assert config.dnssec.negative_trust_anchors == None
     assert config.dnssec.trust_anchors_files == None
-    assert int(config.dnssec.keep_removed) == 0
-    assert str(config.dnssec.hold_down_time) == "30d"
+    assert config.dnssec.negative_trust_anchors == None
 
 
 def test_dns64_prefix_default():