mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-13 21:50:33 +03:00
nixos/apparmor: profile activation tristate and profile path support
This commit is contained in:
parent
1f750cfa3d
commit
e87b9b1f3e
2 changed files with 61 additions and 40 deletions
|
@ -162,6 +162,9 @@
|
||||||
| virtualBoxOVA | virtualbox-vagrant.box | nixos-image-vagrant-virtualbox-25.05pre-git-x86_64-linux.ova |
|
| virtualBoxOVA | virtualbox-vagrant.box | nixos-image-vagrant-virtualbox-25.05pre-git-x86_64-linux.ova |
|
||||||
| vmwareImage | nixos-25.05pre-git-x86_64-linux.vmdk | nixos-image-vmware-25.05pre-git-x86_64-linux.vmdk |
|
| vmwareImage | nixos-25.05pre-git-x86_64-linux.vmdk | nixos-image-vmware-25.05pre-git-x86_64-linux.vmdk |
|
||||||
|
|
||||||
|
- `security.apparmor.policies.<name>.enforce` and `security.apparmor.policies.<name>.enable` were removed.
|
||||||
|
Configuring the state of apparmor policies must now be done using `security.apparmor.policies.<name>.state` tristate option.
|
||||||
|
|
||||||
- the notmuch vim plugin now lives in a separate output of the `notmuch`
|
- the notmuch vim plugin now lives in a separate output of the `notmuch`
|
||||||
package. Installing `notmuch` will not bring the notmuch vim package anymore,
|
package. Installing `notmuch` will not bring the notmuch vim package anymore,
|
||||||
add `vimPlugins.notmuch-vim` to your (Neo)vim configuration if you want the
|
add `vimPlugins.notmuch-vim` to your (Neo)vim configuration if you want the
|
||||||
|
|
|
@ -5,24 +5,16 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
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 =
|
enabledPolicies = lib.filterAttrs (n: p: p.state != "disable") cfg.policies;
|
||||||
name:
|
buildPolicyPath = n: p: lib.defaultTo (pkgs.writeText n p.profile) p.path;
|
||||||
lib.mkEnableOption name
|
|
||||||
// {
|
# Accessing submodule options when not defined results in an error thunk rather than a regular option object
|
||||||
default = true;
|
# We can emulate the behavior of `<option>.isDefined` by attempting to evaluate it instead
|
||||||
example = false;
|
# This is required because getting isDefined on a submodule is not possible in global module asserts.
|
||||||
};
|
submoduleOptionIsDefined = value: (builtins.tryEval value).success;
|
||||||
enabledPolicies = lib.filterAttrs (n: p: p.enable) cfg.policies;
|
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -31,7 +23,7 @@ in
|
||||||
"security"
|
"security"
|
||||||
"apparmor"
|
"apparmor"
|
||||||
"confineSUIDApplications"
|
"confineSUIDApplications"
|
||||||
] "Please use the new options: `security.apparmor.policies.<policy>.enable'.")
|
] "Please use the new options: `security.apparmor.policies.<policy>.state'.")
|
||||||
(lib.mkRemovedOptionModule [
|
(lib.mkRemovedOptionModule [
|
||||||
"security"
|
"security"
|
||||||
"apparmor"
|
"apparmor"
|
||||||
|
@ -65,20 +57,32 @@ in
|
||||||
AppArmor policies.
|
AppArmor policies.
|
||||||
'';
|
'';
|
||||||
type = types.attrsOf (
|
type = types.attrsOf (
|
||||||
types.submodule (
|
types.submodule {
|
||||||
{ name, config, ... }:
|
options = {
|
||||||
{
|
state = lib.mkOption {
|
||||||
options = {
|
description = "How strictly this policy should be enforced";
|
||||||
enable = mkDisableOption "loading of the profile into the kernel";
|
type = types.enum [
|
||||||
enforce = mkDisableOption "enforcing of the policy or only complain in the logs";
|
"disable"
|
||||||
profile = lib.mkOption {
|
"complain"
|
||||||
description = "The policy of the profile.";
|
"enforce"
|
||||||
type = types.lines;
|
];
|
||||||
apply = pkgs.writeText name;
|
# should enforce really be the default?
|
||||||
};
|
# the docs state that this should only be used once one is REALLY sure nothing's gonna break
|
||||||
|
default = "enforce";
|
||||||
};
|
};
|
||||||
}
|
|
||||||
)
|
profile = lib.mkOption {
|
||||||
|
description = "The profile file contents. Incompatible with path.";
|
||||||
|
type = types.lines;
|
||||||
|
};
|
||||||
|
|
||||||
|
path = lib.mkOption {
|
||||||
|
description = "A path of a profile file to include. Incompatible with profile.";
|
||||||
|
type = types.nullOr types.path;
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
);
|
);
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
|
@ -117,12 +121,20 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
assertions = map (policy: {
|
assertions = lib.concatLists (
|
||||||
assertion = match ".*/.*" policy == null;
|
lib.mapAttrsToList (policyName: policyCfg: [
|
||||||
message = "`security.apparmor.policies.\"${policy}\"' must not contain a slash.";
|
{
|
||||||
# Because, for instance, aa-remove-unknown uses profiles_names_list() in rc.apparmor.functions
|
assertion = builtins.match ".*/.*" policyName == null;
|
||||||
# which does not recurse into sub-directories.
|
message = "`security.apparmor.policies.\"${policyName}\"' must not contain a slash.";
|
||||||
}) (attrNames cfg.policies);
|
# Because, for instance, aa-remove-unknown uses profiles_names_list() in rc.apparmor.functions
|
||||||
|
# which does not recurse into sub-directories.
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = lib.xor (policyCfg.path != null) (submoduleOptionIsDefined policyCfg.profile);
|
||||||
|
message = "`security.apparmor.policies.\"${policyName}\"` must define exactly one of either path or profile.";
|
||||||
|
}
|
||||||
|
]) cfg.policies
|
||||||
|
);
|
||||||
|
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
pkgs.apparmor-utils
|
pkgs.apparmor-utils
|
||||||
|
@ -133,7 +145,7 @@ in
|
||||||
# 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: {
|
lib.mapAttrsToList (name: p: {
|
||||||
inherit name;
|
inherit name;
|
||||||
path = p.profile;
|
path = buildPolicyPath name p;
|
||||||
}) enabledPolicies
|
}) enabledPolicies
|
||||||
++ lib.mapAttrsToList (name: path: { inherit name path; }) cfg.includes
|
++ lib.mapAttrsToList (name: path: { inherit name path; }) cfg.includes
|
||||||
);
|
);
|
||||||
|
@ -226,21 +238,24 @@ in
|
||||||
kill
|
kill
|
||||||
'';
|
'';
|
||||||
commonOpts =
|
commonOpts =
|
||||||
p: "--verbose --show-cache ${lib.optionalString (!p.enforce) "--complain "}${p.profile}";
|
n: p:
|
||||||
|
"--verbose --show-cache ${
|
||||||
|
lib.optionalString (p.state == "complain") "--complain "
|
||||||
|
}${buildPolicyPath n p}";
|
||||||
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 (
|
ExecStart = lib.mapAttrsToList (
|
||||||
n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts p}"
|
n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts n p}"
|
||||||
) enabledPolicies;
|
) enabledPolicies;
|
||||||
ExecStartPost = lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
|
ExecStartPost = lib.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 (
|
lib.mapAttrsToList (
|
||||||
n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts p}"
|
n: p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts n p}"
|
||||||
) enabledPolicies
|
) enabledPolicies
|
||||||
++
|
++
|
||||||
# Remove from the kernel any profile whose name is not
|
# Remove from the kernel any profile whose name is not
|
||||||
|
@ -262,5 +277,8 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
meta.maintainers = with lib.maintainers; [ julm grimmauld ];
|
meta.maintainers = with lib.maintainers; [
|
||||||
|
julm
|
||||||
|
grimmauld
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue