mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-07-06 17:13:24 -05:00
nixos/profiles: remove hardened
- It lacks a consistent and transparent baseline or standard, - It may introduce unexpected breakage or degrade performance without clear benefit, - It is difficult to manage user expectations, especially since the implications of enabling it are not always obvious, - and as multiple contributors have noted, it is often more of a “grab bag” of settings than a cohesive security policy.
This commit is contained in:
parent
f27b06d07e
commit
18a45284a2
8 changed files with 16 additions and 271 deletions
|
|
@ -24,7 +24,6 @@ profiles/clone-config.section.md
|
|||
profiles/demo.section.md
|
||||
profiles/docker-container.section.md
|
||||
profiles/graphical.section.md
|
||||
profiles/hardened.section.md
|
||||
profiles/headless.section.md
|
||||
profiles/installation-device.section.md
|
||||
profiles/perlless.section.md
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
# Hardened {#sec-profile-hardened}
|
||||
|
||||
A profile with most (vanilla) hardening options enabled by default,
|
||||
potentially at the cost of stability, features and performance.
|
||||
|
||||
This includes a hardened kernel, and limiting the system information
|
||||
available to processes through the `/sys` and
|
||||
`/proc` filesystems. It also disables the User Namespaces
|
||||
feature of the kernel, which stops Nix from being able to build anything
|
||||
(this particular setting can be overridden via
|
||||
[](#opt-security.allowUserNamespaces)). See the
|
||||
[profile source](https://github.com/nixos/nixpkgs/tree/master/nixos/modules/profiles/hardened.nix)
|
||||
for further detail on which settings are altered.
|
||||
|
||||
::: {.warning}
|
||||
This profile enables options that are known to affect system
|
||||
stability. If you experience any stability issues when using the
|
||||
profile, try disabling it. If you report an issue and use this
|
||||
profile, always mention that you do.
|
||||
:::
|
||||
|
|
@ -1680,7 +1680,8 @@
|
|||
"sec-profile-graphical": [
|
||||
"index.html#sec-profile-graphical"
|
||||
],
|
||||
"sec-profile-hardened": [
|
||||
"sec-release-26.05-incompatibilities-profiles-hardened-removed": [
|
||||
"release-notes.html#sec-release-26.05-incompatibilities-profiles-hardened-removed",
|
||||
"index.html#sec-profile-hardened"
|
||||
],
|
||||
"sec-profile-headless": [
|
||||
|
|
|
|||
|
|
@ -86,6 +86,12 @@
|
|||
|
||||
- `opentrack`, `slushload`, `synthesia`, `vtfedit`, `winbox`, `wineasio`, and `yabridge` use wineWow64Packages instead of wineWowPackages as wine versions >= 11.0 have deprecated wineWowPackages. As such, the prefixes for these packages are NOT backwards compatible and need to be regenerated with potential for data loss.
|
||||
|
||||
- []{#sec-release-26.05-incompatibilities-profiles-hardened-removed} `profiles/hardened` has been removed, because:
|
||||
- It lacks a consistent and transparent baseline or standard,
|
||||
- It may introduce unexpected breakage or degrade performance without clear benefit,
|
||||
- It is difficult to manage user expectations, especially since the implications of enabling it are not always obvious,
|
||||
- and as multiple contributors have noted, it is often more of a “grab bag” of settings than a cohesive security policy.
|
||||
|
||||
- `services.crabfit` was removed because its upstream packages are unmaintained and insecure.
|
||||
|
||||
- `sing-box` has been updated to 1.13.0, which has removed some deprecated options. See [upstream documentation](https://sing-box.sagernet.org/configuration/) for details and migration options.
|
||||
|
|
|
|||
|
|
@ -1,136 +1,11 @@
|
|||
# A profile with most (vanilla) hardening options enabled by default,
|
||||
# potentially at the cost of stability, features and performance.
|
||||
#
|
||||
# This profile enables options that are known to affect system
|
||||
# stability. If you experience any stability issues when using the
|
||||
# profile, try disabling it. If you report an issue and use this
|
||||
# profile, always mention that you do.
|
||||
# This profile included most standard hardening options enabled by default,
|
||||
# which may have impacted system stability, feature availability, and performance.
|
||||
|
||||
{ lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
mkDefault
|
||||
mkOverride
|
||||
mkEnableOption
|
||||
mkIf
|
||||
maintainers
|
||||
;
|
||||
in
|
||||
{
|
||||
options.profiles.hardened = mkEnableOption "hardened" // {
|
||||
default = true;
|
||||
example = false;
|
||||
};
|
||||
config = mkIf config.profiles.hardened {
|
||||
meta = {
|
||||
maintainers = [
|
||||
maintainers.emily
|
||||
];
|
||||
};
|
||||
|
||||
boot.kernelPackages = mkDefault pkgs.linuxKernel.packages.linux_hardened;
|
||||
|
||||
nix.settings.allowed-users = mkDefault [ "@users" ];
|
||||
|
||||
environment.memoryAllocator.provider = mkDefault "scudo";
|
||||
environment.variables.SCUDO_OPTIONS = mkDefault "zero_contents=true";
|
||||
|
||||
security.lockKernelModules = mkDefault true;
|
||||
|
||||
security.protectKernelImage = mkDefault true;
|
||||
|
||||
security.allowSimultaneousMultithreading = mkDefault false;
|
||||
|
||||
security.forcePageTableIsolation = mkDefault true;
|
||||
|
||||
# This is required by podman to run containers in rootless mode.
|
||||
security.unprivilegedUsernsClone = mkDefault config.virtualisation.containers.enable;
|
||||
|
||||
security.virtualisation.flushL1DataCache = mkDefault "always";
|
||||
|
||||
security.apparmor.enable = mkDefault true;
|
||||
security.apparmor.killUnconfinedConfinables = mkDefault true;
|
||||
|
||||
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"
|
||||
];
|
||||
|
||||
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"
|
||||
];
|
||||
|
||||
# Hide kptrs even for processes with CAP_SYSLOG
|
||||
boot.kernel.sysctl."kernel.kptr_restrict" = mkOverride 500 2;
|
||||
|
||||
# Disable bpf() JIT (to eliminate spray attacks)
|
||||
boot.kernel.sysctl."net.core.bpf_jit_enable" = mkDefault false;
|
||||
|
||||
# Disable ftrace debugging
|
||||
boot.kernel.sysctl."kernel.ftrace_enabled" = mkDefault 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" = mkDefault true;
|
||||
boot.kernel.sysctl."net.ipv4.conf.all.rp_filter" = mkDefault "1";
|
||||
boot.kernel.sysctl."net.ipv4.conf.default.log_martians" = mkDefault true;
|
||||
boot.kernel.sysctl."net.ipv4.conf.default.rp_filter" = mkDefault "1";
|
||||
|
||||
# Ignore broadcast ICMP (mitigate SMURF)
|
||||
boot.kernel.sysctl."net.ipv4.icmp_echo_ignore_broadcasts" = mkDefault 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" = mkDefault false;
|
||||
boot.kernel.sysctl."net.ipv4.conf.all.secure_redirects" = mkDefault false;
|
||||
boot.kernel.sysctl."net.ipv4.conf.default.accept_redirects" = mkDefault false;
|
||||
boot.kernel.sysctl."net.ipv4.conf.default.secure_redirects" = mkDefault false;
|
||||
boot.kernel.sysctl."net.ipv6.conf.all.accept_redirects" = mkDefault false;
|
||||
boot.kernel.sysctl."net.ipv6.conf.default.accept_redirects" = mkDefault false;
|
||||
|
||||
# Ignore outgoing ICMP redirects (this is ipv4 only)
|
||||
boot.kernel.sysctl."net.ipv4.conf.all.send_redirects" = mkDefault false;
|
||||
boot.kernel.sysctl."net.ipv4.conf.default.send_redirects" = mkDefault false;
|
||||
};
|
||||
imports = [
|
||||
(lib.mkRemovedOptionModule [ "profiles" "hardened" ] ''
|
||||
The hardened profile has been removed, see the backward incompatibilities section of the 26.05 release notes for more information.
|
||||
'')
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -717,7 +717,6 @@ in
|
|||
package = pkgs.hadoop_3_3;
|
||||
};
|
||||
haproxy = runTest ./haproxy.nix;
|
||||
hardened = runTest ./hardened.nix;
|
||||
harmonia = runTest ./harmonia.nix;
|
||||
haste-server = runTest ./haste-server.nix;
|
||||
hbase2 = runTest {
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
name = "hardened";
|
||||
meta = {
|
||||
maintainers = [ ];
|
||||
};
|
||||
|
||||
nodes.machine =
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
users.users.alice = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "proc" ];
|
||||
};
|
||||
users.users.sybil = {
|
||||
isNormalUser = true;
|
||||
group = "wheel";
|
||||
};
|
||||
imports = [ ../modules/profiles/hardened.nix ];
|
||||
environment.memoryAllocator.provider = "graphene-hardened";
|
||||
nix.settings.sandbox = false;
|
||||
virtualisation.emptyDiskImages = [
|
||||
{
|
||||
size = 4096;
|
||||
driveConfig.deviceExtraOpts.serial = "deferred";
|
||||
}
|
||||
];
|
||||
virtualisation.fileSystems = {
|
||||
"/deferred" = {
|
||||
device = "/dev/disk/by-id/virtio-deferred";
|
||||
fsType = "vfat";
|
||||
autoFormat = true;
|
||||
options = [ "noauto" ];
|
||||
};
|
||||
};
|
||||
boot.extraModulePackages = pkgs.lib.optional (pkgs.lib.versionOlder config.boot.kernelPackages.kernel.version "5.6") config.boot.kernelPackages.wireguard;
|
||||
boot.kernelModules = [ "wireguard" ];
|
||||
};
|
||||
|
||||
testScript =
|
||||
let
|
||||
hardened-malloc-tests = pkgs.graphene-hardened-malloc.ld-preload-tests;
|
||||
in
|
||||
''
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
|
||||
|
||||
with subtest("AppArmor profiles are loaded"):
|
||||
machine.succeed("systemctl status apparmor.service")
|
||||
|
||||
|
||||
# AppArmor securityfs
|
||||
with subtest("AppArmor securityfs is mounted"):
|
||||
machine.succeed("mountpoint -q /sys/kernel/security")
|
||||
machine.succeed("cat /sys/kernel/security/apparmor/profiles")
|
||||
|
||||
|
||||
# Test loading out-of-tree modules
|
||||
with subtest("Out-of-tree modules can be loaded"):
|
||||
machine.succeed("grep -Fq wireguard /proc/modules")
|
||||
|
||||
|
||||
# Test kernel module hardening
|
||||
with subtest("No more kernel modules can be loaded"):
|
||||
# note: this better a be module we normally wouldn't load ...
|
||||
machine.wait_for_unit("disable-kernel-module-loading.service")
|
||||
machine.fail("modprobe dccp")
|
||||
|
||||
|
||||
# Test userns
|
||||
with subtest("User namespaces are restricted"):
|
||||
machine.succeed("unshare --user true")
|
||||
machine.fail("su -l alice -c 'unshare --user true'")
|
||||
|
||||
|
||||
# Test dmesg restriction
|
||||
with subtest("Regular users cannot access dmesg"):
|
||||
machine.fail("su -l alice -c dmesg")
|
||||
|
||||
|
||||
# Test access to kcore
|
||||
with subtest("Kcore is inaccessible as root"):
|
||||
machine.fail("cat /proc/kcore")
|
||||
|
||||
|
||||
# Test deferred mount
|
||||
with subtest("Deferred mounts work"):
|
||||
machine.fail("mountpoint -q /deferred") # was deferred
|
||||
machine.systemctl("start deferred.mount")
|
||||
machine.succeed("mountpoint -q /deferred") # now mounted
|
||||
|
||||
|
||||
# Test Nix dæmon usage
|
||||
with subtest("nix-daemon cannot be used by all users"):
|
||||
machine.fail("su -l nobody -s /bin/sh -c 'nix --extra-experimental-features nix-command ping-store'")
|
||||
machine.succeed("su -l alice -c 'nix --extra-experimental-features nix-command ping-store'")
|
||||
|
||||
|
||||
# Test kernel image protection
|
||||
with subtest("The kernel image is protected"):
|
||||
machine.fail("systemctl hibernate")
|
||||
machine.fail("systemctl kexec")
|
||||
|
||||
|
||||
with subtest("The hardened memory allocator works"):
|
||||
machine.succeed("${hardened-malloc-tests}/bin/run-tests")
|
||||
'';
|
||||
}
|
||||
|
|
@ -6,8 +6,6 @@
|
|||
# boot via sysctl or kernel cmdline are left enabled here, for improved
|
||||
# flexibility.
|
||||
#
|
||||
# See also <nixos/modules/profiles/hardened.nix>
|
||||
|
||||
{
|
||||
stdenv,
|
||||
lib,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue