Merge pull request #10464 from abbradar/encrypted-swap
nixos/swap: refactor, add randomEncryption option
This commit is contained in:
commit
00f79aab90
@ -3,6 +3,84 @@
|
|||||||
with utils;
|
with utils;
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
swapCfg = {config, options, ...}: {
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
device = mkOption {
|
||||||
|
example = "/dev/sda3";
|
||||||
|
type = types.str;
|
||||||
|
description = "Path of the device.";
|
||||||
|
};
|
||||||
|
|
||||||
|
label = mkOption {
|
||||||
|
example = "swap";
|
||||||
|
type = types.str;
|
||||||
|
description = ''
|
||||||
|
Label of the device. Can be used instead of <varname>device</varname>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
size = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = 2048;
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
description = ''
|
||||||
|
If this option is set, ‘device’ is interpreted as the
|
||||||
|
path of a swapfile that will be created automatically
|
||||||
|
with the indicated size (in megabytes) if it doesn't
|
||||||
|
exist.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
priority = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = 2048;
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
description = ''
|
||||||
|
Specify the priority of the swap device. Priority is a value between 0 and 32767.
|
||||||
|
Higher numbers indicate higher priority.
|
||||||
|
null lets the kernel choose a priority, which will show up as a negative value.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
randomEncryption = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Encrypt swap device with a random key. This way you won't have a persistent swap device.
|
||||||
|
|
||||||
|
WARNING: Don't try to hibernate when you have at least one swap partition with
|
||||||
|
this option enabled! We have no way to set the partition into which hibernation image
|
||||||
|
is saved, so if your image ends up on an encrypted one you would lose it!
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
deviceName = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
internal = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
realDevice = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
internal = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = rec {
|
||||||
|
device = mkIf options.label.isDefined
|
||||||
|
"/dev/disk/by-label/${config.label}";
|
||||||
|
deviceName = escapeSystemdPath config.device;
|
||||||
|
realDevice = if config.randomEncryption then "/dev/mapper/${deviceName}" else config.device;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
###### interface
|
###### interface
|
||||||
@ -26,58 +104,7 @@ with lib;
|
|||||||
recommended.
|
recommended.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
type = types.listOf types.optionSet;
|
type = types.listOf (types.submodule swapCfg);
|
||||||
|
|
||||||
options = {config, options, ...}: {
|
|
||||||
|
|
||||||
options = {
|
|
||||||
|
|
||||||
device = mkOption {
|
|
||||||
example = "/dev/sda3";
|
|
||||||
type = types.str;
|
|
||||||
description = "Path of the device.";
|
|
||||||
};
|
|
||||||
|
|
||||||
label = mkOption {
|
|
||||||
example = "swap";
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Label of the device. Can be used instead of <varname>device</varname>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
size = mkOption {
|
|
||||||
default = null;
|
|
||||||
example = 2048;
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
description = ''
|
|
||||||
If this option is set, ‘device’ is interpreted as the
|
|
||||||
path of a swapfile that will be created automatically
|
|
||||||
with the indicated size (in megabytes) if it doesn't
|
|
||||||
exist.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
priority = mkOption {
|
|
||||||
default = null;
|
|
||||||
example = 2048;
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
description = ''
|
|
||||||
Specify the priority of the swap device. Priority is a value between 0 and 32767.
|
|
||||||
Higher numbers indicate higher priority.
|
|
||||||
null lets the kernel choose a priority, which will show up as a negative value.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
device = mkIf options.label.isDefined
|
|
||||||
"/dev/disk/by-label/${config.label}";
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -95,27 +122,37 @@ with lib;
|
|||||||
|
|
||||||
createSwapDevice = sw:
|
createSwapDevice = sw:
|
||||||
assert sw.device != "";
|
assert sw.device != "";
|
||||||
let device' = escapeSystemdPath sw.device; in
|
let realDevice' = escapeSystemdPath sw.realDevice;
|
||||||
nameValuePair "mkswap-${escapeSystemdPath sw.device}"
|
in nameValuePair "mkswap-${sw.deviceName}"
|
||||||
{ description = "Initialisation of Swapfile ${sw.device}";
|
{ description = "Initialisation of swap device ${sw.device}";
|
||||||
wantedBy = [ "${device'}.swap" ];
|
wantedBy = [ "${realDevice'}.swap" ];
|
||||||
before = [ "${device'}.swap" ];
|
before = [ "${realDevice'}.swap" ];
|
||||||
path = [ pkgs.utillinux ];
|
path = [ pkgs.utillinux ] ++ optional sw.randomEncryption pkgs.cryptsetup;
|
||||||
script =
|
script =
|
||||||
''
|
''
|
||||||
if [ ! -e "${sw.device}" ]; then
|
${optionalString (sw.size != null) ''
|
||||||
fallocate -l ${toString sw.size}M "${sw.device}" ||
|
if [ ! -e "${sw.device}" ]; then
|
||||||
dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size}
|
fallocate -l ${toString sw.size}M "${sw.device}" ||
|
||||||
chmod 0600 ${sw.device}
|
dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size}
|
||||||
mkswap ${sw.device}
|
chmod 0600 ${sw.device}
|
||||||
fi
|
${optionalString (!sw.randomEncryption) "mkswap ${sw.realDevice}"}
|
||||||
|
fi
|
||||||
|
''}
|
||||||
|
${optionalString sw.randomEncryption ''
|
||||||
|
echo "secretkey" | cryptsetup luksFormat --batch-mode ${sw.device}
|
||||||
|
echo "secretkey" | cryptsetup luksOpen ${sw.device} ${sw.deviceName}
|
||||||
|
cryptsetup luksErase --batch-mode ${sw.device}
|
||||||
|
mkswap ${sw.realDevice}
|
||||||
|
''}
|
||||||
'';
|
'';
|
||||||
unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ];
|
unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ];
|
||||||
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
|
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
|
||||||
serviceConfig.Type = "oneshot";
|
serviceConfig.Type = "oneshot";
|
||||||
|
serviceConfig.RemainAfterExit = sw.randomEncryption;
|
||||||
|
serviceConfig.ExecStop = optionalString sw.randomEncryption "cryptsetup luksClose ${sw.deviceName}";
|
||||||
};
|
};
|
||||||
|
|
||||||
in listToAttrs (map createSwapDevice (filter (sw: sw.size != null) config.swapDevices));
|
in listToAttrs (map createSwapDevice (filter (sw: sw.size != null || sw.randomEncryption) config.swapDevices));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ let
|
|||||||
preLVMCommands postDeviceCommands postMountCommands kernelModules;
|
preLVMCommands postDeviceCommands postMountCommands kernelModules;
|
||||||
|
|
||||||
resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
|
resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
|
||||||
(filter (sd: sd ? label || hasPrefix "/dev/" sd.device) config.swapDevices);
|
(filter (sd: (sd ? label || hasPrefix "/dev/" sd.device) && !sd.randomEncryption) config.swapDevices);
|
||||||
|
|
||||||
fsInfo =
|
fsInfo =
|
||||||
let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType fs.options ];
|
let f = fs: [ fs.mountPoint (if fs.device != null then fs.device else "/dev/disk/by-label/${fs.label}") fs.fsType fs.options ];
|
||||||
|
@ -174,7 +174,7 @@ in
|
|||||||
|
|
||||||
# Swap devices.
|
# Swap devices.
|
||||||
${flip concatMapStrings config.swapDevices (sw:
|
${flip concatMapStrings config.swapDevices (sw:
|
||||||
"${sw.device} none swap${prioOption sw.priority}\n"
|
"${sw.realDevice} none swap${prioOption sw.priority}\n"
|
||||||
)}
|
)}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user