File system mounts as non-root user/group

Goal

High level

I’m attempting to mount a file system as a non root user/group. Specifically, I’ve created a group with a gid=500, and I pass the mount option gid=500 mode=775 to allow any users of that group to have full rwx permissions on that file system location. I add the user account to that group as well of course.

Specifics

With help of the community up to this point, I’ve managed to configure a system I’m getting more happy and comfortable with that combines using an encrypted Btrfs fs and tmpfs as root fs. I don’t use Btrfs snapshots yet and won’t need rollbacks mentioned in the first article as my root is a tmpfs. So that’s the approach I’m shooting for.

  • Any state I want to keep around will be bind mounted from /persist (btrfs subvolume) or defined in configuration.nix. I also want normal non root users to be able to write to this directory. Or be able to mount subdirectories of this subvolume to the ~/Documents folder for non root users.
  • My hardware-configuration.nix and relative parts of configuration.nix are included below.

Outcome

I tried some of the options mentioned in this Nixpkgs Github issue, but it didn’t work as I’d expected. Unless I’m not understanding the mount man page, I can use the mode option to set permissions on the resulting directory.

My non root user cannot write to the /persist mount which is specified with options gid=501 mode=775 in my hardware-configuration.nix and I have a group defined as users.groups.persist.gid = 501. My non root user has users.users.myUser.extraGroups = [ "persist" ] defined in configuration.nix.

The reason my user cannot write to /persist is because it’s actually not mounted with a gid=501 mode=775. Those options are indeed listed in the /etc/fstab file generated, but running ls -l / or mount (prints mounts and options) does not show consistent results with what’s specified in the /etc/fstab file.

Output of ls -l /:

[...]$ ls -l /
total 4
drwxr-xr-x   2 root root   60 May 15 11:48 bin
drwxr-xr-x   6 root root 4096 Dec 31  1969 boot
drwxr-xr-x  19 root root 3640 May 15 11:38 dev
drwxr-xr-x  28 root root 1540 May 15 11:48 etc
drwxr-xr-x   4 root root   80 May 15 11:38 home
drwxr-xr-x   1 root root   16 Apr 23 23:21 nix
drwxr-xr-x   1 root root   22 May 15 11:51 persist
dr-xr-xr-x 291 root root    0 May 15 11:38 proc
drwx------   5 root root  120 May 15 11:48 root
drwxr-xr-x  24 root root  680 May 15 11:53 run
drwxr-xr-x   1 root root    0 Apr 23 22:12 snapshots
drwxr-xr-x   2 root root   40 May 15 11:38 srv
dr-xr-xr-x  13 root root    0 May 15 11:38 sys
drwxrwxrwt  19 root root  580 May 15 13:47 tmp
drwxr-xr-x   3 root root   60 May 15 11:38 usr
drwxr-xr-x   9 root root  240 May 15 11:38 var

Output of cat /etc/fstab:

[...]$ cat /etc/fstab
# This is a generated file.  Do not edit!
#
# To make changes, edit the fileSystems and swapDevices NixOS options
# in your /etc/nixos/configuration.nix file.

# Filesystems.
none / tmpfs defaults,size=2G,mode=755 0 0
/dev/disk/by-uuid/6581-E393 /boot vfat defaults 0 2
/persist/etc/machine-id /etc/machine-id none bind,mode=775,gid=500 0 0
/persist/etc/nixos /etc/nixos none bind,mode=775,gid=500 0 0
/persist/etc/ssh /etc/ssh none bind,mode=775,gid=500 0 0
/dev/mapper/crypt-system /nix btrfs subvol=@nixos/@nix,autodefrag,compress=zstd,ssd,discard,noatime 0 0
/dev/mapper/crypt-system /persist btrfs subvol=@nixos/@persist,autodefrag,compress=zstd,ssd,discard,noatime,mode=775,gid=501 0 0
/dev/mapper/crypt-system /snapshots btrfs subvol=@nixos/@snapshots,autodefrag,compress=zstd,ssd,discard,noatime,mode=775,gid=500 0 0
/dev/mapper/crypt-system /var/log btrfs subvol=@nixos/@log,ssd,noatime,mode=775,gid=500 0 0


# Swap devices.
/dev/disk/by-uuid/30fe863f-431a-43b9-ab6d-529d0b4414a3 none swap defaults

Output of mount command:

[...]$ mount
devtmpfs on /dev type devtmpfs (rw,nosuid,size=399980k,nr_inodes=997788,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=3,mode=620,ptmxmode=666)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /run type tmpfs (rw,nosuid,nodev,size=1999888k,mode=755)
none on /run/keys type ramfs (rw,nosuid,nodev,relatime,mode=750)
tmpfs on /run/wrappers type tmpfs (rw,nodev,relatime,mode=755)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
none on / type tmpfs (rw,relatime,size=2097152k,mode=755)
/dev/mapper/crypt-system on /nix type btrfs (rw,noatime,compress=zstd:3,ssd,discard,space_cache,autodefrag,subvolid=258,subvol=/@nixos/@nix)
/dev/mapper/crypt-system on /var/log type btrfs (rw,noatime,compress=zstd:3,ssd,discard,space_cache,autodefrag,subvolid=259,subvol=/@nixos/@log)
/dev/mapper/crypt-system on /nix/store type btrfs (ro,noatime,compress=zstd:3,ssd,discard,space_cache,autodefrag,subvolid=258,subvol=/@nixos/@nix)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)
efivarfs on /sys/firmware/efi/efivars type efivarfs (rw,nosuid,nodev,noexec,relatime)
none on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime,mode=700)
debugfs on /sys/kernel/debug type debugfs (rw,nosuid,nodev,noexec,relatime)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw,nosuid,nodev,noexec,relatime)
configfs on /sys/kernel/config type configfs (rw,nosuid,nodev,noexec,relatime)
/dev/mapper/crypt-system on /persist type btrfs (rw,noatime,compress=zstd:3,ssd,discard,space_cache,autodefrag,subvolid=261,subvol=/@nixos/@persist)
/dev/nvme0n1p1 on /boot type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
/dev/mapper/crypt-system on /snapshots type btrfs (rw,noatime,compress=zstd:3,ssd,discard,space_cache,autodefrag,subvolid=262,subvol=/@nixos/@snapshots)
/dev/mapper/crypt-system on /etc/machine-id type btrfs (rw,noatime,compress=zstd:3,ssd,discard,space_cache,autodefrag,subvolid=261,subvol=/@nixos/@persist)
/dev/mapper/crypt-system on /etc/nixos type btrfs (rw,noatime,compress=zstd:3,ssd,discard,space_cache,autodefrag,subvolid=261,subvol=/@nixos/@persist)
/dev/mapper/crypt-system on /etc/ssh type btrfs (rw,noatime,compress=zstd:3,ssd,discard,space_cache,autodefrag,subvolid=261,subvol=/@nixos/@persist)
tmpfs on /run/user/1001 type tmpfs (rw,nosuid,nodev,relatime,size=799952k,nr_inodes=199988,mode=700,uid=1001,gid=100)

Background

OS: NixOS
NIX_CHANNEL: nixos-unstable (21.05)
hardware-configuration.nix:

{ config, lib, pkgs, modulesPath, ... }:

{
  imports = [ 
    (modulesPath + "/installer/scan/not-detected.nix")
    "${builtins.fetchGit { url = "https://github.com/NixOS/nixos-hardware.git"; }}/system76"
  ];

  boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
  boot.initrd.kernelModules = [ ];
  boot.kernelModules = [ "kvm-intel" ];
  boot.extraModulePackages = [ ];

  boot.loader.grub.enable = true;
  boot.loader.grub.version = 2;
  boot.loader.grub.device = "nodev";
  boot.loader.grub.efiSupport = true;
  boot.loader.grub.enableCryptodisk = true;
  boot.loader.grub.efiInstallAsRemovable = true;
  #boot.loader.efi.canTouchEfiVariables = true;
  boot.kernelPackages = pkgs.linuxPackages_latest; 

  hardware.system76.enableAll = true;

  boot.initrd.luks.devices."crypt-system".device = "/dev/disk/by-uuid/7bd4e969-7bab-442d-a660-83e841a068c5";

  users.groups = {
    sys.gid = 500;
    persist.gid = 501;
  };

  fileSystems = {
    "/" = { 
      device = "none";
      fsType = "tmpfs"; # `ncdu -exr /` or `find -mmin -5 .`
      options = ["defaults" "size=2G" "mode=755" ];
    };
    "/boot" = { 
      device = "/dev/disk/by-uuid/6581-E393";
      fsType = "vfat";
    };
    "/var/log" = { 
      device = "/dev/mapper/crypt-system";
      fsType = "btrfs";
      options = [ "subvol=@nixos/@log" "ssd" "noatime" "mode=775" "gid=500" ];
      neededForBoot = true;
    };
    "/snapshots" = { 
      device = "/dev/mapper/crypt-system";
      fsType = "btrfs";
      options = [ "subvol=@nixos/@snapshots" "autodefrag" "compress=zstd" "ssd" "discard" "noatime" "mode=775" "gid=500" ];
    };
    "/persist" = { 
      device = "/dev/mapper/crypt-system";
      fsType = "btrfs";
      options = [ "subvol=@nixos/@persist" "autodefrag" "compress=zstd" "ssd" "discard" "noatime" "mode=775" "gid=501" ];
    };
    "/nix" = { 
      device = "/dev/mapper/crypt-system";
      fsType = "btrfs";
      options = [ "subvol=@nixos/@nix" "autodefrag" "compress=zstd" "ssd" "discard" "noatime" ];
    };
    "/etc/nixos" = { 
      device = "/persist/etc/nixos";
      fsType = "none";
      options = [ "bind" ]; 
    };
    "/etc/machine-id" = {
      device = "/persist/etc/machine-id";
      fsType = "none";
      options = [ "bind" ]; 
    };
    "/etc/ssh" = { 
      device = "/persist/etc/ssh";
      fsType = "none";
      options = [ "bind" ]; 
    };
  };

  swapDevices = [ 
    { device = "/dev/disk/by-uuid/30fe863f-431a-43b9-ab6d-529d0b4414a3"; }
  ];

  powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
}

configuration.nix (partial):

  users.users.myUser = {
    description = "Full Name";
    isNormalUser = true;
    extraGroups = [ "wheel" "sys" "persist" ];
    initialHashedPassword = "..."; # nix-shell --run "mkpasswd -m SHA-512 -s" -p mkpasswd
    packages = with pkgs; [ "..." ];
  };

Let me know if anymore information is needed. I’m trying to figure out whether or not I should post this as a bug on Github. But, I want to make sure this isn’t just a blunder on my part (often is with NixOS).

Thanks, Tyler

2 Likes