summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleš Mrázek <ales.mrazek@nic.cz>2025-01-14 10:02:02 +0100
committerAleš Mrázek <ales.mrazek@nic.cz>2025-01-14 10:02:02 +0100
commit3c2bc79515ead4e28cc2eca9eeac4625d18caf62 (patch)
tree06c464b480cd7c9158bb14b7975ef7205a2f227f
parentMerge !1641: Request prioritization (defer) (diff)
parentNEWS: update (diff)
downloadknot-resolver-3c2bc79515ead4e28cc2eca9eeac4625d18caf62.tar.xz
knot-resolver-3c2bc79515ead4e28cc2eca9eeac4625d18caf62.zip
Merge branch 'manager-files-reload' into 'master'
manager: TLS cert files reload (force) See merge request knot/knot-resolver!1644
-rw-r--r--NEWS2
-rw-r--r--python/knot_resolver/manager/config_store.py19
-rw-r--r--python/knot_resolver/manager/files/__init__.py3
-rw-r--r--python/knot_resolver/manager/files/reload.py17
-rw-r--r--python/knot_resolver/manager/manager.py11
-rwxr-xr-xtests/packaging/interactive/files_reload.sh93
6 files changed, 143 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index a9857e8b..d6dd1652 100644
--- a/NEWS
+++ b/NEWS
@@ -6,9 +6,11 @@ Improvements
- avoid multiple log lines when IPv6 isn't available (!1633)
- manager: fix startup on Linux without libsystemd (!1608)
- auto-reload TLS certificate files (!1626)
+- reload TLS certificate files even if the configuration has not changed (!1644)
- kresctl: bash command-line TAB completion (!1622)
- add request prioritization (defer) to mitigate DoS attacks (!1641)
+
Knot Resolver 6.0.9 (2024-11-11)
================================
diff --git a/python/knot_resolver/manager/config_store.py b/python/knot_resolver/manager/config_store.py
index 214062b2..70a9d942 100644
--- a/python/knot_resolver/manager/config_store.py
+++ b/python/knot_resolver/manager/config_store.py
@@ -59,6 +59,25 @@ class ConfigStore:
return self._config
+def only_on_no_changes_update(selector: Callable[[KresConfig], Any]) -> Callable[[UpdateCallback], UpdateCallback]:
+ def decorator(orig_func: UpdateCallback) -> UpdateCallback:
+ original_value_set: Any = False
+ original_value: Any = None
+
+ async def new_func_update(config: KresConfig) -> None:
+ nonlocal original_value_set
+ nonlocal original_value
+ if not original_value_set:
+ original_value_set = True
+ elif original_value == selector(config):
+ await orig_func(config)
+ original_value = selector(config)
+
+ return new_func_update
+
+ return decorator
+
+
def only_on_real_changes_update(selector: Callable[[KresConfig], Any]) -> Callable[[UpdateCallback], UpdateCallback]:
def decorator(orig_func: UpdateCallback) -> UpdateCallback:
original_value_set: Any = False
diff --git a/python/knot_resolver/manager/files/__init__.py b/python/knot_resolver/manager/files/__init__.py
index 49700656..29fbc741 100644
--- a/python/knot_resolver/manager/files/__init__.py
+++ b/python/knot_resolver/manager/files/__init__.py
@@ -1,3 +1,4 @@
+from .reload import files_reload
from .watchdog import init_files_watchdog
-__all__ = ["init_files_watchdog"]
+__all__ = ["files_reload", "init_files_watchdog"]
diff --git a/python/knot_resolver/manager/files/reload.py b/python/knot_resolver/manager/files/reload.py
new file mode 100644
index 00000000..6dfd5874
--- /dev/null
+++ b/python/knot_resolver/manager/files/reload.py
@@ -0,0 +1,17 @@
+import logging
+
+from knot_resolver.controller.registered_workers import command_registered_workers
+from knot_resolver.datamodel import KresConfig
+
+logger = logging.getLogger(__name__)
+
+
+async def files_reload(config: KresConfig) -> None:
+ cert_file = config.network.tls.cert_file
+ key_file = config.network.tls.key_file
+
+ if cert_file and key_file:
+ logger.info("TLS cert files reload triggered")
+
+ cmd = f"net.tls('{cert_file}', '{key_file}')"
+ await command_registered_workers(cmd)
diff --git a/python/knot_resolver/manager/manager.py b/python/knot_resolver/manager/manager.py
index 68edb915..e2fa33b3 100644
--- a/python/knot_resolver/manager/manager.py
+++ b/python/knot_resolver/manager/manager.py
@@ -11,7 +11,13 @@ from knot_resolver.controller.exceptions import SubprocessControllerError
from knot_resolver.controller.interface import Subprocess, SubprocessController, SubprocessStatus, SubprocessType
from knot_resolver.controller.registered_workers import command_registered_workers, get_registered_workers_kresids
from knot_resolver.datamodel import KresConfig
-from knot_resolver.manager.config_store import ConfigStore, only_on_real_changes_update, only_on_real_changes_verifier
+from knot_resolver.manager.config_store import (
+ ConfigStore,
+ only_on_no_changes_update,
+ only_on_real_changes_update,
+ only_on_real_changes_verifier,
+)
+from knot_resolver.manager.files import files_reload
from knot_resolver.utils.compat.asyncio import create_task
from knot_resolver.utils.functional import Result
from knot_resolver.utils.modeling.types import NoneType
@@ -152,6 +158,9 @@ class KresManager: # pylint: disable=too-many-instance-attributes
only_on_real_changes_update(config_nodes)(self.set_new_tls_sticket_secret)
)
+ # register callback that reloads files (TLS cert files) if selected configuration has not been changed
+ await config_store.register_on_change_callback(only_on_no_changes_update(config_nodes)(files_reload))
+
# register controller config change listeners
await config_store.register_verifier(_deny_max_worker_changes)
diff --git a/tests/packaging/interactive/files_reload.sh b/tests/packaging/interactive/files_reload.sh
new file mode 100755
index 00000000..b787100d
--- /dev/null
+++ b/tests/packaging/interactive/files_reload.sh
@@ -0,0 +1,93 @@
+#!/usr/bin/env bash
+
+set -e
+
+gitroot=$(git rev-parse --show-toplevel)
+cert_file=$gitroot/modules/http/test_tls/test.crt
+key_file=$gitroot/modules/http/test_tls/test.key
+
+tls_certificate_conf=$(cat <<EOF
+{
+ "cert-file": "$cert_file",
+ "key-file": "$key_file"
+}
+EOF
+)
+
+function count_errors(){
+ echo "$(journalctl -u knot-resolver.service | grep -c error)"
+}
+
+function count_reloads(){
+ echo "$(journalctl -u knot-resolver.service | grep -c "TLS cert files reload triggered")"
+}
+
+
+
+# test reload without files configure
+# {{
+
+err_count=$(count_errors)
+rel_count=$(count_reloads)
+
+kresctl reload
+if [ $(count_errors) -ne $err_count ] || [ $(count_reloads) -ne $rel_count ]; then
+ echo "TLS cert files reload triggered when should not be."
+ exit 1
+fi
+
+# }}
+
+# configure TLS certificate files
+kresctl config set -p /network/tls "$tls_certificate_conf"
+if [ "$?" -ne "0" ]; then
+ echo "Could not set TLS certificate files."
+ exit 1
+fi
+
+# test reload on no config changes
+# {{
+
+rel_count=$(count_reloads)
+
+kresctl config set -p /workers 2
+if [ $(count_errors) -ne $err_count ] || [ $(count_reloads) -eq $rel_count ]; then
+ echo "TLS cert files reload not triggered whe should be."
+ exit 1
+fi
+
+# }}
+
+# test reload on config changes
+# {{
+
+rel_count=$(count_reloads)
+
+kresctl config set -p /workers 5
+if [ $(count_errors) -ne $err_count ] || [ $(count_reloads) -ne $rel_count ]; then
+ echo "TLS cert files reload triggered when should not be."
+ exit 1
+fi
+
+# }}
+
+# test reload again on no config changes
+# {{
+
+rel_count=$(count_reloads)
+
+kresctl config set -p /workers 5
+if [ $(count_errors) -ne $err_count ] || [ $(count_reloads) -eq $rel_count ]; then
+ echo "TLS cert files reload not triggered whe should be."
+ exit 1
+fi
+
+# }}
+
+# reload to defaults
+kresctl reload
+if [ "$?" -ne "0" ]; then
+ echo "The resolver reload failed."
+ exit 1
+fi
+