Record CFG-13 privilege evidence

This commit is contained in:
Mario Fetka
2026-07-22 18:26:25 +02:00
parent cdbf93201d
commit d21691e7ec
4 changed files with 72 additions and 1 deletions
+18
View File
@@ -12,6 +12,7 @@ fi
manager=$(sudo -n /usr/bin/systemctl show "$SERVICE" -p MainPID --value)
bongo_uid=$(/usr/bin/id -u bongo)
bongo_gid=$(/usr/bin/id -g bongo)
allowed_caps=" cap_chown cap_dac_override cap_fowner cap_setgid cap_setuid cap_net_bind_service "
if [ -z "$manager" ] || [ "$manager" -le 1 ] ||
! sudo -n /usr/bin/systemctl is-active "$SERVICE" >/dev/null; then
@@ -19,6 +20,22 @@ if [ -z "$manager" ] || [ "$manager" -le 1 ] ||
exit 1
fi
bounding=$(sudo -n /usr/bin/systemctl show "$SERVICE" \
-p CapabilityBoundingSet --value)
if [ -z "$bounding" ]; then
echo "$SERVICE has an empty or unavailable capability boundary" >&2
exit 1
fi
for capability in $bounding; do
case "$allowed_caps" in
*" $capability "*) ;;
*)
echo "$SERVICE permits unexpected capability $capability" >&2
exit 1
;;
esac
done
status_field()
{
field=$1
@@ -135,3 +152,4 @@ for name in $EXPECTED; do
done
echo "PASS all configured agents are manager children with bounded privilege"
echo "PASS service capability boundary: $bounding"
+11
View File
@@ -51,6 +51,17 @@ TLS, protocol I/O, Store access, and Queue access. GNU GSASL is shared by the
mail protocols; its direct Bongo verification callback does not create or
consult a second user database.
Agents which bind a privileged listener start with the manager's restricted
credentials, bind, and permanently change their real/effective/saved UID and
GID to `bongo` before accepting clients. Non-listener agents do the permanent
drop immediately. The manager itself normally has effective UID `bongo` but
retains a bounded supervisor identity so a crashed listener can be replaced.
`bongoworker` has the same inactive exception solely for the short atomic ACME
certificate deployment step. systemd restricts both to `CHOWN`,
`DAC_OVERRIDE`, `FOWNER`, `SETGID`, `SETUID`, and `NET_BIND_SERVICE`; active
and ambient capabilities are empty while idle. Moving ACME deployment into a
smaller dedicated privileged helper remains a future hardening improvement.
## Internal interfaces
The Store protocol on TCP 689 and Queue protocol on TCP 8670 are private
+1 -1
View File
@@ -97,7 +97,7 @@ inputs and outputs is absent from the ZIP.
| CFG-10 | Existing certificate/key validation and safe rejection of broken pairs | [PASS](test-evidence/0.7-r1.md#cfg-10) | | |
| CFG-11 | DKIM/SPF/DMARC discovery, key import/generation, DNS hints, and task | [PASS](test-evidence/0.7-r1.md#cfg-11) | | |
| CFG-12 | Manager start, reload, restart, clean stop, stale PID, and crash recovery | [PASS](test-evidence/0.7-r1.md#cfg-12) | | |
| CFG-13 | Every agent starts as intended and drops privileges | | | |
| CFG-13 | Every agent starts as intended; permanent/effective privilege drops and supervisor exceptions are bounded | [PASS](test-evidence/0.7-r1.md#cfg-13) | | |
| CFG-14 | tmpfiles creates runtime paths; package contains no runtime PID directories | | | |
| CFG-15 | systemd ordering, hardening, scanner timer, and worker scheduling | | | |
| CFG-16 | Timezone cache rebuild uses the installed checked-in snapshot | | | |
+42
View File
@@ -1189,3 +1189,45 @@ Runtime configuration: the installed Gentoo live package and existing
disposable Bongo configuration were used. The test intentionally interrupted
the Queue and manager processes, restored the service automatically on every
exit path, and left the service active.
## CFG-13
Result: **PASS**
The live process tree was audited after installing commit `cdbf9320` and
restarting the systemd service. `contrib/testing/agent-privilege-check.sh`
verified every UID, GID, supplementary-group, and capability tuple directly
from `/proc`, as well as parentage below the manager and systemd's capability
boundary.
All 13 configured agents were present beneath the manager: Store, Queue,
Antispam, Antivirus, Rules, ManageSieve, Collector, Worker, SMTP receive, SMTP
client, IMAP, POP3, and Web. With the documented Worker exception, every
agent had real, effective, saved, and filesystem UID/GID 404 (`bongo`), no
supplementary groups, and zero inherited, permitted, effective, and ambient
capabilities. Antispam and Antivirus had previously retained real/saved root;
the repair changes them to the same permanent drop used by the other
non-privileged agents.
The manager and scheduled Worker were separately checked: their effective and
filesystem UID was `bongo`, supplementary groups were empty, and inherited,
effective, and ambient capabilities were zero while idle. They retain only a
bounded permitted set for replacement of privileged listeners and the
Worker's atomic ACME certificate deployment. The installed systemd unit
reduced `CapabilityBoundingSet` to exactly `CHOWN`, `DAC_OVERRIDE`, `FOWNER`,
`SETGID`, `SETUID`, and `NET_BIND_SERVICE`; the earlier full kernel capability
boundary is no longer inherited.
```sh
BONGO_ALLOW_LIVE_PRIVILEGE_TEST=1 \
./contrib/testing/agent-privilege-check.sh
```
- Source: commit `cdbf9320`.
- Complete rebuilt CTest result: 82 of 82 passed in 7.18 seconds.
- Live result: 13 of 13 configured agents passed; service remained
active/running with systemd result `success`.
Runtime configuration: the installed Gentoo live package and existing
disposable Bongo configuration were used. The check was read-only and did not
alter process, configuration, mailbox, Queue, or credential state.