seccomp basics
This commit is contained in:
parent
034977d53f
commit
f1c3eac487
4
Makefile
4
Makefile
|
@ -24,7 +24,7 @@ LOGF = $(TAPIF)Log/
|
||||||
LOGO = $(LOGF)Log.o
|
LOGO = $(LOGF)Log.o
|
||||||
|
|
||||||
INCLUDES = -I$(LOGF) -I$(TAPIF)include/ $(addprefix -I, $(INCFS))
|
INCLUDES = -I$(LOGF) -I$(TAPIF)include/ $(addprefix -I, $(INCFS))
|
||||||
LDFLAGS = -lcurl
|
LDFLAGS = -lcurl -lseccomp -lcap
|
||||||
|
|
||||||
SRCFILES = $(shell find $(SRCF) -name "*.cpp")
|
SRCFILES = $(shell find $(SRCF) -name "*.cpp")
|
||||||
OBJFILES = $(patsubst $(SRCF)%, $(BUILDDIR)%, $(patsubst %.cpp, %.o, $(SRCFILES))) $(LOGO)
|
OBJFILES = $(patsubst $(SRCF)%, $(BUILDDIR)%, $(patsubst %.cpp, %.o, $(SRCFILES))) $(LOGO)
|
||||||
|
@ -71,7 +71,7 @@ clean:
|
||||||
|
|
||||||
$(NAMETEST): $(BUILDDIRS) $(DEPF) $(TESTF)*.cpp $(OBJFILESTEST) $(TAPIA)
|
$(NAMETEST): $(BUILDDIRS) $(DEPF) $(TESTF)*.cpp $(OBJFILESTEST) $(TAPIA)
|
||||||
@echo "Compiling tests"
|
@echo "Compiling tests"
|
||||||
@$(CXX) -o $@ $(filter %.o, $^) $(filter %.a, $^) $(filter %.cpp, $^) $(CFLAGS) -I$(SRCF) $(INCLUDES) $(LDFLAGS)
|
$(CXX) -o $@ $(filter %.o, $^) $(filter %.a, $^) $(filter %.cpp, $^) $(CFLAGS) -I$(SRCF) $(INCLUDES) $(LDFLAGS)
|
||||||
|
|
||||||
runtest: $(NAMETEST)
|
runtest: $(NAMETEST)
|
||||||
@echo "Running tests"
|
@echo "Running tests"
|
||||||
|
|
81
src/main.cpp
81
src/main.cpp
|
@ -6,6 +6,15 @@
|
||||||
#include <functional> //std bind
|
#include <functional> //std bind
|
||||||
#include <signal.h> // signal
|
#include <signal.h> // signal
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <sched.h> //unshare
|
||||||
|
#include <unistd.h> //getpid
|
||||||
|
#include <sys/mount.h> // umount
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#include <seccomp.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/capability.h>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
@ -29,6 +38,68 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool enableSecurity() {
|
||||||
|
// create new mount and user namespace
|
||||||
|
if(unshare(CLONE_NEWUSER|CLONE_NEWNS) == -1) {
|
||||||
|
Log::warn << "unsahre(NEWUSER|NEWNS) failed: " << strerror(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info << "new userid: " << getuid();
|
||||||
|
|
||||||
|
// chroot in current directory
|
||||||
|
if(chroot("./") == -1) {
|
||||||
|
Log::fatal << "chroot failed " << strerror(errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//setup seccomp
|
||||||
|
scmp_filter_ctx scmp = seccomp_init(SCMP_ACT_KILL_PROCESS);
|
||||||
|
if(!scmp) {
|
||||||
|
Log::fatal << "init seccmp failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0);
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(poll), 0);
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(openat), 1, SCMP_A2_64(SCMP_CMP_MASKED_EQ, ~ (O_RDONLY | O_NONBLOCK | O_CLOEXEC), 0)); // datein nur readonly und ggf nonblock öffnen
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(stat), 0);
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(close), 0);
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
|
||||||
|
seccomp_rule_add(scmp, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction), 0);
|
||||||
|
|
||||||
|
//apply seccomp
|
||||||
|
int err = seccomp_load(scmp);
|
||||||
|
if(err != 0) {
|
||||||
|
seccomp_release(scmp);
|
||||||
|
Log::fatal << "could not load seccomp " << strerror(err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seccomp_release(scmp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
//drop all capabilities and apply nobody uid
|
||||||
|
const uid_t nobody = 65534;
|
||||||
|
const gid_t groups[] = {65534};
|
||||||
|
if (cap_setgroups(groups[0], 1, groups) != 0) {
|
||||||
|
Log::fatal << "cap_setgroups() failed: " << strerror(errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cap_setuid(nobody) != 0) {
|
||||||
|
Log::fatal << "cap_setuid() failed: " << strerror(errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cap_set_mode(CAP_MODE_NOPRIV) != 0) {
|
||||||
|
Log::fatal << "cap_set_mode(CAP_MODE_NOPRIV) failed: " << strerror(errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, const char** argv) {
|
int main(int argc, const char** argv) {
|
||||||
Log::init();
|
Log::init();
|
||||||
Log::setConsoleLogLevel(Log::Level::TRACE);
|
Log::setConsoleLogLevel(Log::Level::TRACE);
|
||||||
|
@ -37,7 +108,7 @@ int main(int argc, const char** argv) {
|
||||||
Log::setColoredOutput(true);
|
Log::setColoredOutput(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Log::info << "Hello, World!";
|
Log::info << "Hello, World! pid: " << getpid() << " userid: " << getuid();
|
||||||
|
|
||||||
//read config
|
//read config
|
||||||
std::ifstream configfile("config.json");
|
std::ifstream configfile("config.json");
|
||||||
|
@ -47,6 +118,14 @@ int main(int argc, const char** argv) {
|
||||||
FontBot bot;
|
FontBot bot;
|
||||||
TelegramAPI::Manager tapi(j["telegram"]["apikey"]);
|
TelegramAPI::Manager tapi(j["telegram"]["apikey"]);
|
||||||
|
|
||||||
|
if(!enableSecurity())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// test seccomp settings
|
||||||
|
// Log::info << "try to open this file";
|
||||||
|
// int fd = open(argv[0], O_WRONLY);
|
||||||
|
// Log::fatal << "ok";
|
||||||
|
|
||||||
std::unique_ptr<TelegramAPI::Command> cmd(new CommandStart());
|
std::unique_ptr<TelegramAPI::Command> cmd(new CommandStart());
|
||||||
tapi.registerCommand(std::move(cmd));
|
tapi.registerCommand(std::move(cmd));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue