mirror of
https://github.com/aviallon/nixos-lib.git
synced 2026-04-05 17:27:50 +00:00
150 lines
4.8 KiB
Nix
150 lines
4.8 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
lib,
|
|
...
|
|
}:
|
|
with lib;
|
|
let
|
|
cfg = config.aviallon.hardening;
|
|
desktopCfg = config.aviallon.desktop;
|
|
_mkForcePrio = lib.mkForce null;
|
|
mkQuasiForce = x: lib.mkOverride (_mkForcePrio.priority + 1) x;
|
|
in
|
|
{
|
|
options.aviallon.hardening = {
|
|
enable = mkOption {
|
|
default = true;
|
|
example = false;
|
|
description = "Enable aviallon's hardening";
|
|
type = types.bool;
|
|
};
|
|
|
|
hardcore = mkOption {
|
|
default = !desktopCfg.enable;
|
|
example = desktopCfg.enable;
|
|
description = "Enable hardcore hardening, which might break things. Forces expensive hardening.";
|
|
type = types.bool;
|
|
};
|
|
|
|
expensive = mkOption {
|
|
default = cfg.hardcore || !desktopCfg.enable;
|
|
example = desktopCfg.enable;
|
|
description = "Enable expensive hardening option (reduces performance)";
|
|
type = types.bool;
|
|
};
|
|
|
|
};
|
|
|
|
imports = [
|
|
(mkRemovedOptionModule [
|
|
"aviallon"
|
|
"hardening"
|
|
"services"
|
|
"dbus"
|
|
] "dbus should use AppArmor hardening instead")
|
|
];
|
|
|
|
config = mkIf cfg.enable {
|
|
aviallon.boot.kernel.package = mkIf cfg.hardcore (
|
|
mkDefault pkgs.linuxKernel.kernels.linux_hardened
|
|
);
|
|
security.lockKernelModules = mkIf cfg.hardcore (mkQuasiForce true);
|
|
# security.protectKernelImage = mkIf cfg.hardcore (mkOverride 500 false); # needed for kexec
|
|
|
|
aviallon.hardening.expensive = mkIf cfg.hardcore (mkQuasiForce true);
|
|
|
|
security.sudo.execWheelOnly = true;
|
|
|
|
services.openssh.settings.PermitRootLogin = if cfg.hardcore then "no" else "prohibit-password";
|
|
|
|
security.apparmor.enable = true;
|
|
services.dbus.apparmor = "enabled";
|
|
|
|
aviallon.boot.cmdline = {
|
|
"lsm" = [
|
|
"landlock"
|
|
]
|
|
++ optional cfg.hardcore "lockdown"
|
|
++ [ "yama" ]
|
|
# Apparmor https://wiki.archlinux.org/title/AppArmor#Installation
|
|
++ optionals config.security.apparmor.enable [ "apparmor" ]
|
|
++ [ "bpf" ];
|
|
"lockdown" = if cfg.hardcore then "confidentiality" else "integrity";
|
|
|
|
# Vsyscall page not readable (default is "emulate". "none" might break statically-linked binaries.)
|
|
vsyscall = mkIf cfg.hardcore "xonly";
|
|
}
|
|
// (ifEnable cfg.expensive {
|
|
# Slab/slub sanity checks, redzoning, and poisoning
|
|
"init_on_alloc" = 1;
|
|
"init_on_free" = 1;
|
|
|
|
# Overwrite free'd memory
|
|
"page_poison" = 1;
|
|
|
|
# Enable page allocator randomization
|
|
"page_alloc.shuffle" = 1;
|
|
|
|
"nordrand" = "";
|
|
"random.trust_cpu" = "off";
|
|
});
|
|
|
|
boot.kernel.sysctl = {
|
|
# Almost free security. https://www.kernel.org/doc/html/latest/admin-guide/LSM/Yama.html
|
|
"kernel.yama.ptrace_scope" = mkQuasiForce 1;
|
|
|
|
# https://lwn.net/Articles/420403/
|
|
"kernel.kptr_restrict" = mkQuasiForce 2;
|
|
|
|
# Can be used by developers. Should be disabled on regular desktops.
|
|
# https://www.kernel.org/doc/html/latest/trace/ftrace.html
|
|
"kernel.ftrace_enabled" = mkIf cfg.hardcore (mkQuasiForce false);
|
|
};
|
|
|
|
# Is used in podman containers, for instance
|
|
security.allowUserNamespaces = mkDefault true;
|
|
# boot.blacklistedKernelModules = mkForce [ ];
|
|
|
|
# Only authorize admins to use nix in hardcore mode
|
|
nix.allowedUsers = mkIf cfg.hardcore (mkQuasiForce [ "@wheel" ]);
|
|
|
|
# Can really badly affect performance in some occasions.
|
|
security.audit.enable = mkDefault true;
|
|
security.auditd.enable = mkQuasiForce false;
|
|
|
|
systemd.services.systemd-journald =
|
|
let
|
|
rules = pkgs.writeText "audit.rules" (concatStringsSep "\n" config.security.audit.rules);
|
|
in
|
|
mkIf config.security.audit.enable {
|
|
serviceConfig = {
|
|
#ExecStartPre = "-${pkgs.audit}/bin/augenrules --load";
|
|
ExecStartPre = ''-${pkgs.audit}/bin/auditctl -R ${rules} -e 1 -f 1 -r 1000 -b 64'';
|
|
Sockets = [ "systemd-journald-audit.socket" ];
|
|
};
|
|
aliases = [ "auditd.service" ];
|
|
path = [ pkgs.audit ];
|
|
};
|
|
|
|
security.audit.rules =
|
|
[ ]
|
|
++ [
|
|
"-A exclude,always -F msgtype=SERVICE_START"
|
|
"-A exclude,always -F msgtype=SERVICE_STOP"
|
|
"-A exclude,always -F msgtype=BPF"
|
|
"-w /etc/apparmor/ -p wa -k apparmor_changes"
|
|
"-w /etc/apparmor.d/ -p wa -k apparmor_changes"
|
|
|
|
"-a exit,always -F arch=b64 -S init_module -S finit_module -k module_insertion"
|
|
"-a exit,always -F arch=b32 -S init_module -S finit_module -k module_insertion"
|
|
"-a exit,always -F arch=b64 -C auid!=euid -F auid!=unset -F euid=0 -S execve -k privesc_execve"
|
|
"-a exit,always -F arch=b32 -C auid!=euid -F auid!=unset -F euid=0 -S execve -k privesc_execve"
|
|
]
|
|
++ optional cfg.expensive "-a exit,always -F arch=b64 -S execve -k execve_calls";
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
sbctl # Secure Boot keys generation
|
|
];
|
|
};
|
|
}
|