Merge fort-nix/nix-bitcoin#846: netns-isolation: fix netns-exec being executable by all normal users

34a18f92ee netns-isolation: fix netns-exec being executable by all normal users (Jonas Nick)

Pull request description:

Top commit has no ACKs.

Tree-SHA512: 3aa359bb61967b76299918b893b85f5d92909029237cba892b367f94c82643268dceaf2928157b47d4973a8af81e5e9ef29651bc45db0e3b149966b16c41bc8b
This commit is contained in:
Jonas Nick
2026-08-12 18:26:21 +00:00
3 changed files with 23 additions and 10 deletions
+4 -3
View File
@@ -37,7 +37,6 @@ let
type = types.str; type = types.str;
description = '' description = ''
User that is allowed to execute commands in the service network namespaces. User that is allowed to execute commands in the service network namespaces.
The user's group is also authorized.
''; '';
default = config.nix-bitcoin.operator.name; default = config.nix-bitcoin.operator.name;
}; };
@@ -122,8 +121,10 @@ in {
source = config.nix-bitcoin.pkgs.netns-exec; source = config.nix-bitcoin.pkgs.netns-exec;
capabilities = "cap_sys_admin=ep"; capabilities = "cap_sys_admin=ep";
owner = cfg.allowedUser; owner = cfg.allowedUser;
group = ""; # Set to the group of `owner` # Don't authorize the group of `owner`. For normal users, this group is
permissions = "550"; # `users`, which is shared by all normal users.
group = "root";
permissions = "500";
}; };
systemd.services = { systemd.services = {
+4
View File
@@ -279,6 +279,10 @@ let
test.data.netns = config.nix-bitcoin.netns-isolation.netns; test.data.netns = config.nix-bitcoin.netns-isolation.netns;
tests.netns-isolation = true; tests.netns-isolation = true;
environment.systemPackages = [ pkgs.fping ]; environment.systemPackages = [ pkgs.fping ];
# Used for testing that `netns-exec` is not executable by users other than
# the operator. Like all normal users, this user is a member of group `users`.
users.users.unauthorized.isNormalUser = true;
}; };
regtestBase = { config, pkgs, ... }: { regtestBase = { config, pkgs, ... }: {
+15 -7
View File
@@ -332,6 +332,21 @@ def _():
f"nc -l {ip('bitcoind')} 1080 2>&1 || true", "nc: Cannot assign requested address" f"nc -l {ip('bitcoind')} 1080 2>&1 || true", "nc: Cannot assign requested address"
) )
# netns-exec should fail for unauthorized namespaces
assert_matches(
"runuser -u operator -- netns-exec nb-clightning ip a 2>&1 || true",
"nb-clightning is not an allowed netns",
)
# netns-exec should only be executable by the operator user.
# User `unauthorized` is a member of group `users`, like all normal users.
# Netns `nb-clightning` is rejected by netns-exec before it accesses the
# netns, so the error below can only originate from the exec permissions.
assert_matches(
"runuser -u unauthorized -- netns-exec nb-clightning ip a 2>&1 || true",
"Permission denied",
)
if "joinmarket" in enabled_tests: if "joinmarket" in enabled_tests:
# netns-exec should drop capabilities # netns-exec should drop capabilities
assert_matches( assert_matches(
@@ -339,13 +354,6 @@ def _():
re.compile("^Current: =$", re.MULTILINE), re.compile("^Current: =$", re.MULTILINE),
) )
if "clightning" in enabled_tests:
# netns-exec should fail for unauthorized namespaces
machine.fail("netns-exec nb-clightning ip a")
# netns-exec should only be executable by the operator user
machine.fail("runuser -u clightning -- netns-exec nb-bitcoind ip a")
# Impure: stops bitcoind (and dependent services) # Impure: stops bitcoind (and dependent services)
@test("backups") @test("backups")