139 lines
3.8 KiB
Nix
139 lines
3.8 KiB
Nix
# Kernel Hardening Module
|
|
# Provides: hardened boot params, sysctl settings, blacklisted modules, ZRAM
|
|
#
|
|
# Usage:
|
|
# myModules.kernelHardening = {
|
|
# enable = true;
|
|
# enableZram = true; # default: true
|
|
# zramPercent = 50; # default: 50
|
|
# };
|
|
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}:
|
|
|
|
let
|
|
cfg = config.myModules.kernelHardening;
|
|
in
|
|
{
|
|
options.myModules.kernelHardening = {
|
|
enable = lib.mkEnableOption "kernel hardening module";
|
|
|
|
enableZram = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = true;
|
|
description = "Enable ZRAM swap";
|
|
};
|
|
|
|
zramPercent = lib.mkOption {
|
|
type = lib.types.int;
|
|
default = 50;
|
|
description = "Percentage of RAM to use for ZRAM";
|
|
};
|
|
|
|
zramAlgorithm = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "lz4";
|
|
description = "Compression algorithm for ZRAM (lz4, zstd, lzo)";
|
|
};
|
|
|
|
tmpfsPercent = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "50%";
|
|
description = "Size of /tmp tmpfs as percentage of RAM";
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
# Secure boot loader settings
|
|
boot.loader.systemd-boot.editor = false;
|
|
|
|
# Use tmpfs for /tmp
|
|
boot.tmp = {
|
|
useTmpfs = true;
|
|
tmpfsSize = cfg.tmpfsPercent;
|
|
};
|
|
|
|
# Runtime kernel hardening
|
|
boot.kernelParams = [
|
|
"slab_nomerge"
|
|
"init_on_alloc=1"
|
|
"init_on_free=1"
|
|
"page_alloc.shuffle=1"
|
|
"randomize_kstack_offset=on"
|
|
"vsyscall=none"
|
|
"oops=panic"
|
|
];
|
|
|
|
# Kernel sysctl hardening
|
|
boot.kernel.sysctl = {
|
|
"kernel.kptr_restrict" = 2;
|
|
"kernel.dmesg_restrict" = 1;
|
|
"fs.protected_hardlinks" = 1;
|
|
"fs.protected_symlinks" = 1;
|
|
"net.ipv4.tcp_syncookies" = 1;
|
|
"net.ipv4.tcp_rfc1337" = 1;
|
|
"net.ipv4.ip_forward" = 1;
|
|
"kernel.unprivileged_bpf_disabled" = 1;
|
|
"kernel.kexec_load_disabled" = 1;
|
|
"kernel.perf_event_paranoid" = 3;
|
|
"net.ipv4.tcp_timestamps" = 0;
|
|
"dev.tty.ldisc_autoload" = 0;
|
|
"kernel.yama.ptrace_scope" = 1;
|
|
"kernel.core_pattern" = "|/bin/false";
|
|
"net.ipv4.conf.all.accept_redirects" = 0;
|
|
"net.ipv4.conf.default.accept_redirects" = 0;
|
|
"net.ipv4.conf.all.secure_redirects" = 0;
|
|
"net.ipv4.conf.default.secure_redirects" = 0;
|
|
"net.ipv6.conf.all.accept_redirects" = 0;
|
|
"net.ipv6.conf.default.accept_redirects" = 0;
|
|
"net.ipv4.conf.all.send_redirects" = 0;
|
|
"net.ipv4.conf.default.send_redirects" = 0;
|
|
"net.ipv4.conf.all.rp_filter" = 2;
|
|
"net.ipv4.conf.default.rp_filter" = 2;
|
|
"net.ipv4.conf.all.log_martians" = 1;
|
|
"net.ipv4.conf.default.log_martians" = 1;
|
|
"net.ipv4.icmp_echo_ignore_broadcasts" = 1;
|
|
|
|
# Network optimization (TCP Buffers)
|
|
"net.core.rmem_max" = 2500000;
|
|
"net.core.wmem_max" = 2500000;
|
|
"net.ipv4.tcp_rmem" = "4096 87380 2500000";
|
|
"net.ipv4.tcp_wmem" = "4096 65536 2500000";
|
|
"net.core.netdev_max_backlog" = 5000;
|
|
};
|
|
|
|
# Set IO Scheduler to kyber for NVMe and bfq for SATA
|
|
services.udev.extraRules = ''
|
|
# NVMe
|
|
ACTION=="add|change", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/scheduler}="kyber"
|
|
# SSD/HDD
|
|
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="bfq"
|
|
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
|
|
'';
|
|
|
|
boot.blacklistedKernelModules = [
|
|
"cramfs"
|
|
"freevxfs"
|
|
"jffs2"
|
|
"hfs"
|
|
"hfsplus"
|
|
"udf"
|
|
# DMA vulnerable modules
|
|
"firewire-core"
|
|
"firewire_ohci"
|
|
"thunderbolt"
|
|
];
|
|
|
|
security.lockKernelModules = true;
|
|
|
|
zramSwap = lib.mkIf cfg.enableZram {
|
|
enable = true;
|
|
memoryPercent = cfg.zramPercent;
|
|
algorithm = cfg.zramAlgorithm;
|
|
};
|
|
};
|
|
}
|