Files organization update
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
disko.devices = {
|
||||
# Boot disk LVM configuration
|
||||
lvm_vg = {
|
||||
pool = {
|
||||
type = "lvm_vg";
|
||||
lvs = {
|
||||
root = {
|
||||
size = "100%FREE";
|
||||
content.type = "filesystem";
|
||||
content.format = "btrfs";
|
||||
content.mountpoint = "/";
|
||||
};
|
||||
swap = {
|
||||
size = "16G";
|
||||
content.type = "swap";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
disk = {
|
||||
# Boot disk
|
||||
"boot-1" = {
|
||||
type = "disk";
|
||||
device = "${BOOT_DISK_1_ID}";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
ESP = {
|
||||
size = "1G";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [ "umask=0077" ];
|
||||
};
|
||||
};
|
||||
luks = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted-boot-1";
|
||||
settings = {
|
||||
keyFile = "/etc/secrets/disks/boot-1";
|
||||
allowDiscards = true;
|
||||
};
|
||||
content = {
|
||||
type = "lvm_pv";
|
||||
vg = "pool";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
disko.devices = {
|
||||
disk = {
|
||||
"boot-1" = {
|
||||
type = "disk";
|
||||
device = "${BOOT_DISK_1_ID}";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
ESP = {
|
||||
size = "1G";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [ "umask=0077" ];
|
||||
};
|
||||
};
|
||||
crypt_p1 = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted-boot-1";
|
||||
settings = {
|
||||
keyFile = "/etc/secrets/disks/boot-1";
|
||||
allowDiscards = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
"boot-2" = {
|
||||
type = "disk";
|
||||
device = "${BOOT_DISK_2_ID}";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
crypt_p2 = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted-boot-2";
|
||||
settings = {
|
||||
keyFile = "/etc/secrets/disks/boot-2";
|
||||
allowDiscards = true;
|
||||
};
|
||||
content = {
|
||||
type = "btrfs";
|
||||
extraArgs = [
|
||||
"-d raid1"
|
||||
"/dev/mapper/crypted-boot-1"
|
||||
];
|
||||
subvolumes = {
|
||||
"/root" = {
|
||||
mountpoint = "/";
|
||||
mountOptions = [
|
||||
"rw"
|
||||
"relatime"
|
||||
"ssd"
|
||||
];
|
||||
};
|
||||
"/swap" = {
|
||||
mountpoint = "none";
|
||||
swap.size = "16G";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
"content-${j}" = {
|
||||
type = "disk";
|
||||
device = "${CONTENT_DISK_ID}";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
luks = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted-content-${j}";
|
||||
initrdUnlock = false;
|
||||
settings = {
|
||||
keyFile = "/etc/secrets/disks/content-${j}";
|
||||
allowDiscards = ${ALLOW_DISCARDS:-false};
|
||||
crypttabExtraOpts = [ "nofail" "noauto" ];
|
||||
};
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "xfs";
|
||||
mountpoint = "/mnt/content-${j}";
|
||||
mountOptions = [ "nofail" "noauto" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
# Data mirror disks
|
||||
"content-1" = {
|
||||
type = "disk";
|
||||
device = "/dev/disk/by-id/ata-FUJITSU_MHW2120BH_NZ2TT772DCN5";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
"data-1" = {
|
||||
size = "$PARTITION_SIZE";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted-content-1";
|
||||
settings.keyFile = "/etc/secrets/disks/content-1";
|
||||
content = {
|
||||
type = "mdraid";
|
||||
name = "data-storage";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
"parity-1" = {
|
||||
type = "disk";
|
||||
device = "/dev/disk/by-id/ata-TOSHIBA_MQ04ABF100_X7CXT0D8T";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
"parity-1" = {
|
||||
size = "$PARTITION_SIZE";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted-parity-1";
|
||||
settings.keyFile = "/etc/secrets/disks/parity-1";
|
||||
content = {
|
||||
type = "mdraid";
|
||||
name = "data-storage";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# RAID 1 Configuration
|
||||
mdadm = {
|
||||
"data-storage" = {
|
||||
type = "mdadm";
|
||||
level = 1;
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "xfs";
|
||||
mountpoint = "/mnt/data-storage";
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
"parity-${j}" = {
|
||||
type = "disk";
|
||||
device = "${PARITY_DISK_ID}";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
luks = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "crypted-parity-${j}";
|
||||
initrdUnlock = false;
|
||||
settings = {
|
||||
keyFile = "/etc/secrets/disks/parity-${j}";
|
||||
allowDiscards = ${ALLOW_DISCARDS:-false};
|
||||
crypttabExtraOpts = [ "nofail" "noauto" ];
|
||||
};
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "xfs";
|
||||
mountpoint = "/mnt/parity-${j}";
|
||||
mountOptions = [ "nofail" "noauto" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,124 @@
|
||||
{ lib, utils, config, ... }:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
head
|
||||
optional
|
||||
foldl'
|
||||
nameValuePair
|
||||
listToAttrs
|
||||
optionals
|
||||
concatStringsSep
|
||||
sortOn
|
||||
mkIf
|
||||
mkEnableOption
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
systemIdentity = {
|
||||
enable = mkEnableOption "hashing of Luks values into PCR 15 and subsequent checks";
|
||||
pcr15 = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
The expected value of PCR 15 after all luks partitions have been unlocked
|
||||
Should be a 64 character hex string as ouput by the sha256 field of
|
||||
'systemd-analyze pcrs 15 --json=short'
|
||||
If set to null (the default) it will not check the value.
|
||||
If the check fails the boot will abort and you will be dropped into an emergency shell, if enabled.
|
||||
In ermergency shell type:
|
||||
'systemctl disable check-pcrs'
|
||||
'systemctl default'
|
||||
to continue booting
|
||||
'';
|
||||
};
|
||||
};
|
||||
boot.initrd.luks.devices = lib.mkOption {
|
||||
type =
|
||||
with lib.types;
|
||||
attrsOf (submodule {
|
||||
config.crypttabExtraOpts = optionals config.systemIdentity.enable [
|
||||
"tpm2-device=auto"
|
||||
"tpm2-measure-pcr=yes"
|
||||
];
|
||||
});
|
||||
};
|
||||
};
|
||||
config = mkIf config.systemIdentity.enable {
|
||||
boot.kernelParams = [
|
||||
"rd.luks=no"
|
||||
];
|
||||
boot.initrd.systemd.services =
|
||||
{
|
||||
check-pcrs = mkIf (config.systemIdentity.pcr15 != null) {
|
||||
script = ''
|
||||
echo "Checking PCR 15 value"
|
||||
if [[ $(systemd-analyze pcrs 15 --json=short | jq -r ".[0].sha256") != "${config.systemIdentity.pcr15}" ]] ; then
|
||||
echo "PCR 15 check failed"
|
||||
exit 1
|
||||
else
|
||||
echo "PCR 15 check succeeded"
|
||||
fi
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
unitConfig.DefaultDependencies = "no";
|
||||
after = [ "cryptsetup.target" ];
|
||||
before = [ "sysroot.mount" ];
|
||||
requiredBy = [ "sysroot.mount" ];
|
||||
};
|
||||
}
|
||||
// (listToAttrs (
|
||||
foldl' (
|
||||
acc: attrs:
|
||||
let
|
||||
extraOpts = attrs.value.crypttabExtraOpts ++ (optional attrs.value.allowDiscards "discard");
|
||||
cfg = config.boot.initrd.systemd;
|
||||
in
|
||||
[
|
||||
(nameValuePair "cryptsetup-${attrs.name}" {
|
||||
unitConfig = {
|
||||
Description = "Cryptography setup for ${attrs.name}";
|
||||
DefaultDependencies = "no";
|
||||
IgnoreOnIsolate = true;
|
||||
Conflicts = [ "umount.target" ];
|
||||
BindsTo = "${utils.escapeSystemdPath attrs.value.device}.device";
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
TimeoutSec = "infinity";
|
||||
KeyringMode = "shared";
|
||||
OOMScoreAdjust = 500;
|
||||
ImportCredential = "cryptsetup.*";
|
||||
ExecStart = ''${cfg.package}/bin/systemd-cryptsetup attach '${attrs.name}' '${attrs.value.device}' '-' '${concatStringsSep "," extraOpts}' '';
|
||||
ExecStop = ''${cfg.package}/bin/systemd-cryptsetup detach '${attrs.name}' '';
|
||||
};
|
||||
after =
|
||||
[
|
||||
"cryptsetup-pre.target"
|
||||
"systemd-udevd-kernel.socket"
|
||||
"${utils.escapeSystemdPath attrs.value.device}.device"
|
||||
]
|
||||
++ (optional cfg.tpm2.enable "systemd-tpm2-setup-early.service")
|
||||
++ optional (acc != [ ]) "${(head acc).name}.service";
|
||||
before = [
|
||||
"blockdev@dev-mapper-${attrs.name}.target"
|
||||
"cryptsetup.target"
|
||||
"umount.target"
|
||||
];
|
||||
wants = [ "blockdev@dev-mapper-${attrs.name}.target" ];
|
||||
requiredBy = [ "sysroot.mount" ];
|
||||
})
|
||||
]
|
||||
++ acc
|
||||
) [ ] (sortOn (x: x.name) (lib.attrsets.attrsToList config.boot.initrd.luks.devices))
|
||||
));
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
### --> MergerFS setup
|
||||
fileSystems."/mnt/data" = {
|
||||
device = "/mnt/content-*";
|
||||
fsType = "fuse.mergerfs";
|
||||
options = [
|
||||
"category.create=ff"
|
||||
"cache.files=partial"
|
||||
"dropcacheonclose=true"
|
||||
"defaults"
|
||||
"noauto"
|
||||
"nofail"
|
||||
"allow_other"
|
||||
"moveonenospc=1"
|
||||
"minfreespace=50G"
|
||||
"func.getattr=newest"
|
||||
"fsname=mergerfs_data"
|
||||
"x-mount.mkdir"
|
||||
"x-systemd.automount"
|
||||
"x-systemd.requires=mount-dependencies.service"
|
||||
];
|
||||
};
|
||||
### MergerFS setup <--
|
||||
|
||||
systemd.services.mount-dependencies = {
|
||||
description = "This service will mount the encrypted disks for mergerFS";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
# Bring the service up
|
||||
ExecStart = pkgs.writeShellScript "mount-disks" ''
|
||||
$MOUNT_DEPENDENCIES_START
|
||||
'';
|
||||
# Take it down gracefully
|
||||
ExecStop = pkgs.writeShellScript "unmount-disks" ''
|
||||
$MOUNT_DEPENDENCIES_STOP
|
||||
'';
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
||||
### --> SnapRAID setup
|
||||
services.snapraid = {
|
||||
enable = true;
|
||||
contentFiles = [
|
||||
$SNAPRAID_CONTENT_FILES
|
||||
];
|
||||
parityFiles = [
|
||||
$SNAPRAID_PARITY_FILES
|
||||
];
|
||||
dataDisks = {
|
||||
$SNAPRAID_DATA_DISKS
|
||||
};
|
||||
};
|
||||
### SnapRAID setup <--
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
hardDrives = [
|
||||
DISK_LIST
|
||||
];
|
||||
in
|
||||
|
||||
{
|
||||
### --> Disk spindown
|
||||
systemd.services.hd-idle = {
|
||||
description = "External HD spin down daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart =
|
||||
let
|
||||
idleTime = toString 1800;
|
||||
hardDriveParameter = lib.strings.concatMapStringsSep " " (x: "-a ${x} -i ${idleTime}") hardDrives;
|
||||
in
|
||||
"${pkgs.hd-idle}/bin/hd-idle -i 0 ${hardDriveParameter}";
|
||||
};
|
||||
};
|
||||
### Disk spindown <--
|
||||
}
|
||||
Reference in New Issue
Block a user