mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +00:00
Merge pull request #25280 from kssenii/bridges-constraints
Privilege drop and resource constraints for bridge processes
This commit is contained in:
commit
b4840bc4a9
@ -8,7 +8,12 @@
|
|||||||
#include <Formats/registerFormats.h>
|
#include <Formats/registerFormats.h>
|
||||||
#include <common/logger_useful.h>
|
#include <common/logger_useful.h>
|
||||||
#include <Common/SensitiveDataMasker.h>
|
#include <Common/SensitiveDataMasker.h>
|
||||||
|
#include <common/errnoToString.h>
|
||||||
#include <Server/HTTP/HTTPServer.h>
|
#include <Server/HTTP/HTTPServer.h>
|
||||||
|
#include <IO/WriteBufferFromFile.h>
|
||||||
|
#include <IO/WriteHelpers.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
#if USE_ODBC
|
#if USE_ODBC
|
||||||
# include <Poco/Data/ODBC/Connector.h>
|
# include <Poco/Data/ODBC/Connector.h>
|
||||||
@ -163,6 +168,31 @@ void IBridge::initialize(Application & self)
|
|||||||
max_server_connections = config().getUInt("max-server-connections", 1024);
|
max_server_connections = config().getUInt("max-server-connections", 1024);
|
||||||
keep_alive_timeout = config().getUInt64("keep-alive-timeout", 10);
|
keep_alive_timeout = config().getUInt64("keep-alive-timeout", 10);
|
||||||
|
|
||||||
|
struct rlimit limit;
|
||||||
|
const UInt64 gb = 1024 * 1024 * 1024;
|
||||||
|
|
||||||
|
/// Set maximum RSS to 1 GiB.
|
||||||
|
limit.rlim_max = limit.rlim_cur = gb;
|
||||||
|
if (setrlimit(RLIMIT_RSS, &limit))
|
||||||
|
LOG_WARNING(log, "Unable to set maximum RSS to 1GB: {} (current rlim_cur={}, rlim_max={})",
|
||||||
|
errnoToString(errno), limit.rlim_cur, limit.rlim_max);
|
||||||
|
|
||||||
|
if (!getrlimit(RLIMIT_RSS, &limit))
|
||||||
|
LOG_INFO(log, "RSS limit: cur={}, max={}", limit.rlim_cur, limit.rlim_max);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const auto oom_score = toString(config().getUInt64("bridge_oom_score", 500));
|
||||||
|
WriteBufferFromFile buf("/proc/self/oom_score_adj");
|
||||||
|
buf.write(oom_score.data(), oom_score.size());
|
||||||
|
buf.close();
|
||||||
|
LOG_INFO(log, "OOM score is set to {}", oom_score);
|
||||||
|
}
|
||||||
|
catch (const Exception & e)
|
||||||
|
{
|
||||||
|
LOG_WARNING(log, "Failed to set OOM score, error: {}", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
initializeTerminationAndSignalProcessing();
|
initializeTerminationAndSignalProcessing();
|
||||||
|
|
||||||
ServerApplication::initialize(self); // NOLINT
|
ServerApplication::initialize(self); // NOLINT
|
||||||
|
@ -75,6 +75,9 @@ namespace ErrorCodes
|
|||||||
#define HILITE "\033[1m"
|
#define HILITE "\033[1m"
|
||||||
#define END_HILITE "\033[0m"
|
#define END_HILITE "\033[0m"
|
||||||
|
|
||||||
|
static constexpr auto CLICKHOUSE_BRIDGE_USER = "clickhouse-bridge";
|
||||||
|
static constexpr auto CLICKHOUSE_BRIDGE_GROUP = "clickhouse-bridge";
|
||||||
|
|
||||||
using namespace DB;
|
using namespace DB;
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
@ -150,7 +153,6 @@ int mainEntryClickHouseInstall(int argc, char ** argv)
|
|||||||
<< argv[0]
|
<< argv[0]
|
||||||
<< " install [options]\n";
|
<< " install [options]\n";
|
||||||
std::cout << desc << '\n';
|
std::cout << desc << '\n';
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -324,26 +326,34 @@ int mainEntryClickHouseInstall(int argc, char ** argv)
|
|||||||
std::string user = options["user"].as<std::string>();
|
std::string user = options["user"].as<std::string>();
|
||||||
std::string group = options["group"].as<std::string>();
|
std::string group = options["group"].as<std::string>();
|
||||||
|
|
||||||
|
auto create_group = [](const String & group_name)
|
||||||
|
{
|
||||||
|
std::string command = fmt::format("groupadd -r {}", group_name);
|
||||||
|
fmt::print(" {}\n", command);
|
||||||
|
executeScript(command);
|
||||||
|
};
|
||||||
|
|
||||||
if (!group.empty())
|
if (!group.empty())
|
||||||
{
|
{
|
||||||
{
|
fmt::print("Creating clickhouse group if it does not exist.\n");
|
||||||
fmt::print("Creating clickhouse group if it does not exist.\n");
|
create_group(group);
|
||||||
std::string command = fmt::format("groupadd -r {}", group);
|
|
||||||
fmt::print(" {}\n", command);
|
|
||||||
executeScript(command);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fmt::print("Will not create clickhouse group");
|
fmt::print("Will not create clickhouse group");
|
||||||
|
|
||||||
|
auto create_user = [](const String & user_name, const String & group_name)
|
||||||
|
{
|
||||||
|
std::string command = group_name.empty()
|
||||||
|
? fmt::format("useradd -r --shell /bin/false --home-dir /nonexistent --user-group {}", user_name)
|
||||||
|
: fmt::format("useradd -r --shell /bin/false --home-dir /nonexistent -g {} {}", group_name, user_name);
|
||||||
|
fmt::print(" {}\n", command);
|
||||||
|
executeScript(command);
|
||||||
|
};
|
||||||
|
|
||||||
if (!user.empty())
|
if (!user.empty())
|
||||||
{
|
{
|
||||||
fmt::print("Creating clickhouse user if it does not exist.\n");
|
fmt::print("Creating clickhouse user if it does not exist.\n");
|
||||||
std::string command = group.empty()
|
create_user(user, group);
|
||||||
? fmt::format("useradd -r --shell /bin/false --home-dir /nonexistent --user-group {}", user)
|
|
||||||
: fmt::format("useradd -r --shell /bin/false --home-dir /nonexistent -g {} {}", group, user);
|
|
||||||
fmt::print(" {}\n", command);
|
|
||||||
executeScript(command);
|
|
||||||
|
|
||||||
if (group.empty())
|
if (group.empty())
|
||||||
group = user;
|
group = user;
|
||||||
@ -475,12 +485,15 @@ int mainEntryClickHouseInstall(int argc, char ** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Chmod and chown configs
|
auto change_ownership = [](const String & file_name, const String & user_name, const String & group_name)
|
||||||
{
|
{
|
||||||
std::string command = fmt::format("chown --recursive {}:{} '{}'", user, group, config_dir.string());
|
std::string command = fmt::format("chown --recursive {}:{} '{}'", user_name, group_name, file_name);
|
||||||
fmt::print(" {}\n", command);
|
fmt::print(" {}\n", command);
|
||||||
executeScript(command);
|
executeScript(command);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/// Chmod and chown configs
|
||||||
|
change_ownership(config_dir.string(), user, group);
|
||||||
|
|
||||||
/// Symlink "preprocessed_configs" is created by the server, so "write" is needed.
|
/// Symlink "preprocessed_configs" is created by the server, so "write" is needed.
|
||||||
fs::permissions(config_dir, fs::perms::owner_all, fs::perm_options::replace);
|
fs::permissions(config_dir, fs::perms::owner_all, fs::perm_options::replace);
|
||||||
@ -558,7 +571,19 @@ int mainEntryClickHouseInstall(int argc, char ** argv)
|
|||||||
/// Data directory is not accessible to anyone except clickhouse.
|
/// Data directory is not accessible to anyone except clickhouse.
|
||||||
fs::permissions(data_path, fs::perms::owner_all, fs::perm_options::replace);
|
fs::permissions(data_path, fs::perms::owner_all, fs::perm_options::replace);
|
||||||
|
|
||||||
/// Set up password for default user.
|
fs::path odbc_bridge_path = bin_dir / "clickhouse-odbc-bridge";
|
||||||
|
fs::path library_bridge_path = bin_dir / "clickhouse-library-bridge";
|
||||||
|
|
||||||
|
if (fs::exists(odbc_bridge_path) || fs::exists(library_bridge_path))
|
||||||
|
{
|
||||||
|
create_group(CLICKHOUSE_BRIDGE_GROUP);
|
||||||
|
create_user(CLICKHOUSE_BRIDGE_USER, CLICKHOUSE_BRIDGE_GROUP);
|
||||||
|
|
||||||
|
if (fs::exists(odbc_bridge_path))
|
||||||
|
change_ownership(odbc_bridge_path, CLICKHOUSE_BRIDGE_USER, CLICKHOUSE_BRIDGE_GROUP);
|
||||||
|
if (fs::exists(library_bridge_path))
|
||||||
|
change_ownership(library_bridge_path, CLICKHOUSE_BRIDGE_USER, CLICKHOUSE_BRIDGE_GROUP);
|
||||||
|
}
|
||||||
|
|
||||||
bool stdin_is_a_tty = isatty(STDIN_FILENO);
|
bool stdin_is_a_tty = isatty(STDIN_FILENO);
|
||||||
bool stdout_is_a_tty = isatty(STDOUT_FILENO);
|
bool stdout_is_a_tty = isatty(STDOUT_FILENO);
|
||||||
@ -573,6 +598,7 @@ int mainEntryClickHouseInstall(int argc, char ** argv)
|
|||||||
/// We can ask password even if stdin is closed/redirected but /dev/tty is available.
|
/// We can ask password even if stdin is closed/redirected but /dev/tty is available.
|
||||||
bool can_ask_password = !noninteractive && stdout_is_a_tty;
|
bool can_ask_password = !noninteractive && stdout_is_a_tty;
|
||||||
|
|
||||||
|
/// Set up password for default user.
|
||||||
if (has_password_for_default_user)
|
if (has_password_for_default_user)
|
||||||
{
|
{
|
||||||
fmt::print(HILITE "Password for default user is already specified. To remind or reset, see {} and {}." END_HILITE "\n",
|
fmt::print(HILITE "Password for default user is already specified. To remind or reset, see {} and {}." END_HILITE "\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user