chore(koi): ecryptfs -> gocryptfs
This commit is contained in:
parent
3e5ff3efb3
commit
00473ef07a
6 changed files with 93 additions and 131 deletions
|
@ -37,7 +37,7 @@ in {
|
|||
"--group-add=${builtins.toString config.users.groups.geesefs.gid}"
|
||||
];
|
||||
};
|
||||
systemd.services.docker-navidrome.requires = [ "ecryptfs.service" ];
|
||||
systemd.services.docker-navidrome.requires = [ "gocryptfs.service" ];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /srv/navidrome 0755 ${builtins.toString UID} ${builtins.toString UID} -"
|
||||
|
|
|
@ -51,7 +51,7 @@ in {
|
|||
"${builtins.toString WEBDAV_PORT}:80"
|
||||
];
|
||||
};
|
||||
systemd.services.docker-sftpgo.requires = [ "ecryptfs.service" ];
|
||||
systemd.services.docker-sftpgo.requires = [ "gocryptfs.service" ];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /srv/sftpgo/data 0700 ${builtins.toString UID} ${builtins.toString UID} -"
|
||||
|
|
|
@ -9,7 +9,7 @@ in {
|
|||
extraGroups = [ "geesefs" ];
|
||||
};
|
||||
|
||||
systemd.services.docker-slskd.requires = [ "ecryptfs.service" ];
|
||||
systemd.services.docker-slskd.requires = [ "gocryptfs.service" ];
|
||||
virtualisation.oci-containers.containers.slskd = {
|
||||
image = "slskd/slskd:0.21.4.65534-9a68c184";
|
||||
volumes = [
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{
|
||||
imports = [
|
||||
(abs "services/geesefs.nix")
|
||||
(abs "services/ecryptfs.nix")
|
||||
(abs "services/gocryptfs.nix")
|
||||
];
|
||||
|
||||
desu.secrets.geesefs-credentials = {};
|
||||
|
@ -40,12 +40,12 @@
|
|||
mountPoint = "/mnt/s3-desu-priv";
|
||||
};
|
||||
|
||||
services.ecryptfs = {
|
||||
services.gocryptfs = {
|
||||
enable = true;
|
||||
cipherDir = "/mnt/s3-desu-priv/encrypted";
|
||||
passphrasePath = config.desu.secrets.desu-priv-passphrase.path;
|
||||
masterKeyPath = "/mnt/s3-desu-priv/encrypted.key";
|
||||
cipherDir = "/mnt/s3-desu-priv/encrypted-go";
|
||||
mountPoint = "/mnt/s3-desu-priv-encrypted";
|
||||
passwordFile = config.desu.secrets.desu-priv-passphrase.path;
|
||||
extraOptions = [ "-allow_other" ];
|
||||
};
|
||||
systemd.services.ecryptfs-setup.requires = [ "geesefs.service" ];
|
||||
systemd.services.gocryptfs.requires = [ "geesefs.service" ];
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
# todo: ideally we should support multiple encrypted directories
|
||||
options.services.ecryptfs = with lib; {
|
||||
enable = mkEnableOption "ecryptfs";
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.ecryptfs;
|
||||
defaultText = "pkgs.ecryptfs";
|
||||
description = "ecryptfs package";
|
||||
};
|
||||
serviceName = mkOption {
|
||||
type = types.str;
|
||||
default = "ecryptfs";
|
||||
description = "ecryptfs service name";
|
||||
};
|
||||
|
||||
cipherDir = mkOption {
|
||||
type = types.str;
|
||||
description = "path to the directory used as the underlying encrypted storage";
|
||||
};
|
||||
|
||||
passphrasePath = mkOption {
|
||||
type = types.str;
|
||||
description = "path to the file containing the passphrase (this can be rotated down the line without needing to re-encrypt the data)";
|
||||
};
|
||||
|
||||
masterKeyPath = mkOption {
|
||||
type = types.str;
|
||||
description = "path to the master key (i.e. the wrapped passphrase file)";
|
||||
};
|
||||
|
||||
mountPoint = mkOption {
|
||||
type = types.str;
|
||||
description = "ecryptfs mount point";
|
||||
};
|
||||
|
||||
encryptFilenames = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "whether to encrypt filenames";
|
||||
};
|
||||
|
||||
encryptionKeySize = mkOption {
|
||||
type = types.int;
|
||||
default = 32;
|
||||
description = "size of the encryption key in bytes";
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "additional options to pass to ecryptfs";
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
cfg = config.services.ecryptfs;
|
||||
|
||||
mountOptions =
|
||||
[
|
||||
"ecryptfs_sig=$sig"
|
||||
"ecryptfs_key_bytes=${toString cfg.encryptionKeySize}"
|
||||
"ecryptfs_cipher=aes"
|
||||
"ecryptfs_unlink_sigs"
|
||||
"no_sig_cache"
|
||||
] ++
|
||||
(lib.optional cfg.encryptFilenames "ecryptfs_fnek_sig=$sig") ++
|
||||
cfg.extraOptions;
|
||||
in {
|
||||
systemd.services.${cfg.serviceName} = {
|
||||
description = "${cfg.serviceName} setup";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ cfg.package pkgs.keyutils ];
|
||||
serviceConfig = {
|
||||
User = "root";
|
||||
Group = "root";
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStop = "${pkgs.utillinux}/bin/umount ${lib.escapeShellArg cfg.mountPoint}";
|
||||
};
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
if [ ! -f ${lib.escapeShellArg cfg.masterKeyPath} ]; then
|
||||
echo "master key file ${cfg.masterKeyPath} does not exist, generating..."
|
||||
passphrase=$(${pkgs.coreutils}/bin/head -c 48 /dev/random | base64)
|
||||
wrapping_passphrase=$(cat ${lib.escapeShellArg cfg.passphrasePath})
|
||||
printf "%s\n%s" "$passphrase" "$wrapping_passphrase" | ecryptfs-wrap-passphrase ${lib.escapeShellArg cfg.masterKeyPath} -
|
||||
fi
|
||||
|
||||
if [ ! -d ${lib.escapeShellArg cfg.cipherDir} ]; then
|
||||
echo "ecryptfs: directory ${lib.escapeShellArg cfg.cipherDir} does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d ${lib.escapeShellArg cfg.mountPoint} ]; then
|
||||
mkdir -p ${lib.escapeShellArg cfg.mountPoint}
|
||||
fi
|
||||
|
||||
result=$(cat ${lib.escapeShellArg cfg.passphrasePath} | ecryptfs-insert-wrapped-passphrase-into-keyring ${lib.escapeShellArg cfg.masterKeyPath} -)
|
||||
sig=$(echo "$result" | sed -r 's/^.*sig \[(.*)\] into.*$/\1/')
|
||||
|
||||
if [ -z "$sig" ]; then
|
||||
echo "failed to extract signature"
|
||||
echo "$result"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Keyring signature: $sig"
|
||||
|
||||
if ! keyctl show | grep -q "_uid.0"; then
|
||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=870126
|
||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=870335
|
||||
keyctl link @u @s
|
||||
fi
|
||||
|
||||
${pkgs.utillinux}/bin/mount -i -t ecryptfs ${lib.escapeShellArg cfg.cipherDir} ${lib.escapeShellArg cfg.mountPoint} -o "${lib.concatStringsSep "," mountOptions}"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
84
services/gocryptfs.nix
Normal file
84
services/gocryptfs.nix
Normal file
|
@ -0,0 +1,84 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
# todo: ideally we should support multiple encrypted directories
|
||||
options.services.gocryptfs = with lib; {
|
||||
enable = mkEnableOption "gocryptfs";
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.gocryptfs;
|
||||
defaultText = "pkgs.gocryptfs";
|
||||
description = "gocryptfs package";
|
||||
};
|
||||
serviceName = mkOption {
|
||||
type = types.str;
|
||||
default = "gocryptfs";
|
||||
description = "gocryptfs service name";
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.str;
|
||||
description = "path to the file containing the password";
|
||||
};
|
||||
|
||||
cipherDir = mkOption {
|
||||
type = types.str;
|
||||
description = "path to the directory used as the underlying encrypted storage";
|
||||
};
|
||||
|
||||
mountPoint = mkOption {
|
||||
type = types.str;
|
||||
description = "gocryptfs mount point";
|
||||
};
|
||||
|
||||
extraInitOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "additional options to pass to gocryptfs -init";
|
||||
};
|
||||
|
||||
extraOptions = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "additional options to pass to gocryptfs mount";
|
||||
};
|
||||
};
|
||||
|
||||
config = let
|
||||
cfg = config.services.gocryptfs;
|
||||
in {
|
||||
systemd.services.${cfg.serviceName} = {
|
||||
description = "${cfg.serviceName} daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ cfg.package ];
|
||||
serviceConfig = {
|
||||
User = "root";
|
||||
Group = "root";
|
||||
};
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
if [ ! -d ${lib.escapeShellArg cfg.cipherDir} ]; then
|
||||
echo "gocryptfs: directory ${lib.escapeShellArg cfg.cipherDir} does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f ${lib.escapeShellArg cfg.cipherDir}/gocryptfs.conf ]; then
|
||||
echo "gocryptfs: running gocryptfs -init"
|
||||
gocryptfs -init \
|
||||
-passfile ${lib.escapeShellArg cfg.passwordFile} \
|
||||
${builtins.concatStringsSep " " (map lib.escapeShellArg cfg.extraInitOptions)} \
|
||||
${lib.escapeShellArg cfg.cipherDir}
|
||||
fi
|
||||
|
||||
if [ ! -d ${lib.escapeShellArg cfg.mountPoint} ]; then
|
||||
mkdir -p ${lib.escapeShellArg cfg.mountPoint}
|
||||
fi
|
||||
|
||||
gocryptfs -fg -passfile ${lib.escapeShellArg cfg.passwordFile} \
|
||||
${builtins.concatStringsSep " " (map lib.escapeShellArg cfg.extraOptions)} \
|
||||
${lib.escapeShellArg cfg.cipherDir} ${lib.escapeShellArg cfg.mountPoint}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue