Add initial support for encrypted filesystems.
This commit is contained in:
parent
db108dde93
commit
b9067e7f13
@ -20,6 +20,7 @@ with lib; {
|
|||||||
./fudo/global.nix
|
./fudo/global.nix
|
||||||
./fudo/grafana.nix
|
./fudo/grafana.nix
|
||||||
./fudo/hosts.nix
|
./fudo/hosts.nix
|
||||||
|
./fudo/host-filesystems.nix
|
||||||
./fudo/initrd-network.nix
|
./fudo/initrd-network.nix
|
||||||
./fudo/ipfs.nix
|
./fudo/ipfs.nix
|
||||||
./fudo/kdc.nix
|
./fudo/kdc.nix
|
||||||
|
69
lib/fudo/host-filesystems.nix
Normal file
69
lib/fudo/host-filesystems.nix
Normal 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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -102,6 +102,21 @@ in {
|
|||||||
default = { };
|
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 {
|
secret-users = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
description = "List of users with read-access to secrets.";
|
description = "List of users with read-access to secrets.";
|
||||||
|
@ -2,6 +2,55 @@
|
|||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
rec {
|
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 = { ... }: {
|
masterKeyOpts = { ... }: {
|
||||||
options = with types; {
|
options = with types; {
|
||||||
key-path = mkOption {
|
key-path = mkOption {
|
||||||
@ -177,6 +226,12 @@ rec {
|
|||||||
|
|
||||||
android-dev = mkEnableOption "Enable ADB on the host.";
|
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
|
initrd-network = let
|
||||||
keypair-type = { ... }: {
|
keypair-type = { ... }: {
|
||||||
options = {
|
options = {
|
||||||
@ -202,6 +257,10 @@ rec {
|
|||||||
type = (submodule keypair-type);
|
type = (submodule keypair-type);
|
||||||
description = "SSH host key pair to use for initrd.";
|
description = "SSH host key pair to use for initrd.";
|
||||||
};
|
};
|
||||||
|
interface = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = "Name of interface on which to listen for connections.";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user