diff --git a/Makefile b/Makefile index 4e42bc8..666f1af 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ LOGF = $(TAPIF)Log/ LOGO = $(LOGF)Log.o INCLUDES = -I$(LOGF) -I$(TAPIF)include/ $(addprefix -I, $(INCFS)) -LDFLAGS = -lcurl +LDFLAGS = -lcurl -lseccomp -lcap SRCFILES = $(shell find $(SRCF) -name "*.cpp") OBJFILES = $(patsubst $(SRCF)%, $(BUILDDIR)%, $(patsubst %.cpp, %.o, $(SRCFILES))) $(LOGO) @@ -71,7 +71,7 @@ clean: $(NAMETEST): $(BUILDDIRS) $(DEPF) $(TESTF)*.cpp $(OBJFILESTEST) $(TAPIA) @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) @echo "Running tests" diff --git a/src/main.cpp b/src/main.cpp index 60329d3..7eaff76 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,15 @@ #include //std bind #include // signal #include + +#include //unshare +#include //getpid +#include // umount +#include +#include +#include +#include + #include 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) { Log::init(); Log::setConsoleLogLevel(Log::Level::TRACE); @@ -37,7 +108,7 @@ int main(int argc, const char** argv) { Log::setColoredOutput(true); #endif - Log::info << "Hello, World!"; + Log::info << "Hello, World! pid: " << getpid() << " userid: " << getuid(); //read config std::ifstream configfile("config.json"); @@ -47,6 +118,14 @@ int main(int argc, const char** argv) { FontBot bot; 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 cmd(new CommandStart()); tapi.registerCommand(std::move(cmd));