cleanup gocryptfs mounting
there's possibly some latent issues. i think my changes to the gocryptfs package *might* not be necessary: if you work via the fuse front-door, it's a lot harder to get it into these weird places.
This commit is contained in:
@@ -58,19 +58,8 @@
|
|||||||
};
|
};
|
||||||
# enable zsh completions
|
# enable zsh completions
|
||||||
environment.pathsToLink = [ "/share/zsh" ];
|
environment.pathsToLink = [ "/share/zsh" ];
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
# required for pam_mount
|
|
||||||
gocryptfs
|
|
||||||
];
|
|
||||||
|
|
||||||
# link debug symbols into /run/current-system/sw/lib/debug
|
# link debug symbols into /run/current-system/sw/lib/debug
|
||||||
# hopefully picked up by gdb automatically?
|
# hopefully picked up by gdb automatically?
|
||||||
environment.enableDebugInfo = true;
|
environment.enableDebugInfo = true;
|
||||||
|
|
||||||
security.pam.mount.enable = true;
|
|
||||||
# security.pam.mount.debugLevel = 1;
|
|
||||||
# security.pam.enableSSHAgentAuth = true; # ??
|
|
||||||
# needed for `allow_other` in e.g. gocryptfs mounts
|
|
||||||
# or i guess going through mount.fuse sets suid so that's not necessary?
|
|
||||||
# programs.fuse.userAllowOther = true;
|
|
||||||
}
|
}
|
||||||
|
@@ -54,24 +54,41 @@ in
|
|||||||
shell = pkgs.zsh;
|
shell = pkgs.zsh;
|
||||||
openssh.authorizedKeys.keys = builtins.attrValues (import ../../modules/pubkeys.nix).users;
|
openssh.authorizedKeys.keys = builtins.attrValues (import ../../modules/pubkeys.nix).users;
|
||||||
|
|
||||||
|
# some other nix pam users:
|
||||||
|
# - <https://github.com/g00pix/nixconf/blob/32c04f6fa843fed97639dd3f09e157668d3eea1f/profiles/sshfs.nix>
|
||||||
|
# - <https://github.com/lourkeur/distro/blob/11173454c6bb50f7ccab28cc2c757dca21446d1d/nixos/profiles/users/louis-full.nix>
|
||||||
|
# - <https://github.com/dnr/sample-nix-code/blob/03494480c1fae550c033aa54fd96aeb3827761c5/nixos/laptop.nix>
|
||||||
pamMount = {
|
pamMount = {
|
||||||
# mount encrypted stuff at login
|
# mount encrypted stuff at login
|
||||||
# requires that login password == fs encryption password
|
# requires that login password == fs encryption password
|
||||||
# fstype = "fuse";
|
fstype = "fuse";
|
||||||
|
path = "gocryptfs#/nix/persist/home/colin/private";
|
||||||
# path = "${pkgs.gocryptfs}/bin/gocryptfs#/nix/persist/home/colin/private";
|
# path = "${pkgs.gocryptfs}/bin/gocryptfs#/nix/persist/home/colin/private";
|
||||||
fstype = "fuse.gocryptfs";
|
# fstype = "fuse.gocryptfs";
|
||||||
path = "/nix/persist/home/colin/private";
|
# path = "/nix/persist/home/colin/private";
|
||||||
mountpoint = "/home/colin/private";
|
mountpoint = "/home/colin/private";
|
||||||
options="nodev,nosuid,quiet,allow_other";
|
# without allow_other, *root* isn't allowed to list anything in ~/private.
|
||||||
|
# which is weird (root can just `su colin`), but probably doesn't *hurt* anything -- right?
|
||||||
|
options="nodev,nosuid,quiet"; # allow_other
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# required for PAM to find gocryptfs
|
||||||
|
security.pam.mount.additionalSearchPaths = [ pkgs.gocryptfs ];
|
||||||
|
security.pam.mount.enable = true;
|
||||||
|
# security.pam.mount.debugLevel = 1;
|
||||||
|
# security.pam.enableSSHAgentAuth = true; # ??
|
||||||
|
# needed for `allow_other` in e.g. gocryptfs mounts
|
||||||
|
# or i guess going through mount.fuse sets suid so that's not necessary?
|
||||||
|
# programs.fuse.userAllowOther = true;
|
||||||
|
|
||||||
sane.impermanence.home-dirs = [
|
sane.impermanence.home-dirs = [
|
||||||
# cache is probably too big to fit on the tmpfs
|
# cache is probably too big to fit on the tmpfs
|
||||||
# TODO: we could bind-mount it to something which gets cleared per boot, though.
|
# TODO: we could bind-mount it to something which gets cleared per boot, though.
|
||||||
".cache"
|
".cache"
|
||||||
".cargo"
|
".cargo"
|
||||||
".rustup"
|
".rustup"
|
||||||
|
# TODO: move this to ~/private!
|
||||||
".local/share/keyrings"
|
".local/share/keyrings"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@@ -2,9 +2,14 @@
|
|||||||
|
|
||||||
lib.mkIf config.sane.home-manager.enable
|
lib.mkIf config.sane.home-manager.enable
|
||||||
{
|
{
|
||||||
# we don't need to full zsh dir -- just the history file --
|
sane.impermanence.home-dirs = [
|
||||||
# but zsh will sometimes backup the history file and we get fewer errors if we do proper mounts instead of symlinks.
|
# we don't need to full zsh dir -- just the history file --
|
||||||
sane.impermanence.home-dirs = [ ".local/share/zsh" ];
|
# but zsh will sometimes backup the history file and we get fewer errors if we do proper mounts instead of symlinks.
|
||||||
|
# TODO: should be private?
|
||||||
|
".local/share/zsh"
|
||||||
|
# cache gitstatus otherwise p10k fetched it from the net EVERY BOOT
|
||||||
|
".cache/gitstatus"
|
||||||
|
];
|
||||||
|
|
||||||
home-manager.users.colin.programs.zsh = {
|
home-manager.users.colin.programs.zsh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@@ -114,26 +114,46 @@ in
|
|||||||
})
|
})
|
||||||
|
|
||||||
(lib.mkIf cfg.encrypted-clear-on-boot {
|
(lib.mkIf cfg.encrypted-clear-on-boot {
|
||||||
system.activationScripts.mountEncryptedClearedOnBoot.text = let
|
# without this, we get `fusermount: fuse device not found, try 'modprobe fuse' first`.
|
||||||
gocryptfs = "${pkgs.gocryptfs}/bin/gocryptfs";
|
# - that only happens after a activation-via-boot -- not activation-after-rebuild-switch.
|
||||||
backing = "/nix/persist/crypt/cleared-on-boot";
|
# it seems likely that systemd loads `fuse` by default. see:
|
||||||
mountpt = encrypted-clear-on-boot-base;
|
# - </etc/systemd/system/sysinit.target.wants/sys-fs-fuse-connections.mount>
|
||||||
|
# - triggers: /etc/systemd/system/modprobe@.service
|
||||||
|
# - calls `modprobe`
|
||||||
|
# note: even `boot.kernelModules = ...` isn't enough: that option creates /etc/modules-load.d/, which is ingested only by systemd.
|
||||||
|
# note: `boot.initrd.availableKernelModules` ALSO isn't enough: idk why.
|
||||||
|
boot.initrd.kernelModules = [ "fuse" ];
|
||||||
|
|
||||||
|
system.activationScripts.mountEncryptedClearedOnBoot =
|
||||||
|
let
|
||||||
pass-template = "/tmp/encrypted-clear-on-boot.XXXXXXXX";
|
pass-template = "/tmp/encrypted-clear-on-boot.XXXXXXXX";
|
||||||
tmpdir = "/tmp/impermanence";
|
tmpdir = "/tmp/impermanence";
|
||||||
in ''
|
script = pkgs.writeShellApplication {
|
||||||
if !(test -e ${mountpt}/init)
|
name = "mountEncryptedClearedOnBoot";
|
||||||
then
|
runtimeInputs = with pkgs; [ fuse gocryptfs ];
|
||||||
mkdir -p ${backing} ${mountpt} ${tmpdir}
|
text = ''
|
||||||
rm -rf ${backing}/*
|
backing="$1"
|
||||||
passfile=$(mktemp ${pass-template})
|
mountpt="$2"
|
||||||
dd if=/dev/random bs=128 count=1 | base64 --wrap=0 > $passfile
|
if ! test -e "$mountpt"/init
|
||||||
${gocryptfs} -quiet -passfile $passfile -init ${backing}
|
then
|
||||||
${gocryptfs} -quiet -passfile $passfile ${backing} ${mountpt}
|
mkdir -p "$backing" "$mountpt" ${tmpdir}
|
||||||
rm $passfile
|
rm -rf "''${backing:?}"/*
|
||||||
unset passfile
|
passfile=$(mktemp ${pass-template})
|
||||||
touch ${mountpt}/init
|
dd if=/dev/random bs=128 count=1 | base64 --wrap=0 > "$passfile"
|
||||||
fi
|
gocryptfs -quiet -passfile "$passfile" -init "$backing"
|
||||||
'';
|
mount.fuse "gocryptfs#$backing" "$mountpt" -o nodev,nosuid,allow_other,passfile="$passfile"
|
||||||
|
# mount -t fuse.gocryptfs -o passfile="$passfile" "$backing" "$mountpt"
|
||||||
|
# gocryptfs -quiet -passfile "$passfile" "$backing" "$mountpt"
|
||||||
|
rm "$passfile"
|
||||||
|
unset passfile
|
||||||
|
touch "$mountpt"/init
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
deps = [ "modprobe" ];
|
||||||
|
text = ''${script}/bin/mountEncryptedClearedOnBoot /nix/persist/crypt/cleared-on-boot "${encrypted-clear-on-boot-base}"'';
|
||||||
|
};
|
||||||
|
|
||||||
system.activationScripts.createPersistentStorageDirs.deps = [ "mountEncryptedClearedOnBoot" ];
|
system.activationScripts.createPersistentStorageDirs.deps = [ "mountEncryptedClearedOnBoot" ];
|
||||||
})
|
})
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
{ gocryptfs, fuse, util-linux, lib }:
|
{ fuse, gocryptfs, util-linux, lib }:
|
||||||
|
|
||||||
(gocryptfs.overrideAttrs (upstream: {
|
(gocryptfs.overrideAttrs (upstream: {
|
||||||
# XXX `su colin` hangs when pam_mount tries to mount a gocryptfs system
|
# XXX `su colin` hangs when pam_mount tries to mount a gocryptfs system
|
||||||
@@ -7,9 +7,14 @@
|
|||||||
# propagating util-linux through either `environment.systemPackages` or `security.pam.mount.additionalSearchPaths` DOES NOT WORK.
|
# propagating util-linux through either `environment.systemPackages` or `security.pam.mount.additionalSearchPaths` DOES NOT WORK.
|
||||||
#
|
#
|
||||||
# TODO: see about upstreaming this
|
# TODO: see about upstreaming this
|
||||||
|
#
|
||||||
|
# additionally, we need /run/wrappers/bin EXPLICITLY in PATH, for when we run not as root.
|
||||||
|
# but we want to keep `fuse` for when we ARE running as root -- particularly during an activation script BEFORE the wrappers exist.
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
wrapProgram $out/bin/gocryptfs \
|
wrapProgram $out/bin/gocryptfs \
|
||||||
--suffix PATH : ${lib.makeBinPath [ fuse util-linux ]}
|
--suffix PATH : ${lib.makeBinPath [ util-linux ]} \
|
||||||
|
--suffix PATH : /run/wrappers/bin \
|
||||||
|
--suffix PATH : ${lib.makeBinPath [ fuse ]}
|
||||||
ln -s $out/bin/gocryptfs $out/bin/mount.fuse.gocryptfs
|
ln -s $out/bin/gocryptfs $out/bin/mount.fuse.gocryptfs
|
||||||
'';
|
'';
|
||||||
}))
|
}))
|
||||||
|
Reference in New Issue
Block a user