nixos/apparmor: improve code readability

This commit is contained in:
Julien Moutinho 2021-02-27 21:26:47 +01:00
parent b280e64078
commit 45e5d726b2
5 changed files with 276 additions and 232 deletions

View file

@ -1,29 +1,31 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib;
let let
inherit (builtins) attrNames head map match readFile; inherit (builtins) attrNames head map match readFile;
inherit (lib) types; inherit (lib) types;
inherit (config.environment) etc; inherit (config.environment) etc;
cfg = config.security.apparmor; cfg = config.security.apparmor;
mkDisableOption = name: lib.mkEnableOption name // { mkDisableOption = name: mkEnableOption name // {
default = true; default = true;
example = false; example = false;
}; };
enabledPolicies = lib.filterAttrs (n: p: p.enable) cfg.policies; enabledPolicies = filterAttrs (n: p: p.enable) cfg.policies;
in in
{ {
imports = [ imports = [
(lib.mkRenamedOptionModule [ "security" "virtualization" "flushL1DataCache" ] [ "security" "virtualisation" "flushL1DataCache" ]) (mkRemovedOptionModule [ "security" "apparmor" "confineSUIDApplications" ] "Please use the new options: `security.apparmor.policies.<policy>.enable'.")
(lib.mkRemovedOptionModule [ "security" "apparmor" "confineSUIDApplications" ] "Please use the new options: `security.apparmor.policies.<policy>.enable'.") (mkRemovedOptionModule [ "security" "apparmor" "profiles" ] "Please use the new option: `security.apparmor.policies'.")
(lib.mkRemovedOptionModule [ "security" "apparmor" "profiles" ] "Please use the new option: `security.apparmor.policies'.")
apparmor/includes.nix apparmor/includes.nix
apparmor/profiles.nix apparmor/profiles.nix
]; ];
options = { options = {
security.apparmor = { security.apparmor = {
enable = lib.mkEnableOption ''the AppArmor Mandatory Access Control system. enable = mkEnableOption ''
the AppArmor Mandatory Access Control system.
If you're enabling this module on a running system, If you're enabling this module on a running system,
note that a reboot will be required to activate AppArmor in the kernel. note that a reboot will be required to activate AppArmor in the kernel.
@ -38,7 +40,7 @@ in
but leaves already running processes unconfined. but leaves already running processes unconfined.
Set <link linkend="opt-security.apparmor.killUnconfinedConfinables">killUnconfinedConfinables</link> Set <link linkend="opt-security.apparmor.killUnconfinedConfinables">killUnconfinedConfinables</link>
to <literal>false</literal> if you prefer to leave those processes running''; to <literal>false</literal> if you prefer to leave those processes running'';
policies = lib.mkOption { policies = mkOption {
description = '' description = ''
AppArmor policies. AppArmor policies.
''; '';
@ -46,7 +48,7 @@ in
options = { options = {
enable = mkDisableOption "loading of the profile into the kernel"; enable = mkDisableOption "loading of the profile into the kernel";
enforce = mkDisableOption "enforcing of the policy or only complain in the logs"; enforce = mkDisableOption "enforcing of the policy or only complain in the logs";
profile = lib.mkOption { profile = mkOption {
description = "The policy of the profile."; description = "The policy of the profile.";
type = types.lines; type = types.lines;
apply = pkgs.writeText name; apply = pkgs.writeText name;
@ -55,28 +57,29 @@ in
})); }));
default = {}; default = {};
}; };
includes = lib.mkOption { includes = mkOption {
type = types.attrsOf types.lines; type = types.attrsOf types.lines;
default = {}; default = {};
description = '' description = ''
List of paths to be added to AppArmor's searched paths List of paths to be added to AppArmor's searched paths
when resolving <literal>include</literal> directives. when resolving <literal>include</literal> directives.
''; '';
apply = lib.mapAttrs pkgs.writeText; apply = mapAttrs pkgs.writeText;
}; };
packages = lib.mkOption { packages = mkOption {
type = types.listOf types.package; type = types.listOf types.package;
default = []; default = [];
description = "List of packages to be added to AppArmor's include path"; description = "List of packages to be added to AppArmor's include path";
}; };
enableCache = lib.mkEnableOption ''caching of AppArmor policies enableCache = mkEnableOption ''
caching of AppArmor policies
in <literal>/var/cache/apparmor/</literal>. in <literal>/var/cache/apparmor/</literal>.
Beware that AppArmor policies almost always contain Nix store paths, Beware that AppArmor policies almost always contain Nix store paths,
and thus produce at each change of these paths and thus produce at each change of these paths
a new cached version accumulating in the cache''; a new cached version accumulating in the cache'';
killUnconfinedConfinables = mkDisableOption ''killing of processes killUnconfinedConfinables = mkDisableOption ''
which have an AppArmor profile enabled killing of processes which have an AppArmor profile enabled
(in <link linkend="opt-security.apparmor.policies">policies</link>) (in <link linkend="opt-security.apparmor.policies">policies</link>)
but are not confined (because AppArmor can only confine new processes). but are not confined (because AppArmor can only confine new processes).
Beware that due to a current limitation of AppArmor, Beware that due to a current limitation of AppArmor,
@ -84,7 +87,7 @@ in
}; };
}; };
config = lib.mkIf cfg.enable { config = mkIf cfg.enable {
assertions = map (policy: assertions = map (policy:
{ assertion = match ".*/.*" policy == null; { assertion = match ".*/.*" policy == null;
message = "`security.apparmor.policies.\"${policy}\"' must not contain a slash."; message = "`security.apparmor.policies.\"${policy}\"' must not contain a slash.";
@ -100,15 +103,15 @@ in
environment.etc."apparmor.d".source = pkgs.linkFarm "apparmor.d" ( environment.etc."apparmor.d".source = pkgs.linkFarm "apparmor.d" (
# It's important to put only enabledPolicies here and not all cfg.policies # It's important to put only enabledPolicies here and not all cfg.policies
# because aa-remove-unknown reads profiles from all /etc/apparmor.d/* # because aa-remove-unknown reads profiles from all /etc/apparmor.d/*
lib.mapAttrsToList (name: p: {inherit name; path=p.profile;}) enabledPolicies ++ mapAttrsToList (name: p: { inherit name; path = p.profile; }) enabledPolicies ++
lib.mapAttrsToList (name: path: {inherit name path;}) cfg.includes mapAttrsToList (name: path: { inherit name path; }) cfg.includes
); );
environment.etc."apparmor/parser.conf".text = '' environment.etc."apparmor/parser.conf".text = ''
${if cfg.enableCache then "write-cache" else "skip-cache"} ${if cfg.enableCache then "write-cache" else "skip-cache"}
cache-loc /var/cache/apparmor cache-loc /var/cache/apparmor
Include /etc/apparmor.d Include /etc/apparmor.d
'' + '' +
lib.concatMapStrings (p: "Include ${p}/etc/apparmor.d\n") cfg.packages; concatMapStrings (p: "Include ${p}/etc/apparmor.d\n") cfg.packages;
# For aa-logprof # For aa-logprof
environment.etc."apparmor/apparmor.conf".text = '' environment.etc."apparmor/apparmor.conf".text = ''
''; '';
@ -134,12 +137,13 @@ in
# 3 - force all perms on the rule to be user # 3 - force all perms on the rule to be user
default_owner_prompt = 1 default_owner_prompt = 1
custom_includes = /etc/apparmor.d ${lib.concatMapStringsSep " " (p: "${p}/etc/apparmor.d") cfg.packages} custom_includes = /etc/apparmor.d ${concatMapStringsSep " " (p: "${p}/etc/apparmor.d") cfg.packages}
[qualifiers] [qualifiers]
${pkgs.runtimeShell} = icnu ${pkgs.runtimeShell} = icnu
${pkgs.bashInteractive}/bin/sh = icnu ${pkgs.bashInteractive}/bin/sh = icnu
${pkgs.bashInteractive}/bin/bash = icnu ${pkgs.bashInteractive}/bin/bash = icnu
${config.users.defaultUserShell} = icnu
''; '';
footer = "${pkgs.apparmor-utils}/etc/apparmor/logprof.conf"; footer = "${pkgs.apparmor-utils}/etc/apparmor/logprof.conf";
passAsFile = [ "header" ]; passAsFile = [ "header" ];
@ -177,17 +181,17 @@ in
xargs --verbose --no-run-if-empty --delimiter='\n' \ xargs --verbose --no-run-if-empty --delimiter='\n' \
kill kill
''; '';
commonOpts = p: "--verbose --show-cache ${lib.optionalString (!p.enforce) "--complain "}${p.profile}"; commonOpts = p: "--verbose --show-cache ${optionalString (!p.enforce) "--complain "}${p.profile}";
in { in {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = "yes"; RemainAfterExit = "yes";
ExecStartPre = "${pkgs.apparmor-utils}/bin/aa-teardown"; ExecStartPre = "${pkgs.apparmor-utils}/bin/aa-teardown";
ExecStart = lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts p}") enabledPolicies; ExecStart = mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts p}") enabledPolicies;
ExecStartPost = lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables; ExecStartPost = optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
ExecReload = ExecReload =
# Add or replace into the kernel profiles in enabledPolicies # Add or replace into the kernel profiles in enabledPolicies
# (because AppArmor can do that without stopping the processes already confined). # (because AppArmor can do that without stopping the processes already confined).
lib.mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts p}") enabledPolicies ++ mapAttrsToList (n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts p}") enabledPolicies ++
# Remove from the kernel any profile whose name is not # Remove from the kernel any profile whose name is not
# one of the names within the content of the profiles in enabledPolicies # one of the names within the content of the profiles in enabledPolicies
# (indirectly read from /etc/apparmor.d/*, without recursing into sub-directory). # (indirectly read from /etc/apparmor.d/*, without recursing into sub-directory).
@ -195,7 +199,7 @@ in
[ "${pkgs.apparmor-utils}/bin/aa-remove-unknown" ] ++ [ "${pkgs.apparmor-utils}/bin/aa-remove-unknown" ] ++
# Optionaly kill the processes which are unconfined but now have a profile loaded # Optionaly kill the processes which are unconfined but now have a profile loaded
# (because AppArmor can only start to confine new processes). # (because AppArmor can only start to confine new processes).
lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables; optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
ExecStop = "${pkgs.apparmor-utils}/bin/aa-teardown"; ExecStop = "${pkgs.apparmor-utils}/bin/aa-teardown";
CacheDirectory = [ "apparmor" "apparmor/logprof" ]; CacheDirectory = [ "apparmor" "apparmor/logprof" ];
CacheDirectoryMode = "0700"; CacheDirectoryMode = "0700";
@ -203,5 +207,5 @@ in
}; };
}; };
meta.maintainers = with lib.maintainers; [ julm ]; meta.maintainers = with maintainers; [ julm ];
} }

View file

@ -3,13 +3,15 @@ let
inherit (builtins) attrNames hasAttr isAttrs; inherit (builtins) attrNames hasAttr isAttrs;
inherit (lib) getLib; inherit (lib) getLib;
inherit (config.environment) etc; inherit (config.environment) etc;
# Utility to generate an AppArmor rule
# only when the given path exists in config.environment.etc
etcRule = arg: etcRule = arg:
let go = {path ? null, mode ? "r", trail ? ""}: let go = { path ? null, mode ? "r", trail ? "" }:
lib.optionalString (hasAttr path etc) lib.optionalString (hasAttr path etc)
"${mode} ${config.environment.etc.${path}.source}${trail},"; "${mode} ${config.environment.etc.${path}.source}${trail},";
in if isAttrs arg in if isAttrs arg
then go arg then go arg
else go {path=arg;}; else go { path = arg; };
in in
{ {
# FIXME: most of the etcRule calls below have been # FIXME: most of the etcRule calls below have been
@ -29,76 +31,80 @@ config.security.apparmor.includes = {
''; '';
"abstractions/audio" = '' "abstractions/audio" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/audio" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/audio"
${etcRule "asound.conf"} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule "esound/esd.conf"} "asound.conf"
${etcRule "libao.conf"} "esound/esd.conf"
${etcRule {path="pulse"; trail="/";}} "libao.conf"
${etcRule {path="pulse"; trail="/**";}} { path = "pulse"; trail = "/"; }
${etcRule {path="sound"; trail="/";}} { path = "pulse"; trail = "/**"; }
${etcRule {path="sound"; trail="/**";}} { path = "sound"; trail = "/"; }
${etcRule {path="alsa/conf.d"; trail="/";}} { path = "sound"; trail = "/**"; }
${etcRule {path="alsa/conf.d"; trail="/*";}} { path = "alsa/conf.d"; trail = "/"; }
${etcRule "openal/alsoft.conf"} { path = "alsa/conf.d"; trail = "/*"; }
${etcRule "wildmidi/wildmidi.conf"} "openal/alsoft.conf"
''; "wildmidi/wildmidi.conf"
];
"abstractions/authentication" = '' "abstractions/authentication" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/authentication" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/authentication"
# Defined in security.pam # Defined in security.pam
include <abstractions/pam> include <abstractions/pam>
${etcRule "nologin"} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule "securetty"} "nologin"
${etcRule {path="security"; trail="/*";}} "securetty"
${etcRule "shadow"} { path = "security"; trail = "/*"; }
${etcRule "gshadow"} "shadow"
${etcRule "pwdb.conf"} "gshadow"
${etcRule "default/passwd"} "pwdb.conf"
${etcRule "login.defs"} "default/passwd"
''; "login.defs"
];
"abstractions/base" = '' "abstractions/base" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/base" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/base"
r ${pkgs.stdenv.cc.libc}/share/locale/**, r ${pkgs.stdenv.cc.libc}/share/locale/**,
r ${pkgs.stdenv.cc.libc}/share/locale.alias, r ${pkgs.stdenv.cc.libc}/share/locale.alias,
${lib.optionalString (pkgs.glibcLocales != null) "r ${pkgs.glibcLocales}/lib/locale/locale-archive,"} ${lib.optionalString (pkgs.glibcLocales != null) "r ${pkgs.glibcLocales}/lib/locale/locale-archive,"}
${etcRule "localtime"} ${etcRule "localtime"}
r ${pkgs.tzdata}/share/zoneinfo/**, r ${pkgs.tzdata}/share/zoneinfo/**,
r ${pkgs.stdenv.cc.libc}/share/i18n/**, r ${pkgs.stdenv.cc.libc}/share/i18n/**,
''; '';
"abstractions/bash" = '' "abstractions/bash" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/bash" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/bash"
# system-wide bash configuration
${etcRule "profile.dos"}
${etcRule "profile"}
${etcRule "profile.d"}
${etcRule {path="profile.d"; trail="/*";}}
${etcRule "bashrc"}
${etcRule "bash.bashrc"}
${etcRule "bash.bashrc.local"}
${etcRule "bash_completion"}
${etcRule "bash_completion.d"}
${etcRule {path="bash_completion.d"; trail="/*";}}
# bash relies on system-wide readline configuration
${etcRule "inputrc"}
# bash inspects filesystems at startup # bash inspects filesystems at startup
# and /etc/mtab is linked to /proc/mounts # and /etc/mtab is linked to /proc/mounts
@{PROC}/mounts @{PROC}/mounts
# run out of /etc/bash.bashrc # system-wide bash configuration
${etcRule "DIR_COLORS"} '' + lib.concatMapStringsSep "\n" etcRule [
"profile.dos"
"profile"
"profile.d"
{ path = "profile.d"; trail = "/*"; }
"bashrc"
"bash.bashrc"
"bash.bashrc.local"
"bash_completion"
"bash_completion.d"
{ path = "bash_completion.d"; trail = "/*"; }
# bash relies on system-wide readline configuration
"inputrc"
# run out of /etc/bash.bashrc
"DIR_COLORS"
];
"abstractions/consoles" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/consoles"
''; '';
"abstractions/cups-client" = '' "abstractions/cups-client" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/cpus-client" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/cpus-client"
${etcRule "cups/cups-client.conf"} ${etcRule "cups/cups-client.conf"}
''; '';
"abstractions/consoles" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/consoles"
'';
"abstractions/dbus-session-strict" = '' "abstractions/dbus-session-strict" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dbus-session-strict" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dbus-session-strict"
${etcRule "machine-id"} ${etcRule "machine-id"}
''; '';
"abstractions/dconf" = '' "abstractions/dconf" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dconf" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dconf"
${etcRule {path="dconf"; trail="/**";}} ${etcRule { path = "dconf"; trail = "/**"; }}
''; '';
"abstractions/dri-common" = '' "abstractions/dri-common" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dri-common" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dri-common"
@ -109,62 +115,66 @@ config.security.apparmor.includes = {
# those are therefore added there to this "abstractions/fonts". # those are therefore added there to this "abstractions/fonts".
"abstractions/fonts" = '' "abstractions/fonts" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/fonts" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/fonts"
${etcRule {path="fonts"; trail="/**";}} ${etcRule { path = "fonts"; trail = "/**"; }}
''; '';
"abstractions/gnome" = '' "abstractions/gnome" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/gnome" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/gnome"
${etcRule {path="gnome"; trail="/gtkrc*";}}
${etcRule {path="gtk"; trail="/*";}}
${etcRule {path="gtk-2.0"; trail="/*";}}
${etcRule {path="gtk-3.0"; trail="/*";}}
${etcRule "orbitrc"}
include <abstractions/fonts> include <abstractions/fonts>
${etcRule {path="pango"; trail="/*";}} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/";}} { path = "gnome"; trail = "/gtkrc*"; }
${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/*";}} { path = "gtk"; trail = "/*"; }
${etcRule "papersize"} { path = "gtk-2.0"; trail = "/*"; }
${etcRule {path="cups"; trail="/lpoptions";}} { path = "gtk-3.0"; trail = "/*"; }
${etcRule {path="gnome"; trail="/defaults.list";}} "orbitrc"
${etcRule {path="xdg"; trail="/{,*-}mimeapps.list";}} { path = "pango"; trail = "/*"; }
${etcRule "xdg/mimeapps.list"} { path = "/etc/gnome-vfs-2.0"; trail = "/modules/"; }
''; { path = "/etc/gnome-vfs-2.0"; trail = "/modules/*"; }
"papersize"
{ path = "cups"; trail = "/lpoptions"; }
{ path = "gnome"; trail = "/defaults.list"; }
{ path = "xdg"; trail = "/{,*-}mimeapps.list"; }
"xdg/mimeapps.list"
];
"abstractions/kde" = '' "abstractions/kde" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kde" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kde"
${etcRule {path="qt3"; trail="/kstylerc";}} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule {path="qt3"; trail="/qt_plugins_3.3rc";}} { path = "qt3"; trail = "/kstylerc"; }
${etcRule {path="qt3"; trail="/qtrc";}} { path = "qt3"; trail = "/qt_plugins_3.3rc"; }
${etcRule "kderc"} { path = "qt3"; trail = "/qtrc"; }
${etcRule {path="kde3"; trail="/*";}} "kderc"
${etcRule "kde4rc"} { path = "kde3"; trail = "/*"; }
${etcRule {path="xdg"; trail="/kdeglobals";}} "kde4rc"
${etcRule {path="xdg"; trail="/Trolltech.conf";}} { path = "xdg"; trail = "/kdeglobals"; }
''; { path = "xdg"; trail = "/Trolltech.conf"; }
];
"abstractions/kerberosclient" = '' "abstractions/kerberosclient" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kerberosclient" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kerberosclient"
${etcRule {path="krb5.keytab"; mode="rk";}} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule "krb5.conf"} { path = "krb5.keytab"; mode="rk"; }
${etcRule "krb5.conf.d"} "krb5.conf"
${etcRule {path="krb5.conf.d"; trail="/*";}} "krb5.conf.d"
{ path = "krb5.conf.d"; trail = "/*"; }
# config files found via strings on libs # config files found via strings on libs
${etcRule "krb.conf"} "krb.conf"
${etcRule "krb.realms"} "krb.realms"
${etcRule "srvtab"} "srvtab"
''; ];
"abstractions/ldapclient" = '' "abstractions/ldapclient" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ldapclient" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ldapclient"
${etcRule "ldap.conf"} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule "ldap.secret"} "ldap.conf"
${etcRule {path="openldap"; trail="/*";}} "ldap.secret"
${etcRule {path="openldap"; trail="/cacerts/*";}} { path = "openldap"; trail = "/*"; }
${etcRule {path="sasl2"; trail="/*";}} { path = "openldap"; trail = "/cacerts/*"; }
''; { path = "sasl2"; trail = "/*"; }
];
"abstractions/likewise" = '' "abstractions/likewise" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/likewise" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/likewise"
''; '';
"abstractions/mdns" = '' "abstractions/mdns" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/mdns" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/mdns"
${etcRule "nss_mdns.conf"} ${etcRule "nss_mdns.conf"}
''; '';
"abstractions/nameservice" = '' "abstractions/nameservice" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nameservice" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nameservice"
@ -173,31 +183,31 @@ config.security.apparmor.includes = {
# looking up users by name or id, groups by name or id, hosts by name # looking up users by name or id, groups by name or id, hosts by name
# or IP, etc. These operations may be performed through files, dns, # or IP, etc. These operations may be performed through files, dns,
# NIS, NIS+, LDAP, hesiod, wins, etc. Allow them all here. # NIS, NIS+, LDAP, hesiod, wins, etc. Allow them all here.
${etcRule "group"}
${etcRule "host.conf"}
${etcRule "hosts"}
${etcRule "nsswitch.conf"}
${etcRule "gai.conf"}
${etcRule "passwd"}
${etcRule "protocols"}
# libtirpc (used for NIS/YP login) needs this
${etcRule "netconfig"}
${etcRule "resolv.conf"}
${etcRule {path="samba"; trail="/lmhosts";}}
${etcRule "services"}
${etcRule "default/nss"}
# libnl-3-200 via libnss-gw-name
${etcRule {path="libnl"; trail="/classid";}}
${etcRule {path="libnl-3"; trail="/classid";}}
mr ${getLib pkgs.nss}/lib/libnss_*.so*, mr ${getLib pkgs.nss}/lib/libnss_*.so*,
mr ${getLib pkgs.nss}/lib64/libnss_*.so*, mr ${getLib pkgs.nss}/lib64/libnss_*.so*,
''; '' + lib.concatMapStringsSep "\n" etcRule [
"group"
"host.conf"
"hosts"
"nsswitch.conf"
"gai.conf"
"passwd"
"protocols"
# libtirpc (used for NIS/YP login) needs this
"netconfig"
"resolv.conf"
{ path = "samba"; trail = "/lmhosts"; }
"services"
"default/nss"
# libnl-3-200 via libnss-gw-name
{ path = "libnl"; trail = "/classid"; }
{ path = "libnl-3"; trail = "/classid"; }
];
"abstractions/nis" = '' "abstractions/nis" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nis" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nis"
''; '';
@ -207,7 +217,7 @@ config.security.apparmor.includes = {
''; '';
"abstractions/opencl-common" = '' "abstractions/opencl-common" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-common" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-common"
${etcRule {path="OpenCL"; trail="/**";}} ${etcRule { path = "OpenCL"; trail = "/**"; }}
''; '';
"abstractions/opencl-mesa" = '' "abstractions/opencl-mesa" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-mesa" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-mesa"
@ -215,68 +225,74 @@ config.security.apparmor.includes = {
''; '';
"abstractions/openssl" = '' "abstractions/openssl" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/openssl" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/openssl"
${etcRule {path="ssl"; trail="/openssl.cnf";}} ${etcRule { path = "ssl"; trail = "/openssl.cnf"; }}
''; '';
"abstractions/p11-kit" = '' "abstractions/p11-kit" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/p11-kit" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/p11-kit"
${etcRule {path="pkcs11"; trail="/";}} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule {path="pkcs11"; trail="/pkcs11.conf";}} { path = "pkcs11"; trail = "/"; }
${etcRule {path="pkcs11"; trail="/modules/";}} { path = "pkcs11"; trail = "/pkcs11.conf"; }
${etcRule {path="pkcs11"; trail="/modules/*";}} { path = "pkcs11"; trail = "/modules/"; }
''; { path = "pkcs11"; trail = "/modules/*"; }
];
"abstractions/perl" = '' "abstractions/perl" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/perl" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/perl"
${etcRule {path="perl"; trail="/**";}} ${etcRule { path = "perl"; trail = "/**"; }}
''; '';
"abstractions/php" = '' "abstractions/php" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/php" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/php"
${etcRule {path="php"; trail="/**/";}} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule {path="php5"; trail="/**/";}} { path = "php"; trail = "/**/"; }
${etcRule {path="php7"; trail="/**/";}} { path = "php5"; trail = "/**/"; }
${etcRule {path="php"; trail="/**.ini";}} { path = "php7"; trail = "/**/"; }
${etcRule {path="php5"; trail="/**.ini";}} { path = "php"; trail = "/**.ini"; }
${etcRule {path="php7"; trail="/**.ini";}} { path = "php5"; trail = "/**.ini"; }
''; { path = "php7"; trail = "/**.ini"; }
];
"abstractions/postfix-common" = '' "abstractions/postfix-common" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/postfix-common" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/postfix-common"
${etcRule "mailname"} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule {path="postfix"; trail="/*.cf";}} "mailname"
${etcRule "postfix/main.cf"} { path = "postfix"; trail = "/*.cf"; }
${etcRule "postfix/master.cf"} "postfix/main.cf"
''; "postfix/master.cf"
];
"abstractions/python" = '' "abstractions/python" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/python" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/python"
''; '';
"abstractions/qt5" = '' "abstractions/qt5" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/qt5" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/qt5"
${etcRule {path="xdg"; trail="/QtProject/qtlogging.ini";}} '' + lib.concatMapStringsSep "\n" etcRule [
${etcRule {path="xdg/QtProject"; trail="/qtlogging.ini";}} { path = "xdg"; trail = "/QtProject/qtlogging.ini"; }
${etcRule "xdg/QtProject/qtlogging.ini"} { path = "xdg/QtProject"; trail = "/qtlogging.ini"; }
''; "xdg/QtProject/qtlogging.ini"
];
"abstractions/samba" = '' "abstractions/samba" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/samba" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/samba"
${etcRule {path="samba"; trail="/*";}} ${etcRule { path = "samba"; trail = "/*"; }}
''; '';
"abstractions/ssl_certs" = '' "abstractions/ssl_certs" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ssl_certs" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ssl_certs"
${etcRule "ssl/certs/ca-certificates.crt"}
${etcRule "ssl/certs/ca-bundle.crt"}
${etcRule "pki/tls/certs/ca-bundle.crt"}
${etcRule {path="ssl/trust"; trail="/";}} # For the NixOS module: security.acme
${etcRule {path="ssl/trust"; trail="/*";}}
${etcRule {path="ssl/trust/anchors"; trail="/";}}
${etcRule {path="ssl/trust/anchors"; trail="/**";}}
${etcRule {path="pki/trust"; trail="/";}}
${etcRule {path="pki/trust"; trail="/*";}}
${etcRule {path="pki/trust/anchors"; trail="/";}}
${etcRule {path="pki/trust/anchors"; trail="/**";}}
# security.acme NixOS module
r /var/lib/acme/*/cert.pem, r /var/lib/acme/*/cert.pem,
r /var/lib/acme/*/chain.pem, r /var/lib/acme/*/chain.pem,
r /var/lib/acme/*/fullchain.pem, r /var/lib/acme/*/fullchain.pem,
'';
'' + lib.concatMapStringsSep "\n" etcRule [
"ssl/certs/ca-certificates.crt"
"ssl/certs/ca-bundle.crt"
"pki/tls/certs/ca-bundle.crt"
{ path = "ssl/trust"; trail = "/"; }
{ path = "ssl/trust"; trail = "/*"; }
{ path = "ssl/trust/anchors"; trail = "/"; }
{ path = "ssl/trust/anchors"; trail = "/**"; }
{ path = "pki/trust"; trail = "/"; }
{ path = "pki/trust"; trail = "/*"; }
{ path = "pki/trust/anchors"; trail = "/"; }
{ path = "pki/trust/anchors"; trail = "/**"; }
];
"abstractions/ssl_keys" = '' "abstractions/ssl_keys" = ''
# security.acme NixOS module # security.acme NixOS module
r /var/lib/acme/*/full.pem, r /var/lib/acme/*/full.pem,
@ -284,18 +300,18 @@ config.security.apparmor.includes = {
''; '';
"abstractions/vulkan" = '' "abstractions/vulkan" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/vulkan" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/vulkan"
${etcRule {path="vulkan/icd.d"; trail="/";}} ${etcRule { path = "vulkan/icd.d"; trail = "/"; }}
${etcRule {path="vulkan/icd.d"; trail="/*.json";}} ${etcRule { path = "vulkan/icd.d"; trail = "/*.json"; }}
''; '';
"abstractions/winbind" = '' "abstractions/winbind" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/winbind" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/winbind"
${etcRule {path="samba"; trail="/smb.conf";}} ${etcRule { path = "samba"; trail = "/smb.conf"; }}
${etcRule {path="samba"; trail="/dhcp.conf";}} ${etcRule { path = "samba"; trail = "/dhcp.conf"; }}
''; '';
"abstractions/X" = '' "abstractions/X" = ''
include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/X" include "${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/X"
${etcRule {path="X11/cursors"; trail="/";}} ${etcRule { path = "X11/cursors"; trail = "/"; }}
${etcRule {path="X11/cursors"; trail="/**";}} ${etcRule { path = "X11/cursors"; trail = "/**"; }}
''; '';
}; };
} }

View file

@ -7,6 +7,10 @@ with lib;
maintainers = [ maintainers.joachifm ]; maintainers = [ maintainers.joachifm ];
}; };
imports = [
(lib.mkRenamedOptionModule [ "security" "virtualization" "flushL1DataCache" ] [ "security" "virtualisation" "flushL1DataCache" ])
];
options = { options = {
security.allowUserNamespaces = mkOption { security.allowUserNamespaces = mkOption {
type = types.bool; type = types.bool;

View file

@ -897,59 +897,79 @@ in
security.apparmor.includes."abstractions/pam" = let security.apparmor.includes."abstractions/pam" = let
isEnabled = test: fold or false (map test (attrValues config.security.pam.services)); isEnabled = test: fold or false (map test (attrValues config.security.pam.services));
in '' in
${lib.concatMapStringsSep "\n" lib.concatMapStringsSep "\n"
(name: "r ${config.environment.etc."pam.d/${name}".source},") (name: "r ${config.environment.etc."pam.d/${name}".source},")
(attrNames config.security.pam.services)} (attrNames config.security.pam.services) +
''
mr ${getLib pkgs.pam}/lib/security/pam_filter/*, mr ${getLib pkgs.pam}/lib/security/pam_filter/*,
mr ${getLib pkgs.pam}/lib/security/pam_*.so, mr ${getLib pkgs.pam}/lib/security/pam_*.so,
r ${getLib pkgs.pam}/lib/security/, r ${getLib pkgs.pam}/lib/security/,
${optionalString use_ldap '' +
"mr ${pam_ldap}/lib/security/pam_ldap.so,"} optionalString use_ldap ''
${optionalString config.services.sssd.enable mr ${pam_ldap}/lib/security/pam_ldap.so,
"mr ${pkgs.sssd}/lib/security/pam_sss.so,"} '' +
${optionalString config.krb5.enable '' optionalString config.services.sssd.enable ''
mr ${pkgs.sssd}/lib/security/pam_sss.so,
'' +
optionalString config.krb5.enable ''
mr ${pam_krb5}/lib/security/pam_krb5.so, mr ${pam_krb5}/lib/security/pam_krb5.so,
mr ${pam_ccreds}/lib/security/pam_ccreds.so, mr ${pam_ccreds}/lib/security/pam_ccreds.so,
''} '' +
${optionalString (isEnabled (cfg: cfg.googleOsLoginAccountVerification)) '' optionalString (isEnabled (cfg: cfg.googleOsLoginAccountVerification)) ''
mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so, mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,
mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so, mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_admin.so,
''} '' +
${optionalString (isEnabled (cfg: cfg.googleOsLoginAuthentication)) optionalString (isEnabled (cfg: cfg.googleOsLoginAuthentication)) ''
"mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,"} mr ${pkgs.google-compute-engine-oslogin}/lib/pam_oslogin_login.so,
${optionalString (config.security.pam.enableSSHAgentAuth && isEnabled (cfg: cfg.sshAgentAuth)) '' +
"mr ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so,"} optionalString (config.security.pam.enableSSHAgentAuth
${optionalString (isEnabled (cfg: cfg.fprintAuth)) && isEnabled (cfg: cfg.sshAgentAuth)) ''
"mr ${pkgs.fprintd}/lib/security/pam_fprintd.so,"} mr ${pkgs.pam_ssh_agent_auth}/libexec/pam_ssh_agent_auth.so,
${optionalString (isEnabled (cfg: cfg.u2fAuth)) '' +
"mr ${pkgs.pam_u2f}/lib/security/pam_u2f.so,"} optionalString (isEnabled (cfg: cfg.fprintAuth)) ''
${optionalString (isEnabled (cfg: cfg.usbAuth)) mr ${pkgs.fprintd}/lib/security/pam_fprintd.so,
"mr ${pkgs.pam_usb}/lib/security/pam_usb.so,"} '' +
${optionalString (isEnabled (cfg: cfg.oathAuth)) optionalString (isEnabled (cfg: cfg.u2fAuth)) ''
"mr ${pkgs.oathToolkit}/lib/security/pam_oath.so,"} mr ${pkgs.pam_u2f}/lib/security/pam_u2f.so,
${optionalString (isEnabled (cfg: cfg.yubicoAuth)) '' +
"mr ${pkgs.yubico-pam}/lib/security/pam_yubico.so,"} optionalString (isEnabled (cfg: cfg.usbAuth)) ''
${optionalString (isEnabled (cfg: cfg.duoSecurity.enable)) mr ${pkgs.pam_usb}/lib/security/pam_usb.so,
"mr ${pkgs.duo-unix}/lib/security/pam_duo.so,"} '' +
${optionalString (isEnabled (cfg: cfg.otpwAuth)) optionalString (isEnabled (cfg: cfg.oathAuth)) ''
"mr ${pkgs.otpw}/lib/security/pam_otpw.so,"} "mr ${pkgs.oathToolkit}/lib/security/pam_oath.so,
${optionalString config.security.pam.enableEcryptfs '' +
"mr ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so,"} optionalString (isEnabled (cfg: cfg.yubicoAuth)) ''
${optionalString (isEnabled (cfg: cfg.pamMount)) mr ${pkgs.yubico-pam}/lib/security/pam_yubico.so,
"mr ${pkgs.pam_mount}/lib/security/pam_mount.so,"} '' +
${optionalString (isEnabled (cfg: cfg.enableGnomeKeyring)) optionalString (isEnabled (cfg: cfg.duoSecurity.enable)) ''
"mr ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so,"} mr ${pkgs.duo-unix}/lib/security/pam_duo.so,
${optionalString (isEnabled (cfg: cfg.startSession)) '' +
"mr ${pkgs.systemd}/lib/security/pam_systemd.so,"} optionalString (isEnabled (cfg: cfg.otpwAuth)) ''
${optionalString (isEnabled (cfg: cfg.enableAppArmor) && config.security.apparmor.enable) mr ${pkgs.otpw}/lib/security/pam_otpw.so,
"mr ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so,"} '' +
${optionalString (isEnabled (cfg: cfg.enableKwallet)) optionalString config.security.pam.enableEcryptfs ''
"mr ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so,"} mr ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so,
${optionalString config.virtualisation.lxc.lxcfs.enable '' +
"mr ${pkgs.lxc}/lib/security/pam_cgfs.so"} optionalString (isEnabled (cfg: cfg.pamMount)) ''
''; mr ${pkgs.pam_mount}/lib/security/pam_mount.so,
'' +
optionalString (isEnabled (cfg: cfg.enableGnomeKeyring)) ''
mr ${pkgs.gnome3.gnome-keyring}/lib/security/pam_gnome_keyring.so,
'' +
optionalString (isEnabled (cfg: cfg.startSession)) ''
mr ${pkgs.systemd}/lib/security/pam_systemd.so,
'' +
optionalString (isEnabled (cfg: cfg.enableAppArmor)
&& config.security.apparmor.enable) ''
mr ${pkgs.apparmor-pam}/lib/security/pam_apparmor.so,
'' +
optionalString (isEnabled (cfg: cfg.enableKwallet)) ''
mr ${pkgs.plasma5.kwallet-pam}/lib/security/pam_kwallet5.so,
'' +
optionalString config.virtualisation.lxc.lxcfs.enable ''
mr ${pkgs.lxc}/lib/security/pam_cgfs.so
'';
}; };
} }

View file

@ -290,7 +290,7 @@ let
, name ? "" , name ? ""
}: rootPaths: runCommand }: rootPaths: runCommand
( "apparmor-closure-rules" ( "apparmor-closure-rules"
+ lib.optionalString (name != "") "-${name}") {} '' + lib.optionalString (name != "") "-${name}" ) {} ''
touch $out touch $out
while read -r path while read -r path
do printf >>$out "%s,\n" ${lib.concatMapStringsSep " " (x: "\"${x}\"") (baseRules ++ additionalRules)} do printf >>$out "%s,\n" ${lib.concatMapStringsSep " " (x: "\"${x}\"") (baseRules ++ additionalRules)}