Set cgroup defaults, add some audit multicast support
This commit is contained in:
Родитель
301bdcef86
Коммит
73d8e08505
|
@ -229,6 +229,7 @@ add_executable(auomsctl
|
|||
UnixDomainListener.cpp
|
||||
Event.cpp
|
||||
UserDB.cpp
|
||||
KernelInfo.cpp
|
||||
)
|
||||
|
||||
# See https://gcc.gnu.org/onlinedocs/libstdc++/manual/license.html
|
||||
|
|
|
@ -17,16 +17,14 @@
|
|||
#include "CPULimits.h"
|
||||
|
||||
#define CG_NAME_CONFIG_NAME "cpu_cgroup_name"
|
||||
#define HARD_LIMIT_NAME "cpu_per_core_limit"
|
||||
#define SOFT_LIMIT_NAME "cpu_soft_limit"
|
||||
|
||||
std::shared_ptr<CGroupCPU> CPULimits::CGFromConfig(const Config& config, const std::string& default_cg_name) {
|
||||
std::string cg_name = default_cg_name;
|
||||
double hard_limit = MAX_PCT;
|
||||
double soft_limit = MAX_PCT;
|
||||
|
||||
if (config.HasKey(HARD_LIMIT_NAME)) {
|
||||
hard_limit = config.GetDouble(HARD_LIMIT_NAME);
|
||||
if (config.HasKey(CPU_HARD_LIMIT_NAME)) {
|
||||
hard_limit = config.GetDouble(CPU_HARD_LIMIT_NAME);
|
||||
}
|
||||
|
||||
if (hard_limit > MAX_PCT) {
|
||||
|
@ -35,8 +33,8 @@ std::shared_ptr<CGroupCPU> CPULimits::CGFromConfig(const Config& config, const s
|
|||
hard_limit = MIN_PCT;
|
||||
}
|
||||
|
||||
if (config.HasKey(SOFT_LIMIT_NAME)) {
|
||||
soft_limit = config.GetDouble(SOFT_LIMIT_NAME);
|
||||
if (config.HasKey(CPU_SOFT_LIMIT_NAME)) {
|
||||
soft_limit = config.GetDouble(CPU_SOFT_LIMIT_NAME);
|
||||
}
|
||||
|
||||
if (soft_limit > MAX_PCT) {
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include "Config.h"
|
||||
#include "CGroups.h"
|
||||
|
||||
#define CPU_HARD_LIMIT_NAME "cpu_per_core_limit"
|
||||
#define CPU_SOFT_LIMIT_NAME "cpu_soft_limit"
|
||||
|
||||
class CPULimits {
|
||||
public:
|
||||
static constexpr double MAX_PCT = 100.0;
|
||||
|
|
8
Gate.h
8
Gate.h
|
@ -50,7 +50,13 @@ public:
|
|||
// Return true if desired state reached, false on timeout
|
||||
bool Wait(state_t state, int timeout) {
|
||||
std::unique_lock lock(_mutex);
|
||||
return _cond.wait_for(lock, std::chrono::milliseconds(timeout), [this,state]() { return _state == state; });
|
||||
if (timeout < 0) {
|
||||
_cond.wait(lock, [this, state]() { return _state == state; });
|
||||
return true;
|
||||
} else {
|
||||
return _cond.wait_for(lock, std::chrono::milliseconds(timeout),
|
||||
[this, state]() { return _state == state; });
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define MINIMUM_INTERFIELD_COMPARE_VERSION "3.10"
|
||||
#define MINIMUM_EXE_FIELD_VERSION "4.4"
|
||||
#define MINIMUM_SESSIONID_FIELD_VERSION "4.10"
|
||||
#define MINIMUM_AUDIT_MULTICAST_VERSION "3.16"
|
||||
|
||||
static std::once_flag s_init_flag;
|
||||
|
||||
|
@ -59,6 +60,7 @@ void KernelInfo::load() noexcept {
|
|||
_compare = kver >= Version(MINIMUM_INTERFIELD_COMPARE_VERSION);
|
||||
_exe_field = kver >= Version(MINIMUM_EXE_FIELD_VERSION);
|
||||
_session_id_field = kver >= Version(MINIMUM_SESSIONID_FIELD_VERSION);
|
||||
_audit_multicast = kver >= Version(MINIMUM_AUDIT_MULTICAST_VERSION);
|
||||
|
||||
std::string config_path = "/boot/config-" + _kver;
|
||||
try {
|
||||
|
|
|
@ -33,9 +33,10 @@ public:
|
|||
static bool HasAuditInterfieldCompare() { return ptr()->_compare; };
|
||||
static bool HasAuditExeField() { return ptr()->_exe_field; };
|
||||
static bool HasAuditSessionIdField() { return ptr()->_session_id_field; };
|
||||
static bool HasAuditMulticast() { return ptr()->_audit_multicast; };
|
||||
|
||||
private:
|
||||
KernelInfo(): _kver(), _is_64bit(false), _syscall(false), _compare(false), _exe_field(false), _session_id_field(false) {};
|
||||
KernelInfo(): _kver(), _is_64bit(false), _syscall(false), _compare(false), _exe_field(false), _session_id_field(false), _audit_multicast(false) {};
|
||||
|
||||
static void init();
|
||||
static KernelInfo* ptr();
|
||||
|
@ -49,6 +50,7 @@ private:
|
|||
bool _compare;
|
||||
bool _exe_field;
|
||||
bool _session_id_field;
|
||||
bool _audit_multicast;
|
||||
};
|
||||
|
||||
|
||||
|
|
30
Netlink.cpp
30
Netlink.cpp
|
@ -30,7 +30,7 @@
|
|||
#define SOL_NETLINK 270
|
||||
#endif
|
||||
|
||||
int Netlink::Open(reply_fn_t&& default_msg_handler_fn) {
|
||||
int Netlink::Open(reply_fn_t&& default_msg_handler_fn, bool multicast) {
|
||||
std::unique_lock<std::mutex> _lock(_run_mutex);
|
||||
|
||||
if (_start) {
|
||||
|
@ -51,6 +51,33 @@ int Netlink::Open(reply_fn_t&& default_msg_handler_fn) {
|
|||
return -saved_errno;
|
||||
}
|
||||
|
||||
sockaddr_nl addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.nl_family = AF_NETLINK;
|
||||
addr.nl_pid = 0;
|
||||
if (multicast) {
|
||||
addr.nl_groups = 1; // AUDIT_NLGRP_READLOG
|
||||
} else {
|
||||
addr.nl_groups = 0;
|
||||
}
|
||||
|
||||
if (bind(fd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) != 0) {
|
||||
auto saved_errno = errno;
|
||||
Logger::Error("Failed to bind NETLINK socket: %s", std::strerror(errno));
|
||||
close(fd);
|
||||
return -saved_errno;
|
||||
}
|
||||
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addr_len) != 0) {
|
||||
auto saved_errno = errno;
|
||||
Logger::Error("Failed to get assigned NETLINK 'port': %s", std::strerror(errno));
|
||||
close(fd);
|
||||
return -saved_errno;
|
||||
}
|
||||
|
||||
_pid = addr.nl_pid;
|
||||
|
||||
int on = 1;
|
||||
if (setsockopt(fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &on, sizeof(on)) != 0) {
|
||||
Logger::Error("Cannot set NETLINK_NO_ENOBUFS option on audit NETLINK socket: %s", std::strerror(errno));
|
||||
|
@ -94,6 +121,7 @@ int Netlink::Send(uint16_t type, const void* data, size_t len, reply_fn_t&& repl
|
|||
} while (_replies.count(seq) > 0 || _known_seq.count(seq) > 0);
|
||||
|
||||
nl->nlmsg_seq = seq;
|
||||
nl->nlmsg_pid = _pid;
|
||||
|
||||
if (data != nullptr && len > 0) {
|
||||
nl->nlmsg_len = static_cast<uint32_t>(NLMSG_SPACE(len));
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
* If request fails for another reason will return -errno
|
||||
*/
|
||||
|
||||
int Open(reply_fn_t&& default_msg_handler_fn);
|
||||
int Open(reply_fn_t&& default_msg_handler_fn, bool multicast = false);
|
||||
void Close();
|
||||
|
||||
int Send(uint16_t type, const void* data, size_t len, reply_fn_t&& reply_fn);
|
||||
|
@ -102,6 +102,7 @@ private:
|
|||
void handle_msg(uint16_t msg_type, uint16_t msg_flags, uint32_t msg_seq, const void* payload_data, size_t payload_len);
|
||||
|
||||
int _fd;
|
||||
uint32_t _pid;
|
||||
volatile uint32_t _sequence;
|
||||
reply_fn_t _default_msg_handler_fn;
|
||||
bool _quite;
|
||||
|
|
10
auoms.cpp
10
auoms.cpp
|
@ -274,6 +274,16 @@ int main(int argc, char**argv) {
|
|||
Logger::OpenSyslog("auoms", LOG_DAEMON);
|
||||
}
|
||||
|
||||
// Set cgroup defaults
|
||||
if (!config.HasKey(CPU_SOFT_LIMIT_NAME)) {
|
||||
config.SetString(CPU_SOFT_LIMIT_NAME, "5");
|
||||
}
|
||||
|
||||
if (!config.HasKey(CPU_HARD_LIMIT_NAME)) {
|
||||
config.SetString(CPU_HARD_LIMIT_NAME, "25");
|
||||
}
|
||||
|
||||
// Set EventPrioritizer defaults
|
||||
if (!config.HasKey("event_priority_by_syscall")) {
|
||||
config.SetString("event_priority_by_syscall", R"json({"execve":2,"execveat":2,"*":3})json");
|
||||
}
|
||||
|
|
|
@ -457,6 +457,16 @@ int main(int argc, char**argv) {
|
|||
Logger::OpenSyslog("auomscollect", LOG_DAEMON);
|
||||
}
|
||||
|
||||
// Set cgroup defaults
|
||||
if (!config.HasKey(CPU_SOFT_LIMIT_NAME)) {
|
||||
config.SetString(CPU_SOFT_LIMIT_NAME, "3");
|
||||
}
|
||||
|
||||
if (!config.HasKey(CPU_HARD_LIMIT_NAME)) {
|
||||
config.SetString(CPU_HARD_LIMIT_NAME, "20");
|
||||
}
|
||||
|
||||
// Set EventPrioritizer defaults
|
||||
if (!config.HasKey("event_priority_by_syscall")) {
|
||||
config.SetString("event_priority_by_syscall", R"json({"execve":2,"execveat":2,"*":3})json");
|
||||
}
|
||||
|
|
54
auomsctl.cpp
54
auomsctl.cpp
|
@ -39,6 +39,7 @@
|
|||
#include <sstream>
|
||||
|
||||
#include "env_config.h"
|
||||
#include "KernelInfo.h"
|
||||
|
||||
#define AUOMS_SERVICE_NAME "auoms"
|
||||
#define AUDITD_SERVICE_NAME "auditd"
|
||||
|
@ -1164,6 +1165,50 @@ int tap_audit() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************
|
||||
**
|
||||
*********************************************************************************************************************/
|
||||
|
||||
int tap_audit_multicast() {
|
||||
if (!check_permissions()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
auto ki = KernelInfo::GetKernelInfo();
|
||||
if (!ki.HasAuditMulticast()) {
|
||||
Logger::Error("Audit multicast not supported in kerenel version %s", ki.KernelVersion().c_str());
|
||||
return 1;
|
||||
}
|
||||
} catch (std::exception &ex) {
|
||||
Logger::Error("Failed to determine if audit multicast is supported: %s", ex.what());
|
||||
}
|
||||
|
||||
Netlink netlink;
|
||||
Gate _stop_gate;
|
||||
|
||||
std::function handler = [](uint16_t type, uint16_t flags, const void* data, size_t len) -> bool {
|
||||
if (type >= AUDIT_FIRST_USER_MSG) {
|
||||
std::cout << "type=" << RecordTypeToName(static_cast<RecordType>(type)) << " " << std::string_view(reinterpret_cast<const char*>(data), len) << std::endl;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Logger::Info("Connecting to AUDIT NETLINK socket");
|
||||
auto ret = netlink.Open(std::move(handler), true);
|
||||
if (ret != 0) {
|
||||
Logger::Error("Failed to open AUDIT NETLINK connection: %s", std::strerror(-ret));
|
||||
return 1;
|
||||
}
|
||||
Defer _close_netlink([&netlink]() { netlink.Close(); });
|
||||
|
||||
Signals::SetExitHandler([&_stop_gate]() { _stop_gate.Open(); });
|
||||
|
||||
_stop_gate.Wait(Gate::OPEN, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************
|
||||
**
|
||||
*********************************************************************************************************************/
|
||||
|
@ -1735,23 +1780,26 @@ int main(int argc, char**argv) {
|
|||
return disable_auoms();
|
||||
} else if (strcmp(argv[1], "start") == 0) {
|
||||
bool all = false;
|
||||
if (argc > 2 && strcmp(argv[1], "all") == 0) {
|
||||
if (argc > 2 && strcmp(argv[2], "all") == 0) {
|
||||
all = true;
|
||||
}
|
||||
return start_auoms(all);
|
||||
} else if (strcmp(argv[1], "restart") == 0) {
|
||||
bool all = false;
|
||||
if (argc > 2 && strcmp(argv[1], "all") == 0) {
|
||||
if (argc > 2 && strcmp(argv[2], "all") == 0) {
|
||||
all = true;
|
||||
}
|
||||
return restart_auoms(all);
|
||||
} else if (strcmp(argv[1], "stop") == 0) {
|
||||
bool all = false;
|
||||
if (argc > 2 && strcmp(argv[1], "all") == 0) {
|
||||
if (argc > 2 && strcmp(argv[2], "all") == 0) {
|
||||
all = true;
|
||||
}
|
||||
return stop_auoms(all);
|
||||
} else if (strcmp(argv[1], "tap") == 0) {
|
||||
if (argc > 2 && strcmp(argv[2], "multicast") == 0) {
|
||||
return tap_audit_multicast();
|
||||
}
|
||||
return tap_audit();
|
||||
} else if (strcmp(argv[1], "monitor") == 0) {
|
||||
return monitor_auoms_events();
|
||||
|
|
Загрузка…
Ссылка в новой задаче