Skip to content

Commit 86f9eeb

Browse files
nixos-container: add support for --private-users (#362210)
2 parents c9377b1 + a0d8644 commit 86f9eeb

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

nixos/modules/virtualisation/nixos-containers.nix

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ let
115115
extraFlags+=("--private-network")
116116
fi
117117
118+
NIX_BIND_OPT=""
119+
if [ -n "$PRIVATE_USERS" ]; then
120+
extraFlags+=("--private-users=$PRIVATE_USERS")
121+
if [ "$PRIVATE_USERS" = "pick" ] || ( [ "$PRIVATE_USERS" != "identity" ] && [ "$PRIVATE_USERS" -gt 0 ] ); then
122+
# when user namespacing is enabled, we use `idmap` mount option
123+
# so that bind mounts under /nix get proper owner (and not nobody/nogroup).
124+
NIX_BIND_OPT=":idmap"
125+
fi
126+
fi
127+
118128
if [ -n "$HOST_ADDRESS" ] || [ -n "$LOCAL_ADDRESS" ] ||
119129
[ -n "$HOST_ADDRESS6" ] || [ -n "$LOCAL_ADDRESS6" ]; then
120130
extraFlags+=("--network-veth")
@@ -171,13 +181,14 @@ let
171181
$EXTRA_NSPAWN_FLAGS \
172182
--notify-ready=yes \
173183
--kill-signal=SIGRTMIN+3 \
174-
--bind-ro=/nix/store \
175-
--bind-ro=/nix/var/nix/db \
176-
--bind-ro=/nix/var/nix/daemon-socket \
177-
--bind="/nix/var/nix/profiles/per-container/$INSTANCE:/nix/var/nix/profiles" \
178-
--bind="/nix/var/nix/gcroots/per-container/$INSTANCE:/nix/var/nix/gcroots" \
184+
--bind-ro=/nix/store:/nix/store$NIX_BIND_OPT \
185+
--bind-ro=/nix/var/nix/db:/nix/var/nix/db$NIX_BIND_OPT \
186+
--bind-ro=/nix/var/nix/daemon-socket:/nix/var/nix/daemon-socket$NIX_BIND_OPT \
187+
--bind="/nix/var/nix/profiles/per-container/$INSTANCE:/nix/var/nix/profiles$NIX_BIND_OPT" \
188+
--bind="/nix/var/nix/gcroots/per-container/$INSTANCE:/nix/var/nix/gcroots$NIX_BIND_OPT" \
179189
${optionalString (!cfg.ephemeral) "--link-journal=try-guest"} \
180190
--setenv PRIVATE_NETWORK="$PRIVATE_NETWORK" \
191+
--setenv PRIVATE_USERS="$PRIVATE_USERS" \
181192
--setenv HOST_BRIDGE="$HOST_BRIDGE" \
182193
--setenv HOST_ADDRESS="$HOST_ADDRESS" \
183194
--setenv LOCAL_ADDRESS="$LOCAL_ADDRESS" \
@@ -650,6 +661,27 @@ in
650661
'';
651662
};
652663

664+
privateUsers = mkOption {
665+
type = types.either types.ints.u32 (types.enum [ "no" "identity" "pick" ]);
666+
default = "no";
667+
description = ''
668+
Whether to give the container its own private UIDs/GIDs space (user namespacing).
669+
Disabled by default (`no`).
670+
671+
If set to a number (usually above host's UID/GID range: 65536),
672+
user namespacing is enabled and the container UID/GIDs will start at that number.
673+
674+
If set to `identity`, mostly equivalent to `0`, this will only provide
675+
process capability isolation (no UID/GID isolation, as they are the same as host).
676+
677+
If set to `pick`, user namespacing is enabled and the UID/GID range is automatically chosen,
678+
so that no overlapping UID/GID ranges are assigned to multiple containers.
679+
This is the recommanded option as it enhances container security massively and operates fully automatically in most cases.
680+
681+
See https://www.freedesktop.org/software/systemd/man/latest/systemd-nspawn.html#--private-users= for details.
682+
'';
683+
};
684+
653685
interfaces = mkOption {
654686
type = types.listOf types.str;
655687
default = [];
@@ -862,6 +894,13 @@ in
862894
additionalCapabilities = cfg.additionalCapabilities
863895
++ [ "CAP_NET_ADMIN" ];
864896
}
897+
) // (
898+
optionalAttrs (!cfg.enableTun && cfg.privateNetwork
899+
&& (cfg.privateUsers == "pick" || (builtins.isInt cfg.privateUsers && cfg.privateUsers > 0 )))
900+
{
901+
allowedDevices = cfg.allowedDevices
902+
++ [ { node = "/dev/net/tun"; modifier = "rwm"; } ];
903+
}
865904
);
866905
in
867906
recursiveUpdate unit {
@@ -923,6 +962,7 @@ in
923962
${optionalString (cfg.networkNamespace != null) ''
924963
NETWORK_NAMESPACE_PATH=${cfg.networkNamespace}
925964
''}
965+
PRIVATE_USERS=${toString cfg.privateUsers}
926966
INTERFACES="${toString cfg.interfaces}"
927967
MACVLANS="${toString cfg.macvlans}"
928968
${optionalString cfg.autoStart ''

pkgs/by-name/ni/nixos-container/nixos-container.pl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ sub restartContainer {
364364
sub runInContainer {
365365
my @args = @_;
366366
my $leader = getLeader;
367-
exec($nsenter, "-t", $leader, "-m", "-u", "-i", "-n", "-p", "--", @args);
367+
exec($nsenter, "--all", "-t", $leader, "--", @args);
368368
die "cannot run ‘nsenter’: $!\n";
369369
}
370370

0 commit comments

Comments
 (0)