nixpkgs/nixos/modules/security/auditd.nix

147 lines
5.1 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
config,
lib,
pkgs,
...
}:
let
cfg = config.security.auditd;
settingsType =
with lib.types;
nullOr (oneOf [
bool
nonEmptyStr
path
int
]);
prepareConfigValue =
v:
if lib.isBool v then
(if v then "yes" else "no")
else if lib.isList v then
lib.concatStringsSep " " (map prepareConfigValue v)
else
builtins.toString v;
prepareConfigText =
conf:
lib.concatLines (
lib.mapAttrsToList (k: v: if v == null then "#${k} =" else "${k} = ${prepareConfigValue v}") conf
);
in
{
options.security.auditd = {
enable = lib.mkEnableOption "the Linux Audit daemon";
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = lib.types.attrsOf settingsType;
options = {
# space_left needs to be larger than admin_space_left, yet they default to be the same if left open.
space_left = lib.mkOption {
type = lib.types.either lib.types.int (lib.types.strMatching "[0-9]+%");
default = 75;
description = ''
If the free space in the filesystem containing log_file drops below this value, the audit daemon takes the action specified by
{option}`space_left_action`. If the value of {option}`space_left` is specified as a whole number, it is interpreted as an absolute size in mebibytes
(MiB). If the value is specified as a number between 1 and 99 followed by a percentage sign (e.g., 5%), the audit daemon calculates
the absolute size in megabytes based on the size of the filesystem containing {option}`log_file`. (E.g., if the filesystem containing
{option}`log_file` is 2 gibibytes in size, and {option}`space_left` is set to 25%, then the audit daemon sets {option}`space_left` to approximately 500 mebibytes.
::: {.note}
This calculation is performed when the audit daemon starts, so if you resize the filesystem containing {option}`log_file` while the
audit daemon is running, you should send the audit daemon SIGHUP to re-read the configuration file and recalculate the correct per
centage.
:::
'';
};
admin_space_left = lib.mkOption {
type = lib.types.either lib.types.int (lib.types.strMatching "[0-9]+%");
default = 50;
description = ''
This is a numeric value in mebibytes (MiB) that tells the audit daemon when to perform a configurable action because the system is running
low on disk space. This should be considered the last chance to do something before running out of disk space. The numeric value for
this parameter should be lower than the number for {option}`space_left`. You may also append a percent sign (e.g. 1%) to the number to have
the audit daemon calculate the number based on the disk partition size.
'';
};
};
};
default = { };
description = "auditd configuration file contents. See {auditd.conf} for supported values.";
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion =
let
cfg' = cfg.settings;
in
(
(lib.isInt cfg'.space_left && lib.isInt cfg'.admin_space_left)
-> cfg'.space_left > cfg'.admin_space_left
)
&& (
let
get_percent = s: lib.toInt (lib.strings.removeSuffix "%" s);
in
(lib.isString cfg'.space_left && lib.isString cfg'.admin_space_left)
-> (get_percent cfg'.space_left) > (get_percent cfg'.admin_space_left)
);
message = "`security.auditd.settings.space_left` must be larger than `security.auditd.settings.admin_space_left`";
}
];
# Starting auditd should also enable loading the audit rules..
security.audit.enable = lib.mkDefault true;
environment.systemPackages = [ pkgs.audit ];
environment.etc = {
"audit/auditd.conf".text = prepareConfigText cfg.settings;
};
systemd.services.auditd = {
description = "Security Audit Logging Service";
documentation = [ "man:auditd(8)" ];
wantedBy = [ "sysinit.target" ];
after = [
"local-fs.target"
"systemd-tmpfiles-setup.service"
];
before = [
"sysinit.target"
"shutdown.target"
];
conflicts = [ "shutdown.target" ];
unitConfig = {
DefaultDependencies = false;
RefuseManualStop = true;
ConditionVirtualization = "!container";
ConditionKernelCommandLine = [
"!audit=0"
"!audit=off"
];
};
serviceConfig = {
LogsDirectory = "audit";
ExecStart = "${pkgs.audit}/bin/auditd -l -n -s nochange";
Restart = "on-failure";
# Do not restart for intentional exits. See EXIT CODES section in auditd(8).
RestartPreventExitStatus = "2 4 6";
# Upstream hardening settings
MemoryDenyWriteExecute = true;
LockPersonality = true;
RestrictRealtime = true;
};
};
};
}