forked from extern/nixos-installer
a4ae2ab551
- disable wip.fs.disks.devices.*.gptOffset (patch broken with 22.11), - add wip.bootloader.extlinux, - add wip.hardware.hetzner-vps profile, - fix wip.services.dropbear.socketActivation,
3.3 KiB
3.3 KiB
/*
mount a -o noexec
Experiment
This is a (so far not successful) experiment to mount (almost) all filesystems as noexec
, nosuid
and nodev
-- and to then deal with the consequences.
Exceptions
/dev
and/dev/pts
needdev
/run/wrappers
needsexec
suid
/run/binfmt
needsexec
/run
/run/user/*
may needexec
(TODO: test)- The Nix build dir (default:
/tmp
) needsexec
(TODO!) - Some parts of
/home/<user>/
will needexec
Implementation
#*/# end of MarkDown, beginning of NixOS module:
dirname: inputs: specialArgs@{ config, pkgs, lib, name, ... }: let inherit (inputs.self) lib; in let
prefix = inputs.config.prefix;
cfg = config.${prefix}.experiments.noexec;
in {
options.${prefix} = { experiments.noexec = {
enable = lib.mkEnableOption "(almost) all filesystems being mounted as »noexec« (and »nosuid« and »nodev«)";
}; };
config = let
in lib.mkIf cfg.enable (lib.mkMerge [ ({
# This was the only "special" mount that did not have »nosuid« and »nodev« set:
systemd.packages = [ (lib.wip.mkSystemdOverride pkgs "dev-hugepages.mount" "[Mount]\nOptions=nosuid,nodev,noexec\n") ];
# And these were missing »noexec«:
boot.specialFileSystems."/dev".options = [ "noexec" ];
boot.specialFileSystems."/dev/shm".options = [ "noexec" ];
boot.specialFileSystems."/run/keys".options = [ "noexec" ];
# Make all "real" FSs »noexec« (if »wip.fs.temproot.enable = true«):
${prefix}.fs.temproot = let
it = { mountOptions = { nosuid = true; noexec = true; nodev = true; }; };
in { temp = it; local = it; remote = it; };
# Ensure that the /nix/store is not »noexec«, even if the FS it is on is:
boot.initrd.postMountCommands = ''
if ! mountpoint -q $targetRoot/nix/store ; then
mount --bind $targetRoot/nix/store $targetRoot/nix/store
fi
mount -o remount,exec $targetRoot/nix/store
'';
# Nix has no (direct) settings to change where the builders have their »/build« bound to, but many builds will need it to be »exec«:
systemd.services.nix-daemon = { # TODO: while noexec on /tmp is the problem, neither of this solve it:
serviceConfig.PrivateTmp = true;
#serviceConfig.PrivateMounts = true; serviceConfig.ExecStartPre = "/run/wrappers/bin/mount -o remount,exec /tmp";
};
nix.allowedUsers = [ "root" "@wheel" ]; # This goes hand-in-hand with setting mounts as »noexec«. Cases where a user other than root should build stuff are probably fairly rare. A "real" user might want to, but that is either already in the wheel(sudo) group, or explicitly adding that user is pretty reasonable.
boot.postBootCommands = ''
# Make the /nix/store non-iterable, to make it harder for unprivileged programs to search the store for programs they should not have access to:
unshare --fork --mount --uts --mount-proc --pid -- ${pkgs.bash}/bin/bash -euc '
mount --make-rprivate / ; mount --bind /nix/store /nix/store ; mount -o remount,rw /nix/store
chmod -f 1770 /nix/store
chmod -f 751 /nix/store/.links
'
'';
}) ]);
}