at 23.05-pre 3.5 kB view raw
1import ./make-test-python.nix ({ pkgs, ... } : { 2 name = "hardened"; 3 meta = with pkgs.lib.maintainers; { 4 maintainers = [ joachifm ]; 5 }; 6 7 nodes.machine = 8 { lib, pkgs, config, ... }: 9 with lib; 10 { users.users.alice = { isNormalUser = true; extraGroups = [ "proc" ]; }; 11 users.users.sybil = { isNormalUser = true; group = "wheel"; }; 12 imports = [ ../modules/profiles/hardened.nix ]; 13 environment.memoryAllocator.provider = "graphene-hardened"; 14 nix.settings.sandbox = false; 15 nixpkgs.overlays = [ 16 (final: super: { 17 dhcpcd = super.dhcpcd.override { enablePrivSep = false; }; 18 }) 19 ]; 20 virtualisation.emptyDiskImages = [ 4096 ]; 21 boot.initrd.postDeviceCommands = '' 22 ${pkgs.dosfstools}/bin/mkfs.vfat -n EFISYS /dev/vdb 23 ''; 24 virtualisation.fileSystems = { 25 "/efi" = { 26 device = "/dev/disk/by-label/EFISYS"; 27 fsType = "vfat"; 28 options = [ "noauto" ]; 29 }; 30 }; 31 boot.extraModulePackages = 32 optional (versionOlder config.boot.kernelPackages.kernel.version "5.6") 33 config.boot.kernelPackages.wireguard; 34 boot.kernelModules = [ "wireguard" ]; 35 }; 36 37 testScript = 38 let 39 hardened-malloc-tests = pkgs.graphene-hardened-malloc.ld-preload-tests; 40 in 41 '' 42 machine.wait_for_unit("multi-user.target") 43 44 45 with subtest("AppArmor profiles are loaded"): 46 machine.succeed("systemctl status apparmor.service") 47 48 49 # AppArmor securityfs 50 with subtest("AppArmor securityfs is mounted"): 51 machine.succeed("mountpoint -q /sys/kernel/security") 52 machine.succeed("cat /sys/kernel/security/apparmor/profiles") 53 54 55 # Test loading out-of-tree modules 56 with subtest("Out-of-tree modules can be loaded"): 57 machine.succeed("grep -Fq wireguard /proc/modules") 58 59 60 # Test kernel module hardening 61 with subtest("No more kernel modules can be loaded"): 62 # note: this better a be module we normally wouldn't load ... 63 machine.wait_for_unit("disable-kernel-module-loading.service") 64 machine.fail("modprobe dccp") 65 66 67 # Test userns 68 with subtest("User namespaces are restricted"): 69 machine.succeed("unshare --user true") 70 machine.fail("su -l alice -c 'unshare --user true'") 71 72 73 # Test dmesg restriction 74 with subtest("Regular users cannot access dmesg"): 75 machine.fail("su -l alice -c dmesg") 76 77 78 # Test access to kcore 79 with subtest("Kcore is inaccessible as root"): 80 machine.fail("cat /proc/kcore") 81 82 83 # Test deferred mount 84 with subtest("Deferred mounts work"): 85 machine.fail("mountpoint -q /efi") # was deferred 86 machine.execute("mkdir -p /efi") 87 machine.succeed("mount /dev/disk/by-label/EFISYS /efi") 88 machine.succeed("mountpoint -q /efi") # now mounted 89 90 91 # Test Nix dæmon usage 92 with subtest("nix-daemon cannot be used by all users"): 93 machine.fail("su -l nobody -s /bin/sh -c 'nix --extra-experimental-features nix-command ping-store'") 94 machine.succeed("su -l alice -c 'nix --extra-experimental-features nix-command ping-store'") 95 96 97 # Test kernel image protection 98 with subtest("The kernel image is protected"): 99 machine.fail("systemctl hibernate") 100 machine.fail("systemctl kexec") 101 102 103 with subtest("The hardened memory allocator works"): 104 machine.succeed("${hardened-malloc-tests}/bin/run-tests") 105 ''; 106})