From 182cfebe40bd49ca23070ebca9b18e71e78bfbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Grzebieluch?= Date: Mon, 5 Feb 2024 17:50:50 +0100 Subject: [PATCH] maintenance_socket: add option to set owning group Option `maintenance-socket-group` sets the owning group of the maintenance socket. If not set, the group will be the same as the user running the scylla node. --- db/config.cc | 2 ++ db/config.hh | 1 + .../admin-tools/maintenance-socket.rst | 4 ++++ transport/controller.cc | 21 ++++++++++++++++++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/db/config.cc b/db/config.cc index d6475729e1..790d42ec3b 100644 --- a/db/config.cc +++ b/db/config.cc @@ -764,6 +764,8 @@ db::config::config(std::shared_ptr exts) "\tworkdir the node will open the maintenance socket on the path /cql.m,\n" "\t where is a path defined by the workdir configuration option\n" "\t the node will open the maintenance socket on the path ") + , maintenance_socket_group(this, "maintenance_socket_group", value_status::Used, "", + "The group that the maintenance socket will be owned by. If not set, the group will be the same as the user running the scylla node.") , maintenance_mode(this, "maintenance_mode", value_status::Used, false, "If set to true, the node will not connect to other nodes. It will only serve requests to its local data.") , native_transport_port_ssl(this, "native_transport_port_ssl", value_status::Used, 9142, "Port on which the CQL TLS native transport listens for clients." diff --git a/db/config.hh b/db/config.hh index 5a6e440ec0..a6de585e46 100644 --- a/db/config.hh +++ b/db/config.hh @@ -276,6 +276,7 @@ public: named_value start_native_transport; named_value native_transport_port; named_value maintenance_socket; + named_value maintenance_socket_group; named_value maintenance_mode; named_value native_transport_port_ssl; named_value native_shard_aware_transport_port; diff --git a/docs/operating-scylla/admin-tools/maintenance-socket.rst b/docs/operating-scylla/admin-tools/maintenance-socket.rst index f35d7e6759..b95a67a95f 100644 --- a/docs/operating-scylla/admin-tools/maintenance-socket.rst +++ b/docs/operating-scylla/admin-tools/maintenance-socket.rst @@ -11,11 +11,15 @@ To set up the maintenance socket, use the `maintenance-socket` option when start * If set to `workdir` maintenance socket will be created in `/cql.m`. * Otherwise maintenance socket will be created in the specified path. + The maintenance socket path has to satisfy following restrictions: * the path has to be shorter than `108` chars (due to linux limits), * a file or a directory cannot exists in this path. +Option `maintenance-socket-group` sets the owning group of the maintenance socket. If not set, the group will be the same as the user running the scylla node. +The user running the scylla node has to be in the group specified by `maintenance-socket-group` option or have root privileges. + Connect to maintenance socket ----------------------------- diff --git a/transport/controller.cc b/transport/controller.cc index e23904944d..00a87ebe06 100644 --- a/transport/controller.cc +++ b/transport/controller.cc @@ -6,6 +6,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ +#include #include "transport/controller.hh" #include #include @@ -181,7 +182,25 @@ future<> controller::start_listening_on_maintenance_socket(sharded& file_permissions::user_read | file_permissions::user_write | file_permissions::group_read | file_permissions::group_write; - return listen_on_all_shards(cserver, addr, nullptr, false, _config.rpc_keepalive(), unix_domain_socket_permissions); + co_await listen_on_all_shards(cserver, addr, nullptr, false, _config.rpc_keepalive(), unix_domain_socket_permissions); + + if (_config.maintenance_socket_group.is_set()) { + auto group_name = _config.maintenance_socket_group(); + struct group *grp; + grp = ::getgrnam(group_name.c_str()); + if (!grp) { + throw std::runtime_error(format("Group id of {} not found. Make sure the group exists.", group_name)); + } + + auto chown_result = ::chown(socket.c_str(), ::geteuid(), grp->gr_gid); + if (chown_result < 0) { + if (errno == EPERM) { + throw std::runtime_error(format("Failed to change group of {}: Permission denied. Make sure the user has the root privilege or is a member of the group {}.", socket, group_name)); + } else { + throw std::runtime_error(format("Failed to chown {}: {} ()", socket, strerror(errno))); + } + } + } } future<> controller::do_start_server() {