From d1ef7da74a2d23fdf919b800b92fb2854c66a39c Mon Sep 17 00:00:00 2001 From: Thomas Markwalder Date: Wed, 11 Jun 2025 15:47:07 -0400 Subject: [PATCH] [#3848] Warn if running as root Servers now all warn if they are running as root. --- src/bin/dhcp4/dhcp4_messages.cc | 2 ++ src/bin/dhcp4/dhcp4_messages.h | 1 + src/bin/dhcp4/dhcp4_messages.mes | 14 ++++++++++++++ src/bin/dhcp4/main.cc | 4 ++++ src/bin/dhcp6/dhcp6_messages.cc | 2 ++ src/bin/dhcp6/dhcp6_messages.h | 1 + src/bin/dhcp6/dhcp6_messages.mes | 14 ++++++++++++++ src/bin/dhcp6/main.cc | 4 ++++ src/lib/process/d_controller.cc | 7 +++++++ src/lib/process/process_messages.cc | 2 ++ src/lib/process/process_messages.h | 1 + src/lib/process/process_messages.mes | 6 ++++++ src/lib/util/filesystem.cc | 4 ++++ src/lib/util/filesystem.h | 7 +++++++ 14 files changed, 69 insertions(+) diff --git a/src/bin/dhcp4/dhcp4_messages.cc b/src/bin/dhcp4/dhcp4_messages.cc index e06ce6a121..63aac9fd4f 100644 --- a/src/bin/dhcp4/dhcp4_messages.cc +++ b/src/bin/dhcp4/dhcp4_messages.cc @@ -157,6 +157,7 @@ extern const isc::log::MessageID DHCP4_RESPONSE_DATA = "DHCP4_RESPONSE_DATA"; extern const isc::log::MessageID DHCP4_RESPONSE_FQDN_DATA = "DHCP4_RESPONSE_FQDN_DATA"; extern const isc::log::MessageID DHCP4_RESPONSE_HOSTNAME_DATA = "DHCP4_RESPONSE_HOSTNAME_DATA"; extern const isc::log::MessageID DHCP4_RESPONSE_HOSTNAME_GENERATE = "DHCP4_RESPONSE_HOSTNAME_GENERATE"; +extern const isc::log::MessageID DHCP4_ROOT_USER_SECURITY_WARN = "DHCP4_ROOT_USER_SECURITY_WARN"; extern const isc::log::MessageID DHCP4_SECURITY_CHECKS_DISABLED = "DHCP4_SECURITY_CHECKS_DISABLED"; extern const isc::log::MessageID DHCP4_SERVER_FAILED = "DHCP4_SERVER_FAILED"; extern const isc::log::MessageID DHCP4_SERVER_INITIATED_DECLINE = "DHCP4_SERVER_INITIATED_DECLINE"; @@ -337,6 +338,7 @@ const char* values[] = { "DHCP4_RESPONSE_FQDN_DATA", "%1: including FQDN option in the server's response: %2", "DHCP4_RESPONSE_HOSTNAME_DATA", "%1: including Hostname option in the server's response: %2", "DHCP4_RESPONSE_HOSTNAME_GENERATE", "%1: server has generated hostname %2 for the client", + "DHCP4_ROOT_USER_SECURITY_WARN", "kea-dhcp4 running as root user!", "DHCP4_SECURITY_CHECKS_DISABLED", "Invoked with command line option -X, Security checks are disabled!!", "DHCP4_SERVER_FAILED", "server failed: %1", "DHCP4_SERVER_INITIATED_DECLINE", "%1: Lease for addr %2 has been found to be already in use. The lease will be unavailable for %3 seconds.", diff --git a/src/bin/dhcp4/dhcp4_messages.h b/src/bin/dhcp4/dhcp4_messages.h index 9a4d0cda21..76de2b30bd 100644 --- a/src/bin/dhcp4/dhcp4_messages.h +++ b/src/bin/dhcp4/dhcp4_messages.h @@ -158,6 +158,7 @@ extern const isc::log::MessageID DHCP4_RESPONSE_DATA; extern const isc::log::MessageID DHCP4_RESPONSE_FQDN_DATA; extern const isc::log::MessageID DHCP4_RESPONSE_HOSTNAME_DATA; extern const isc::log::MessageID DHCP4_RESPONSE_HOSTNAME_GENERATE; +extern const isc::log::MessageID DHCP4_ROOT_USER_SECURITY_WARN; extern const isc::log::MessageID DHCP4_SECURITY_CHECKS_DISABLED; extern const isc::log::MessageID DHCP4_SERVER_FAILED; extern const isc::log::MessageID DHCP4_SERVER_INITIATED_DECLINE; diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes index 1deb2e6074..97d9a8128c 100644 --- a/src/bin/dhcp4/dhcp4_messages.mes +++ b/src/bin/dhcp4/dhcp4_messages.mes @@ -1190,3 +1190,17 @@ expected: the erroneous response is dropped, the request query is displayed. An DHCPOFFER for the 0.0.0.0 address was generated for a client requesting the v6-only-preferred (108) option but the option is not in the response as expected: the erroneous response is dropped, the discover query is displayed. + +% DHCP4_SECURITY_CHECKS_DISABLED Invoked with command line option -X, Security checks are disabled!! +This warning is emitted when internal security checks normally +performed by kea-dhcp4 have been disabled via command line option '-X'. +This means the server is not enforcing restrictions on resource +paths or permissions. This mode of operation may expose your +environment to security vulnerabilities and should only be used +after careful consideration. + +% DHCP4_ROOT_USER_SECURITY_WARN kea-dhcp4 running as root user! +This warning is emitted when kea-dhcp4 is running as a root user. +While the server will function fully, this mode of operation may +expose your environment to security vulnerabilities and should +only be used after careful consideration. diff --git a/src/bin/dhcp4/main.cc b/src/bin/dhcp4/main.cc index 4f88e294aa..32b62f6c53 100644 --- a/src/bin/dhcp4/main.cc +++ b/src/bin/dhcp4/main.cc @@ -246,6 +246,10 @@ main(int argc, char* argv[]) { LOG_WARN(dhcp4_logger, DHCP4_DEVELOPMENT_VERSION); } + if (amRoot()) { + LOG_WARN(dhcp4_logger, DHCP4_ROOT_USER_SECURITY_WARN); + } + if (!PathChecker::shouldEnforceSecurity()) { LOG_WARN(dhcp4_logger, DHCP4_SECURITY_CHECKS_DISABLED); } diff --git a/src/bin/dhcp6/dhcp6_messages.cc b/src/bin/dhcp6/dhcp6_messages.cc index 229ba74450..18b9cbb49a 100644 --- a/src/bin/dhcp6/dhcp6_messages.cc +++ b/src/bin/dhcp6/dhcp6_messages.cc @@ -160,6 +160,7 @@ extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_IAID = "DHCP6_RELEA extern const isc::log::MessageID DHCP6_REQUIRED_OPTIONS_CHECK_FAIL = "DHCP6_REQUIRED_OPTIONS_CHECK_FAIL"; extern const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED = "DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED"; extern const isc::log::MessageID DHCP6_RESPONSE_DATA = "DHCP6_RESPONSE_DATA"; +extern const isc::log::MessageID DHCP6_ROOT_USER_SECURITY_WARN = "DHCP6_ROOT_USER_SECURITY_WARN"; extern const isc::log::MessageID DHCP6_SECURITY_CHECKS_DISABLED = "DHCP6_SECURITY_CHECKS_DISABLED"; extern const isc::log::MessageID DHCP6_SERVER_FAILED = "DHCP6_SERVER_FAILED"; extern const isc::log::MessageID DHCP6_SHUTDOWN = "DHCP6_SHUTDOWN"; @@ -336,6 +337,7 @@ const char* values[] = { "DHCP6_REQUIRED_OPTIONS_CHECK_FAIL", "%1: %2 message received from %3 failed the following check: %4", "DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED", "Multi-threading is enabled and host reservations lookup is always performed first.", "DHCP6_RESPONSE_DATA", "%1: responding with packet %2 (type %3), packet details: %4", + "DHCP6_ROOT_USER_SECURITY_WARN", "kea-dhcp6 running as root user!", "DHCP6_SECURITY_CHECKS_DISABLED", "Invoked with command line option -X, Security checks are disabled!!", "DHCP6_SERVER_FAILED", "server failed: %1", "DHCP6_SHUTDOWN", "server shutdown", diff --git a/src/bin/dhcp6/dhcp6_messages.h b/src/bin/dhcp6/dhcp6_messages.h index 186f7d557a..d0c5f4afdd 100644 --- a/src/bin/dhcp6/dhcp6_messages.h +++ b/src/bin/dhcp6/dhcp6_messages.h @@ -161,6 +161,7 @@ extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_IAID; extern const isc::log::MessageID DHCP6_REQUIRED_OPTIONS_CHECK_FAIL; extern const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED; extern const isc::log::MessageID DHCP6_RESPONSE_DATA; +extern const isc::log::MessageID DHCP6_ROOT_USER_SECURITY_WARN; extern const isc::log::MessageID DHCP6_SECURITY_CHECKS_DISABLED; extern const isc::log::MessageID DHCP6_SERVER_FAILED; extern const isc::log::MessageID DHCP6_SHUTDOWN; diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes index fff50ed367..ac178fa960 100644 --- a/src/bin/dhcp6/dhcp6_messages.mes +++ b/src/bin/dhcp6/dhcp6_messages.mes @@ -1167,3 +1167,17 @@ such modification. The clients will remember previous server-id, and will use it to extend their leases. As a result, they will have to go through a rebinding phase to re-acquire their leases and associate them with a new server id. + +% DHCP6_SECURITY_CHECKS_DISABLED Invoked with command line option -X, Security checks are disabled!! +This warning is emitted when internal security checks normally +performed by kea-dhcp6 have been disabled via command line option '-X'. +This means the server is not enforcing restrictions on resource +paths or permissions. This mode of operation may expose your +environment to security vulnerabilities and should only be used +after careful consideration. + +% DHCP6_ROOT_USER_SECURITY_WARN kea-dhcp6 running as root user! +This warning is emitted when kea-dhcp6 is running as a root user. +While the server will function fully, this mode of operation may +expose your environment to security vulnerabilities and should +only be used after careful consideration diff --git a/src/bin/dhcp6/main.cc b/src/bin/dhcp6/main.cc index 7ab199981f..faff52da50 100644 --- a/src/bin/dhcp6/main.cc +++ b/src/bin/dhcp6/main.cc @@ -246,6 +246,10 @@ main(int argc, char* argv[]) { LOG_WARN(dhcp6_logger, DHCP6_DEVELOPMENT_VERSION); } + if (amRoot()) { + LOG_WARN(dhcp6_logger, DHCP6_ROOT_USER_SECURITY_WARN); + } + if (!PathChecker::shouldEnforceSecurity()) { LOG_WARN(dhcp6_logger, DHCP6_SECURITY_CHECKS_DISABLED); } diff --git a/src/lib/process/d_controller.cc b/src/lib/process/d_controller.cc index 0d0902b67d..0d330943c9 100644 --- a/src/lib/process/d_controller.cc +++ b/src/lib/process/d_controller.cc @@ -127,10 +127,17 @@ DControllerBase::launch(int argc, char* argv[], const bool test_mode) { .arg(getpid()) .arg(VERSION) .arg(PACKAGE_VERSION_TYPE); + // When it is not a stable version dissuade use in production. if (std::string(PACKAGE_VERSION_TYPE) == "development") { LOG_WARN(dctl_logger, DCTL_DEVELOPMENT_VERSION); } + + if (file::amRoot()) { + LOG_WARN(dctl_logger, DCTL_ROOT_USER_SECURITY_WARN) + .arg(app_name_); + } + try { // Step 2 is to create and initialize the application process object. initProcess(); diff --git a/src/lib/process/process_messages.cc b/src/lib/process/process_messages.cc index b0c6711620..32ab9353d8 100644 --- a/src/lib/process/process_messages.cc +++ b/src/lib/process/process_messages.cc @@ -27,6 +27,7 @@ extern const isc::log::MessageID DCTL_OPEN_CONFIG_DB = "DCTL_OPEN_CONFIG_DB"; extern const isc::log::MessageID DCTL_PARSER_FAIL = "DCTL_PARSER_FAIL"; extern const isc::log::MessageID DCTL_PID_FILE_ERROR = "DCTL_PID_FILE_ERROR"; extern const isc::log::MessageID DCTL_PROCESS_FAILED = "DCTL_PROCESS_FAILED"; +extern const isc::log::MessageID DCTL_ROOT_USER_SECURITY_WARN = "DCTL_ROOT_USER_SECURITY_WARN"; extern const isc::log::MessageID DCTL_RUN_PROCESS = "DCTL_RUN_PROCESS"; extern const isc::log::MessageID DCTL_SHUTDOWN = "DCTL_SHUTDOWN"; extern const isc::log::MessageID DCTL_SHUTDOWN_SIGNAL_RECVD = "DCTL_SHUTDOWN_SIGNAL_RECVD"; @@ -61,6 +62,7 @@ const char* values[] = { "DCTL_PARSER_FAIL", "Parser error: %1", "DCTL_PID_FILE_ERROR", "%1 could not create a PID file: %2", "DCTL_PROCESS_FAILED", "%1 application execution failed: %2", + "DCTL_ROOT_USER_SECURITY_WARN", "%1 running as root user!", "DCTL_RUN_PROCESS", "%1 starting application event loop", "DCTL_SHUTDOWN", "%1 has shut down, pid: %2, version: %3", "DCTL_SHUTDOWN_SIGNAL_RECVD", "OS signal %1 received, starting shutdown", diff --git a/src/lib/process/process_messages.h b/src/lib/process/process_messages.h index df99a467f0..5fcdcd8d6b 100644 --- a/src/lib/process/process_messages.h +++ b/src/lib/process/process_messages.h @@ -28,6 +28,7 @@ extern const isc::log::MessageID DCTL_OPEN_CONFIG_DB; extern const isc::log::MessageID DCTL_PARSER_FAIL; extern const isc::log::MessageID DCTL_PID_FILE_ERROR; extern const isc::log::MessageID DCTL_PROCESS_FAILED; +extern const isc::log::MessageID DCTL_ROOT_USER_SECURITY_WARN; extern const isc::log::MessageID DCTL_RUN_PROCESS; extern const isc::log::MessageID DCTL_SHUTDOWN; extern const isc::log::MessageID DCTL_SHUTDOWN_SIGNAL_RECVD; diff --git a/src/lib/process/process_messages.mes b/src/lib/process/process_messages.mes index 1754f048c6..98eabf27e5 100644 --- a/src/lib/process/process_messages.mes +++ b/src/lib/process/process_messages.mes @@ -152,3 +152,9 @@ disabled and the output path specified for a given logger does not comply with the supported path. The server will still use the specified path but is warning that doing so may pose a security risk. + +% DCTL_ROOT_USER_SECURITY_WARN %1 running as root user! +This warning is emitted when the server is running as a root user. +While the server will function fully, this mode of operation may +expose your environment to security vulnerabilities and should +only be used after careful consideration. diff --git a/src/lib/util/filesystem.cc b/src/lib/util/filesystem.cc index 29d12a67d2..92f6f0df51 100644 --- a/src/lib/util/filesystem.cc +++ b/src/lib/util/filesystem.cc @@ -104,6 +104,10 @@ setUmask() { } } +bool amRoot() { + return (getuid() == 0 || geteuid() == 0); +} + Path::Path(string const& full_name) { dir_present_ = false; if (!full_name.empty()) { diff --git a/src/lib/util/filesystem.h b/src/lib/util/filesystem.h index 587bdf366f..efc9a21eca 100644 --- a/src/lib/util/filesystem.h +++ b/src/lib/util/filesystem.h @@ -99,6 +99,13 @@ isSocket(const std::string& path); void setUmask(); +/// @brief Indicates if current user is root +/// +/// @return True if either the uid or the effective +/// uid is root. +bool +amRoot(); + /// @brief Paths on a filesystem struct Path { /// @brief Constructor