]> Git — Sourcephile - sourcephile-nix.git/blob - nixos/modules/security/apparmor.nix
apparmor: fix/rewrite security.apparmor
[sourcephile-nix.git] / nixos / modules / security / apparmor.nix
1 { config, lib, pkgs, ... }:
2
3 let
4 inherit (builtins) attrNames head match readFile;
5 inherit (lib) types;
6 inherit (config.environment) etc;
7 cfg = config.security.apparmor;
8 in
9
10 {
11 options = {
12 security.apparmor = {
13 enable = lib.mkEnableOption "Enable the AppArmor Mandatory Access Control system.";
14 profiles = lib.mkOption {
15 type = types.attrsOf types.lines;
16 default = {};
17 description = ''
18 Available AppArmor profiles.
19 '';
20 apply = lib.mapAttrs (name: text: pkgs.writeText "${name}" text);
21 };
22 enforceProfiles = lib.mkOption {
23 type = (types.listOf (types.enum (attrNames cfg.profiles))) // {
24 description = "list of profiles";
25 };
26 default = [];
27 description = "List of AppArmor profiles to be enforced.";
28 };
29 complainProfiles = lib.mkOption {
30 type = (types.listOf (types.enum (attrNames cfg.profiles))) // {
31 description = "list of profiles";
32 };
33 default = [];
34 description = "List of AppArmor profiles to be complained.";
35 };
36 includes = lib.mkOption {
37 type = types.listOf types.path;
38 default = [];
39 description = ''
40 List of paths to be added to AppArmor's searched paths
41 when resolving absolute #include directives.
42 '';
43 };
44 };
45 };
46
47 config = lib.mkIf cfg.enable {
48 environment.systemPackages = [ pkgs.apparmor-utils ];
49 environment.etc."apparmor.d".source = pkgs.linkFarm "apparmor.d" (
50 lib.mapAttrsToList (name: path: {inherit name path;}) cfg.profiles
51 );
52 environment.etc."apparmor/parser.conf".text =
53 lib.concatMapStringsSep "\n" (p: "#Include ${p}") cfg.includes;
54 environment.etc."apparmor/logprof.conf".text = ''
55 [settings]
56 profiledir = /etc/apparmor.d /etc/subdomain.d
57 inactive_profiledir = ${pkgs.apparmor-profiles}/share/apparmor/extra-profiles
58 logfiles = /var/log/audit/audit.log /var/log/syslog /var/log/messages
59
60 parser = ${pkgs.apparmor-parser}/bin/apparmor_parser ${pkgs.apparmor-parser}/bin/subdomain_parser
61 ldd = ${pkgs.glibc.bin}/bin/ldd
62 logger = ${pkgs.utillinux}/bin/logger
63
64 # customize how file ownership permissions are presented
65 # 0 - off
66 # 1 - default of what ever mode the log reported
67 # 2 - force the new permissions to be user
68 # 3 - force all perms on the rule to be user
69 default_owner_prompt = 1
70
71 # custom directory locations to look for #includes
72 #
73 # each name should be a valid directory containing possible #include
74 # candidate files under the profile dir which by default is /etc/apparmor.d.
75 #
76 # So an entry of my-includes will allow /etc/apparmor.d/my-includes to
77 # be used by the yast UI and profiling tools as a source of #include
78 # files.
79 custom_includes =
80
81 [qualifiers]
82 ${pkgs.runtimeShell} = icnu
83 '' + head (match "^.*\\[qualifiers](.*)" (readFile "${pkgs.apparmor-utils}/etc/apparmor/logprof.conf"));
84 security.apparmor.profiles = {
85 "abstractions/tunables/alias" = ''
86 alias /bin -> /run/current-system/sw/bin,
87 #alias /etc -> /run/current-system/etc,
88 alias /lib/modules -> /run/current-system/kernel/lib/modules,
89 alias /sbin -> /run/current-system/sw/sbin,
90 alias /usr -> /run/current-system/sw,
91 '';
92 "abstractions/base" = ''
93 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/base
94 ${etc."hosts".source} r,
95 /etc/ld-nix.so.preload r,
96 ${etc."ld-nix.so.preload".source} r,
97 ${lib.concatMapStrings (p: lib.optionalString (p != "") (p+" mr,\n"))
98 (lib.splitString "\n" etc."ld-nix.so.preload".text)}
99 ${pkgs.tzdata}/share/zoneinfo/** r,
100 '';
101 "abstractions/consoles" = ''
102 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/consoles
103 '';
104 "abstractions/ldapclient" = ''
105 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ldapclient
106 '';
107 "abstractions/kerberosclient" = ''
108 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kerberosclient
109 '';
110 "abstractions/likewise" = ''
111 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/likewise
112 '';
113 "abstractions/mdns" = ''
114 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/mdns
115 '';
116 "abstractions/nameservice" = ''
117 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nameservice
118 '';
119 "abstractions/nis" = ''
120 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nis
121 '';
122 "abstractions/ssl_certs" = ''
123 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ssl_certs
124 ${etc."ssl/certs/ca-certificates.crt".source} r,
125 ${etc."ssl/certs/ca-bundle.crt".source} r,
126 '';
127 "abstractions/winbind" = ''
128 #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/winbind
129 '';
130 };
131 security.apparmor.includes = [ (pkgs.apparmor-profiles+"/etc/apparmor.d/") ];
132
133 boot.kernelParams = [ "apparmor=1" "security=apparmor" ];
134
135 systemd.services.apparmor = {
136 after = [ "local-fs.target" ];
137 before = [ "sysinit.target" ];
138 wantedBy = [ "multi-user.target" ];
139 unitConfig = {
140 DefaultDependencies = "no";
141 };
142 serviceConfig =
143 let includes = lib.concatMapStringsSep " " (p: "-I ${p}") cfg.includes;
144 in {
145 Type = "oneshot";
146 RemainAfterExit = "yes";
147 ExecStart =
148 map (p: ''${pkgs.apparmor-parser}/bin/apparmor_parser -rKv ${includes} "${cfg.profiles."${p}"}"'') cfg.enforceProfiles ++
149 map (p: ''${pkgs.apparmor-parser}/bin/apparmor_parser -rKvC ${includes} "${cfg.profiles."${p}"}"'') cfg.complainProfiles;
150 ExecStop =
151 map (p: ''${pkgs.apparmor-parser}/bin/apparmor_parser -Rv ${includes} "${cfg.profiles."${p}"}"'') cfg.enforceProfiles ++
152 map (p: ''${pkgs.apparmor-parser}/bin/apparmor_parser -RvC ${includes} "${cfg.profiles."${p}"}"'') cfg.complainProfiles;
153 ExecReload =
154 map (p: ''${pkgs.apparmor-parser}/bin/apparmor_parser --reload ${includes} "${cfg.profiles."${p}"}"'') cfg.enforceProfiles ++
155 map (p: ''${pkgs.apparmor-parser}/bin/apparmor_parser --reload -C ${includes} "${cfg.profiles."${p}"}"'') cfg.complainProfiles;
156 };
157 };
158 };
159
160 meta.maintainers = with lib.maintainers; [ julm ];
161 }