···1515 </listitem>
1516 <listitem>
1517 <para>
0000000000000000001518 With this release <literal>systemd-networkd</literal> (when enabled through <xref linkend="opt-networking.useNetworkd"/>)
1519 has it's netlink socket created through a <literal>systemd.socket</literal> unit. This gives us control over
1520 socket buffer sizes and other parameters. For larger setups where networkd has to create a lot of (virtual)
···1515 </listitem>
1516 <listitem>
1517 <para>
1518+ The <literal>security.apparmor</literal> module,
1519+ for the <link xlink:href="https://gitlab.com/apparmor/apparmor/-/wikis/Documentation">AppArmor</link>
1520+ Mandatory Access Control system,
1521+ has been substantialy improved along with related tools,
1522+ so that module maintainers can now more easily write AppArmor profiles for NixOS.
1523+ The most notable change on the user-side is the new option <xref linkend="opt-security.apparmor.policies"/>,
1524+ replacing the previous <literal>profiles</literal> option
1525+ to provide a way to disable a profile
1526+ and to select whether to confine in enforce mode (default)
1527+ or in complain mode (see <literal>journalctl -b --grep apparmor</literal>).
1528+ Before enabling this module, either directly
1529+ or by importing <literal><nixpkgs/nixos/modules/profiles/hardened.nix></literal>,
1530+ please be sure to read the documentation of <link linkend="opt-security.apparmor.enable">security.apparmor.enable</link>,
1531+ and especially the part about <xref linkend="opt-security.apparmor.killUnconfinedConfinables"/>.
1532+ </para>
1533+ </listitem>
1534+ <listitem>
1535+ <para>
1536 With this release <literal>systemd-networkd</literal> (when enabled through <xref linkend="opt-networking.useNetworkd"/>)
1537 has it's netlink socket created through a <literal>systemd.socket</literal> unit. This gives us control over
1538 socket buffer sizes and other parameters. For larger setups where networkd has to create a lot of (virtual)
···1{ config, lib, pkgs, ... }:
23let
4+ inherit (builtins) attrNames head map match readFile;
5+ inherit (lib) types;
6+ inherit (config.environment) etc;
7 cfg = config.security.apparmor;
8+ mkDisableOption = name: lib.mkEnableOption name // {
9+ default = true;
10+ example = false;
11+ };
12+ enabledPolicies = lib.filterAttrs (n: p: p.enable) cfg.policies;
13in
1415{
16+ imports = [
17+ (lib.mkRenamedOptionModule [ "security" "virtualization" "flushL1DataCache" ] [ "security" "virtualisation" "flushL1DataCache" ])
18+ (lib.mkRemovedOptionModule [ "security" "apparmor" "confineSUIDApplications" ] "Please use the new options: `security.apparmor.policies.<policy>.enable'.")
19+ (lib.mkRemovedOptionModule [ "security" "apparmor" "profiles" ] "Please use the new option: `security.apparmor.policies'.")
20+ apparmor/includes.nix
21+ apparmor/profiles.nix
22+ ];
23+24+ options = {
25+ security.apparmor = {
26+ enable = lib.mkEnableOption ''the AppArmor Mandatory Access Control system.
27+28+ If you're enabling this module on a running system,
29+ note that a reboot will be required to activate AppArmor in the kernel.
30+31+ Also, beware that enabling this module will by default
32+ try to kill unconfined but confinable running processes,
33+ in order to obtain a confinement matching what is declared in the NixOS configuration.
34+ This will happen when upgrading to a NixOS revision
35+ introducing an AppArmor profile for the executable of a running process.
36+ This is because enabling an AppArmor profile for an executable
37+ can only confine new or already confined processes of that executable,
38+ but leaves already running processes unconfined.
39+ Set <link linkend="opt-security.apparmor.killUnconfinedConfinables">killUnconfinedConfinables</link>
40+ to <literal>false</literal> if you prefer to leave those processes running'';
41+ policies = lib.mkOption {
42+ description = ''
43+ AppArmor policies.
44+ '';
45+ type = types.attrsOf (types.submodule ({ name, config, ... }: {
46+ options = {
47+ enable = mkDisableOption "loading of the profile into the kernel";
48+ enforce = mkDisableOption "enforcing of the policy or only complain in the logs";
49+ profile = lib.mkOption {
50+ description = "The policy of the profile.";
51+ type = types.lines;
52+ apply = pkgs.writeText name;
53+ };
54+ };
55+ }));
56+ default = {};
57+ };
58+ includes = lib.mkOption {
59+ type = types.attrsOf types.lines;
60+ default = {};
61+ description = ''
62+ List of paths to be added to AppArmor's searched paths
63+ when resolving <literal>include</literal> directives.
64+ '';
65+ apply = lib.mapAttrs pkgs.writeText;
66+ };
67+ packages = lib.mkOption {
68+ type = types.listOf types.package;
69+ default = [];
70+ description = "List of packages to be added to AppArmor's include path";
71+ };
72+ enableCache = lib.mkEnableOption ''caching of AppArmor policies
73+ in <literal>/var/cache/apparmor/</literal>.
74+75+ Beware that AppArmor policies almost always contain Nix store paths,
76+ and thus produce at each change of these paths
77+ a new cached version accumulating in the cache'';
78+ killUnconfinedConfinables = mkDisableOption ''killing of processes
79+ which have an AppArmor profile enabled
80+ (in <link linkend="opt-security.apparmor.policies">policies</link>)
81+ but are not confined (because AppArmor can only confine new processes).
82+ Beware that due to a current limitation of AppArmor,
83+ only profiles with exact paths (and no name) can enable such kills'';
84+ };
85+ };
86+87+ config = lib.mkIf cfg.enable {
88+ assertions = map (policy:
89+ { assertion = match ".*/.*" policy == null;
90+ message = "`security.apparmor.policies.\"${policy}\"' must not contain a slash.";
91+ # Because, for instance, aa-remove-unknown uses profiles_names_list() in rc.apparmor.functions
92+ # which does not recurse into sub-directories.
93+ }
94+ ) (attrNames cfg.policies);
95+96+ environment.systemPackages = [ pkgs.apparmor-utils ];
97+ environment.etc."apparmor.d".source = pkgs.linkFarm "apparmor.d" (
98+ # It's important to put only enabledPolicies here and not all cfg.policies
99+ # because aa-remove-unknown reads profiles from all /etc/apparmor.d/*
100+ lib.mapAttrsToList (name: p: {inherit name; path=p.profile;}) enabledPolicies ++
101+ lib.mapAttrsToList (name: path: {inherit name path;}) cfg.includes
102+ );
103+ environment.etc."apparmor/parser.conf".text = ''
104+ ${if cfg.enableCache then "write-cache" else "skip-cache"}
105+ cache-loc /var/cache/apparmor
106+ Include /etc/apparmor.d
107+ '' +
108+ lib.concatMapStrings (p: "Include ${p}/etc/apparmor.d\n") cfg.packages;
109+ # For aa-logprof
110+ environment.etc."apparmor/apparmor.conf".text = ''
111+ '';
112+ # For aa-logprof
113+ environment.etc."apparmor/severity.db".source = pkgs.apparmor-utils + "/etc/apparmor/severity.db";
114+ environment.etc."apparmor/logprof.conf".text = ''
115+ [settings]
116+ # /etc/apparmor.d/ is read-only on NixOS
117+ profiledir = /var/cache/apparmor/logprof
118+ inactive_profiledir = /etc/apparmor.d/disable
119+ # Use: journalctl -b --since today --grep audit: | aa-logprof
120+ logfiles = /dev/stdin
121+122+ parser = ${pkgs.apparmor-parser}/bin/apparmor_parser
123+ ldd = ${pkgs.glibc.bin}/bin/ldd
124+ logger = ${pkgs.utillinux}/bin/logger
125+126+ # customize how file ownership permissions are presented
127+ # 0 - off
128+ # 1 - default of what ever mode the log reported
129+ # 2 - force the new permissions to be user
130+ # 3 - force all perms on the rule to be user
131+ default_owner_prompt = 1
132+133+ custom_includes = /etc/apparmor.d ${lib.concatMapStringsSep " " (p: "${p}/etc/apparmor.d") cfg.packages}
134+135+ [qualifiers]
136+ ${pkgs.runtimeShell} = icnu
137+ ${pkgs.bashInteractive}/bin/sh = icnu
138+ ${pkgs.bashInteractive}/bin/bash = icnu
139+ '' + head (match "^.*\\[qualifiers](.*)" # Drop the original [settings] section.
140+ (readFile "${pkgs.apparmor-utils}/etc/apparmor/logprof.conf"));
141142+ boot.kernelParams = [ "apparmor=1" "security=apparmor" ];
0143144+ systemd.services.apparmor = {
145+ after = [
146+ "local-fs.target"
147+ "systemd-journald-audit.socket"
148+ ];
149+ before = [ "sysinit.target" ];
150+ wantedBy = [ "multi-user.target" ];
151+ unitConfig = {
152+ Description="Load AppArmor policies";
153+ DefaultDependencies = "no";
154+ ConditionSecurity = "apparmor";
155+ };
156+ # Reloading instead of restarting enables to load new AppArmor profiles
157+ # without necessarily restarting all services which have Requires=apparmor.service
158+ reloadIfChanged = true;
159+ restartTriggers = [
160+ etc."apparmor/parser.conf".source
161+ etc."apparmor.d".source
162+ ];
163+ serviceConfig = let
164+ killUnconfinedConfinables = pkgs.writeShellScript "apparmor-kill" ''
165+ set -eu
166+ ${pkgs.apparmor-utils}/bin/aa-status --json |
167+ ${pkgs.jq}/bin/jq --raw-output '.processes | .[] | .[] | select (.status == "unconfined") | .pid' |
168+ xargs --verbose --no-run-if-empty --delimiter='\n' \
169+ kill
170+ '';
171+ commonOpts = p: "--verbose --show-cache ${lib.optionalString (!p.enforce) "--complain "}${p.profile}";
172+ in {
173+ Type = "oneshot";
174+ RemainAfterExit = "yes";
175+ ExecStartPre = "${pkgs.apparmor-utils}/bin/aa-teardown";
176+ ExecStart = lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts p}") enabledPolicies;
177+ ExecStartPost = lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
178+ ExecReload =
179+ # Add or replace into the kernel profiles in enabledPolicies
180+ # (because AppArmor can do that without stopping the processes already confined).
181+ lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts p}") enabledPolicies ++
182+ # Remove from the kernel any profile whose name is not
183+ # one of the names within the content of the profiles in enabledPolicies
184+ # (indirectly read from /etc/apparmor.d/*, without recursing into sub-directory).
185+ # Note that this does not remove profiles dynamically generated by libvirt.
186+ [ "${pkgs.apparmor-utils}/bin/aa-remove-unknown" ] ++
187+ # Optionaly kill the processes which are unconfined but now have a profile loaded
188+ # (because AppArmor can only start to confine new processes).
189+ lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
190+ ExecStop = "${pkgs.apparmor-utils}/bin/aa-teardown";
191+ CacheDirectory = [ "apparmor" "apparmor/logprof" ];
192+ CacheDirectoryMode = "0700";
193+ };
194+ };
195+ };
196197+ meta.maintainers = with lib.maintainers; [ julm ];
000000000000000000000000198}
···1+{ config, lib, pkgs, ... }:
2+let
3+ inherit (builtins) attrNames hasAttr isAttrs;
4+ inherit (lib) getLib;
5+ inherit (config.environment) etc;
6+ etcRule = arg:
7+ let go = {path ? null, mode ? "r", trail ? ""}:
8+ lib.optionalString (hasAttr path etc)
9+ "${mode} ${config.environment.etc.${path}.source}${trail},";
10+ in if isAttrs arg
11+ then go arg
12+ else go {path=arg;};
13+in
14+{
15+# FIXME: most of the etcRule calls below have been
16+# written systematically by converting from apparmor-profiles's profiles
17+# without testing nor deep understanding of their uses,
18+# and thus may need more rules or can have less rules;
19+# this remains to be determined case by case,
20+# some may even be completely useless.
21+config.security.apparmor.includes = {
22+ # This one is included by <tunables/global>
23+ # which is usualy included before any profile.
24+ "abstractions/tunables/alias" = ''
25+ alias /bin -> /run/current-system/sw/bin,
26+ alias /lib/modules -> /run/current-system/kernel/lib/modules,
27+ alias /sbin -> /run/current-system/sw/sbin,
28+ alias /usr -> /run/current-system/sw,
29+ '';
30+ "abstractions/audio" = ''
31+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/audio"
32+ ${etcRule "asound.conf"}
33+ ${etcRule "esound/esd.conf"}
34+ ${etcRule "libao.conf"}
35+ ${etcRule {path="pulse"; trail="/";}}
36+ ${etcRule {path="pulse"; trail="/**";}}
37+ ${etcRule {path="sound"; trail="/";}}
38+ ${etcRule {path="sound"; trail="/**";}}
39+ ${etcRule {path="alsa/conf.d"; trail="/";}}
40+ ${etcRule {path="alsa/conf.d"; trail="/*";}}
41+ ${etcRule "openal/alsoft.conf"}
42+ ${etcRule "wildmidi/wildmidi.conf"}
43+ '';
44+ "abstractions/authentication" = ''
45+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/authentication"
46+ # Defined in security.pam
47+ include <abstractions/pam>
48+ ${etcRule "nologin"}
49+ ${etcRule "securetty"}
50+ ${etcRule {path="security"; trail="/*";}}
51+ ${etcRule "shadow"}
52+ ${etcRule "gshadow"}
53+ ${etcRule "pwdb.conf"}
54+ ${etcRule "default/passwd"}
55+ ${etcRule "login.defs"}
56+ '';
57+ "abstractions/base" = ''
58+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/base"
59+ r ${pkgs.stdenv.cc.libc}/share/locale/**,
60+ r ${pkgs.stdenv.cc.libc}/share/locale.alias,
61+ ${lib.optionalString (pkgs.glibcLocales != null) "r ${pkgs.glibcLocales}/lib/locale/locale-archive,"}
62+ ${etcRule "localtime"}
63+ r ${pkgs.tzdata}/share/zoneinfo/**,
64+ r ${pkgs.stdenv.cc.libc}/share/i18n/**,
65+ '';
66+ "abstractions/bash" = ''
67+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/bash"
68+ # system-wide bash configuration
69+ ${etcRule "profile.dos"}
70+ ${etcRule "profile"}
71+ ${etcRule "profile.d"}
72+ ${etcRule {path="profile.d"; trail="/*";}}
73+ ${etcRule "bashrc"}
74+ ${etcRule "bash.bashrc"}
75+ ${etcRule "bash.bashrc.local"}
76+ ${etcRule "bash_completion"}
77+ ${etcRule "bash_completion.d"}
78+ ${etcRule {path="bash_completion.d"; trail="/*";}}
79+ # bash relies on system-wide readline configuration
80+ ${etcRule "inputrc"}
81+ # bash inspects filesystems at startup
82+ # and /etc/mtab is linked to /proc/mounts
83+ @{PROC}/mounts
84+85+ # run out of /etc/bash.bashrc
86+ ${etcRule "DIR_COLORS"}
87+ '';
88+ "abstractions/cups-client" = ''
89+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/cpus-client"
90+ ${etcRule "cups/cups-client.conf"}
91+ '';
92+ "abstractions/consoles" = ''
93+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/consoles"
94+ '';
95+ "abstractions/dbus-session-strict" = ''
96+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dbus-session-strict"
97+ ${etcRule "machine-id"}
98+ '';
99+ "abstractions/dconf" = ''
100+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dconf"
101+ ${etcRule {path="dconf"; trail="/**";}}
102+ '';
103+ "abstractions/dri-common" = ''
104+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dri-common"
105+ ${etcRule "drirc"}
106+ '';
107+ # The config.fonts.fontconfig NixOS module adds many files to /etc/fonts/
108+ # by symlinking them but without exporting them outside of its NixOS module,
109+ # those are therefore added there to this "abstractions/fonts".
110+ "abstractions/fonts" = ''
111+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/fonts"
112+ ${etcRule {path="fonts"; trail="/**";}}
113+ '';
114+ "abstractions/gnome" = ''
115+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/gnome"
116+ ${etcRule {path="gnome"; trail="/gtkrc*";}}
117+ ${etcRule {path="gtk"; trail="/*";}}
118+ ${etcRule {path="gtk-2.0"; trail="/*";}}
119+ ${etcRule {path="gtk-3.0"; trail="/*";}}
120+ ${etcRule "orbitrc"}
121+ include <abstractions/fonts>
122+ ${etcRule {path="pango"; trail="/*";}}
123+ ${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/";}}
124+ ${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/*";}}
125+ ${etcRule "papersize"}
126+ ${etcRule {path="cups"; trail="/lpoptions";}}
127+ ${etcRule {path="gnome"; trail="/defaults.list";}}
128+ ${etcRule {path="xdg"; trail="/{,*-}mimeapps.list";}}
129+ ${etcRule "xdg/mimeapps.list"}
130+ '';
131+ "abstractions/kde" = ''
132+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kde"
133+ ${etcRule {path="qt3"; trail="/kstylerc";}}
134+ ${etcRule {path="qt3"; trail="/qt_plugins_3.3rc";}}
135+ ${etcRule {path="qt3"; trail="/qtrc";}}
136+ ${etcRule "kderc"}
137+ ${etcRule {path="kde3"; trail="/*";}}
138+ ${etcRule "kde4rc"}
139+ ${etcRule {path="xdg"; trail="/kdeglobals";}}
140+ ${etcRule {path="xdg"; trail="/Trolltech.conf";}}
141+ '';
142+ "abstractions/kerberosclient" = ''
143+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kerberosclient"
144+ ${etcRule {path="krb5.keytab"; mode="rk";}}
145+ ${etcRule "krb5.conf"}
146+ ${etcRule "krb5.conf.d"}
147+ ${etcRule {path="krb5.conf.d"; trail="/*";}}
148+149+ # config files found via strings on libs
150+ ${etcRule "krb.conf"}
151+ ${etcRule "krb.realms"}
152+ ${etcRule "srvtab"}
153+ '';
154+ "abstractions/ldapclient" = ''
155+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ldapclient"
156+ ${etcRule "ldap.conf"}
157+ ${etcRule "ldap.secret"}
158+ ${etcRule {path="openldap"; trail="/*";}}
159+ ${etcRule {path="openldap"; trail="/cacerts/*";}}
160+ ${etcRule {path="sasl2"; trail="/*";}}
161+ '';
162+ "abstractions/likewise" = ''
163+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/likewise"
164+ '';
165+ "abstractions/mdns" = ''
166+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/mdns"
167+ ${etcRule "nss_mdns.conf"}
168+ '';
169+ "abstractions/nameservice" = ''
170+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nameservice"
171+172+ # Many programs wish to perform nameservice-like operations, such as
173+ # looking up users by name or id, groups by name or id, hosts by name
174+ # or IP, etc. These operations may be performed through files, dns,
175+ # NIS, NIS+, LDAP, hesiod, wins, etc. Allow them all here.
176+ ${etcRule "group"}
177+ ${etcRule "host.conf"}
178+ ${etcRule "hosts"}
179+ ${etcRule "nsswitch.conf"}
180+ ${etcRule "gai.conf"}
181+ ${etcRule "passwd"}
182+ ${etcRule "protocols"}
183+184+ # libtirpc (used for NIS/YP login) needs this
185+ ${etcRule "netconfig"}
186+187+ ${etcRule "resolv.conf"}
188+189+ ${etcRule {path="samba"; trail="/lmhosts";}}
190+ ${etcRule "services"}
191+192+ ${etcRule "default/nss"}
193+194+ # libnl-3-200 via libnss-gw-name
195+ ${etcRule {path="libnl"; trail="/classid";}}
196+ ${etcRule {path="libnl-3"; trail="/classid";}}
197+198+ mr ${getLib pkgs.nss}/lib/libnss_*.so*,
199+ mr ${getLib pkgs.nss}/lib64/libnss_*.so*,
200+ '';
201+ "abstractions/nis" = ''
202+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nis"
203+ '';
204+ "abstractions/nvidia" = ''
205+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nvidia"
206+ ${etcRule "vdpau_wrapper.cfg"}
207+ '';
208+ "abstractions/opencl-common" = ''
209+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-common"
210+ ${etcRule {path="OpenCL"; trail="/**";}}
211+ '';
212+ "abstractions/opencl-mesa" = ''
213+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-mesa"
214+ ${etcRule "default/drirc"}
215+ '';
216+ "abstractions/openssl" = ''
217+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/openssl"
218+ ${etcRule {path="ssl"; trail="/openssl.cnf";}}
219+ '';
220+ "abstractions/p11-kit" = ''
221+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/p11-kit"
222+ ${etcRule {path="pkcs11"; trail="/";}}
223+ ${etcRule {path="pkcs11"; trail="/pkcs11.conf";}}
224+ ${etcRule {path="pkcs11"; trail="/modules/";}}
225+ ${etcRule {path="pkcs11"; trail="/modules/*";}}
226+ '';
227+ "abstractions/perl" = ''
228+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/perl"
229+ ${etcRule {path="perl"; trail="/**";}}
230+ '';
231+ "abstractions/php" = ''
232+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/php"
233+ ${etcRule {path="php"; trail="/**/";}}
234+ ${etcRule {path="php5"; trail="/**/";}}
235+ ${etcRule {path="php7"; trail="/**/";}}
236+ ${etcRule {path="php"; trail="/**.ini";}}
237+ ${etcRule {path="php5"; trail="/**.ini";}}
238+ ${etcRule {path="php7"; trail="/**.ini";}}
239+ '';
240+ "abstractions/postfix-common" = ''
241+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/postfix-common"
242+ ${etcRule "mailname"}
243+ ${etcRule {path="postfix"; trail="/*.cf";}}
244+ ${etcRule "postfix/main.cf"}
245+ ${etcRule "postfix/master.cf"}
246+ '';
247+ "abstractions/python" = ''
248+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/python"
249+ '';
250+ "abstractions/qt5" = ''
251+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/qt5"
252+ ${etcRule {path="xdg"; trail="/QtProject/qtlogging.ini";}}
253+ ${etcRule {path="xdg/QtProject"; trail="/qtlogging.ini";}}
254+ ${etcRule "xdg/QtProject/qtlogging.ini"}
255+ '';
256+ "abstractions/samba" = ''
257+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/samba"
258+ ${etcRule {path="samba"; trail="/*";}}
259+ '';
260+ "abstractions/ssl_certs" = ''
261+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ssl_certs"
262+ ${etcRule "ssl/certs/ca-certificates.crt"}
263+ ${etcRule "ssl/certs/ca-bundle.crt"}
264+ ${etcRule "pki/tls/certs/ca-bundle.crt"}
265+266+ ${etcRule {path="ssl/trust"; trail="/";}}
267+ ${etcRule {path="ssl/trust"; trail="/*";}}
268+ ${etcRule {path="ssl/trust/anchors"; trail="/";}}
269+ ${etcRule {path="ssl/trust/anchors"; trail="/**";}}
270+ ${etcRule {path="pki/trust"; trail="/";}}
271+ ${etcRule {path="pki/trust"; trail="/*";}}
272+ ${etcRule {path="pki/trust/anchors"; trail="/";}}
273+ ${etcRule {path="pki/trust/anchors"; trail="/**";}}
274+275+ # security.acme NixOS module
276+ r /var/lib/acme/*/cert.pem,
277+ r /var/lib/acme/*/chain.pem,
278+ r /var/lib/acme/*/fullchain.pem,
279+ '';
280+ "abstractions/ssl_keys" = ''
281+ # security.acme NixOS module
282+ r /var/lib/acme/*/full.pem,
283+ r /var/lib/acme/*/key.pem,
284+ '';
285+ "abstractions/vulkan" = ''
286+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/vulkan"
287+ ${etcRule {path="vulkan/icd.d"; trail="/";}}
288+ ${etcRule {path="vulkan/icd.d"; trail="/*.json";}}
289+ '';
290+ "abstractions/winbind" = ''
291+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/winbind"
292+ ${etcRule {path="samba"; trail="/smb.conf";}}
293+ ${etcRule {path="samba"; trail="/dhcp.conf";}}
294+ '';
295+ "abstractions/X" = ''
296+ include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/X"
297+ ${etcRule {path="X11/cursors"; trail="/";}}
298+ ${etcRule {path="X11/cursors"; trail="/**";}}
299+ '';
300+};
301+}
+11
nixos/modules/security/apparmor/profiles.nix
···00000000000
···1+{ config, lib, pkgs, ... }:
2+let apparmor = config.security.apparmor; in
3+{
4+config.security.apparmor.packages = [ pkgs.apparmor-profiles ];
5+config.security.apparmor.policies."bin.ping".profile = lib.mkIf apparmor.policies."bin.ping".enable ''
6+ include "${pkgs.iputils.apparmor}/bin.ping"
7+ include "${pkgs.inetutils.apparmor}/bin.ping"
8+ # Note that including those two profiles in the same profile
9+ # would not work if the second one were to re-include <tunables/global>.
10+'';
11+}
···5let
6 cfg = config.services.transmission;
7 inherit (config.environment) etc;
8- apparmor = config.security.apparmor.enable;
9 rootDir = "/run/transmission";
10 homeDir = "/var/lib/transmission";
11 settingsDir = ".config/transmission-daemon";
···184185 systemd.services.transmission = {
186 description = "Transmission BitTorrent Service";
187- after = [ "network.target" ] ++ optional apparmor "apparmor.service";
188- requires = optional apparmor "apparmor.service";
189 wantedBy = [ "multi-user.target" ];
190 environment.CURL_CA_BUNDLE = etc."ssl/certs/ca-certificates.crt".source;
191···358 })
359 ];
360361- security.apparmor.profiles = mkIf apparmor [
362- (pkgs.writeText "apparmor-transmission-daemon" ''
363 include <tunables/global>
364-365 ${pkgs.transmission}/bin/transmission-daemon {
366 include <abstractions/base>
367 include <abstractions/nameservice>
368-369- # NOTE: https://github.com/NixOS/nixpkgs/pull/93457
370- # will remove the need for these by fixing <abstractions/base>
371- r ${etc."hosts".source},
372- r /etc/ld-nix.so.preload,
373- ${lib.optionalString (builtins.hasAttr "ld-nix.so.preload" etc) ''
374- r ${etc."ld-nix.so.preload".source},
375- ${concatMapStrings (p: optionalString (p != "") ("mr ${p},\n"))
376- (splitString "\n" config.environment.etc."ld-nix.so.preload".text)}
377- ''}
378- r ${etc."ssl/certs/ca-certificates.crt".source},
379- r ${pkgs.tzdata}/share/zoneinfo/**,
380- r ${pkgs.stdenv.cc.libc}/share/i18n/**,
381- r ${pkgs.stdenv.cc.libc}/share/locale/**,
382-383- mr ${getLib pkgs.stdenv.cc.cc}/lib/*.so*,
384- mr ${getLib pkgs.stdenv.cc.libc}/lib/*.so*,
385- mr ${getLib pkgs.attr}/lib/libattr*.so*,
386- mr ${getLib pkgs.c-ares}/lib/libcares*.so*,
387- mr ${getLib pkgs.curl}/lib/libcurl*.so*,
388- mr ${getLib pkgs.keyutils}/lib/libkeyutils*.so*,
389- mr ${getLib pkgs.libcap}/lib/libcap*.so*,
390- mr ${getLib pkgs.libevent}/lib/libevent*.so*,
391- mr ${getLib pkgs.libgcrypt}/lib/libgcrypt*.so*,
392- mr ${getLib pkgs.libgpgerror}/lib/libgpg-error*.so*,
393- mr ${getLib pkgs.libkrb5}/lib/lib*.so*,
394- mr ${getLib pkgs.libssh2}/lib/libssh2*.so*,
395- mr ${getLib pkgs.lz4}/lib/liblz4*.so*,
396- mr ${getLib pkgs.nghttp2}/lib/libnghttp2*.so*,
397- mr ${getLib pkgs.openssl}/lib/libcrypto*.so*,
398- mr ${getLib pkgs.openssl}/lib/libssl*.so*,
399- mr ${getLib pkgs.systemd}/lib/libsystemd*.so*,
400- mr ${getLib pkgs.util-linuxMinimal.out}/lib/libblkid.so*,
401- mr ${getLib pkgs.util-linuxMinimal.out}/lib/libmount.so*,
402- mr ${getLib pkgs.util-linuxMinimal.out}/lib/libuuid.so*,
403- mr ${getLib pkgs.xz}/lib/liblzma*.so*,
404- mr ${getLib pkgs.zlib}/lib/libz*.so*,
405406 r @{PROC}/sys/kernel/random/uuid,
407 r @{PROC}/sys/vm/overcommit_memory,
408- # @{pid} is not a kernel variable yet but a regexp
409- #r @{PROC}/@{pid}/environ,
410 r @{PROC}/@{pid}/mounts,
411 rwk /tmp/tr_session_id_*,
412 r /run/systemd/resolve/stub-resolv.conf,
413414 r ${pkgs.openssl.out}/etc/**,
415 r ${config.systemd.services.transmission.environment.CURL_CA_BUNDLE},
416- r ${pkgs.transmission}/share/transmission/**,
417418 owner rw ${cfg.home}/${settingsDir}/**,
419 rw ${cfg.settings.download-dir}/**,
···441 # https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking#seccomp-and-no_new_privs
442 px ${cfg.settings.script-torrent-done-filename} -> &@{dirs},
443 ''}
444-445- # FIXME: enable customizing using https://github.com/NixOS/nixpkgs/pull/93457
446- # include <local/transmission-daemon>
447 }
448- '')
449- ];
450 };
451452 meta.maintainers = with lib.maintainers; [ julm ];
···5let
6 cfg = config.services.transmission;
7 inherit (config.environment) etc;
8+ apparmor = config.security.apparmor;
9 rootDir = "/run/transmission";
10 homeDir = "/var/lib/transmission";
11 settingsDir = ".config/transmission-daemon";
···184185 systemd.services.transmission = {
186 description = "Transmission BitTorrent Service";
187+ after = [ "network.target" ] ++ optional apparmor.enable "apparmor.service";
188+ requires = optional apparmor.enable "apparmor.service";
189 wantedBy = [ "multi-user.target" ];
190 environment.CURL_CA_BUNDLE = etc."ssl/certs/ca-certificates.crt".source;
191···358 })
359 ];
360361+ security.apparmor.policies."bin.transmission-daemon".profile = ''
0362 include <tunables/global>
0363 ${pkgs.transmission}/bin/transmission-daemon {
364 include <abstractions/base>
365 include <abstractions/nameservice>
366+ include <abstractions/ssl_certs>
367+ include "${pkgs.apparmorRulesFromClosure
368+ { name = "transmission-daemon"; }
369+ [ pkgs.transmission ]}"
370+ include <local/bin.transmission-daemon>
00000000000000000000000000000000371372 r @{PROC}/sys/kernel/random/uuid,
373 r @{PROC}/sys/vm/overcommit_memory,
374+ r @{PROC}/@{pid}/environ,
0375 r @{PROC}/@{pid}/mounts,
376 rwk /tmp/tr_session_id_*,
377 r /run/systemd/resolve/stub-resolv.conf,
378379 r ${pkgs.openssl.out}/etc/**,
380 r ${config.systemd.services.transmission.environment.CURL_CA_BUNDLE},
0381382 owner rw ${cfg.home}/${settingsDir}/**,
383 rw ${cfg.settings.download-dir}/**,
···405 # https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorStacking#seccomp-and-no_new_privs
406 px ${cfg.settings.script-torrent-done-filename} -> &@{dirs},
407 ''}
000408 }
409+ '';
410+ security.apparmor.includes."local/bin.transmission-daemon" = "";
411 };
412413 meta.maintainers = with lib.maintainers; [ julm ];
+15
nixos/modules/tasks/network-interfaces.nix
···1111 } else {
1112 ping.source = "${pkgs.iputils.out}/bin/ping";
1113 };
00000000000000011141115 # Set the host and domain names in the activation script. Don't
1116 # clear it if it's not configured in the NixOS configuration,
···1111 } else {
1112 ping.source = "${pkgs.iputils.out}/bin/ping";
1113 };
1114+ security.apparmor.policies."bin.ping".profile = lib.mkIf config.security.apparmor.policies."bin.ping".enable (lib.mkAfter ''
1115+ /run/wrappers/bin/ping {
1116+ include <abstractions/base>
1117+ include <nixos/security.wrappers>
1118+ rpx /run/wrappers/wrappers.*/ping,
1119+ }
1120+ /run/wrappers/wrappers.*/ping {
1121+ include <abstractions/base>
1122+ include <nixos/security.wrappers>
1123+ r /run/wrappers/wrappers.*/ping.real,
1124+ mrpx ${config.security.wrappers.ping.source},
1125+ capability net_raw,
1126+ capability setpcap,
1127+ }
1128+ '');
11291130 # Set the host and domain names in the activation script. Don't
1131 # clear it if it's not configured in the NixOS configuration,