]> Git — Sourcephile - sourcephile-nix.git/blob - nixpkgs/patches/apparmor.diff
openvpn: add riseup in net namespace
[sourcephile-nix.git] / nixpkgs / patches / apparmor.diff
1 diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix
2 index 3f60da6e7a7..4871600b5ba 100644
3 --- a/maintainers/maintainer-list.nix
4 +++ b/maintainers/maintainer-list.nix
5 @@ -4287,7 +4287,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 782227de06f..dae2616b6ad 100644
16 --- a/nixos/doc/manual/release-notes/rl-2009.xml
17 +++ b/nixos/doc/manual/release-notes/rl-2009.xml
18 @@ -1040,6 +1040,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 31a659ee83f..5c5752ef515 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 cce4e8e74b4..c583e3a2593 100644
107 --- a/nixos/modules/module-list.nix
108 +++ b/nixos/modules/module-list.nix
109 @@ -188,7 +188,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..3bf1e0fefc3 100644
174 --- a/nixos/modules/security/apparmor.nix
175 +++ b/nixos/modules/security/apparmor.nix
176 @@ -1,59 +1,198 @@
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 = [ pkgs.apparmor-utils ];
321 + environment.etc."apparmor.d".source = pkgs.linkFarm "apparmor.d" (
322 + # It's important to put only enabledPolicies here and not all cfg.policies
323 + # because aa-remove-unknown reads profiles from all /etc/apparmor.d/*
324 + lib.mapAttrsToList (name: p: {inherit name; path=p.profile;}) enabledPolicies ++
325 + lib.mapAttrsToList (name: path: {inherit name path;}) cfg.includes
326 + );
327 + environment.etc."apparmor/parser.conf".text = ''
328 + ${if cfg.enableCache then "write-cache" else "skip-cache"}
329 + cache-loc /var/cache/apparmor
330 + Include /etc/apparmor.d
331 + '' +
332 + lib.concatMapStrings (p: "Include ${p}/etc/apparmor.d\n") cfg.packages;
333 + # For aa-logprof
334 + environment.etc."apparmor/apparmor.conf".text = ''
335 + '';
336 + # For aa-logprof
337 + environment.etc."apparmor/severity.db".source = pkgs.apparmor-utils + "/etc/apparmor/severity.db";
338 + environment.etc."apparmor/logprof.conf".text = ''
339 + [settings]
340 + # /etc/apparmor.d/ is read-only on NixOS
341 + profiledir = /var/cache/apparmor/logprof
342 + inactive_profiledir = /etc/apparmor.d/disable
343 + # Use: journalctl -b --since today --grep audit: | aa-logprof
344 + logfiles = /dev/stdin
345 +
346 + parser = ${pkgs.apparmor-parser}/bin/apparmor_parser
347 + ldd = ${pkgs.glibc.bin}/bin/ldd
348 + logger = ${pkgs.utillinux}/bin/logger
349 +
350 + # customize how file ownership permissions are presented
351 + # 0 - off
352 + # 1 - default of what ever mode the log reported
353 + # 2 - force the new permissions to be user
354 + # 3 - force all perms on the rule to be user
355 + default_owner_prompt = 1
356 +
357 + custom_includes = /etc/apparmor.d ${lib.concatMapStringsSep " " (p: "${p}/etc/apparmor.d") cfg.packages}
358 +
359 + [qualifiers]
360 + ${pkgs.runtimeShell} = icnu
361 + ${pkgs.bashInteractive}/bin/sh = icnu
362 + ${pkgs.bashInteractive}/bin/bash = icnu
363 + '' + head (match "^.*\\[qualifiers](.*)" # Drop the original [settings] section.
364 + (readFile "${pkgs.apparmor-utils}/etc/apparmor/logprof.conf"));
365 +
366 + boot.kernelParams = [ "apparmor=1" "security=apparmor" ];
367 +
368 + systemd.services.apparmor = {
369 + after = [
370 + "local-fs.target"
371 + "systemd-journald-audit.socket"
372 + ];
373 + before = [ "sysinit.target" ];
374 + wantedBy = [ "multi-user.target" ];
375 + unitConfig = {
376 + Description="Load AppArmor policies";
377 + DefaultDependencies = "no";
378 + ConditionSecurity = "apparmor";
379 + };
380 + # Reloading instead of restarting enables to load new AppArmor profiles
381 + # without necessarily restarting all services which have Requires=apparmor.service
382 + reloadIfChanged = true;
383 + restartTriggers = [
384 + etc."apparmor/parser.conf".source
385 + etc."apparmor.d".source
386 + ];
387 + serviceConfig = let
388 + killUnconfinedConfinables = pkgs.writeShellScript "apparmor-kill" ''
389 + set -eu
390 + ${pkgs.apparmor-utils}/bin/aa-status --json |
391 + ${pkgs.jq}/bin/jq --raw-output '.processes | .[] | .[] | select (.status == "unconfined") | .pid' |
392 + xargs --verbose --no-run-if-empty --delimiter='\n' \
393 + kill
394 + '';
395 + commonOpts = p: "--verbose --show-cache ${lib.optionalString (!p.enforce) "--complain "}${p.profile}";
396 + in {
397 + Type = "oneshot";
398 + RemainAfterExit = "yes";
399 + ExecStartPre = "${pkgs.apparmor-utils}/bin/aa-teardown";
400 + ExecStart = lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts p}") enabledPolicies;
401 + ExecStartPost = lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
402 + ExecReload =
403 + # Add or replace into the kernel profiles in enabledPolicies
404 + # (because AppArmor can do that without stopping the processes already confined).
405 + lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts p}") enabledPolicies ++
406 + # Remove from the kernel any profile whose name is not
407 + # one of the names within the content of the profiles in enabledPolicies
408 + # (indirectly read from /etc/apparmor.d/*, without recursing into sub-directory).
409 + # Note that this does not remove profiles dynamically generated by libvirt.
410 + [ "${pkgs.apparmor-utils}/bin/aa-remove-unknown" ] ++
411 + # Optionaly kill the processes which are unconfined but now have a profile loaded
412 + # (because AppArmor can only start to confine new processes).
413 + lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
414 + ExecStop = "${pkgs.apparmor-utils}/bin/aa-teardown";
415 + CacheDirectory = [ "apparmor" "apparmor/logprof" ];
416 + CacheDirectoryMode = "0700";
417 + };
418 + };
419 + };
420 +
421 + meta.maintainers = with lib.maintainers; [ julm ];
422 }
423 diff --git a/nixos/modules/security/apparmor/includes.nix b/nixos/modules/security/apparmor/includes.nix
424 new file mode 100644
425 index 00000000000..498d7e77650
426 --- /dev/null
427 +++ b/nixos/modules/security/apparmor/includes.nix
428 @@ -0,0 +1,301 @@
429 +{ config, lib, pkgs, ... }:
430 +let
431 + inherit (builtins) attrNames hasAttr isAttrs;
432 + inherit (lib) getLib;
433 + inherit (config.environment) etc;
434 + etcRule = arg:
435 + let go = {path ? null, mode ? "r", trail ? ""}:
436 + lib.optionalString (hasAttr path etc)
437 + "${mode} ${config.environment.etc.${path}.source}${trail},";
438 + in if isAttrs arg
439 + then go arg
440 + else go {path=arg;};
441 +in
442 +{
443 +# FIXME: most of the etcRule calls below have been
444 +# written systematically by converting from apparmor-profiles's profiles
445 +# without testing nor deep understanding of their uses,
446 +# and thus may need more rules or can have less rules;
447 +# this remains to be determined case by case,
448 +# some may even be completely useless.
449 +config.security.apparmor.includes = {
450 + # This one is included by <tunables/global>
451 + # which is usualy included before any profile.
452 + "abstractions/tunables/alias" = ''
453 + alias /bin -> /run/current-system/sw/bin,
454 + alias /lib/modules -> /run/current-system/kernel/lib/modules,
455 + alias /sbin -> /run/current-system/sw/sbin,
456 + alias /usr -> /run/current-system/sw,
457 + '';
458 + "abstractions/audio" = ''
459 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/audio"
460 + ${etcRule "asound.conf"}
461 + ${etcRule "esound/esd.conf"}
462 + ${etcRule "libao.conf"}
463 + ${etcRule {path="pulse"; trail="/";}}
464 + ${etcRule {path="pulse"; trail="/**";}}
465 + ${etcRule {path="sound"; trail="/";}}
466 + ${etcRule {path="sound"; trail="/**";}}
467 + ${etcRule {path="alsa/conf.d"; trail="/";}}
468 + ${etcRule {path="alsa/conf.d"; trail="/*";}}
469 + ${etcRule "openal/alsoft.conf"}
470 + ${etcRule "wildmidi/wildmidi.conf"}
471 + '';
472 + "abstractions/authentication" = ''
473 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/authentication"
474 + # Defined in security.pam
475 + include <abstractions/pam>
476 + ${etcRule "nologin"}
477 + ${etcRule "securetty"}
478 + ${etcRule {path="security"; trail="/*";}}
479 + ${etcRule "shadow"}
480 + ${etcRule "gshadow"}
481 + ${etcRule "pwdb.conf"}
482 + ${etcRule "default/passwd"}
483 + ${etcRule "login.defs"}
484 + '';
485 + "abstractions/base" = ''
486 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/base"
487 + r ${pkgs.stdenv.cc.libc}/share/locale/**,
488 + r ${pkgs.stdenv.cc.libc}/share/locale.alias,
489 + ${lib.optionalString (pkgs.glibcLocales != null) "r ${pkgs.glibcLocales}/lib/locale/locale-archive,"}
490 + ${etcRule "localtime"}
491 + r ${pkgs.tzdata}/share/zoneinfo/**,
492 + r ${pkgs.stdenv.cc.libc}/share/i18n/**,
493 + '';
494 + "abstractions/bash" = ''
495 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/bash"
496 + # system-wide bash configuration
497 + ${etcRule "profile.dos"}
498 + ${etcRule "profile"}
499 + ${etcRule "profile.d"}
500 + ${etcRule {path="profile.d"; trail="/*";}}
501 + ${etcRule "bashrc"}
502 + ${etcRule "bash.bashrc"}
503 + ${etcRule "bash.bashrc.local"}
504 + ${etcRule "bash_completion"}
505 + ${etcRule "bash_completion.d"}
506 + ${etcRule {path="bash_completion.d"; trail="/*";}}
507 + # bash relies on system-wide readline configuration
508 + ${etcRule "inputrc"}
509 + # bash inspects filesystems at startup
510 + # and /etc/mtab is linked to /proc/mounts
511 + @{PROC}/mounts
512 +
513 + # run out of /etc/bash.bashrc
514 + ${etcRule "DIR_COLORS"}
515 + '';
516 + "abstractions/cups-client" = ''
517 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/cpus-client"
518 + ${etcRule "cups/cups-client.conf"}
519 + '';
520 + "abstractions/consoles" = ''
521 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/consoles"
522 + '';
523 + "abstractions/dbus-session-strict" = ''
524 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dbus-session-strict"
525 + ${etcRule "machine-id"}
526 + '';
527 + "abstractions/dconf" = ''
528 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dconf"
529 + ${etcRule {path="dconf"; trail="/**";}}
530 + '';
531 + "abstractions/dri-common" = ''
532 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dri-common"
533 + ${etcRule "drirc"}
534 + '';
535 + # The config.fonts.fontconfig NixOS module adds many files to /etc/fonts/
536 + # by symlinking them but without exporting them outside of its NixOS module,
537 + # those are therefore added there to this "abstractions/fonts".
538 + "abstractions/fonts" = ''
539 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/fonts"
540 + ${etcRule {path="fonts"; trail="/**";}}
541 + '';
542 + "abstractions/gnome" = ''
543 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/gnome"
544 + ${etcRule {path="gnome"; trail="/gtkrc*";}}
545 + ${etcRule {path="gtk"; trail="/*";}}
546 + ${etcRule {path="gtk-2.0"; trail="/*";}}
547 + ${etcRule {path="gtk-3.0"; trail="/*";}}
548 + ${etcRule "orbitrc"}
549 + include <abstractions/fonts>
550 + ${etcRule {path="pango"; trail="/*";}}
551 + ${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/";}}
552 + ${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/*";}}
553 + ${etcRule "papersize"}
554 + ${etcRule {path="cups"; trail="/lpoptions";}}
555 + ${etcRule {path="gnome"; trail="/defaults.list";}}
556 + ${etcRule {path="xdg"; trail="/{,*-}mimeapps.list";}}
557 + ${etcRule "xdg/mimeapps.list"}
558 + '';
559 + "abstractions/kde" = ''
560 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kde"
561 + ${etcRule {path="qt3"; trail="/kstylerc";}}
562 + ${etcRule {path="qt3"; trail="/qt_plugins_3.3rc";}}
563 + ${etcRule {path="qt3"; trail="/qtrc";}}
564 + ${etcRule "kderc"}
565 + ${etcRule {path="kde3"; trail="/*";}}
566 + ${etcRule "kde4rc"}
567 + ${etcRule {path="xdg"; trail="/kdeglobals";}}
568 + ${etcRule {path="xdg"; trail="/Trolltech.conf";}}
569 + '';
570 + "abstractions/kerberosclient" = ''
571 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kerberosclient"
572 + ${etcRule {path="krb5.keytab"; mode="rk";}}
573 + ${etcRule "krb5.conf"}
574 + ${etcRule "krb5.conf.d"}
575 + ${etcRule {path="krb5.conf.d"; trail="/*";}}
576 +
577 + # config files found via strings on libs
578 + ${etcRule "krb.conf"}
579 + ${etcRule "krb.realms"}
580 + ${etcRule "srvtab"}
581 + '';
582 + "abstractions/ldapclient" = ''
583 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ldapclient"
584 + ${etcRule "ldap.conf"}
585 + ${etcRule "ldap.secret"}
586 + ${etcRule {path="openldap"; trail="/*";}}
587 + ${etcRule {path="openldap"; trail="/cacerts/*";}}
588 + ${etcRule {path="sasl2"; trail="/*";}}
589 + '';
590 + "abstractions/likewise" = ''
591 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/likewise"
592 + '';
593 + "abstractions/mdns" = ''
594 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/mdns"
595 + ${etcRule "nss_mdns.conf"}
596 + '';
597 + "abstractions/nameservice" = ''
598 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nameservice"
599 +
600 + # Many programs wish to perform nameservice-like operations, such as
601 + # looking up users by name or id, groups by name or id, hosts by name
602 + # or IP, etc. These operations may be performed through files, dns,
603 + # NIS, NIS+, LDAP, hesiod, wins, etc. Allow them all here.
604 + ${etcRule "group"}
605 + ${etcRule "host.conf"}
606 + ${etcRule "hosts"}
607 + ${etcRule "nsswitch.conf"}
608 + ${etcRule "gai.conf"}
609 + ${etcRule "passwd"}
610 + ${etcRule "protocols"}
611 +
612 + # libtirpc (used for NIS/YP login) needs this
613 + ${etcRule "netconfig"}
614 +
615 + ${etcRule "resolv.conf"}
616 +
617 + ${etcRule {path="samba"; trail="/lmhosts";}}
618 + ${etcRule "services"}
619 +
620 + ${etcRule "default/nss"}
621 +
622 + # libnl-3-200 via libnss-gw-name
623 + ${etcRule {path="libnl"; trail="/classid";}}
624 + ${etcRule {path="libnl-3"; trail="/classid";}}
625 +
626 + mr ${getLib pkgs.nss}/lib/libnss_*.so*,
627 + mr ${getLib pkgs.nss}/lib64/libnss_*.so*,
628 + '';
629 + "abstractions/nis" = ''
630 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nis"
631 + '';
632 + "abstractions/nvidia" = ''
633 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nvidia"
634 + ${etcRule "vdpau_wrapper.cfg"}
635 + '';
636 + "abstractions/opencl-common" = ''
637 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-common"
638 + ${etcRule {path="OpenCL"; trail="/**";}}
639 + '';
640 + "abstractions/opencl-mesa" = ''
641 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-mesa"
642 + ${etcRule "default/drirc"}
643 + '';
644 + "abstractions/openssl" = ''
645 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/openssl"
646 + ${etcRule {path="ssl"; trail="/openssl.cnf";}}
647 + '';
648 + "abstractions/p11-kit" = ''
649 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/p11-kit"
650 + ${etcRule {path="pkcs11"; trail="/";}}
651 + ${etcRule {path="pkcs11"; trail="/pkcs11.conf";}}
652 + ${etcRule {path="pkcs11"; trail="/modules/";}}
653 + ${etcRule {path="pkcs11"; trail="/modules/*";}}
654 + '';
655 + "abstractions/perl" = ''
656 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/perl"
657 + ${etcRule {path="perl"; trail="/**";}}
658 + '';
659 + "abstractions/php" = ''
660 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/php"
661 + ${etcRule {path="php"; trail="/**/";}}
662 + ${etcRule {path="php5"; trail="/**/";}}
663 + ${etcRule {path="php7"; trail="/**/";}}
664 + ${etcRule {path="php"; trail="/**.ini";}}
665 + ${etcRule {path="php5"; trail="/**.ini";}}
666 + ${etcRule {path="php7"; trail="/**.ini";}}
667 + '';
668 + "abstractions/postfix-common" = ''
669 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/postfix-common"
670 + ${etcRule "mailname"}
671 + ${etcRule {path="postfix"; trail="/*.cf";}}
672 + ${etcRule "postfix/main.cf"}
673 + ${etcRule "postfix/master.cf"}
674 + '';
675 + "abstractions/python" = ''
676 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/python"
677 + '';
678 + "abstractions/qt5" = ''
679 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/qt5"
680 + ${etcRule {path="xdg"; trail="/QtProject/qtlogging.ini";}}
681 + ${etcRule {path="xdg/QtProject"; trail="/qtlogging.ini";}}
682 + ${etcRule "xdg/QtProject/qtlogging.ini"}
683 + '';
684 + "abstractions/samba" = ''
685 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/samba"
686 + ${etcRule {path="samba"; trail="/*";}}
687 + '';
688 + "abstractions/ssl_certs" = ''
689 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ssl_certs"
690 + ${etcRule "ssl/certs/ca-certificates.crt"}
691 + ${etcRule "ssl/certs/ca-bundle.crt"}
692 + ${etcRule "pki/tls/certs/ca-bundle.crt"}
693 +
694 + ${etcRule {path="ssl/trust"; trail="/";}}
695 + ${etcRule {path="ssl/trust"; trail="/*";}}
696 + ${etcRule {path="ssl/trust/anchors"; trail="/";}}
697 + ${etcRule {path="ssl/trust/anchors"; trail="/**";}}
698 + ${etcRule {path="pki/trust"; trail="/";}}
699 + ${etcRule {path="pki/trust"; trail="/*";}}
700 + ${etcRule {path="pki/trust/anchors"; trail="/";}}
701 + ${etcRule {path="pki/trust/anchors"; trail="/**";}}
702 +
703 + # security.acme NixOS module
704 + r /var/lib/acme/*/cert.pem,
705 + r /var/lib/acme/*/chain.pem,
706 + r /var/lib/acme/*/fullchain.pem,
707 + '';
708 + "abstractions/ssl_keys" = ''
709 + # security.acme NixOS module
710 + r /var/lib/acme/*/full.pem,
711 + r /var/lib/acme/*/key.pem,
712 + '';
713 + "abstractions/vulkan" = ''
714 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/vulkan"
715 + ${etcRule {path="vulkan/icd.d"; trail="/";}}
716 + ${etcRule {path="vulkan/icd.d"; trail="/*.json";}}
717 + '';
718 + "abstractions/winbind" = ''
719 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/winbind"
720 + ${etcRule {path="samba"; trail="/smb.conf";}}
721 + ${etcRule {path="samba"; trail="/dhcp.conf";}}
722 + '';
723 + "abstractions/X" = ''
724 + include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/X"
725 + ${etcRule {path="X11/cursors"; trail="/";}}
726 + ${etcRule {path="X11/cursors"; trail="/**";}}
727 + '';
728 +};
729 +}
730 diff --git a/nixos/modules/security/apparmor/profiles.nix b/nixos/modules/security/apparmor/profiles.nix
731 new file mode 100644
732 index 00000000000..8eb630b5a48
733 --- /dev/null
734 +++ b/nixos/modules/security/apparmor/profiles.nix
735 @@ -0,0 +1,11 @@
736 +{ config, lib, pkgs, ... }:
737 +let apparmor = config.security.apparmor; in
738 +{
739 +config.security.apparmor.packages = [ pkgs.apparmor-profiles ];
740 +config.security.apparmor.policies."bin.ping".profile = lib.mkIf apparmor.policies."bin.ping".enable ''
741 + include "${pkgs.iputils.apparmor}/bin.ping"
742 + include "${pkgs.inetutils.apparmor}/bin.ping"
743 + # Note that including those two profiles in the same profile
744 + # would not work if the second one were to re-include <tunables/global>.
745 +'';
746 +}
747 diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
748 index a20d0a243a8..b29f51260a8 100644
749 --- a/nixos/modules/security/pam.nix
750 +++ b/nixos/modules/security/pam.nix
751 @@ -850,6 +850,61 @@ in
752 runuser-l = { rootOK = true; unixAuth = false; };
753 };
754
755 + security.apparmor.includes."abstractions/pam" = let
756 + isEnabled = test: fold or false (map test (attrValues config.security.pam.services));
757 + in ''
758 + ${lib.concatMapStringsSep "\n"
759 + (name: "r ${config.environment.etc."pam.d/${name}".source},")
760 + (attrNames config.security.pam.services)}
761 + mr ${getLib pkgs.pam}/lib/security/pam_filter/*,
762 + mr ${getLib pkgs.pam}/lib/security/pam_*.so,
763 + r ${getLib pkgs.pam}/lib/security/,
764 + ${optionalString use_ldap
765 + "mr ${pam_ldap}/lib/security/pam_ldap.so,"}
766 + ${optionalString config.services.sssd.enable
767 + "mr ${pkgs.sssd}/lib/security/pam_sss.so,"}
768 + ${optionalString config.krb5.enable ''
769 + mr ${pam_krb5}/lib/security/pam_krb5.so,
770 + mr ${pam_ccreds}/lib/security/pam_ccreds.so,
771 + ''}
772 + ${optionalString (isEnabled (cfg: cfg.googleOsLoginAccountVerification)) ''
773 + mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,
774 + mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so,
775 + ''}
776 + ${optionalString (isEnabled (cfg: cfg.googleOsLoginAuthentication))
777 + "mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,"}
778 + ${optionalString (config.security.pam.enableSSHAgentAuth && isEnabled (cfg: cfg.sshAgentAuth))
779 + "mr ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so,"}
780 + ${optionalString (isEnabled (cfg: cfg.fprintAuth))
781 + "mr ${pkgs.fprintd}/lib/security/pam_fprintd.so,"}
782 + ${optionalString (isEnabled (cfg: cfg.u2fAuth))
783 + "mr ${pkgs.pam_u2f}/lib/security/pam_u2f.so,"}
784 + ${optionalString (isEnabled (cfg: cfg.usbAuth))
785 + "mr ${pkgs.pam_usb}/lib/security/pam_usb.so,"}
786 + ${optionalString (isEnabled (cfg: cfg.oathAuth))
787 + "mr ${pkgs.oathToolkit}/lib/security/pam_oath.so,"}
788 + ${optionalString (isEnabled (cfg: cfg.yubicoAuth))
789 + "mr ${pkgs.yubico-pam}/lib/security/pam_yubico.so,"}
790 + ${optionalString (isEnabled (cfg: cfg.duoSecurity.enable))
791 + "mr ${pkgs.duo-unix}/lib/security/pam_duo.so,"}
792 + ${optionalString (isEnabled (cfg: cfg.otpwAuth))
793 + "mr ${pkgs.otpw}/lib/security/pam_otpw.so,"}
794 + ${optionalString config.security.pam.enableEcryptfs
795 + "mr ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so,"}
796 + ${optionalString (isEnabled (cfg: cfg.pamMount))
797 + "mr ${pkgs.pam_mount}/lib/security/pam_mount.so,"}
798 + ${optionalString (isEnabled (cfg: cfg.enableGnomeKeyring))
799 + "mr ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so,"}
800 + ${optionalString (isEnabled (cfg: cfg.startSession))
801 + "mr ${pkgs.systemd}/lib/security/pam_systemd.so,"}
802 + ${optionalString (isEnabled (cfg: cfg.enableAppArmor) && config.security.apparmor.enable)
803 + "mr ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so,"}
804 + ${optionalString (isEnabled (cfg: cfg.enableKwallet))
805 + "mr ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so,"}
806 + ${optionalString config.virtualisation.lxc.lxcfs.enable
807 + "mr ${pkgs.lxc}/lib/security/pam_cgfs.so"}
808 + '';
809 +
810 };
811
812 }
813 diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix
814 index 52de21bca9b..f560f5c7628 100644
815 --- a/nixos/modules/security/wrappers/default.nix
816 +++ b/nixos/modules/security/wrappers/default.nix
817 @@ -179,6 +179,14 @@ in
818 export PATH="${wrapperDir}:$PATH"
819 '';
820
821 + security.apparmor.includes."nixos/security.wrappers" = ''
822 + include "${pkgs.apparmorRulesFromClosure {} [
823 + securityWrapper
824 + pkgs.stdenv.cc.cc
825 + pkgs.stdenv.cc.libc
826 + ]}"
827 + '';
828 +
829 ###### setcap activation script
830 system.activationScripts.wrappers =
831 lib.stringAfter [ "specialfs" "users" ]
832 diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix
833 index 014a22bb5a8..57982c20ccd 100644
834 --- a/nixos/modules/services/torrent/transmission.nix
835 +++ b/nixos/modules/services/torrent/transmission.nix
836 @@ -5,7 +5,7 @@ with lib;
837 let
838 cfg = config.services.transmission;
839 inherit (config.environment) etc;
840 - apparmor = config.security.apparmor.enable;
841 + apparmor = config.security.apparmor;
842 rootDir = "/run/transmission";
843 homeDir = "/var/lib/transmission";
844 settingsDir = ".config/transmission-daemon";
845 @@ -184,8 +184,8 @@ in
846
847 systemd.services.transmission = {
848 description = "Transmission BitTorrent Service";
849 - after = [ "network.target" ] ++ optional apparmor "apparmor.service";
850 - requires = optional apparmor "apparmor.service";
851 + after = [ "network.target" ] ++ optional apparmor.enable "apparmor.service";
852 + requires = optional apparmor.enable "apparmor.service";
853 wantedBy = [ "multi-user.target" ];
854 environment.CURL_CA_BUNDLE = etc."ssl/certs/ca-certificates.crt".source;
855
856 @@ -357,61 +357,21 @@ in
857 })
858 ];
859
860 - security.apparmor.profiles = mkIf apparmor [
861 - (pkgs.writeText "apparmor-transmission-daemon" ''
862 + security.apparmor.policies."bin.transmission-daemon".profile = ''
863 include <tunables/global>
864 -
865 ${pkgs.transmission}/bin/transmission-daemon {
866 include <abstractions/base>
867 include <abstractions/nameservice>
868 -
869 - # NOTE: https://github.com/NixOS/nixpkgs/pull/93457
870 - # will remove the need for these by fixing <abstractions/base>
871 - r ${etc."hosts".source},
872 - r /etc/ld-nix.so.preload,
873 - ${lib.optionalString (builtins.hasAttr "ld-nix.so.preload" etc) ''
874 - r ${etc."ld-nix.so.preload".source},
875 - ${concatMapStrings (p: optionalString (p != "") ("mr ${p},\n"))
876 - (splitString "\n" config.environment.etc."ld-nix.so.preload".text)}
877 - ''}
878 - r ${etc."ssl/certs/ca-certificates.crt".source},
879 - r ${pkgs.tzdata}/share/zoneinfo/**,
880 - r ${pkgs.stdenv.cc.libc}/share/i18n/**,
881 - r ${pkgs.stdenv.cc.libc}/share/locale/**,
882 -
883 - mr ${getLib pkgs.stdenv.cc.cc}/lib/*.so*,
884 - mr ${getLib pkgs.stdenv.cc.libc}/lib/*.so*,
885 - mr ${getLib pkgs.attr}/lib/libattr*.so*,
886 - mr ${getLib pkgs.c-ares}/lib/libcares*.so*,
887 - mr ${getLib pkgs.curl}/lib/libcurl*.so*,
888 - mr ${getLib pkgs.keyutils}/lib/libkeyutils*.so*,
889 - mr ${getLib pkgs.libcap}/lib/libcap*.so*,
890 - mr ${getLib pkgs.libevent}/lib/libevent*.so*,
891 - mr ${getLib pkgs.libgcrypt}/lib/libgcrypt*.so*,
892 - mr ${getLib pkgs.libgpgerror}/lib/libgpg-error*.so*,
893 - mr ${getLib pkgs.libkrb5}/lib/lib*.so*,
894 - mr ${getLib pkgs.libssh2}/lib/libssh2*.so*,
895 - mr ${getLib pkgs.lz4}/lib/liblz4*.so*,
896 - mr ${getLib pkgs.nghttp2}/lib/libnghttp2*.so*,
897 - mr ${getLib pkgs.openssl}/lib/libcrypto*.so*,
898 - mr ${getLib pkgs.openssl}/lib/libssl*.so*,
899 - mr ${getLib pkgs.systemd}/lib/libsystemd*.so*,
900 - mr ${getLib pkgs.utillinuxMinimal.out}/lib/libblkid.so*,
901 - mr ${getLib pkgs.utillinuxMinimal.out}/lib/libmount.so*,
902 - mr ${getLib pkgs.utillinuxMinimal.out}/lib/libuuid.so*,
903 - mr ${getLib pkgs.xz}/lib/liblzma*.so*,
904 - mr ${getLib pkgs.zlib}/lib/libz*.so*,
905 + include <abstractions/ssl_certs>
906 + include "${pkgs.apparmorRulesFromClosure {} [pkgs.transmission]}"
907 + include <local/bin.transmission-daemon>
908
909 r @{PROC}/sys/kernel/random/uuid,
910 r @{PROC}/sys/vm/overcommit_memory,
911 - # @{pid} is not a kernel variable yet but a regexp
912 - #r @{PROC}/@{pid}/environ,
913 + r @{PROC}/@{pid}/environ,
914 r @{PROC}/@{pid}/mounts,
915 rwk /tmp/tr_session_id_*,
916 -
917 - r ${pkgs.openssl.out}/etc/**,
918 r ${config.systemd.services.transmission.environment.CURL_CA_BUNDLE},
919 - r ${pkgs.transmission}/share/transmission/**,
920
921 owner rw ${cfg.home}/${settingsDir}/**,
922 rw ${cfg.settings.download-dir}/**,
923 @@ -439,12 +399,9 @@ in
924 # https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking#seccomp-and-no_new_privs
925 px ${cfg.settings.script-torrent-done-filename} -> &@{dirs},
926 ''}
927 -
928 - # FIXME: enable customizing using https://github.com/NixOS/nixpkgs/pull/93457
929 - # include <local/transmission-daemon>
930 }
931 - '')
932 - ];
933 + '';
934 + security.apparmor.includes."local/bin.transmission-daemon" = "";
935 };
936
937 meta.maintainers = with lib.maintainers; [ julm ];
938 diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
939 index e5bd5775368..02723c6a164 100644
940 --- a/nixos/modules/tasks/network-interfaces.nix
941 +++ b/nixos/modules/tasks/network-interfaces.nix
942 @@ -1094,6 +1094,21 @@ in
943 } else {
944 ping.source = "${pkgs.iputils.out}/bin/ping";
945 };
946 + security.apparmor.policies."bin.ping".profile = lib.mkIf config.security.apparmor.policies."bin.ping".enable (lib.mkAfter ''
947 + /run/wrappers/bin/ping {
948 + include <abstractions/base>
949 + include <nixos/security.wrappers>
950 + rpx /run/wrappers/wrappers.*/ping,
951 + }
952 + /run/wrappers/wrappers.*/ping {
953 + include <abstractions/base>
954 + include <nixos/security.wrappers>
955 + r /run/wrappers/wrappers.*/ping.real,
956 + mrpx ${config.security.wrappers.ping.source},
957 + capability net_raw,
958 + capability setpcap,
959 + }
960 + '');
961
962 # Set the host and domain names in the activation script. Don't
963 # clear it if it's not configured in the NixOS configuration,
964 diff --git a/nixos/modules/virtualisation/lxc.nix b/nixos/modules/virtualisation/lxc.nix
965 index f484d5ee59a..0f8b22a45df 100644
966 --- a/nixos/modules/virtualisation/lxc.nix
967 +++ b/nixos/modules/virtualisation/lxc.nix
968 @@ -74,9 +74,13 @@ in
969 systemd.tmpfiles.rules = [ "d /var/lib/lxc/rootfs 0755 root root -" ];
970
971 security.apparmor.packages = [ pkgs.lxc ];
972 - security.apparmor.profiles = [
973 - "${pkgs.lxc}/etc/apparmor.d/lxc-containers"
974 - "${pkgs.lxc}/etc/apparmor.d/usr.bin.lxc-start"
975 - ];
976 + security.apparmor.policies = {
977 + "bin.lxc-start".profile = ''
978 + include ${pkgs.lxc}/etc/apparmor.d/usr.bin.lxc-start
979 + '';
980 + "lxc-containers".profile = ''
981 + include ${pkgs.lxc}/etc/apparmor.d/lxc-containers
982 + '';
983 + };
984 };
985 }
986 diff --git a/nixos/modules/virtualisation/lxd.nix b/nixos/modules/virtualisation/lxd.nix
987 index 3958fc2c1d7..876956f654b 100644
988 --- a/nixos/modules/virtualisation/lxd.nix
989 +++ b/nixos/modules/virtualisation/lxd.nix
990 @@ -93,11 +93,15 @@ in
991
992 security.apparmor = {
993 enable = true;
994 - profiles = [
995 - "${cfg.lxcPackage}/etc/apparmor.d/usr.bin.lxc-start"
996 - "${cfg.lxcPackage}/etc/apparmor.d/lxc-containers"
997 - ];
998 packages = [ cfg.lxcPackage ];
999 + policies = {
1000 + "bin.lxc-start".profile = ''
1001 + include ${cfg.lxcPackage}/etc/apparmor.d/usr.bin.lxc-start
1002 + '';
1003 + "lxc-containers".profile = ''
1004 + include ${cfg.lxcPackage}/etc/apparmor.d/lxc-containers
1005 + '';
1006 + };
1007 };
1008
1009 systemd.services.lxd = {
1010 diff --git a/pkgs/os-specific/linux/apparmor/default.nix b/pkgs/os-specific/linux/apparmor/default.nix
1011 index 0e10add5561..8806f6c50d3 100644
1012 --- a/pkgs/os-specific/linux/apparmor/default.nix
1013 +++ b/pkgs/os-specific/linux/apparmor/default.nix
1014 @@ -10,6 +10,13 @@
1015 , pam
1016 , libnotify
1017 , buildPackages
1018 +, coreutils
1019 +, gnugrep
1020 +, gnused
1021 +, kmod
1022 +, writeShellScript
1023 +, closureInfo
1024 +, runCommand
1025 }:
1026
1027 let
1028 @@ -38,6 +45,12 @@ let
1029 sha256 = "0xw028iqp69j9mxv0kbwraplgkj5i5djdlgf0anpkc5cdbsf96r9";
1030 };
1031
1032 + aa-teardown = writeShellScript "aa-teardown" ''
1033 + PATH="${lib.makeBinPath [coreutils gnused gnugrep]}:$PATH"
1034 + . ${apparmor-parser}/lib/apparmor/rc.apparmor.functions
1035 + remove_profiles
1036 + '';
1037 +
1038 prePatchCommon = ''
1039 patch -p1 < ${gnumake43Patch}
1040 chmod a+x ./common/list_capabilities.sh ./common/list_af_names.sh
1041 @@ -149,6 +162,15 @@ let
1042 # aa-notify checks its name and does not work named ".aa-notify-wrapped"
1043 mv $out/bin/aa-notify $out/bin/aa-notify-wrapped
1044 makeWrapper ${perl}/bin/perl $out/bin/aa-notify --set PERL5LIB ${libapparmor}/${perl.libPrefix} --add-flags $out/bin/aa-notify-wrapped
1045 +
1046 + substituteInPlace $out/bin/aa-remove-unknown \
1047 + --replace "/usr/bin/aa-status" "$out/bin/aa-status" \
1048 + --replace "/sbin/modprobe" "${kmod}/bin/modprobe" \
1049 + --replace "/lib/apparmor/rc.apparmor.functions" "${apparmor-parser}/lib/apparmor/rc.apparmor.functions"
1050 + wrapProgram $out/bin/aa-remove-unknown \
1051 + --prefix PATH : ${lib.makeBinPath [gawk]}
1052 +
1053 + ln -s ${aa-teardown} $out/bin/aa-teardown
1054 '';
1055
1056 inherit doCheck;
1057 @@ -197,6 +219,9 @@ let
1058 substituteInPlace ./parser/Makefile --replace "/usr/include/linux/capability.h" "${linuxHeaders}/include/linux/capability.h"
1059 ## techdoc.pdf still doesn't build ...
1060 substituteInPlace ./parser/Makefile --replace "manpages htmlmanpages pdf" "manpages htmlmanpages"
1061 + substituteInPlace parser/rc.apparmor.functions \
1062 + --replace "/sbin/apparmor_parser" "$out/bin/apparmor_parser"
1063 + sed -i parser/rc.apparmor.functions -e '2i . ${./fix-rc.apparmor.functions.sh}'
1064 '';
1065 inherit patches;
1066 postPatch = "cd ./parser";
1067 @@ -258,8 +283,32 @@ let
1068 meta = apparmor-meta "kernel patches";
1069 };
1070
1071 + # Generate generic AppArmor rules in a file,
1072 + # from the closure of given rootPaths.
1073 + # To be included in an AppArmor profile like so:
1074 + # include "$(apparmorRulesFromClosure {} [pkgs.hello]}"
1075 + apparmorRulesFromClosure =
1076 + { # The store path of the derivation is given in $path
1077 + additionalRules ? []
1078 + # TODO: factorize here some other common paths
1079 + # that may emerge from use cases.
1080 + , baseRules ? [
1081 + "r $path"
1082 + "r $path/etc/**"
1083 + "r $path/share/**"
1084 + # Note that not all libraries are prefixed with "lib",
1085 + # eg. glibc-2.30/lib/ld-2.30.so
1086 + "mr $path/lib/**.so*"
1087 + # eg. glibc-2.30/lib/gconv/gconv-modules
1088 + "r $path/lib/**"
1089 + ]
1090 + }: rootPaths: runCommand "apparmor-closure-rules" {} ''
1091 + touch $out
1092 + while read -r path
1093 + do printf >>$out "%s,\n" ${lib.concatMapStringsSep " " (x: "\"${x}\"") (baseRules ++ additionalRules)}
1094 + done <${closureInfo {inherit rootPaths;}}/store-paths
1095 + '';
1096 in
1097 -
1098 {
1099 inherit
1100 libapparmor
1101 @@ -268,5 +317,6 @@ in
1102 apparmor-parser
1103 apparmor-pam
1104 apparmor-profiles
1105 - apparmor-kernel-patches;
1106 + apparmor-kernel-patches
1107 + apparmorRulesFromClosure;
1108 }
1109 diff --git a/pkgs/os-specific/linux/apparmor/fix-rc.apparmor.functions.sh b/pkgs/os-specific/linux/apparmor/fix-rc.apparmor.functions.sh
1110 new file mode 100644
1111 index 00000000000..ebc1baaa92d
1112 --- /dev/null
1113 +++ b/pkgs/os-specific/linux/apparmor/fix-rc.apparmor.functions.sh
1114 @@ -0,0 +1,32 @@
1115 +aa_action() {
1116 + STRING=$1
1117 + shift
1118 + $*
1119 + rc=$?
1120 + if [ $rc -eq 0 ] ; then
1121 + aa_log_success_msg $"$STRING "
1122 + else
1123 + aa_log_failure_msg $"$STRING "
1124 + fi
1125 + return $rc
1126 +}
1127 +
1128 +aa_log_success_msg() {
1129 + [ -n "$1" ] && echo -n $1
1130 + echo ": done."
1131 +}
1132 +
1133 +aa_log_warning_msg() {
1134 + [ -n "$1" ] && echo -n $1
1135 + echo ": Warning."
1136 +}
1137 +
1138 +aa_log_failure_msg() {
1139 + [ -n "$1" ] && echo -n $1
1140 + echo ": Failed."
1141 +}
1142 +
1143 +aa_log_skipped_msg() {
1144 + [ -n "$1" ] && echo -n $1
1145 + echo ": Skipped."
1146 +}
1147 diff --git a/pkgs/os-specific/linux/iputils/default.nix b/pkgs/os-specific/linux/iputils/default.nix
1148 index 3bb653ebcf7..26953bcf91b 100644
1149 --- a/pkgs/os-specific/linux/iputils/default.nix
1150 +++ b/pkgs/os-specific/linux/iputils/default.nix
1151 @@ -1,6 +1,7 @@
1152 { stdenv, fetchFromGitHub, fetchpatch
1153 , meson, ninja, pkgconfig, gettext, libxslt, docbook_xsl_ns
1154 , libcap, libidn2
1155 +, apparmorRulesFromClosure
1156 }:
1157
1158 with stdenv.lib;
1159 @@ -30,6 +31,8 @@ in stdenv.mkDerivation rec {
1160 })
1161 ];
1162
1163 + outputs = ["out" "apparmor"];
1164 +
1165 mesonFlags = [
1166 "-DBUILD_RARPD=true"
1167 "-DBUILD_TRACEROUTE6=true"
1168 @@ -44,6 +47,25 @@ in stdenv.mkDerivation rec {
1169 nativeBuildInputs = [ meson ninja pkgconfig gettext libxslt.bin docbook_xsl_ns ];
1170 buildInputs = [ libcap ]
1171 ++ optional (!stdenv.hostPlatform.isMusl) libidn2;
1172 + postInstall = ''
1173 + install -D /dev/stdin $apparmor/bin.ping <<EOF
1174 + include <tunables/global>
1175 + $out/bin/ping {
1176 + include <abstractions/base>
1177 + include <abstractions/consoles>
1178 + include <abstractions/nameservice>
1179 + include "${apparmorRulesFromClosure {}
1180 + ([libcap] ++ optional (!stdenv.hostPlatform.isMusl) libidn2)}"
1181 + include <local/bin.ping>
1182 + capability net_raw,
1183 + network inet raw,
1184 + network inet6 raw,
1185 + mr $out/bin/ping,
1186 + r $out/share/locale/**,
1187 + r @{PROC}/@{pid}/environ,
1188 + }
1189 + EOF
1190 + '';
1191
1192 meta = {
1193 description = "A set of small useful utilities for Linux networking";
1194 diff --git a/pkgs/tools/networking/inetutils/default.nix b/pkgs/tools/networking/inetutils/default.nix
1195 index 1290ec2bdb1..bcc4237f434 100644
1196 --- a/pkgs/tools/networking/inetutils/default.nix
1197 +++ b/pkgs/tools/networking/inetutils/default.nix
1198 @@ -1,4 +1,6 @@
1199 -{ stdenv, lib, fetchurl, ncurses, perl, help2man }:
1200 +{ stdenv, lib, fetchurl, ncurses, perl, help2man
1201 +, apparmorRulesFromClosure
1202 +}:
1203
1204 stdenv.mkDerivation rec {
1205 name = "inetutils-1.9.4";
1206 @@ -8,6 +10,8 @@ stdenv.mkDerivation rec {
1207 sha256 = "05n65k4ixl85dc6rxc51b1b732gnmm8xnqi424dy9f1nz7ppb3xy";
1208 };
1209
1210 + outputs = ["out" "apparmor"];
1211 +
1212 patches = [
1213 ./whois-Update-Canadian-TLD-server.patch
1214 ./service-name.patch
1215 @@ -41,6 +45,22 @@ stdenv.mkDerivation rec {
1216
1217 installFlags = [ "SUIDMODE=" ];
1218
1219 + postInstall = ''
1220 + install -D /dev/stdin $apparmor/bin.ping <<EOF
1221 + $out/bin/ping {
1222 + include <abstractions/base>
1223 + include <abstractions/consoles>
1224 + include <abstractions/nameservice>
1225 + include "${apparmorRulesFromClosure {} [stdenv.cc.libc]}"
1226 + include <local/bin.ping>
1227 + capability net_raw,
1228 + network inet raw,
1229 + network inet6 raw,
1230 + mr $out/bin/ping,
1231 + }
1232 + EOF
1233 + '';
1234 +
1235 meta = with lib; {
1236 description = "Collection of common network programs";
1237
1238 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
1239 index 8afc133f51b..4dcb1178730 100644
1240 --- a/pkgs/top-level/all-packages.nix
1241 +++ b/pkgs/top-level/all-packages.nix
1242 @@ -17413,7 +17413,7 @@ in
1243
1244 inherit (callPackages ../os-specific/linux/apparmor { python = python3; })
1245 libapparmor apparmor-utils apparmor-bin-utils apparmor-parser apparmor-pam
1246 - apparmor-profiles apparmor-kernel-patches;
1247 + apparmor-profiles apparmor-kernel-patches apparmorRulesFromClosure;
1248
1249 atop = callPackage ../os-specific/linux/atop { };
1250