Set cgroup defaults, add some audit multicast support

This commit is contained in:
Tad Glines 2020-09-01 12:11:41 -07:00
Родитель 301bdcef86
Коммит 73d8e08505
11 изменённых файлов: 122 добавлений и 13 удалений

Просмотреть файл

@ -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
Просмотреть файл

@ -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,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;

Просмотреть файл

@ -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");
}

Просмотреть файл

@ -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();