mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-18 17:57:39 +03:00
Initial support for the landlock LSM
This commit is contained in:
parent
4cbff962db
commit
8930ec395e
@ -1,3 +1,7 @@
|
|||||||
|
vNEXT:
|
||||||
|
Support for the Landlock LSM. After initial setup,
|
||||||
|
sslh gives up all local file access rights.
|
||||||
|
|
||||||
v2.0:
|
v2.0:
|
||||||
New sslh-ev: this is functionally equivalent to
|
New sslh-ev: this is functionally equivalent to
|
||||||
sslh-select (mono-process, only forks for specified
|
sslh-select (mono-process, only forks for specified
|
||||||
|
7
Makefile
7
Makefile
@ -8,6 +8,7 @@ ENABLE_REGEX=1 # Enable regex probes
|
|||||||
USELIBCONFIG=1 # Use libconfig? (necessary to use configuration files)
|
USELIBCONFIG=1 # Use libconfig? (necessary to use configuration files)
|
||||||
USELIBWRAP?= # Use libwrap?
|
USELIBWRAP?= # Use libwrap?
|
||||||
USELIBCAP= # Use libcap?
|
USELIBCAP= # Use libcap?
|
||||||
|
USELANDLOCK=1 # Use the landlock LSM?
|
||||||
USESYSTEMD= # Make use of systemd socket activation
|
USESYSTEMD= # Make use of systemd socket activation
|
||||||
USELIBBSD?= # Use libbsd (needed to update process name in `ps`)
|
USELIBBSD?= # Use libbsd (needed to update process name in `ps`)
|
||||||
COV_TEST= # Perform test coverage?
|
COV_TEST= # Perform test coverage?
|
||||||
@ -33,7 +34,7 @@ AR ?= ar
|
|||||||
CFLAGS ?=-Wall -O2 -DLIBPCRE -g $(CFLAGS_COV) $(CFLAGS_SAN)
|
CFLAGS ?=-Wall -O2 -DLIBPCRE -g $(CFLAGS_COV) $(CFLAGS_SAN)
|
||||||
|
|
||||||
LIBS=-lm -lpcre2-8
|
LIBS=-lm -lpcre2-8
|
||||||
OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o collection.o gap.o tcp-probe.o
|
OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o collection.o gap.o tcp-probe.o landlock.o
|
||||||
OBJS_A=libsslh.a
|
OBJS_A=libsslh.a
|
||||||
FORK_OBJS=sslh-fork.o $(OBJS_A)
|
FORK_OBJS=sslh-fork.o $(OBJS_A)
|
||||||
SELECT_OBJS=processes.o udp-listener.o sslh-select.o hash.o tcp-listener.o $(OBJS_A)
|
SELECT_OBJS=processes.o udp-listener.o sslh-select.o hash.o tcp-listener.o $(OBJS_A)
|
||||||
@ -71,6 +72,10 @@ ifneq ($(strip $(USELIBBSD)),)
|
|||||||
CPPFLAGS+=-DLIBBSD
|
CPPFLAGS+=-DLIBBSD
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(strip $(USELANDLOCK)),)
|
||||||
|
CPPFLAGS+=-DLANDLOCK
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
all: sslh $(MAN) echosrv $(CONDITIONAL_TARGETS)
|
all: sslh $(MAN) echosrv $(CONDITIONAL_TARGETS)
|
||||||
|
|
||||||
|
4
common.h
4
common.h
@ -183,4 +183,8 @@ void start_shoveler(int);
|
|||||||
|
|
||||||
void main_loop(struct listen_endpoint *listen_sockets, int num_addr_listen);
|
void main_loop(struct listen_endpoint *listen_sockets, int num_addr_listen);
|
||||||
|
|
||||||
|
/* landlock.c */
|
||||||
|
void setup_landlock(void);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
111
landlock.c
Normal file
111
landlock.c
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Setup a sandbox using the Landlock LSM, if available.
|
||||||
|
|
||||||
|
# Copyright (C) 2023 Yves Rutschle
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it
|
||||||
|
# and/or modify it under the terms of the GNU General Public
|
||||||
|
# License as published by the Free Software Foundation; either
|
||||||
|
# version 2 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be
|
||||||
|
# useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
# PURPOSE. See the GNU General Public License for more
|
||||||
|
# details.
|
||||||
|
#
|
||||||
|
# The full text for the General Public License is here:
|
||||||
|
# http://www.gnu.org/licenses/gpl.html
|
||||||
|
#
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef LANDLOCK
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <linux/landlock.h>
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
#ifndef landlock_create_ruleset
|
||||||
|
static inline int
|
||||||
|
landlock_create_ruleset(const struct landlock_ruleset_attr *const attr,
|
||||||
|
const size_t size, const __u32 flags)
|
||||||
|
{
|
||||||
|
return syscall(__NR_landlock_create_ruleset, attr, size, flags);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef landlock_add_rule
|
||||||
|
static inline int landlock_add_rule(const int ruleset_fd,
|
||||||
|
const enum landlock_rule_type rule_type,
|
||||||
|
const void *const rule_attr,
|
||||||
|
const __u32 flags)
|
||||||
|
{
|
||||||
|
return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef landlock_restrict_self
|
||||||
|
static inline int landlock_restrict_self(const int ruleset_fd,
|
||||||
|
const __u32 flags)
|
||||||
|
{
|
||||||
|
return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void setup_landlock(void)
|
||||||
|
{
|
||||||
|
__u64 restrict_rules =
|
||||||
|
LANDLOCK_ACCESS_FS_EXECUTE |
|
||||||
|
LANDLOCK_ACCESS_FS_READ_FILE |
|
||||||
|
LANDLOCK_ACCESS_FS_READ_DIR |
|
||||||
|
LANDLOCK_ACCESS_FS_WRITE_FILE |
|
||||||
|
LANDLOCK_ACCESS_FS_REMOVE_DIR |
|
||||||
|
LANDLOCK_ACCESS_FS_REMOVE_FILE |
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_CHAR |
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_DIR |
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_REG |
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_SOCK |
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_FIFO |
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_BLOCK |
|
||||||
|
LANDLOCK_ACCESS_FS_MAKE_SYM |
|
||||||
|
LANDLOCK_ACCESS_FS_REFER;
|
||||||
|
|
||||||
|
struct landlock_ruleset_attr ruleset_attr = {
|
||||||
|
.handled_access_fs = restrict_rules
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ruleset_addr.handled_access_fs contains all rights that will be restricted
|
||||||
|
* unless explicitly added */
|
||||||
|
int ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
|
||||||
|
if (ruleset_fd < 0) {
|
||||||
|
print_message(msg_config_error, "Landlock: Failed to create a ruleset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No call to landlock_add_rule: we retain no rights whatsoever */
|
||||||
|
|
||||||
|
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
|
||||||
|
print_message(msg_config_error, "Landlock: Failed to restrict privileges");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (landlock_restrict_self(ruleset_fd, 0)) {
|
||||||
|
print_message(msg_config_error, "Landlock: Failed to enforce ruleset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
close(ruleset_fd);
|
||||||
|
|
||||||
|
print_message(msg_config, "Landlock: all restricted\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
void setup_landlock(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
@ -277,6 +277,7 @@ int main(int argc, char *argv[], char* envp[])
|
|||||||
|
|
||||||
if (cfg.user || cfg.chroot)
|
if (cfg.user || cfg.chroot)
|
||||||
drop_privileges(cfg.user, cfg.chroot);
|
drop_privileges(cfg.user, cfg.chroot);
|
||||||
|
setup_landlock();
|
||||||
|
|
||||||
printcaps();
|
printcaps();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user