summaryrefslogtreecommitdiff
path: root/src/core/cgroup.c
diff options
context:
space:
mode:
authorTopi Miettinen <toiwoton@gmail.com>2022-05-22 14:21:02 +0300
committerTopi Miettinen <topimiettinen@users.noreply.github.com>2022-06-08 16:12:25 +0000
commitc0548df0a2f78f3422d77c77c2149d8a7f50d8f6 (patch)
tree4e363ae5071b1c60622f3f8e9ffa621bbeff3150 /src/core/cgroup.c
parentab51fd9dbdc59f9a37acd8acaea3e9088d092bba (diff)
downloadsystemd-c0548df0a2f78f3422d77c77c2149d8a7f50d8f6.tar.gz
core: firewall integration with ControlGroupNFTSet=
New directive `ControlGroupNFTSet=` provides a method for integrating services into firewall rules with NFT sets. Example: ``` table inet filter { ... set timesyncd { type cgroupsv2 } chain ntp_output { socket cgroupv2 != @timesyncd counter drop accept } ... } ``` /etc/systemd/system/systemd-timesyncd.service.d/override.conf ``` [Service] ControlGroupNFTSet=inet:filter:timesyncd ``` ``` $ sudo nft list set inet filter timesyncd table inet filter { set timesyncd { type cgroupsv2 elements = { "system.slice/systemd-timesyncd.service" } } } ```
Diffstat (limited to 'src/core/cgroup.c')
-rw-r--r--src/core/cgroup.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 9282b1ff20..9a07a73f02 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -19,6 +19,7 @@
#include "devnum-util.h"
#include "fd-util.h"
#include "fileio.h"
+#include "firewall-util.h"
#include "in-addr-prefix-util.h"
#include "inotify-util.h"
#include "io-util.h"
@@ -279,6 +280,8 @@ void cgroup_context_done(CGroupContext *c) {
cpu_set_reset(&c->startup_cpuset_cpus);
cpu_set_reset(&c->cpuset_mems);
cpu_set_reset(&c->startup_cpuset_mems);
+
+ c->nft_set_context = nft_set_context_free_many(c->nft_set_context, &c->n_nft_set_contexts);
}
static int unit_get_kernel_memory_limit(Unit *u, const char *file, uint64_t *ret) {
@@ -617,6 +620,11 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
SET_FOREACH(iface, c->restrict_network_interfaces)
fprintf(f, "%sRestrictNetworkInterfaces: %s\n", prefix, iface);
}
+
+ for (size_t i = 0; i < c->n_nft_set_contexts; i++)
+ fprintf(f, "%sControlGroupNFTSet: %s:%s:%s\n", prefix,
+ nfproto_to_string(c->nft_set_context[i].nfproto),
+ c->nft_set_context[i].table, c->nft_set_context[i].set);
}
void cgroup_context_dump_socket_bind_item(const CGroupSocketBindItem *item, FILE *f) {
@@ -1226,6 +1234,46 @@ static void cgroup_apply_firewall(Unit *u) {
(void) bpf_firewall_install(u);
}
+static void cgroup_apply_nft_set(Unit *u) {
+ int r;
+ CGroupContext *c;
+
+ assert(u);
+
+ assert_se(c = unit_get_cgroup_context(u));
+
+ for (size_t i = 0; i < c->n_nft_set_contexts; i++) {
+ NFTSetContext *s = &c->nft_set_context[i];
+ r = nft_set_element_add_uint64(s, u->cgroup_id);
+ if (r < 0)
+ log_warning_errno(r, "Adding NFT family %s table %s set %s cgroup %" PRIu64 " failed, ignoring: %m",
+ nfproto_to_string(s->nfproto),
+ s->table,
+ s->set,
+ u->cgroup_id);
+ }
+}
+
+static void cgroup_delete_nft_set(Unit *u) {
+ int r;
+ CGroupContext *c;
+
+ assert(u);
+
+ assert_se(c = unit_get_cgroup_context(u));
+
+ for (size_t i = 0; i < c->n_nft_set_contexts; i++) {
+ NFTSetContext *s = &c->nft_set_context[i];
+ r = nft_set_element_del_uint64(s, u->cgroup_id);
+ if (r < 0)
+ log_warning_errno(r, "Deleting NFT family %s table %s set %s cgroup %" PRIu64 " failed, ignoring: %m",
+ nfproto_to_string(s->nfproto),
+ s->table,
+ s->set,
+ u->cgroup_id);
+ }
+}
+
static void cgroup_apply_socket_bind(Unit *u) {
assert(u);
@@ -1658,6 +1706,8 @@ static void cgroup_context_apply(
if (apply_mask & CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES)
cgroup_apply_restrict_network_interfaces(u);
+
+ cgroup_apply_nft_set(u);
}
static bool unit_get_needs_bpf_firewall(Unit *u) {
@@ -2807,6 +2857,8 @@ void unit_prune_cgroup(Unit *u) {
(void) lsm_bpf_cleanup(u); /* Remove cgroup from the global LSM BPF map */
#endif
+ cgroup_delete_nft_set(u);
+
is_root_slice = unit_has_name(u, SPECIAL_ROOT_SLICE);
r = cg_trim_everywhere(u->manager->cgroup_supported, u->cgroup_path, !is_root_slice);