Skip to content

Commit 7619927

Browse files
Merge release-25.11 into staging-next-25.11
2 parents 149500a + 056f0cc commit 7619927

32 files changed

Lines changed: 925 additions & 777 deletions

File tree

nixos/modules/services/misc/flaresolverr.nix

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,77 @@ in
4646
RestartSec = 5;
4747
Type = "simple";
4848
DynamicUser = true;
49+
UMask = "0077";
4950
RuntimeDirectory = "flaresolverr";
5051
WorkingDirectory = "/run/flaresolverr";
5152
ExecStart = lib.getExe cfg.package;
5253
TimeoutStopSec = 30;
54+
55+
# Systemd hardening
56+
LockPersonality = true;
57+
PrivateDevices = true;
58+
PrivateMounts = true;
59+
PrivateUsers = true;
60+
ProtectClock = true;
61+
ProtectControlGroups = true;
62+
ProtectHome = true;
63+
ProtectHostname = true;
64+
ProtectKernelLogs = true;
65+
ProtectKernelModules = true;
66+
ProtectKernelTunables = true;
67+
ProtectProc = "invisible";
68+
RestrictRealtime = true;
69+
RestrictAddressFamilies = [
70+
"AF_INET"
71+
"AF_INET6"
72+
"AF_UNIX"
73+
];
74+
RestrictNamespaces = [
75+
"net"
76+
"pid"
77+
"user"
78+
];
79+
CapabilityBoundingSet = [
80+
"~CAP_BLOCK_SUSPEND"
81+
"~CAP_BPF"
82+
"~CAP_CHOWN"
83+
"~CAP_IPC_LOCK"
84+
"~CAP_MKNOD"
85+
"~CAP_NET_ADMIN"
86+
"~CAP_NET_RAW"
87+
"~CAP_PERFMON"
88+
"~CAP_SYSLOG"
89+
"~CAP_SYS_ADMIN"
90+
"~CAP_SYS_BOOT"
91+
"~CAP_SYS_MODULE"
92+
"~CAP_SYS_PACCT"
93+
"~CAP_SYS_PTRACE"
94+
"~CAP_SYS_TIME"
95+
"~CAP_WAKE_ALARM"
96+
];
97+
SystemCallFilter = [
98+
"~@chown"
99+
"~@clock"
100+
"~@cpu-emulation"
101+
"~@debug"
102+
"~@keyring"
103+
"~@memlock"
104+
"~@module"
105+
"~@obsolete"
106+
"~@pkey"
107+
"~@raw-io"
108+
"~@reboot"
109+
"~@setuid"
110+
"~@swap"
111+
"~@timer"
112+
];
113+
SystemCallErrorNumber = "EPERM";
114+
SystemCallArchitectures = "native";
53115
};
54116
};
55117

56118
networking.firewall = lib.mkIf cfg.openFirewall { allowedTCPPorts = [ cfg.port ]; };
57119
};
120+
121+
meta.maintainers = with lib.maintainers; [ diogotcorreia ];
58122
}

nixos/modules/services/system/nix-daemon.nix

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,102 @@ in
6262
];
6363
})
6464
(lib.mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
65+
{
66+
# Unprivileged Nix daemon
67+
config = lib.mkIf (cfg.daemonUser != "root") {
68+
assertions = [
69+
{
70+
message = ''
71+
The Nix daemon cannot run as the root group when not running as the root user.
72+
'';
73+
assertion = cfg.daemonGroup != "root";
74+
}
75+
{
76+
message = ''
77+
Nix must have the `local-overlay-store` experimental feature when not running as the root user.
78+
'';
79+
assertion = lib.elem "local-overlay-store" cfg.settings.experimental-features;
80+
}
81+
{
82+
message = ''
83+
Nix must have the `auto-allocate-uids` experimental feature when not running as the root user.
84+
'';
85+
assertion = lib.elem "auto-allocate-uids" cfg.settings.experimental-features;
86+
}
87+
];
88+
89+
nix.settings = {
90+
sandbox = true;
91+
92+
auto-allocate-uids = true;
93+
94+
# No such group would exist within the sandbox, so chowning to it would fail
95+
build-users-group = "";
96+
97+
# Default settings from Nix, we need to specify them here to use them in nix code though
98+
start-id = lib.mkDefault (832 * 1024 * 1024);
99+
id-count = lib.mkDefault (128 * 65536);
100+
};
101+
102+
systemd.services.nix-daemon = {
103+
# Nix assumes it should use `daemon` if it isn't root, so we have to set `NIX_REMOTE` anyway
104+
environment.NIX_REMOTE = "local?use-roots-daemon=true";
105+
serviceConfig = {
106+
User = cfg.daemonUser;
107+
Group = cfg.daemonGroup;
108+
109+
# Empty string needed to disable old Exec
110+
ExecStart = [
111+
""
112+
"${nixPackage}/libexec/nix-nswrapper ${toString cfg.settings.start-id} ${toString cfg.settings.id-count} ${nixPackage}/bin/nix-daemon --daemon"
113+
];
114+
};
115+
};
116+
117+
# We can't remount rw while unprivileged
118+
boot.nixStoreMountOpts = [
119+
"nodev"
120+
"nosuid"
121+
];
122+
123+
users.users."${cfg.daemonUser}" = {
124+
subUidRanges = [
125+
{
126+
startUid = cfg.settings.start-id;
127+
count = cfg.settings.id-count;
128+
}
129+
];
130+
subGidRanges = [
131+
{
132+
startGid = cfg.settings.start-id;
133+
count = cfg.settings.id-count;
134+
}
135+
];
136+
};
137+
138+
systemd.tmpfiles.rules = [
139+
"d /nix/store 0755 ${config.nix.daemonUser} ${config.nix.daemonGroup} - -"
140+
"Z /nix/var 0755 ${config.nix.daemonUser} ${config.nix.daemonGroup} - -"
141+
"d /nix/var/nix/builds 0755 ${config.nix.daemonUser} ${config.nix.daemonGroup} 7d -"
142+
"d /nix/var/nix/daemon-socket 0755 ${config.nix.daemonUser} ${config.nix.daemonGroup} - -"
143+
"d /nix/var/nix/gc-roots-socket 0755 ${config.nix.daemonUser} ${config.nix.daemonGroup} - -"
144+
];
145+
146+
systemd.services.nix-roots-daemon = {
147+
serviceConfig.ExecStart = "${config.nix.package.out}/bin/nix --extra-experimental-features nix-command store roots-daemon";
148+
};
149+
systemd.sockets.nix-roots-daemon = {
150+
wantedBy = [
151+
"nix-daemon.service"
152+
];
153+
listenStreams = [ "/nix/var/nix/gc-roots-socket/socket" ];
154+
unitConfig = {
155+
ConditionPathIsReadWrite = "/nix/var/nix/gc-roots-socket";
156+
RequiresMountsFor = "/nix/store";
157+
};
158+
};
159+
};
160+
}
65161
];
66162

67163
###### interface
@@ -88,6 +184,24 @@ in
88184
'';
89185
};
90186

187+
daemonUser = lib.mkOption {
188+
type = lib.types.str;
189+
default = "root";
190+
description = ''
191+
User to use to run the Nix daemon.
192+
If this is not "root" then the Nix daemon will set several settings to preserve functionality.
193+
When setting this option, you must also set `nix.daemonGroup`.
194+
'';
195+
};
196+
197+
daemonGroup = lib.mkOption {
198+
type = lib.types.str;
199+
default = "root";
200+
description = ''
201+
Group to use to run the Nix daemon.
202+
'';
203+
};
204+
91205
daemonCPUSchedPolicy = lib.mkOption {
92206
type = lib.types.enum [
93207
"other"
@@ -192,15 +306,18 @@ in
192306

193307
systemd.packages = [ nixPackage ];
194308

195-
systemd.tmpfiles.packages = [ nixPackage ];
309+
# The upstream Nix tmpfiles.d file assumes the daemon runs as root
310+
systemd.tmpfiles.packages = lib.mkIf (cfg.daemonUser == "root") [ nixPackage ];
196311

197312
systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
198313

199314
systemd.services.nix-daemon = {
200315
path = [
201316
nixPackage
202317
config.programs.ssh.package
203-
];
318+
]
319+
# For running "newuidmap"
320+
++ lib.optional (cfg.daemonUser != "root") "/run/wrappers";
204321

205322
environment =
206323
cfg.envVars

nixos/tests/flaresolverr.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{ lib, ... }:
22
{
33
name = "flaresolverr";
4-
meta.maintainers = [ ];
4+
meta.maintainers = with lib.maintainers; [ diogotcorreia ];
55

66
nodes.machine =
77
{ pkgs, ... }:

nixos/tests/matrix/continuwuity.nix

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{ lib, ... }:
22
let
33
name = "continuwuity";
4+
user = "alice";
5+
pass = "my-secret-password";
46
in
57
{
68
inherit name;
@@ -12,8 +14,7 @@ in
1214
settings.global = {
1315
server_name = name;
1416
address = [ "0.0.0.0" ];
15-
allow_registration = true;
16-
yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true;
17+
admin_execute = [ "users create ${user} ${pass}" ];
1718
};
1819
extraEnvironment.RUST_BACKTRACE = "yes";
1920
};
@@ -30,13 +31,10 @@ in
3031
3132
async def main() -> None:
3233
# Connect to continuwuity
33-
client = nio.AsyncClient("http://continuwuity:6167", "alice")
34-
35-
# Register as user alice
36-
response = await client.register("alice", "my-secret-password")
34+
client = nio.AsyncClient("http://continuwuity:6167", "${user}")
3735
3836
# Log in as user alice
39-
response = await client.login("my-secret-password")
37+
response = await client.login("${pass}")
4038
4139
# Create a new room
4240
response = await client.room_create(federate=False)

nixos/tests/rancher/multi-node.nix

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,6 @@ in
218218
# wait for the agent to show up
219219
server.wait_until_succeeds("kubectl get node agent")
220220
221-
${lib.optionalString (rancherDistro == "k3s") ''
222-
for m in machines:
223-
m.succeed("k3s check-config")
224-
''}
225-
226221
server.succeed("kubectl cluster-info")
227222
# Also wait for our service account to show up; it takes a sec
228223
server.wait_until_succeeds("kubectl get serviceaccount default")

nixos/tests/rancher/single-node.nix

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ in
8484
machine.wait_for_unit("${serviceName}")
8585
machine.succeed("kubectl cluster-info")
8686
machine.fail("sudo -u noprivs kubectl cluster-info")
87-
${lib.optionalString (rancherDistro == "k3s") ''
88-
machine.succeed("k3s check-config")
89-
''}
9087
9188
# Also wait for our service account to show up; it takes a sec
9289
machine.wait_until_succeeds("kubectl get serviceaccount default")

0 commit comments

Comments
 (0)