Add initial support for encrypted filesystems.

This commit is contained in:
niten 2021-10-17 22:10:26 -07:00
parent db108dde93
commit b9067e7f13
4 changed files with 144 additions and 0 deletions

View File

@ -20,6 +20,7 @@ with lib; {
./fudo/global.nix
./fudo/grafana.nix
./fudo/hosts.nix
./fudo/host-filesystems.nix
./fudo/initrd-network.nix
./fudo/ipfs.nix
./fudo/kdc.nix

View File

@ -0,0 +1,69 @@
{ config, lib, pkgs, ... }:
with lib;
let
hostname = config.instance.hostname;
host-filesystems = config.fudo.hosts.${hostname}.encrypted-filesystems;
in {
config = {
fileSystems = mapAttrs' (filesystem-name: opts:
nameValuePair opts.target-path
{
device = "/dev/mapper/${filesystem-name}";
fsType = opts.filesystem-type;
options = opts.filesystem-options;
})
host-filesystems;
systemd = {
mounts = let
filesystems = mapAttrstoList
(fs: opts: { filesystem = fs; opts = opts; })
host-filesystems;
mounts = concatMap
(fs: mapAttrsToList
(mp: mp-opts:
nameValuePair "${fs.filesystem}-${mp}-mount" {
what = "/dev/mapper/${fs.filesystem}";
type = fs.opts.filesystem-type;
where = mp;
options = concatStringsSep "," (fs.opts.options ++ mp-opts.options);
wantedBy = [ "default.target" ];
description = "${fs.opts.filesystem-type} filesystem on ${filesystem} mounted to ${mp}";
requires = [ "${fs.filesystem}-decrypt.service" ];
})
fs.opts.mountpoints)
filesystems;
in mounts;
services = mapAttrs' (filesystem-name: opts:
nameValuePair "${filesystem-name}-decrypt"
{
wantedBy = [ "default.target" ];
description = "Decrypt the ${filesystem-name} filesystem when the key is available at ${opts.key-path}";
path = with pkgs; [ cryptsetup ];
serviceConfig = {
ExecStart = pkgs.writeShellScript "decrypt-${filesystem-name}.sh" ''
cryptsetup open --type luks --key-file ${opts.key-path} ${opts.device} ${filesystem-name}
'';
ExecStop = pkgs.writeShellScript "close-${filesystem-name}.sh" ''
cryptsetup close /dev/mapper/${filesystem-name}
'';
};
})
host-filesystems;
paths = mapAttrs' (filesystem-name: opts:
nameValuePair "${filesystem-name}-decrypt"
{
wantedBy = [ "default.target" ];
description = "Watch for decryption key, then decrypt the target filesystem.";
pathConfig = {
PathExists = opts.key-path;
Service = "${filesystem-name}-decrypt.service";
};
}) host-filesystems;
};
};
}

View File

@ -102,6 +102,21 @@ in {
default = { };
};
host-deep-secrets = mkOption {
type = attrsOf (attrsOf (submodule secretOpts));
description = ''
Secrets that are only passed during deployment.
These secrets will be passed as nixops deployment secrets,
_unlike_ regular secrets that are passed to hosts as part of
the nixops store, but encrypted with the host SSH key. Regular
secrets are kept secret from normal users. These secrets will
be kept secret from _everybody_. However, they won't be
available on the host at boot until a new deployment occurs.
'';
default = { };
};
secret-users = mkOption {
type = listOf str;
description = "List of users with read-access to secrets.";

View File

@ -2,6 +2,55 @@
with lib;
rec {
encryptedFilesystemOpts = { ... }: let
mountpoint = { mp, ... }: {
options = with types; {
mountpoint = mkOption {
type = str;
description = "Path at which to mount the filesystem.";
default = mp;
};
options = mkOption {
type = listOf str;
description = "List of filesystem options specific to this mountpoint (eg: subvol).";
};
};
};
in {
options = with types; {
device = mkOption {
type = str;
description = "Path to the encrypted device.";
};
key-path = mkOption {
type = str;
description = ''
Path at which to locate the key file.
The filesystem will be decrypted and mounted once available.";
'';
};
filesystem-type = mkOption {
type = str;
description = "Filesystem type of the decrypted filesystem.";
};
options = mkOption {
type = str;
description = "List of filesystem options with which to mount.";
};
mountpoints = mkOption {
type = attrsOf (submodule mountpoint);
description = "A map of mountpoints for this filesystem to fs options. Multiple to support btrfs.";
default = {};
};
};
};
masterKeyOpts = { ... }: {
options = with types; {
key-path = mkOption {
@ -177,6 +226,12 @@ rec {
android-dev = mkEnableOption "Enable ADB on the host.";
encrypted-filesystems = mkOption {
type = attrsOf (submodule encrypteFSOpts);
description = "List of encrypted filesystems to mount on the local host when the key is available.";
default = { };
};
initrd-network = let
keypair-type = { ... }: {
options = {
@ -202,6 +257,10 @@ rec {
type = (submodule keypair-type);
description = "SSH host key pair to use for initrd.";
};
interface = mkOption {
type = str;
description = "Name of interface on which to listen for connections.";
};
};
};