NixOS Hardening
linux-hardened
linux-hardened is a Linux kernel with additional hardening patches applied.
boot.kernelPackages = pkgs.linuxKernel.packages.linux_hardened;
Lock kernel modules
This option locks kernel modules after the system is initialized. For example it prevents malicious USB devices from exploiting vulnerable kernel modules.
security.lockKernelModules = true;
All needed modules must be loaded at boot by adding them to boot.kernelModules.
Module blacklist
boot.blacklistedKernelModules = [
# Obscure network protocols
"ax25" "netrom" "rose"
# Old or rare or insufficiently audited filesystems
"adfs" "affs"
"bfs" "befs"
"cramfs"
"efs" "erofs" "exofs"
"freevxfs" "f2fs"
"hfs" "hpfs"
"jfs"
"minix"
"nilfs2" "ntfs"
"omfs"
"qnx4" "qnx6"
"sysv"
"ufs"
];
Kernel image protection
Prevents replacing the running kernel image.
security.protectKernelImage = true;
Kernel parameters
boot.kernelParams = [
# Don't merge slabs
"slab_nomerge"
# Overwrite free'd pages
"page_poison=1"
# Enable page allocator randomization
"page_alloc.shuffle=1"
# Disable debugfs
"debugfs=off"
];
Sysctl parameters
# Hide kptrs even for processes with CAP_SYSLOG
boot.kernel.sysctl."kernel.kptr_restrict" = "2";
# Disable bpf() JIT (to eliminate spray attacks)
boot.kernel.sysctl."net.core.bpf_jit_enable" = false;
# Disable ftrace debugging
boot.kernel.sysctl."kernel.ftrace_enabled" = false;
# Enable strict reverse path filtering (that is, do not attempt to route
# packets that "obviously" do not belong to the iface's network; dropped
# packets are logged as martians).
boot.kernel.sysctl."net.ipv4.conf.all.log_martians" = true;
boot.kernel.sysctl."net.ipv4.conf.all.rp_filter" = "1";
boot.kernel.sysctl."net.ipv4.conf.default.log_martians" = true;
boot.kernel.sysctl."net.ipv4.conf.default.rp_filter" = "1";
# Ignore broadcast ICMP (mitigate SMURF)
boot.kernel.sysctl."net.ipv4.icmp_echo_ignore_broadcasts" = true;
# Ignore incoming ICMP redirects (note: default is needed to ensure that the
# setting is applied to interfaces added after the sysctls are set)
boot.kernel.sysctl."net.ipv4.conf.all.accept_redirects" = false;
boot.kernel.sysctl."net.ipv4.conf.all.secure_redirects" = false;
boot.kernel.sysctl."net.ipv4.conf.default.accept_redirects" = false;
boot.kernel.sysctl."net.ipv4.conf.default.secure_redirects" = false;
boot.kernel.sysctl."net.ipv6.conf.all.accept_redirects" = false;
boot.kernel.sysctl."net.ipv6.conf.default.accept_redirects" = false;
# Ignore outgoing ICMP redirects (this is ipv4 only)
boot.kernel.sysctl."net.ipv4.conf.all.send_redirects" = false;
boot.kernel.sysctl."net.ipv4.conf.default.send_redirects" = false;
Disable Simultaneous Multithreading (SMT)
Might cause significant performance cost.
security.allowSimultaneousMultithreading = false;
Force Page Table Isolation
security.forcePageTableIsolation = true;
Memory allocator
You can use security-focused memory allocator like scudo or GrapheneOS hardened_malloc.
# scudo
environment.memoryAllocator.provider = "scudo";
environment.variables.SCUDO_OPTIONS = "zero_contents=true";
# hardened_malloc
environment.memoryAllocator.provider = "graphene-hardened";
Some programs may not work with these memory allocators. You can force them to use the default libc allocator by blacklisting /etc/ld-nix.so.preload with a firejail wrap.
programs.firejail = {
enable = true;
wrappedBinaries = {
chromium = {
executable = "${pkgs.chromium}/bin/chromium-browser";
profile = "${pkgs.firejail}/etc/firejail/chromium-browser.profile";
extraArgs = [
"--blacklist=/etc/ld-nix.so.preload"
];
};
};
};
Nix allowed users
This option allows only users group to connect to the Nix daemon.
nix.settings.allowed-users = [ "@users" ];
Flush L1 data cache
Might cause significant performance cost.
security.virtualisation.flushL1DataCache = "always";
AppArmor
security.apparmor.enable = true;
security.apparmor.killUnconfinedConfinables = true;
Secure Boot
See Secure Boot. Limine bootloader supports coreboot's Secure Boot.