]> Git — Sourcephile - sourcephile-nix.git/blob - nixpkgs/patches/apparmor.diff
prosody: move from losurdo to mermet
[sourcephile-nix.git] / nixpkgs / patches / apparmor.diff
1 diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix
2 index 0fa804c1f9c..dc12a12b139 100644
3 --- a/maintainers/maintainer-list.nix
4 +++ b/maintainers/maintainer-list.nix
5 @@ -4455,7 +4455,7 @@
6 name = "Julien Dehos";
7 };
8 julm = {
9 - email = "julm+nix@sourcephile.fr";
10 + email = "julm+nixpkgs@sourcephile.fr";
11 github = "ju1m";
12 githubId = 21160136;
13 name = "Julien Moutinho";
14 diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml
15 index 3da8080958e..55f913cb3d4 100644
16 --- a/nixos/doc/manual/release-notes/rl-2009.xml
17 +++ b/nixos/doc/manual/release-notes/rl-2009.xml
18 @@ -1495,6 +1495,24 @@ services.transmission.settings.rpc-bind-address = "0.0.0.0";
19 to get the previous behavior of listening on all network interfaces.
20 </para>
21 </listitem>
22 + <listitem>
23 + <para>
24 + The <literal>security.apparmor</literal> module,
25 + for the <link xlink:href="https://gitlab.com/apparmor/apparmor/-/wikis/Documentation">AppArmor</link>
26 + Mandatory Access Control system,
27 + has been substantialy improved along with related tools,
28 + so that module maintainers can now more easily write AppArmor profiles for NixOS.
29 + The most notable change on the user-side is the new option <xref linkend="opt-security.apparmor.policies"/>,
30 + replacing the previous <literal>profiles</literal> option
31 + to provide a way to disable a profile
32 + and to select whether to confine in enforce mode (default)
33 + or in complain mode (see <literal>journalctl -b --grep apparmor</literal>).
34 + Before enabling this module, either directly
35 + or by importing <literal>&lt;nixpkgs/nixos/modules/profiles/hardened.nix&gt;</literal>,
36 + please be sure to read the documentation of <link linkend="opt-security.apparmor.enable">security.apparmor.enable</link>,
37 + and especially the part about <xref linkend="opt-security.apparmor.killUnconfinedConfinables"/>.
38 + </para>
39 + </listitem>
40 <listitem>
41 <para>
42 With this release <literal>systemd-networkd</literal> (when enabled through <xref linkend="opt-networking.useNetworkd"/>)
43 diff --git a/nixos/modules/config/fonts/fontconfig.nix b/nixos/modules/config/fonts/fontconfig.nix
44 index 5b681ca5946..97607134bb1 100644
45 --- a/nixos/modules/config/fonts/fontconfig.nix
46 +++ b/nixos/modules/config/fonts/fontconfig.nix
47 @@ -448,6 +448,40 @@ in
48 (mkIf cfg.enable {
49 environment.systemPackages = [ pkgs.fontconfig ];
50 environment.etc.fonts.source = "${fontconfigEtc}/etc/fonts/";
51 + security.apparmor.includes."abstractions/fonts" = ''
52 + # fonts.conf
53 + r ${pkg.out}/etc/fonts/fonts.conf,
54 +
55 + # fontconfig default config files
56 + r ${pkg.out}/etc/fonts/conf.d/*.conf,
57 +
58 + # 00-nixos-cache.conf
59 + r ${cacheConf},
60 +
61 + # 10-nixos-rendering.conf
62 + r ${renderConf},
63 +
64 + # 50-user.conf
65 + ${optionalString cfg.includeUserConf ''
66 + r ${pkg.out}/etc/fonts/conf.d.bak/50-user.conf,
67 + ''}
68 +
69 + # local.conf (indirect priority 51)
70 + ${optionalString (cfg.localConf != "") ''
71 + r ${localConf},
72 + ''}
73 +
74 + # 52-nixos-default-fonts.conf
75 + r ${defaultFontsConf},
76 +
77 + # 53-no-bitmaps.conf
78 + r ${rejectBitmaps},
79 +
80 + ${optionalString (!cfg.allowType1) ''
81 + # 53-nixos-reject-type1.conf
82 + r ${rejectType1},
83 + ''}
84 + '';
85 })
86 (mkIf cfg.enable {
87 fonts.fontconfig.confPackages = [ confPkg ];
88 diff --git a/nixos/modules/config/malloc.nix b/nixos/modules/config/malloc.nix
89 index a3eb55d8a42..fc35993b5a8 100644
90 --- a/nixos/modules/config/malloc.nix
91 +++ b/nixos/modules/config/malloc.nix
92 @@ -87,5 +87,12 @@ in
93 environment.etc."ld-nix.so.preload".text = ''
94 ${providerLibPath}
95 '';
96 + security.apparmor.includes = {
97 + "abstractions/base" = ''
98 + r /etc/ld-nix.so.preload,
99 + r ${config.environment.etc."ld-nix.so.preload".source},
100 + mr ${providerLibPath},
101 + '';
102 + };
103 };
104 }
105 diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
106 index 3b67a857493..73af364f40a 100644
107 --- a/nixos/modules/module-list.nix
108 +++ b/nixos/modules/module-list.nix
109 @@ -190,7 +190,6 @@
110 ./rename.nix
111 ./security/acme.nix
112 ./security/apparmor.nix
113 - ./security/apparmor-suid.nix
114 ./security/audit.nix
115 ./security/auditd.nix
116 ./security/ca.nix
117 diff --git a/nixos/modules/security/apparmor-suid.nix b/nixos/modules/security/apparmor-suid.nix
118 deleted file mode 100644
119 index 6c479e070e2..00000000000
120 --- a/nixos/modules/security/apparmor-suid.nix
121 +++ /dev/null
122 @@ -1,49 +0,0 @@
123 -{ config, lib, pkgs, ... }:
124 -let
125 - cfg = config.security.apparmor;
126 -in
127 -with lib;
128 -{
129 - imports = [
130 - (mkRenamedOptionModule [ "security" "virtualization" "flushL1DataCache" ] [ "security" "virtualisation" "flushL1DataCache" ])
131 - ];
132 -
133 - options.security.apparmor.confineSUIDApplications = mkOption {
134 - type = types.bool;
135 - default = true;
136 - description = ''
137 - Install AppArmor profiles for commonly-used SUID application
138 - to mitigate potential privilege escalation attacks due to bugs
139 - in such applications.
140 -
141 - Currently available profiles: ping
142 - '';
143 - };
144 -
145 - config = mkIf (cfg.confineSUIDApplications) {
146 - security.apparmor.profiles = [ (pkgs.writeText "ping" ''
147 - #include <tunables/global>
148 - /run/wrappers/bin/ping {
149 - #include <abstractions/base>
150 - #include <abstractions/consoles>
151 - #include <abstractions/nameservice>
152 -
153 - capability net_raw,
154 - capability setuid,
155 - network inet raw,
156 -
157 - ${pkgs.stdenv.cc.libc.out}/lib/*.so mr,
158 - ${pkgs.libcap.lib}/lib/libcap.so* mr,
159 - ${pkgs.attr.out}/lib/libattr.so* mr,
160 -
161 - ${pkgs.iputils}/bin/ping mixr,
162 -
163 - #/etc/modules.conf r,
164 -
165 - ## Site-specific additions and overrides. See local/README for details.
166 - ##include <local/bin.ping>
167 - }
168 - '') ];
169 - };
170 -
171 -}
172 diff --git a/nixos/modules/security/apparmor.nix b/nixos/modules/security/apparmor.nix
173 index cfc65b347bc..dfa695b81bb 100644
174 --- a/nixos/modules/security/apparmor.nix
175 +++ b/nixos/modules/security/apparmor.nix
176 @@ -1,59 +1,207 @@
177 { config, lib, pkgs, ... }:
178
179 let
180 - inherit (lib) mkIf mkOption types concatMapStrings;
181 + inherit (builtins) attrNames head map match readFile;
182 + inherit (lib) types;
183 + inherit (config.environment) etc;
184 cfg = config.security.apparmor;
185 + mkDisableOption = name: lib.mkEnableOption name // {
186 + default = true;
187 + example = false;
188 + };
189 + enabledPolicies = lib.filterAttrs (n: p: p.enable) cfg.policies;
190 in
191
192 {
193 - options = {
194 - security.apparmor = {
195 - enable = mkOption {
196 - type = types.bool;
197 - default = false;
198 - description = "Enable the AppArmor Mandatory Access Control system.";
199 - };
200 - profiles = mkOption {
201 - type = types.listOf types.path;
202 - default = [];
203 - description = "List of files containing AppArmor profiles.";
204 - };
205 - packages = mkOption {
206 - type = types.listOf types.package;
207 - default = [];
208 - description = "List of packages to be added to apparmor's include path";
209 - };
210 - };
211 - };
212 + imports = [
213 + (lib.mkRenamedOptionModule [ "security" "virtualization" "flushL1DataCache" ] [ "security" "virtualisation" "flushL1DataCache" ])
214 + (lib.mkRemovedOptionModule [ "security" "apparmor" "confineSUIDApplications" ] "Please use the new options: `security.apparmor.policies.<policy>.enable'.")
215 + (lib.mkRemovedOptionModule [ "security" "apparmor" "profiles" ] "Please use the new option: `security.apparmor.policies'.")
216 + apparmor/includes.nix
217 + apparmor/profiles.nix
218 + ];
219
220 - config = mkIf cfg.enable {
221 - environment.systemPackages = [ pkgs.apparmor-utils ];
222 + options = {
223 + security.apparmor = {
224 + enable = lib.mkEnableOption ''the AppArmor Mandatory Access Control system.
225
226 - boot.kernelParams = [ "apparmor=1" "security=apparmor" ];
227 + If you're enabling this module on a running system,
228 + note that a reboot will be required to activate AppArmor in the kernel.
229
230 - systemd.services.apparmor = let
231 - paths = concatMapStrings (s: " -I ${s}/etc/apparmor.d")
232 - ([ pkgs.apparmor-profiles ] ++ cfg.packages);
233 - in {
234 - after = [ "local-fs.target" ];
235 - before = [ "sysinit.target" ];
236 - wantedBy = [ "multi-user.target" ];
237 - unitConfig = {
238 - DefaultDependencies = "no";
239 - };
240 - serviceConfig = {
241 - Type = "oneshot";
242 - RemainAfterExit = "yes";
243 - ExecStart = map (p:
244 - ''${pkgs.apparmor-parser}/bin/apparmor_parser -rKv ${paths} "${p}"''
245 - ) cfg.profiles;
246 - ExecStop = map (p:
247 - ''${pkgs.apparmor-parser}/bin/apparmor_parser -Rv "${p}"''
248 - ) cfg.profiles;
249 - ExecReload = map (p:
250 - ''${pkgs.apparmor-parser}/bin/apparmor_parser --reload ${paths} "${p}"''
251 - ) cfg.profiles;
252 - };
253 - };
254 - };
255 + Also, beware that enabling this module will by default
256 + try to kill unconfined but confinable running processes,
257 + in order to obtain a confinement matching what is declared in the NixOS configuration.
258 + This will happen when upgrading to a NixOS revision
259 + introducing an AppArmor profile for the executable of a running process.
260 + This is because enabling an AppArmor profile for an executable
261 + can only confine new or already confined processes of that executable,
262 + but leaves already running processes unconfined.
263 + Set <link linkend="opt-security.apparmor.killUnconfinedConfinables">killUnconfinedConfinables</link>
264 + to <literal>false</literal> if you prefer to leave those processes running'';
265 + policies = lib.mkOption {
266 + description = ''
267 + AppArmor policies.
268 + '';
269 + type = types.attrsOf (types.submodule ({ name, config, ... }: {
270 + options = {
271 + enable = mkDisableOption "loading of the profile into the kernel";
272 + enforce = mkDisableOption "enforcing of the policy or only complain in the logs";
273 + profile = lib.mkOption {
274 + description = "The policy of the profile.";
275 + type = types.lines;
276 + apply = pkgs.writeText name;
277 + };
278 + };
279 + }));
280 + default = {};
281 + };
282 + includes = lib.mkOption {
283 + type = types.attrsOf types.lines;
284 + default = {};
285 + description = ''
286 + List of paths to be added to AppArmor's searched paths
287 + when resolving <literal>include</literal> directives.
288 + '';
289 + apply = lib.mapAttrs pkgs.writeText;
290 + };
291 + packages = lib.mkOption {
292 + type = types.listOf types.package;
293 + default = [];
294 + description = "List of packages to be added to AppArmor's include path";
295 + };
296 + enableCache = lib.mkEnableOption ''caching of AppArmor policies
297 + in <literal>/var/cache/apparmor/</literal>.
298 +
299 + Beware that AppArmor policies almost always contain Nix store paths,
300 + and thus produce at each change of these paths
301 + a new cached version accumulating in the cache'';
302 + killUnconfinedConfinables = mkDisableOption ''killing of processes
303 + which have an AppArmor profile enabled
304 + (in <link linkend="opt-security.apparmor.policies">policies</link>)
305 + but are not confined (because AppArmor can only confine new processes).
306 + Beware that due to a current limitation of AppArmor,
307 + only profiles with exact paths (and no name) can enable such kills'';
308 + };
309 + };
310 +
311 + config = lib.mkIf cfg.enable {
312 + assertions = map (policy:
313 + { assertion = match ".*/.*" policy == null;
314 + message = "`security.apparmor.policies.\"${policy}\"' must not contain a slash.";
315 + # Because, for instance, aa-remove-unknown uses profiles_names_list() in rc.apparmor.functions
316 + # which does not recurse into sub-directories.
317 + }
318 + ) (attrNames cfg.policies);
319 +
320 + environment.systemPackages = [
321 + pkgs.apparmor-utils
322 + pkgs.apparmor-bin-utils
323 + ];
324 + environment.etc."apparmor.d".source = pkgs.linkFarm "apparmor.d" (
325 + # It's important to put only enabledPolicies here and not all cfg.policies
326 + # because aa-remove-unknown reads profiles from all /etc/apparmor.d/*
327 + lib.mapAttrsToList (name: p: {inherit name; path=p.profile;}) enabledPolicies ++
328 + lib.mapAttrsToList (name: path: {inherit name path;}) cfg.includes
329 + );
330 + environment.etc."apparmor/parser.conf".text = ''
331 + ${if cfg.enableCache then "write-cache" else "skip-cache"}
332 + cache-loc /var/cache/apparmor
333 + Include /etc/apparmor.d
334 + '' +
335 + lib.concatMapStrings (p: "Include ${p}/etc/apparmor.d\n") cfg.packages;
336 + # For aa-logprof
337 + environment.etc."apparmor/apparmor.conf".text = ''
338 + '';
339 + # For aa-logprof
340 + environment.etc."apparmor/severity.db".source = pkgs.apparmor-utils + "/etc/apparmor/severity.db";
341 + environment.etc."apparmor/logprof.conf".source = pkgs.runCommand "logprof.conf" {
342 + header = ''
343 + [settings]
344 + # /etc/apparmor.d/ is read-only on NixOS
345 + profiledir = /var/cache/apparmor/logprof
346 + inactive_profiledir = /etc/apparmor.d/disable
347 + # Use: journalctl -b --since today --grep audit: | aa-logprof
348 + logfiles = /dev/stdin
349 +
350 + parser = ${pkgs.apparmor-parser}/bin/apparmor_parser
351 + ldd = ${pkgs.glibc.bin}/bin/ldd
352 + logger = ${pkgs.utillinux}/bin/logger
353 +
354 + # customize how file ownership permissions are presented
355 + # 0 - off
356 + # 1 - default of what ever mode the log reported
357 + # 2 - force the new permissions to be user
358 + # 3 - force all perms on the rule to be user
359 + default_owner_prompt = 1
360 +
361 + custom_includes = /etc/apparmor.d ${lib.concatMapStringsSep " " (p: "${p}/etc/apparmor.d") cfg.packages}
362 +
363 + [qualifiers]
364 + ${pkgs.runtimeShell} = icnu
365 + ${pkgs.bashInteractive}/bin/sh = icnu
366 + ${pkgs.bashInteractive}/bin/bash = icnu
367 + '';
368 + footer = "${pkgs.apparmor-utils}/etc/apparmor/logprof.conf";
369 + passAsFile = [ "header" ];
370 + } ''
371 + cp $headerPath $out
372 + sed '1,/\[qualifiers\]/d' $footer >> $out
373 + '';
374 +
375 + boot.kernelParams = [ "apparmor=1" "security=apparmor" ];
376 +
377 + systemd.services.apparmor = {
378 + after = [
379 + "local-fs.target"
380 + "systemd-journald-audit.socket"
381 + ];
382 + before = [ "sysinit.target" ];
383 + wantedBy = [ "multi-user.target" ];
384 + unitConfig = {
385 + Description="Load AppArmor policies";
386 + DefaultDependencies = "no";
387 + ConditionSecurity = "apparmor";
388 + };
389 + # Reloading instead of restarting enables to load new AppArmor profiles
390 + # without necessarily restarting all services which have Requires=apparmor.service
391 + reloadIfChanged = true;
392 + restartTriggers = [
393 + etc."apparmor/parser.conf".source
394 + etc."apparmor.d".source
395 + ];
396 + serviceConfig = let
397 + killUnconfinedConfinables = pkgs.writeShellScript "apparmor-kill" ''
398 + set -eu
399 + ${pkgs.apparmor-bin-utils}/bin/aa-status --json |
400 + ${pkgs.jq}/bin/jq --raw-output '.processes | .[] | .[] | select (.status == "unconfined") | .pid' |
401 + xargs --verbose --no-run-if-empty --delimiter='\n' \
402 + kill
403 + '';
404 + commonOpts = p: "--verbose --show-cache ${lib.optionalString (!p.enforce) "--complain "}${p.profile}";
405 + in {
406 + Type = "oneshot";
407 + RemainAfterExit = "yes";
408 + ExecStartPre = "${pkgs.apparmor-utils}/bin/aa-teardown";
409 + ExecStart = lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts p}") enabledPolicies;
410 + ExecStartPost = lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
411 + ExecReload =
412 + # Add or replace into the kernel profiles in enabledPolicies
413 + # (because AppArmor can do that without stopping the processes already confined).
414 + lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts p}") enabledPolicies ++
415 + # Remove from the kernel any profile whose name is not
416 + # one of the names within the content of the profiles in enabledPolicies
417 + # (indirectly read from /etc/apparmor.d/*, without recursing into sub-directory).
418 + # Note that this does not remove profiles dynamically generated by libvirt.
419 + [ "${pkgs.apparmor-utils}/bin/aa-remove-unknown" ] ++
420 + # Optionaly kill the processes which are unconfined but now have a profile loaded
421 + # (because AppArmor can only start to confine new processes).
422 + lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
423 + ExecStop = "${pkgs.apparmor-utils}/bin/aa-teardown";
424 + CacheDirectory = [ "apparmor" "apparmor/logprof" ];
425 + CacheDirectoryMode = "0700";
426 + };
427 + };
428 + };
429 +
430 + meta.maintainers = with lib.maintainers; [ julm ];
431 }
432 diff --git a/nixos/modules/security/apparmor/includes.nix b/nixos/modules/security/apparmor/includes.nix
433 new file mode 100644
434 index 00000000000..498d7e77650
435 --- /dev/null
436 +++ b/nixos/modules/security/apparmor/includes.nix
437 @@ -0,0 +1,301 @@
438 +{ config, lib, pkgs, ... }:
439 +let
440 + inherit (builtins) attrNames hasAttr isAttrs;
441 + inherit (lib) getLib;
442 + inherit (config.environment) etc;
443 + etcRule = arg:
444 + let go = {path ? null, mode ? "r", trail ? ""}:
445 + lib.optionalString (hasAttr path etc)
446 + "${mode} ${config.environment.etc.${path}.source}${trail},";
447 + in if isAttrs arg
448 + then go arg
449 + else go {path=arg;};
450 +in
451 +{
452 +# FIXME: most of the etcRule calls below have been
453 +# written systematically by converting from apparmor-profiles's profiles
454 +# without testing nor deep understanding of their uses,
455 +# and thus may need more rules or can have less rules;
456 +# this remains to be determined case by case,
457 +# some may even be completely useless.
458 +config.security.apparmor.includes = {
459 + # This one is included by <tunables/global>
460 + # which is usualy included before any profile.
461 + "abstractions/tunables/alias" = ''
462 + alias /bin -> /run/current-system/sw/bin,
463 + alias /lib/modules -> /run/current-system/kernel/lib/modules,
464 + alias /sbin -> /run/current-system/sw/sbin,
465 + alias /usr -> /run/current-system/sw,
466 + '';
467 + "abstractions/audio" = ''
468 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/audio"
469 + ${etcRule "asound.conf"}
470 + ${etcRule "esound/esd.conf"}
471 + ${etcRule "libao.conf"}
472 + ${etcRule {path="pulse"; trail="/";}}
473 + ${etcRule {path="pulse"; trail="/**";}}
474 + ${etcRule {path="sound"; trail="/";}}
475 + ${etcRule {path="sound"; trail="/**";}}
476 + ${etcRule {path="alsa/conf.d"; trail="/";}}
477 + ${etcRule {path="alsa/conf.d"; trail="/*";}}
478 + ${etcRule "openal/alsoft.conf"}
479 + ${etcRule "wildmidi/wildmidi.conf"}
480 + '';
481 + "abstractions/authentication" = ''
482 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/authentication"
483 + # Defined in security.pam
484 + include <abstractions/pam>
485 + ${etcRule "nologin"}
486 + ${etcRule "securetty"}
487 + ${etcRule {path="security"; trail="/*";}}
488 + ${etcRule "shadow"}
489 + ${etcRule "gshadow"}
490 + ${etcRule "pwdb.conf"}
491 + ${etcRule "default/passwd"}
492 + ${etcRule "login.defs"}
493 + '';
494 + "abstractions/base" = ''
495 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/base"
496 + r ${pkgs.stdenv.cc.libc}/share/locale/**,
497 + r ${pkgs.stdenv.cc.libc}/share/locale.alias,
498 + ${lib.optionalString (pkgs.glibcLocales != null) "r ${pkgs.glibcLocales}/lib/locale/locale-archive,"}
499 + ${etcRule "localtime"}
500 + r ${pkgs.tzdata}/share/zoneinfo/**,
501 + r ${pkgs.stdenv.cc.libc}/share/i18n/**,
502 + '';
503 + "abstractions/bash" = ''
504 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/bash"
505 + # system-wide bash configuration
506 + ${etcRule "profile.dos"}
507 + ${etcRule "profile"}
508 + ${etcRule "profile.d"}
509 + ${etcRule {path="profile.d"; trail="/*";}}
510 + ${etcRule "bashrc"}
511 + ${etcRule "bash.bashrc"}
512 + ${etcRule "bash.bashrc.local"}
513 + ${etcRule "bash_completion"}
514 + ${etcRule "bash_completion.d"}
515 + ${etcRule {path="bash_completion.d"; trail="/*";}}
516 + # bash relies on system-wide readline configuration
517 + ${etcRule "inputrc"}
518 + # bash inspects filesystems at startup
519 + # and /etc/mtab is linked to /proc/mounts
520 + @{PROC}/mounts
521 +
522 + # run out of /etc/bash.bashrc
523 + ${etcRule "DIR_COLORS"}
524 + '';
525 + "abstractions/cups-client" = ''
526 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/cpus-client"
527 + ${etcRule "cups/cups-client.conf"}
528 + '';
529 + "abstractions/consoles" = ''
530 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/consoles"
531 + '';
532 + "abstractions/dbus-session-strict" = ''
533 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dbus-session-strict"
534 + ${etcRule "machine-id"}
535 + '';
536 + "abstractions/dconf" = ''
537 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dconf"
538 + ${etcRule {path="dconf"; trail="/**";}}
539 + '';
540 + "abstractions/dri-common" = ''
541 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dri-common"
542 + ${etcRule "drirc"}
543 + '';
544 + # The config.fonts.fontconfig NixOS module adds many files to /etc/fonts/
545 + # by symlinking them but without exporting them outside of its NixOS module,
546 + # those are therefore added there to this "abstractions/fonts".
547 + "abstractions/fonts" = ''
548 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/fonts"
549 + ${etcRule {path="fonts"; trail="/**";}}
550 + '';
551 + "abstractions/gnome" = ''
552 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/gnome"
553 + ${etcRule {path="gnome"; trail="/gtkrc*";}}
554 + ${etcRule {path="gtk"; trail="/*";}}
555 + ${etcRule {path="gtk-2.0"; trail="/*";}}
556 + ${etcRule {path="gtk-3.0"; trail="/*";}}
557 + ${etcRule "orbitrc"}
558 + include <abstractions/fonts>
559 + ${etcRule {path="pango"; trail="/*";}}
560 + ${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/";}}
561 + ${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/*";}}
562 + ${etcRule "papersize"}
563 + ${etcRule {path="cups"; trail="/lpoptions";}}
564 + ${etcRule {path="gnome"; trail="/defaults.list";}}
565 + ${etcRule {path="xdg"; trail="/{,*-}mimeapps.list";}}
566 + ${etcRule "xdg/mimeapps.list"}
567 + '';
568 + "abstractions/kde" = ''
569 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kde"
570 + ${etcRule {path="qt3"; trail="/kstylerc";}}
571 + ${etcRule {path="qt3"; trail="/qt_plugins_3.3rc";}}
572 + ${etcRule {path="qt3"; trail="/qtrc";}}
573 + ${etcRule "kderc"}
574 + ${etcRule {path="kde3"; trail="/*";}}
575 + ${etcRule "kde4rc"}
576 + ${etcRule {path="xdg"; trail="/kdeglobals";}}
577 + ${etcRule {path="xdg"; trail="/Trolltech.conf";}}
578 + '';
579 + "abstractions/kerberosclient" = ''
580 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kerberosclient"
581 + ${etcRule {path="krb5.keytab"; mode="rk";}}
582 + ${etcRule "krb5.conf"}
583 + ${etcRule "krb5.conf.d"}
584 + ${etcRule {path="krb5.conf.d"; trail="/*";}}
585 +
586 + # config files found via strings on libs
587 + ${etcRule "krb.conf"}
588 + ${etcRule "krb.realms"}
589 + ${etcRule "srvtab"}
590 + '';
591 + "abstractions/ldapclient" = ''
592 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ldapclient"
593 + ${etcRule "ldap.conf"}
594 + ${etcRule "ldap.secret"}
595 + ${etcRule {path="openldap"; trail="/*";}}
596 + ${etcRule {path="openldap"; trail="/cacerts/*";}}
597 + ${etcRule {path="sasl2"; trail="/*";}}
598 + '';
599 + "abstractions/likewise" = ''
600 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/likewise"
601 + '';
602 + "abstractions/mdns" = ''
603 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/mdns"
604 + ${etcRule "nss_mdns.conf"}
605 + '';
606 + "abstractions/nameservice" = ''
607 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nameservice"
608 +
609 + # Many programs wish to perform nameservice-like operations, such as
610 + # looking up users by name or id, groups by name or id, hosts by name
611 + # or IP, etc. These operations may be performed through files, dns,
612 + # NIS, NIS+, LDAP, hesiod, wins, etc. Allow them all here.
613 + ${etcRule "group"}
614 + ${etcRule "host.conf"}
615 + ${etcRule "hosts"}
616 + ${etcRule "nsswitch.conf"}
617 + ${etcRule "gai.conf"}
618 + ${etcRule "passwd"}
619 + ${etcRule "protocols"}
620 +
621 + # libtirpc (used for NIS/YP login) needs this
622 + ${etcRule "netconfig"}
623 +
624 + ${etcRule "resolv.conf"}
625 +
626 + ${etcRule {path="samba"; trail="/lmhosts";}}
627 + ${etcRule "services"}
628 +
629 + ${etcRule "default/nss"}
630 +
631 + # libnl-3-200 via libnss-gw-name
632 + ${etcRule {path="libnl"; trail="/classid";}}
633 + ${etcRule {path="libnl-3"; trail="/classid";}}
634 +
635 + mr ${getLib pkgs.nss}/lib/libnss_*.so*,
636 + mr ${getLib pkgs.nss}/lib64/libnss_*.so*,
637 + '';
638 + "abstractions/nis" = ''
639 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nis"
640 + '';
641 + "abstractions/nvidia" = ''
642 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nvidia"
643 + ${etcRule "vdpau_wrapper.cfg"}
644 + '';
645 + "abstractions/opencl-common" = ''
646 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-common"
647 + ${etcRule {path="OpenCL"; trail="/**";}}
648 + '';
649 + "abstractions/opencl-mesa" = ''
650 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-mesa"
651 + ${etcRule "default/drirc"}
652 + '';
653 + "abstractions/openssl" = ''
654 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/openssl"
655 + ${etcRule {path="ssl"; trail="/openssl.cnf";}}
656 + '';
657 + "abstractions/p11-kit" = ''
658 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/p11-kit"
659 + ${etcRule {path="pkcs11"; trail="/";}}
660 + ${etcRule {path="pkcs11"; trail="/pkcs11.conf";}}
661 + ${etcRule {path="pkcs11"; trail="/modules/";}}
662 + ${etcRule {path="pkcs11"; trail="/modules/*";}}
663 + '';
664 + "abstractions/perl" = ''
665 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/perl"
666 + ${etcRule {path="perl"; trail="/**";}}
667 + '';
668 + "abstractions/php" = ''
669 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/php"
670 + ${etcRule {path="php"; trail="/**/";}}
671 + ${etcRule {path="php5"; trail="/**/";}}
672 + ${etcRule {path="php7"; trail="/**/";}}
673 + ${etcRule {path="php"; trail="/**.ini";}}
674 + ${etcRule {path="php5"; trail="/**.ini";}}
675 + ${etcRule {path="php7"; trail="/**.ini";}}
676 + '';
677 + "abstractions/postfix-common" = ''
678 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/postfix-common"
679 + ${etcRule "mailname"}
680 + ${etcRule {path="postfix"; trail="/*.cf";}}
681 + ${etcRule "postfix/main.cf"}
682 + ${etcRule "postfix/master.cf"}
683 + '';
684 + "abstractions/python" = ''
685 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/python"
686 + '';
687 + "abstractions/qt5" = ''
688 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/qt5"
689 + ${etcRule {path="xdg"; trail="/QtProject/qtlogging.ini";}}
690 + ${etcRule {path="xdg/QtProject"; trail="/qtlogging.ini";}}
691 + ${etcRule "xdg/QtProject/qtlogging.ini"}
692 + '';
693 + "abstractions/samba" = ''
694 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/samba"
695 + ${etcRule {path="samba"; trail="/*";}}
696 + '';
697 + "abstractions/ssl_certs" = ''
698 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ssl_certs"
699 + ${etcRule "ssl/certs/ca-certificates.crt"}
700 + ${etcRule "ssl/certs/ca-bundle.crt"}
701 + ${etcRule "pki/tls/certs/ca-bundle.crt"}
702 +
703 + ${etcRule {path="ssl/trust"; trail="/";}}
704 + ${etcRule {path="ssl/trust"; trail="/*";}}
705 + ${etcRule {path="ssl/trust/anchors"; trail="/";}}
706 + ${etcRule {path="ssl/trust/anchors"; trail="/**";}}
707 + ${etcRule {path="pki/trust"; trail="/";}}
708 + ${etcRule {path="pki/trust"; trail="/*";}}
709 + ${etcRule {path="pki/trust/anchors"; trail="/";}}
710 + ${etcRule {path="pki/trust/anchors"; trail="/**";}}
711 +
712 + # security.acme NixOS module
713 + r /var/lib/acme/*/cert.pem,
714 + r /var/lib/acme/*/chain.pem,
715 + r /var/lib/acme/*/fullchain.pem,
716 + '';
717 + "abstractions/ssl_keys" = ''
718 + # security.acme NixOS module
719 + r /var/lib/acme/*/full.pem,
720 + r /var/lib/acme/*/key.pem,
721 + '';
722 + "abstractions/vulkan" = ''
723 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/vulkan"
724 + ${etcRule {path="vulkan/icd.d"; trail="/";}}
725 + ${etcRule {path="vulkan/icd.d"; trail="/*.json";}}
726 + '';
727 + "abstractions/winbind" = ''
728 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/winbind"
729 + ${etcRule {path="samba"; trail="/smb.conf";}}
730 + ${etcRule {path="samba"; trail="/dhcp.conf";}}
731 + '';
732 + "abstractions/X" = ''
733 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/X"
734 + ${etcRule {path="X11/cursors"; trail="/";}}
735 + ${etcRule {path="X11/cursors"; trail="/**";}}
736 + '';
737 +};
738 +}
739 diff --git a/nixos/modules/security/apparmor/profiles.nix b/nixos/modules/security/apparmor/profiles.nix
740 new file mode 100644
741 index 00000000000..8eb630b5a48
742 --- /dev/null
743 +++ b/nixos/modules/security/apparmor/profiles.nix
744 @@ -0,0 +1,11 @@
745 +{ config, lib, pkgs, ... }:
746 +let apparmor = config.security.apparmor; in
747 +{
748 +config.security.apparmor.packages = [ pkgs.apparmor-profiles ];
749 +config.security.apparmor.policies."bin.ping".profile = lib.mkIf apparmor.policies."bin.ping".enable ''
750 + include "${pkgs.iputils.apparmor}/bin.ping"
751 + include "${pkgs.inetutils.apparmor}/bin.ping"
752 + # Note that including those two profiles in the same profile
753 + # would not work if the second one were to re-include <tunables/global>.
754 +'';
755 +}
756 diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
757 index a428103eaa9..114a448857f 100644
758 --- a/nixos/modules/security/pam.nix
759 +++ b/nixos/modules/security/pam.nix
760 @@ -895,6 +895,61 @@ in
761 runuser-l = { rootOK = true; unixAuth = false; };
762 };
763
764 + security.apparmor.includes."abstractions/pam" = let
765 + isEnabled = test: fold or false (map test (attrValues config.security.pam.services));
766 + in ''
767 + ${lib.concatMapStringsSep "\n"
768 + (name: "r ${config.environment.etc."pam.d/${name}".source},")
769 + (attrNames config.security.pam.services)}
770 + mr ${getLib pkgs.pam}/lib/security/pam_filter/*,
771 + mr ${getLib pkgs.pam}/lib/security/pam_*.so,
772 + r ${getLib pkgs.pam}/lib/security/,
773 + ${optionalString use_ldap
774 + "mr ${pam_ldap}/lib/security/pam_ldap.so,"}
775 + ${optionalString config.services.sssd.enable
776 + "mr ${pkgs.sssd}/lib/security/pam_sss.so,"}
777 + ${optionalString config.krb5.enable ''
778 + mr ${pam_krb5}/lib/security/pam_krb5.so,
779 + mr ${pam_ccreds}/lib/security/pam_ccreds.so,
780 + ''}
781 + ${optionalString (isEnabled (cfg: cfg.googleOsLoginAccountVerification)) ''
782 + mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,
783 + mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so,
784 + ''}
785 + ${optionalString (isEnabled (cfg: cfg.googleOsLoginAuthentication))
786 + "mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,"}
787 + ${optionalString (config.security.pam.enableSSHAgentAuth && isEnabled (cfg: cfg.sshAgentAuth))
788 + "mr ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so,"}
789 + ${optionalString (isEnabled (cfg: cfg.fprintAuth))
790 + "mr ${pkgs.fprintd}/lib/security/pam_fprintd.so,"}
791 + ${optionalString (isEnabled (cfg: cfg.u2fAuth))
792 + "mr ${pkgs.pam_u2f}/lib/security/pam_u2f.so,"}
793 + ${optionalString (isEnabled (cfg: cfg.usbAuth))
794 + "mr ${pkgs.pam_usb}/lib/security/pam_usb.so,"}
795 + ${optionalString (isEnabled (cfg: cfg.oathAuth))
796 + "mr ${pkgs.oathToolkit}/lib/security/pam_oath.so,"}
797 + ${optionalString (isEnabled (cfg: cfg.yubicoAuth))
798 + "mr ${pkgs.yubico-pam}/lib/security/pam_yubico.so,"}
799 + ${optionalString (isEnabled (cfg: cfg.duoSecurity.enable))
800 + "mr ${pkgs.duo-unix}/lib/security/pam_duo.so,"}
801 + ${optionalString (isEnabled (cfg: cfg.otpwAuth))
802 + "mr ${pkgs.otpw}/lib/security/pam_otpw.so,"}
803 + ${optionalString config.security.pam.enableEcryptfs
804 + "mr ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so,"}
805 + ${optionalString (isEnabled (cfg: cfg.pamMount))
806 + "mr ${pkgs.pam_mount}/lib/security/pam_mount.so,"}
807 + ${optionalString (isEnabled (cfg: cfg.enableGnomeKeyring))
808 + "mr ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so,"}
809 + ${optionalString (isEnabled (cfg: cfg.startSession))
810 + "mr ${pkgs.systemd}/lib/security/pam_systemd.so,"}
811 + ${optionalString (isEnabled (cfg: cfg.enableAppArmor) && config.security.apparmor.enable)
812 + "mr ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so,"}
813 + ${optionalString (isEnabled (cfg: cfg.enableKwallet))
814 + "mr ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so,"}
815 + ${optionalString config.virtualisation.lxc.lxcfs.enable
816 + "mr ${pkgs.lxc}/lib/security/pam_cgfs.so"}
817 + '';
818 +
819 };
820
821 }
822 diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix
823 index de6213714ac..4467b909e45 100644
824 --- a/nixos/modules/security/wrappers/default.nix
825 +++ b/nixos/modules/security/wrappers/default.nix
826 @@ -179,6 +179,14 @@ in
827 export PATH="${wrapperDir}:$PATH"
828 '';
829
830 + security.apparmor.includes."nixos/security.wrappers" = ''
831 + include "${pkgs.apparmorRulesFromClosure { name="security.wrappers"; } [
832 + securityWrapper
833 + pkgs.stdenv.cc.cc
834 + pkgs.stdenv.cc.libc
835 + ]}"
836 + '';
837 +
838 ###### setcap activation script
839 system.activationScripts.wrappers =
840 lib.stringAfter [ "specialfs" "users" ]
841 diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix
842 index 7bec073e26f..e9b5834dab4 100644
843 --- a/nixos/modules/services/torrent/transmission.nix
844 +++ b/nixos/modules/services/torrent/transmission.nix
845 @@ -5,7 +5,7 @@ with lib;
846 let
847 cfg = config.services.transmission;
848 inherit (config.environment) etc;
849 - apparmor = config.security.apparmor.enable;
850 + apparmor = config.security.apparmor;
851 rootDir = "/run/transmission";
852 homeDir = "/var/lib/transmission";
853 settingsDir = ".config/transmission-daemon";
854 @@ -184,8 +184,8 @@ in
855
856 systemd.services.transmission = {
857 description = "Transmission BitTorrent Service";
858 - after = [ "network.target" ] ++ optional apparmor "apparmor.service";
859 - requires = optional apparmor "apparmor.service";
860 + after = [ "network.target" ] ++ optional apparmor.enable "apparmor.service";
861 + requires = optional apparmor.enable "apparmor.service";
862 wantedBy = [ "multi-user.target" ];
863 environment.CURL_CA_BUNDLE = etc."ssl/certs/ca-certificates.crt".source;
864
865 @@ -358,62 +358,26 @@ in
866 })
867 ];
868
869 - security.apparmor.profiles = mkIf apparmor [
870 - (pkgs.writeText "apparmor-transmission-daemon" ''
871 + security.apparmor.policies."bin.transmission-daemon".profile = ''
872 include <tunables/global>
873 -
874 ${pkgs.transmission}/bin/transmission-daemon {
875 include <abstractions/base>
876 include <abstractions/nameservice>
877 -
878 - # NOTE: https://github.com/NixOS/nixpkgs/pull/93457
879 - # will remove the need for these by fixing <abstractions/base>
880 - r ${etc."hosts".source},
881 - r /etc/ld-nix.so.preload,
882 - ${lib.optionalString (builtins.hasAttr "ld-nix.so.preload" etc) ''
883 - r ${etc."ld-nix.so.preload".source},
884 - ${concatMapStrings (p: optionalString (p != "") ("mr ${p},\n"))
885 - (splitString "\n" config.environment.etc."ld-nix.so.preload".text)}
886 - ''}
887 - r ${etc."ssl/certs/ca-certificates.crt".source},
888 - r ${pkgs.tzdata}/share/zoneinfo/**,
889 - r ${pkgs.stdenv.cc.libc}/share/i18n/**,
890 - r ${pkgs.stdenv.cc.libc}/share/locale/**,
891 -
892 - mr ${getLib pkgs.stdenv.cc.cc}/lib/*.so*,
893 - mr ${getLib pkgs.stdenv.cc.libc}/lib/*.so*,
894 - mr ${getLib pkgs.attr}/lib/libattr*.so*,
895 - mr ${getLib pkgs.c-ares}/lib/libcares*.so*,
896 - mr ${getLib pkgs.curl}/lib/libcurl*.so*,
897 - mr ${getLib pkgs.keyutils}/lib/libkeyutils*.so*,
898 - mr ${getLib pkgs.libcap}/lib/libcap*.so*,
899 - mr ${getLib pkgs.libevent}/lib/libevent*.so*,
900 - mr ${getLib pkgs.libgcrypt}/lib/libgcrypt*.so*,
901 - mr ${getLib pkgs.libgpgerror}/lib/libgpg-error*.so*,
902 - mr ${getLib pkgs.libkrb5}/lib/lib*.so*,
903 - mr ${getLib pkgs.libssh2}/lib/libssh2*.so*,
904 - mr ${getLib pkgs.lz4}/lib/liblz4*.so*,
905 - mr ${getLib pkgs.nghttp2}/lib/libnghttp2*.so*,
906 - mr ${getLib pkgs.openssl}/lib/libcrypto*.so*,
907 - mr ${getLib pkgs.openssl}/lib/libssl*.so*,
908 - mr ${getLib pkgs.systemd}/lib/libsystemd*.so*,
909 - mr ${getLib pkgs.util-linuxMinimal.out}/lib/libblkid.so*,
910 - mr ${getLib pkgs.util-linuxMinimal.out}/lib/libmount.so*,
911 - mr ${getLib pkgs.util-linuxMinimal.out}/lib/libuuid.so*,
912 - mr ${getLib pkgs.xz}/lib/liblzma*.so*,
913 - mr ${getLib pkgs.zlib}/lib/libz*.so*,
914 + include <abstractions/ssl_certs>
915 + include "${pkgs.apparmorRulesFromClosure
916 + { name = "transmission-daemon"; }
917 + [ pkgs.transmission ]}"
918 + include <local/bin.transmission-daemon>
919
920 r @{PROC}/sys/kernel/random/uuid,
921 r @{PROC}/sys/vm/overcommit_memory,
922 - # @{pid} is not a kernel variable yet but a regexp
923 - #r @{PROC}/@{pid}/environ,
924 + r @{PROC}/@{pid}/environ,
925 r @{PROC}/@{pid}/mounts,
926 rwk /tmp/tr_session_id_*,
927 r /run/systemd/resolve/stub-resolv.conf,
928
929 r ${pkgs.openssl.out}/etc/**,
930 r ${config.systemd.services.transmission.environment.CURL_CA_BUNDLE},
931 - r ${pkgs.transmission}/share/transmission/**,
932
933 owner rw ${cfg.home}/${settingsDir}/**,
934 rw ${cfg.settings.download-dir}/**,
935 @@ -441,12 +405,9 @@ in
936 # https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking#seccomp-and-no_new_privs
937 px ${cfg.settings.script-torrent-done-filename} -> &@{dirs},
938 ''}
939 -
940 - # FIXME: enable customizing using https://github.com/NixOS/nixpkgs/pull/93457
941 - # include <local/transmission-daemon>
942 }
943 - '')
944 - ];
945 + '';
946 + security.apparmor.includes."local/bin.transmission-daemon" = "";
947 };
948
949 meta.maintainers = with lib.maintainers; [ julm ];
950 diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
951 index afb9c540416..d4ad32a300b 100644
952 --- a/nixos/modules/tasks/network-interfaces.nix
953 +++ b/nixos/modules/tasks/network-interfaces.nix
954 @@ -1093,6 +1093,21 @@ in
955 } else {
956 ping.source = "${pkgs.iputils.out}/bin/ping";
957 };
958 + security.apparmor.policies."bin.ping".profile = lib.mkIf config.security.apparmor.policies."bin.ping".enable (lib.mkAfter ''
959 + /run/wrappers/bin/ping {
960 + include <abstractions/base>
961 + include <nixos/security.wrappers>
962 + rpx /run/wrappers/wrappers.*/ping,
963 + }
964 + /run/wrappers/wrappers.*/ping {
965 + include <abstractions/base>
966 + include <nixos/security.wrappers>
967 + r /run/wrappers/wrappers.*/ping.real,
968 + mrpx ${config.security.wrappers.ping.source},
969 + capability net_raw,
970 + capability setpcap,
971 + }
972 + '');
973
974 # Set the host and domain names in the activation script. Don't
975 # clear it if it's not configured in the NixOS configuration,
976 diff --git a/nixos/modules/virtualisation/lxc.nix b/nixos/modules/virtualisation/lxc.nix
977 index f484d5ee59a..0f8b22a45df 100644
978 --- a/nixos/modules/virtualisation/lxc.nix
979 +++ b/nixos/modules/virtualisation/lxc.nix
980 @@ -74,9 +74,13 @@ in
981 systemd.tmpfiles.rules = [ "d /var/lib/lxc/rootfs 0755 root root -" ];
982
983 security.apparmor.packages = [ pkgs.lxc ];
984 - security.apparmor.profiles = [
985 - "${pkgs.lxc}/etc/apparmor.d/lxc-containers"
986 - "${pkgs.lxc}/etc/apparmor.d/usr.bin.lxc-start"
987 - ];
988 + security.apparmor.policies = {
989 + "bin.lxc-start".profile = ''
990 + include ${pkgs.lxc}/etc/apparmor.d/usr.bin.lxc-start
991 + '';
992 + "lxc-containers".profile = ''
993 + include ${pkgs.lxc}/etc/apparmor.d/lxc-containers
994 + '';
995 + };
996 };
997 }
998 diff --git a/nixos/modules/virtualisation/lxd.nix b/nixos/modules/virtualisation/lxd.nix
999 index 3958fc2c1d7..876956f654b 100644
1000 --- a/nixos/modules/virtualisation/lxd.nix
1001 +++ b/nixos/modules/virtualisation/lxd.nix
1002 @@ -93,11 +93,15 @@ in
1003
1004 security.apparmor = {
1005 enable = true;
1006 - profiles = [
1007 - "${cfg.lxcPackage}/etc/apparmor.d/usr.bin.lxc-start"
1008 - "${cfg.lxcPackage}/etc/apparmor.d/lxc-containers"
1009 - ];
1010 packages = [ cfg.lxcPackage ];
1011 + policies = {
1012 + "bin.lxc-start".profile = ''
1013 + include ${cfg.lxcPackage}/etc/apparmor.d/usr.bin.lxc-start
1014 + '';
1015 + "lxc-containers".profile = ''
1016 + include ${cfg.lxcPackage}/etc/apparmor.d/lxc-containers
1017 + '';
1018 + };
1019 };
1020
1021 systemd.services.lxd = {
1022 diff --git a/pkgs/os-specific/linux/apparmor/default.nix b/pkgs/os-specific/linux/apparmor/default.nix
1023 index 3ce310acf23..fc776ff2001 100644
1024 --- a/pkgs/os-specific/linux/apparmor/default.nix
1025 +++ b/pkgs/os-specific/linux/apparmor/default.nix
1026 @@ -10,11 +10,18 @@
1027 , pam
1028 , libnotify
1029 , buildPackages
1030 +, coreutils
1031 +, gnugrep
1032 +, gnused
1033 +, kmod
1034 +, writeShellScript
1035 +, closureInfo
1036 +, runCommand
1037 }:
1038
1039 let
1040 - apparmor-series = "2.13";
1041 - apparmor-patchver = "6";
1042 + apparmor-series = "3.0";
1043 + apparmor-patchver = "1";
1044 apparmor-version = apparmor-series + "." + apparmor-patchver;
1045
1046 apparmor-meta = component: with stdenv.lib; {
1047 @@ -26,10 +33,16 @@ let
1048 };
1049
1050 apparmor-sources = fetchurl {
1051 - url = "https://launchpad.net/apparmor/${apparmor-series}/${apparmor-version}/+download/apparmor-${apparmor-version}.tar.gz";
1052 - sha256 = "13xshy7905d9q9n8d8i0jmdi9m36wr525g4wlsp8k21n7yvvh9j4";
1053 + url = "https://launchpad.net/apparmor/${apparmor-series}/${apparmor-series}.${apparmor-patchver}/+download/apparmor-${apparmor-version}.tar.gz";
1054 + sha256 = "096zbg3v7b51x7f1ly61mzd3iy9alad6sd4lam98j2d6v5ragbcg";
1055 };
1056
1057 + aa-teardown = writeShellScript "aa-teardown" ''
1058 + PATH="${lib.makeBinPath [coreutils gnused gnugrep]}:$PATH"
1059 + . ${apparmor-parser}/lib/apparmor/rc.apparmor.functions
1060 + remove_profiles
1061 + '';
1062 +
1063 prePatchCommon = ''
1064 chmod a+x ./common/list_capabilities.sh ./common/list_af_names.sh
1065 patchShebangs ./common/list_capabilities.sh ./common/list_af_names.sh
1066 @@ -45,12 +58,6 @@ let
1067 name = "0003-Added-missing-typedef-definitions-on-parser.patch";
1068 sha256 = "0yyaqz8jlmn1bm37arggprqz0njb4lhjni2d9c8qfqj0kll0bam0";
1069 })
1070 - (fetchpatch {
1071 - url = "https://git.alpinelinux.org/aports/plain/testing/apparmor/0007-Do-not-build-install-vim-file-with-utils-package.patch?id=74b8427cc21f04e32030d047ae92caa618105b53";
1072 - name = "0007-Do-not-build-install-vim-file-with-utils-package.patch";
1073 - sha256 = "1m4dx901biqgnr4w4wz8a2z9r9dxyw7wv6m6mqglqwf2lxinqmp4";
1074 - })
1075 - # (alpine patches {1,4,5,6,8} are needed for apparmor 2.11, but not 2.12)
1076 ];
1077
1078 # Set to `true` after the next FIXME gets fixed or this gets some
1079 @@ -121,7 +128,11 @@ let
1080 libapparmor.python
1081 ];
1082
1083 - prePatch = prePatchCommon + ''
1084 + prePatch = prePatchCommon +
1085 + # Do not build vim file
1086 + stdenv.lib.optionalString stdenv.hostPlatform.isMusl ''
1087 + sed -i ./utils/Makefile -e "/\<vim\>/d"
1088 + '' + ''
1089 substituteInPlace ./utils/apparmor/easyprof.py --replace "/sbin/apparmor_parser" "${apparmor-parser}/bin/apparmor_parser"
1090 substituteInPlace ./utils/apparmor/aa.py --replace "/sbin/apparmor_parser" "${apparmor-parser}/bin/apparmor_parser"
1091 substituteInPlace ./utils/logprof.conf --replace "/sbin/apparmor_parser" "${apparmor-parser}/bin/apparmor_parser"
1092 @@ -132,7 +143,8 @@ let
1093 installFlags = [ "DESTDIR=$(out)" "BINDIR=$(out)/bin" "VIM_INSTALL_PATH=$(out)/share" "PYPREFIX=" ];
1094
1095 postInstall = ''
1096 - for prog in aa-audit aa-autodep aa-cleanprof aa-complain aa-disable aa-enforce aa-genprof aa-logprof aa-mergeprof aa-status aa-unconfined ; do
1097 + sed -i $out/bin/aa-unconfined -e "/my_env\['PATH'\]/d"
1098 + for prog in aa-audit aa-autodep aa-cleanprof aa-complain aa-disable aa-enforce aa-genprof aa-logprof aa-mergeprof aa-unconfined ; do
1099 wrapProgram $out/bin/$prog --prefix PYTHONPATH : "$out/lib/${python.libPrefix}/site-packages:$PYTHONPATH"
1100 done
1101
1102 @@ -140,6 +152,13 @@ let
1103 # aa-notify checks its name and does not work named ".aa-notify-wrapped"
1104 mv $out/bin/aa-notify $out/bin/aa-notify-wrapped
1105 makeWrapper ${perl}/bin/perl $out/bin/aa-notify --set PERL5LIB ${libapparmor}/${perl.libPrefix} --add-flags $out/bin/aa-notify-wrapped
1106 +
1107 + substituteInPlace $out/bin/aa-remove-unknown \
1108 + --replace "/lib/apparmor/rc.apparmor.functions" "${apparmor-parser}/lib/apparmor/rc.apparmor.functions"
1109 + wrapProgram $out/bin/aa-remove-unknown \
1110 + --prefix PATH : ${lib.makeBinPath [gawk]}
1111 +
1112 + ln -s ${aa-teardown} $out/bin/aa-teardown
1113 '';
1114
1115 inherit doCheck;
1116 @@ -167,7 +186,7 @@ let
1117 prePatch = prePatchCommon;
1118 postPatch = "cd ./binutils";
1119 makeFlags = [ "LANGS=" "USE_SYSTEM=1" ];
1120 - installFlags = [ "DESTDIR=$(out)" "BINDIR=$(out)/bin" ];
1121 + installFlags = [ "DESTDIR=$(out)" "BINDIR=$(out)/bin" "SBINDIR=$(out)/bin" ];
1122
1123 inherit doCheck;
1124
1125 @@ -188,6 +207,9 @@ let
1126 substituteInPlace ./parser/Makefile --replace "/usr/include/linux/capability.h" "${linuxHeaders}/include/linux/capability.h"
1127 ## techdoc.pdf still doesn't build ...
1128 substituteInPlace ./parser/Makefile --replace "manpages htmlmanpages pdf" "manpages htmlmanpages"
1129 + substituteInPlace parser/rc.apparmor.functions \
1130 + --replace "/sbin/apparmor_parser" "$out/bin/apparmor_parser"
1131 + sed -i parser/rc.apparmor.functions -e '2i . ${./fix-rc.apparmor.functions.sh}'
1132 '';
1133 inherit patches;
1134 postPatch = "cd ./parser";
1135 @@ -249,8 +271,35 @@ let
1136 meta = apparmor-meta "kernel patches";
1137 };
1138
1139 + # Generate generic AppArmor rules in a file,
1140 + # from the closure of given rootPaths.
1141 + # To be included in an AppArmor profile like so:
1142 + # include "$(apparmorRulesFromClosure {} [pkgs.hello]}"
1143 + apparmorRulesFromClosure =
1144 + { # The store path of the derivation is given in $path
1145 + additionalRules ? []
1146 + # TODO: factorize here some other common paths
1147 + # that may emerge from use cases.
1148 + , baseRules ? [
1149 + "r $path"
1150 + "r $path/etc/**"
1151 + "r $path/share/**"
1152 + # Note that not all libraries are prefixed with "lib",
1153 + # eg. glibc-2.30/lib/ld-2.30.so
1154 + "mr $path/lib/**.so*"
1155 + # eg. glibc-2.30/lib/gconv/gconv-modules
1156 + "r $path/lib/**"
1157 + ]
1158 + , name ? ""
1159 + }: rootPaths: runCommand
1160 + ( "apparmor-closure-rules"
1161 + + stdenv.lib.optionalString (name != "") "-${name}") {} ''
1162 + touch $out
1163 + while read -r path
1164 + do printf >>$out "%s,\n" ${lib.concatMapStringsSep " " (x: "\"${x}\"") (baseRules ++ additionalRules)}
1165 + done <${closureInfo {inherit rootPaths;}}/store-paths
1166 + '';
1167 in
1168 -
1169 {
1170 inherit
1171 libapparmor
1172 @@ -259,5 +308,6 @@ in
1173 apparmor-parser
1174 apparmor-pam
1175 apparmor-profiles
1176 - apparmor-kernel-patches;
1177 + apparmor-kernel-patches
1178 + apparmorRulesFromClosure;
1179 }
1180 diff --git a/pkgs/os-specific/linux/apparmor/fix-rc.apparmor.functions.sh b/pkgs/os-specific/linux/apparmor/fix-rc.apparmor.functions.sh
1181 new file mode 100644
1182 index 00000000000..ebc1baaa92d
1183 --- /dev/null
1184 +++ b/pkgs/os-specific/linux/apparmor/fix-rc.apparmor.functions.sh
1185 @@ -0,0 +1,32 @@
1186 +aa_action() {
1187 + STRING=$1
1188 + shift
1189 + $*
1190 + rc=$?
1191 + if [ $rc -eq 0 ] ; then
1192 + aa_log_success_msg $"$STRING "
1193 + else
1194 + aa_log_failure_msg $"$STRING "
1195 + fi
1196 + return $rc
1197 +}
1198 +
1199 +aa_log_success_msg() {
1200 + [ -n "$1" ] && echo -n $1
1201 + echo ": done."
1202 +}
1203 +
1204 +aa_log_warning_msg() {
1205 + [ -n "$1" ] && echo -n $1
1206 + echo ": Warning."
1207 +}
1208 +
1209 +aa_log_failure_msg() {
1210 + [ -n "$1" ] && echo -n $1
1211 + echo ": Failed."
1212 +}
1213 +
1214 +aa_log_skipped_msg() {
1215 + [ -n "$1" ] && echo -n $1
1216 + echo ": Skipped."
1217 +}
1218 diff --git a/pkgs/os-specific/linux/iputils/default.nix b/pkgs/os-specific/linux/iputils/default.nix
1219 index 3bb653ebcf7..96134a16635 100644
1220 --- a/pkgs/os-specific/linux/iputils/default.nix
1221 +++ b/pkgs/os-specific/linux/iputils/default.nix
1222 @@ -1,6 +1,7 @@
1223 { stdenv, fetchFromGitHub, fetchpatch
1224 , meson, ninja, pkgconfig, gettext, libxslt, docbook_xsl_ns
1225 , libcap, libidn2
1226 +, apparmorRulesFromClosure
1227 }:
1228
1229 with stdenv.lib;
1230 @@ -30,6 +31,8 @@ in stdenv.mkDerivation rec {
1231 })
1232 ];
1233
1234 + outputs = ["out" "apparmor"];
1235 +
1236 mesonFlags = [
1237 "-DBUILD_RARPD=true"
1238 "-DBUILD_TRACEROUTE6=true"
1239 @@ -44,6 +47,25 @@ in stdenv.mkDerivation rec {
1240 nativeBuildInputs = [ meson ninja pkgconfig gettext libxslt.bin docbook_xsl_ns ];
1241 buildInputs = [ libcap ]
1242 ++ optional (!stdenv.hostPlatform.isMusl) libidn2;
1243 + postInstall = ''
1244 + install -D /dev/stdin $apparmor/bin.ping <<EOF
1245 + include <tunables/global>
1246 + $out/bin/ping {
1247 + include <abstractions/base>
1248 + include <abstractions/consoles>
1249 + include <abstractions/nameservice>
1250 + include "${apparmorRulesFromClosure { name = "ping"; }
1251 + ([libcap] ++ optional (!stdenv.hostPlatform.isMusl) libidn2)}"
1252 + include <local/bin.ping>
1253 + capability net_raw,
1254 + network inet raw,
1255 + network inet6 raw,
1256 + mr $out/bin/ping,
1257 + r $out/share/locale/**,
1258 + r @{PROC}/@{pid}/environ,
1259 + }
1260 + EOF
1261 + '';
1262
1263 meta = {
1264 description = "A set of small useful utilities for Linux networking";
1265 diff --git a/pkgs/tools/networking/inetutils/default.nix b/pkgs/tools/networking/inetutils/default.nix
1266 index 1290ec2bdb1..d88f2697085 100644
1267 --- a/pkgs/tools/networking/inetutils/default.nix
1268 +++ b/pkgs/tools/networking/inetutils/default.nix
1269 @@ -1,4 +1,6 @@
1270 -{ stdenv, lib, fetchurl, ncurses, perl, help2man }:
1271 +{ stdenv, lib, fetchurl, ncurses, perl, help2man
1272 +, apparmorRulesFromClosure
1273 +}:
1274
1275 stdenv.mkDerivation rec {
1276 name = "inetutils-1.9.4";
1277 @@ -8,6 +10,8 @@ stdenv.mkDerivation rec {
1278 sha256 = "05n65k4ixl85dc6rxc51b1b732gnmm8xnqi424dy9f1nz7ppb3xy";
1279 };
1280
1281 + outputs = ["out" "apparmor"];
1282 +
1283 patches = [
1284 ./whois-Update-Canadian-TLD-server.patch
1285 ./service-name.patch
1286 @@ -41,6 +45,22 @@ stdenv.mkDerivation rec {
1287
1288 installFlags = [ "SUIDMODE=" ];
1289
1290 + postInstall = ''
1291 + install -D /dev/stdin $apparmor/bin.ping <<EOF
1292 + $out/bin/ping {
1293 + include <abstractions/base>
1294 + include <abstractions/consoles>
1295 + include <abstractions/nameservice>
1296 + include "${apparmorRulesFromClosure { name = "ping"; } [stdenv.cc.libc]}"
1297 + include <local/bin.ping>
1298 + capability net_raw,
1299 + network inet raw,
1300 + network inet6 raw,
1301 + mr $out/bin/ping,
1302 + }
1303 + EOF
1304 + '';
1305 +
1306 meta = with lib; {
1307 description = "Collection of common network programs";
1308
1309 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
1310 index 32bba34a798..4306fc7662e 100644
1311 --- a/pkgs/top-level/all-packages.nix
1312 +++ b/pkgs/top-level/all-packages.nix
1313 @@ -17979,7 +17979,7 @@ in
1314
1315 inherit (callPackages ../os-specific/linux/apparmor { python = python3; })
1316 libapparmor apparmor-utils apparmor-bin-utils apparmor-parser apparmor-pam
1317 - apparmor-profiles apparmor-kernel-patches;
1318 + apparmor-profiles apparmor-kernel-patches apparmorRulesFromClosure;
1319
1320 atop = callPackage ../os-specific/linux/atop { };
1321