From 15d5b3d1e191d48a83c53f0999ae6a8b062a38ca Mon Sep 17 00:00:00 2001 From: Tomas Krizek Date: Fri, 19 Jun 2020 11:47:33 +0200 Subject: [PATCH] daemon: don't drop capabilities when running as root When the effective user is root, no capabilities are dropped. This change has no effect when running as non-privileged user or when switching to non-privileged user via user() in config. Dropping capabilities as a root user resulted in the following unexpected behaviour: 1. When using trust anchor update, r/w access to root keys is neeeded. These are typically owned by knot-resolver user. When kresd is executed as root and capabilities are dropped, this file was no longer writable, because it is owned by knot-resolver, not root. 2. It is impossible to recreate/resize cache due to the same permission issue as above. If you want to drop capabilities when starting kresd as a root user, you can switch the user with the `user()` command. This changes the effective user ID and drops any capabilities as well. --- NEWS | 8 ++++++++ daemon/main.c | 11 +++++++++-- doc/config-no-systemd-privileges.rst | 7 ++----- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 287c7ea1f..35605d72e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +Knot Resolver 5.2.0 (2020-0m-dd) +================================ + +Improvements +------------ +- capabilities are no longer constrained when running as root (!1012) + + Knot Resolver 5.1.2 (2020-07-01) ================================ diff --git a/daemon/main.c b/daemon/main.c index f936c645c..b7306c773 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -491,7 +491,11 @@ static int start_listening(struct network *net, flagged_fd_array_t *fds) { static void drop_capabilities(void) { #ifdef ENABLE_CAP_NG - /* Drop all capabilities. */ + /* Drop all capabilities when running under non-root user. */ + if (geteuid() == 0) { + kr_log_verbose("[system] running as root, no capabilities dropped\n"); + return; + } if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) { capng_clear(CAPNG_SELECT_BOTH); @@ -499,9 +503,12 @@ static void drop_capabilities(void) if (capng_apply(CAPNG_SELECT_BOTH) < 0) { kr_log_error("[system] failed to set process capabilities: %s\n", strerror(errno)); + } else { + kr_log_verbose("[system] all capabilities dropped\n"); } } else { - kr_log_info("[system] process not allowed to set capabilities, skipping\n"); + /* If user() was called, the capabilities were already dropped along with SETPCAP. */ + kr_log_verbose("[system] process not allowed to set capabilities, skipping\n"); } #endif /* ENABLE_CAP_NG */ } diff --git a/doc/config-no-systemd-privileges.rst b/doc/config-no-systemd-privileges.rst index 9503a456f..86a9c3d70 100644 --- a/doc/config-no-systemd-privileges.rst +++ b/doc/config-no-systemd-privileges.rst @@ -14,7 +14,8 @@ an unprivileged user. * ``CAP_NET_BIND_SERVICE`` is required to bind to well-known ports. * ``CAP_SETPCAP`` when this capability is available, kresd drops any extra - privileges after the daemon successfully starts. + capabilities after the daemon successfully starts when running as + a non-root user. Running as non-privileged user ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -62,7 +63,3 @@ Running as root proccesses have unconstrained access to the complete system at runtime. While not recommended, it is also possible to run kresd directly as root. - -Please note the process will still attempt to drop capabilities after startup. -Among other things, this means the cache directory should belong to root to -have write access. -- 2.47.2