From c390085f964cc2f010adb9c2945ba3a96289d011 Mon Sep 17 00:00:00 2001 From: Blagovest Petrov Date: Thu, 5 Nov 2026 07:21:46 +0200 Subject: [PATCH] feat(agent): run the service at MCS level s0:c1023 on SELinux systems The packaged unit sets SELinuxContext= with a leading "-", so the agent keeps its unconfined service domain but gets a category of its own. The label changes nothing by itself: on the targeted policy MCS binds only container domains for file access. It lets an SELinux policy single the agent process out, for example with a constraint that refuses signals from senders at a lower level, without a module per node. Where the policy lacks the type systemd ignores the failure, and the directive is skipped where SELinux is disabled. Document the category in the hardening guide and on the SELinux policy type page. --- doc/policy-types/selinux.md | 7 ++++++- doc/security/hardening.md | 11 +++++++++++ packaging/systemd/bor-agent.service | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/doc/policy-types/selinux.md b/doc/policy-types/selinux.md index 69f392e3..a89f355b 100644 --- a/doc/policy-types/selinux.md +++ b/doc/policy-types/selinux.md @@ -145,7 +145,12 @@ inapplicable item that names it. parentheses and a statement allowlist; `semodule` on the node reports anything else. A Bor scheduled task can run under a type declared in a custom module: set `SELinuxContext` on the task in a - [Services & timers](systemd.md) policy. + [Services & timers](systemd.md) policy. The agent process itself runs + in the unconfined service domain at MCS level `s0:c1023` (see + [Hardening](../security/hardening.md#built-in-service-hardening)), so + a custom module can single it out by level, for example with a + `constrain` statement that refuses signals from senders whose level + does not dominate the target's. **File contexts** : A path expression (`/opt/corpapp(/.*)?`), the SELinux type, the file diff --git a/doc/security/hardening.md b/doc/security/hardening.md index 2940def4..01022e3e 100644 --- a/doc/security/hardening.md +++ b/doc/security/hardening.md @@ -143,6 +143,17 @@ The agent (`bor-agent.service`) runs as root. It must write system policy files (browser policies, dconf, polkit rules, firewalld zones, repository definitions and so on), so it is not sandboxed. +On SELinux systems the unit starts the agent in the unconfined service +domain at MCS level `s0:c1023` (`SELinuxContext=` in the unit; the leading +`-` lets the agent start where the policy has no such type, and the +directive is ignored where SELinux is disabled). The category confines +nothing by itself. It lets an [SELinux](../policy-types/selinux.md) policy +single the agent process out, for example with a constraint that refuses +signals from senders at a lower level, so that `kill -9` from a root shell +is denied while `systemctl restart bor-agent` keeps working. Files the +agent writes carry the level; on the targeted policy MCS binds only +container domains for file access, so nothing else is affected. + ## File permissions | Path | Owner | Mode | Notes | diff --git a/packaging/systemd/bor-agent.service b/packaging/systemd/bor-agent.service index 4a7e55d4..67180d7e 100644 --- a/packaging/systemd/bor-agent.service +++ b/packaging/systemd/bor-agent.service @@ -13,6 +13,15 @@ RestartSec=30 # cancelled through the agent's context on stop; give them time to wind down # cleanly before systemd escalates to SIGKILL. TimeoutStopSec=120 +# Run the agent with an MCS category of its own on SELinux systems. The +# category changes nothing by itself: the agent stays in the unconfined +# service domain and MCS binds only container domains for file access. It +# lets an SELinux policy single the agent process out, for example a +# constraint that refuses signals from senders at a lower level, without a +# policy module per node. The leading "-" makes systemd ignore a failure to +# set the context (a policy without the type); the directive is ignored +# entirely where SELinux is disabled. +SELinuxContext=-system_u:system_r:unconfined_service_t:s0:c1023 StandardOutput=journal StandardError=journal SyslogIdentifier=bor-agent