- reduce validation strictness for domain names (#934, !1727)
- manager: force a configuration reload via management HTTP API 'api/reload/force' (#939, !1748)
- kresctl: reload: added '--force' flag
+- /fallback: add this feature/module (!1733)
Bugfixes
--------
"minimum": 0.0,
"description": "Multiplies rate-limiting and defer prices of operations, use 0 to whitelist.",
"default": 1.0
+ },
+ "fallback": {
+ "type": "boolean",
+ "description": "Enable/disable fallback on resolution failure.",
+ "default": true
}
},
"default": {
"minimize": true,
"dns64": true,
- "price_factor": 1.0
+ "price_factor": 1.0,
+ "fallback": true
}
}
}
"description": "Subtree(s) to forward."
},
"servers": {
- "anyOf": [
- {
- "type": "array",
- "items": {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
"type": "string"
- }
- },
- {
- "type": "array",
- "items": {
+ },
+ {
"description": "Forward server configuration.",
"type": "object",
"properties": {
}
}
}
- }
- ],
+ ]
+ },
"description": "Forward servers configuration."
},
"options": {
"description": "List of Forward Zones and its configuration.",
"default": null
},
+ "fallback": {
+ "description": "Config for fallback on resolution failure.",
+ "type": "object",
+ "properties": {
+ "enable": {
+ "type": "boolean",
+ "description": "Enable/disable the fallback.",
+ "default": false
+ },
+ "servers": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "description": "Forward server configuration.",
+ "type": "object",
+ "properties": {
+ "address": {
+ "anyOf": [
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "description": "IP address(es) of a forward server."
+ },
+ "transport": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "enum": [
+ "tls"
+ ],
+ "description": "Transport protocol for a forward server.",
+ "default": null
+ },
+ "pin-sha256": {
+ "anyOf": [
+ {
+ "type": "null"
+ },
+ {
+ "anyOf": [
+ {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[A-Za-z\\d+/]{43}=$"
+ }
+ },
+ {
+ "type": "string",
+ "pattern": "^[A-Za-z\\d+/]{43}=$"
+ }
+ ]
+ }
+ ],
+ "description": "Hash of accepted CA certificate.",
+ "default": null
+ },
+ "hostname": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "pattern": "(?=^.{,253}\\.?$)(^(?!-)[^.]{,62}[^.-](\\.(?!-)[^.]{,62}[^.-])*\\.?$)|^\\.$",
+ "description": "Hostname of the Forward server.",
+ "default": null
+ },
+ "ca-file": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "description": "Path to CA certificate file.",
+ "default": null
+ }
+ }
+ }
+ ]
+ },
+ "description": "Forward servers configuration for fallback.",
+ "default": null
+ }
+ },
+ "default": {
+ "enable": false,
+ "servers": null
+ }
+ },
"cache": {
"description": "DNS resolver cache configuration.",
"type": "object",
--- /dev/null
+.. SPDX-License-Identifier: GPL-3.0-or-later
+
+.. _config-serve-stale:
+
+Fallback on resolution failure
+==============================
+
+This allows switching to a fallback forwarding configuration on queries where the resolver is unable to contact upstream servers.
+
+.. code-block:: yaml
+
+ fallback:
+ enable: true
+ servers:
+ - address: [ 2001:148f:fffe::1, 193.17.47.1 ]
+ transport: tls
+ hostname: odvr.nic.cz
+
+The ``servers:`` has the same schema as in :ref:`forwarding <config-forward>`.
+
+If you use fallback within a fleet of servers,
+you will probably want to avoid queries cycling in there,
+i.e. disable the fallback option for them in :ref:`views <config-views>`.
config-cache-predict
config-cache-prefill
config-serve-stale
+ config-fallback
config-rfc7706
config-priming
config-edns-keepalive
from knot_resolver.datamodel.defer_schema import DeferSchema
from knot_resolver.datamodel.dns64_schema import Dns64Schema
from knot_resolver.datamodel.dnssec_schema import DnssecSchema
-from knot_resolver.datamodel.forward_schema import ForwardSchema
+from knot_resolver.datamodel.forward_schema import FallbackSchema, ForwardSchema
from knot_resolver.datamodel.globals import Context, get_global_validation_context, set_global_validation_context
from knot_resolver.datamodel.local_data_schema import LocalDataSchema, RPZSchema, RuleSchema
from knot_resolver.datamodel.logging_schema import LoggingSchema
views: List of views and its configuration.
local_data: Local data for forward records (A/AAAA) and reverse records (PTR).
forward: List of Forward Zones and its configuration.
+ fallback: Config for fallback on resolution failure.
cache: DNS resolver cache configuration.
dnssec: Disable DNSSEC, enable with defaults or set new configuration.
dns64: Disable DNS64 (RFC 6147), enable with defaults or set new configuration.
views: Optional[List[ViewSchema]] = None
local_data: LocalDataSchema = LocalDataSchema()
forward: Optional[List[ForwardSchema]] = None
+ fallback: FallbackSchema = FallbackSchema()
cache: CacheSchema = lazy_default(CacheSchema, {})
dnssec: Union[bool, DnssecSchema] = True
dns64: Union[bool, Dns64Schema] = False
views: Optional[List[ViewSchema]]
local_data: LocalDataSchema
forward: Optional[List[ForwardSchema]]
+ fallback: FallbackSchema
cache: CacheSchema
dnssec: Union[Literal[False], DnssecSchema]
dns64: Union[Literal[False], Dns64Schema]
"""
subtree: ListOrItem[DomainName]
- servers: Union[List[IPAddressOptionalPort], List[ForwardServerSchema]]
+ servers: List[Union[IPAddressOptionalPort, ForwardServerSchema]]
options: ForwardOptionsSchema = ForwardOptionsSchema()
def _validate(self) -> None:
if self.options.authoritative and is_transport_tls(self.servers):
raise ValueError("Forwarding to authoritative servers using TLS protocol is not supported.")
+
+
+class FallbackSchema(ConfigSchema):
+ """
+ Configuration for fallback after resolution failure.
+
+ ---
+ enable: Enable/disable the fallback.
+ servers: Forward servers configuration for fallback.
+ """
+
+ enable: bool = False
+ servers: Optional[List[Union[IPAddressOptionalPort, ForwardServerSchema]]] = None
+
+ def _validate(self) -> None:
+ if self.enable and self.servers is None:
+ raise ValueError("Fallback enabled without configuring servers.")
-{% from 'macros/forward_macros.lua.j2' import policy_rule_forward_add %}
+{% from 'macros/forward_macros.lua.j2' import policy_rule_forward_add, forward_servers %}
{% if cfg.forward %}
{% for fwd in cfg.forward %}
{% endfor %}
{% endfor %}
{% endif %}
+
+
+{% if cfg.fallback and cfg.fallback.enable %}
+modules.load('fallback')
+fallback.config({
+ targets = {{ forward_servers(cfg.fallback.servers) }},
+ options = {},
+})
+{% endif %}