diff --git a/modules/presets/secure-node.nix b/modules/presets/secure-node.nix
index 374dd52..7933487 100644
--- a/modules/presets/secure-node.nix
+++ b/modules/presets/secure-node.nix
@@ -227,6 +227,7 @@ in {
isNormalUser = true;
extraGroups = [
"systemd-journal"
+ "proc" # Enable full /proc access and systemd-status
cfg.bitcoind.group
]
++ (optionals cfg.clightning.enable [ "clightning" ])
diff --git a/modules/security.nix b/modules/security.nix
index 89efc66..f4d2c78 100644
--- a/modules/security.nix
+++ b/modules/security.nix
@@ -7,21 +7,27 @@
# This mitigates a systemd security issue leaking (sub)process
# command lines.
- # Only allow root to retrieve systemd unit information like
+ # Only allow users with group 'proc' to retrieve systemd unit information like
# cgroup paths (i.e. (sub)process command lines) via D-Bus.
# This D-Bus call is used by `systemctl status`.
- services.dbus.packages = [ (pkgs.writeTextDir "etc/dbus-1/system.d/dbus.conf" ''
-
-
-
-
-
-
-
-
- '') ];
+ services.dbus.packages = lib.mkAfter [ # Apply at the end to override the default policy
+ (pkgs.writeTextDir "etc/dbus-1/system.d/dbus.conf" ''
+
+
+
+
+
+
+
+
+ '')
+ ];
}
diff --git a/test/scenarios/lib.py b/test/scenarios/lib.py
index 78c28a8..2ebda30 100644
--- a/test/scenarios/lib.py
+++ b/test/scenarios/lib.py
@@ -103,11 +103,13 @@ def run_tests(extra_tests):
machine.wait_until_succeeds(log_has_string("bitcoind-import-banlist", "Importing node banlist"))
assert_no_failure("bitcoind-import-banlist")
- # test that `systemctl status` can't leak credentials
+ # `systemctl status` run by unprivileged users shouldn't leak cgroup info
assert_matches(
"sudo -u electrs systemctl status clightning 2>&1 >/dev/null",
"Failed to dump process list for 'clightning.service', ignoring: Access denied",
)
+ # The 'operator' with group 'proc' has full access
+ assert_full_match("sudo -u operator systemctl status clightning 2>&1 >/dev/null", "")
machine.succeed("grep -Fq hidepid=2 /proc/mounts")
### Additional tests