diff options
author | Ryan Lahfa <masterancpp@gmail.com> | 2023-05-14 19:01:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-14 19:01:56 +0200 |
commit | 285330f081169c7a5735465fe640095355896650 (patch) | |
tree | f4892b53873d5afc00d594686c254048821f7db5 /nixos | |
parent | 1ee11b8a31ceb765460c9692cd5b4fa445f71b47 (diff) | |
parent | 445d7cae2aebeabe4f9ba6ecd2f2177ac1be4bcb (diff) |
Merge pull request #230153 from mklca/swap-encrypt-enhancement
nixos/config/swap: improve randomEncrytion
Diffstat (limited to 'nixos')
-rw-r--r-- | nixos/doc/manual/release-notes/rl-2305.section.md | 20 | ||||
-rw-r--r-- | nixos/modules/config/swap.nix | 39 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | nixos/tests/swap-random-encryption.nix | 80 |
4 files changed, 137 insertions, 3 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index c6a264a1b037f..e0f18cca17a11 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -385,6 +385,26 @@ In addition to numerous new and upgraded packages, this release has the followin - `nextcloud` has an option to enable SSE-C in S3. +- NixOS swap partitions with random encryption can now control the sector size, cipher, and key size used to setup the plain encryption device over the + underlying block device rather than allowing them to be determined by `cryptsetup(8)`. One can use these features like so: + + ```nix + { + swapDevices = [ + { + device = "/dev/disk/by-partlabel/swapspace"; + + randomEncryption = { + enable = true; + cipher = "aes-xts-plain64"; + keySize = 512; + sectorSize = 4096; + }; + } + ]; + } + ``` + - `services.peertube` now requires you to specify the secret file `secrets.secretsFile`. It can be generated by running `openssl rand -hex 32`. Before upgrading, read the release notes for PeerTube: - [Release v5.0.0](https://github.com/Chocobozzz/PeerTube/releases/tag/v5.0.0) diff --git a/nixos/modules/config/swap.nix b/nixos/modules/config/swap.nix index 2c9c4c9c1a2d8..5c812a9226e84 100644 --- a/nixos/modules/config/swap.nix +++ b/nixos/modules/config/swap.nix @@ -38,6 +38,34 @@ let ''; }; + keySize = mkOption { + default = null; + example = "512"; + type = types.nullOr types.int; + description = lib.mdDoc '' + Set the encryption key size for the plain device. + + If not specified, the amount of data to read from `source` will be + determined by cryptsetup. + + See `cryptsetup-open(8)` for details. + ''; + }; + + sectorSize = mkOption { + default = null; + example = "4096"; + type = types.nullOr types.int; + description = lib.mdDoc '' + Set the sector size for the plain encrypted device type. + + If not specified, the default sector size is determined from the + underlying block device. + + See `cryptsetup-open(8)` for details. + ''; + }; + source = mkOption { default = "/dev/urandom"; example = "/dev/random"; @@ -157,11 +185,11 @@ let }; - config = rec { + config = { device = mkIf options.label.isDefined "/dev/disk/by-label/${config.label}"; deviceName = lib.replaceStrings ["\\"] [""] (escapeSystemdPath config.device); - realDevice = if config.randomEncryption.enable then "/dev/mapper/${deviceName}" else config.device; + realDevice = if config.randomEncryption.enable then "/dev/mapper/${config.deviceName}" else config.device; }; }; @@ -247,7 +275,12 @@ in ''} ${optionalString sw.randomEncryption.enable '' cryptsetup plainOpen -c ${sw.randomEncryption.cipher} -d ${sw.randomEncryption.source} \ - ${optionalString sw.randomEncryption.allowDiscards "--allow-discards"} ${sw.device} ${sw.deviceName} + '' + concatMapStrings (arg: arg + " \\\n") (flatten [ + (optional (sw.randomEncryption.sectorSize != null) "--sector-size=${toString sw.randomEncryption.sectorSize}") + (optional (sw.randomEncryption.keySize != null) "--key-size=${toString sw.randomEncryption.keySize}") + (optional sw.randomEncryption.allowDiscards "--allow-discards") + ]) + '' + ${sw.device} ${sw.deviceName} mkswap ${sw.realDevice} ''} ''; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 2d9f5318a36d0..20b051c1880e9 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -689,6 +689,7 @@ in { sudo = handleTest ./sudo.nix {}; swap-file-btrfs = handleTest ./swap-file-btrfs.nix {}; swap-partition = handleTest ./swap-partition.nix {}; + swap-random-encryption = handleTest ./swap-random-encryption.nix {}; sway = handleTest ./sway.nix {}; switchTest = handleTest ./switch-test.nix {}; sympa = handleTest ./sympa.nix {}; diff --git a/nixos/tests/swap-random-encryption.nix b/nixos/tests/swap-random-encryption.nix new file mode 100644 index 0000000000000..9e919db65dde8 --- /dev/null +++ b/nixos/tests/swap-random-encryption.nix @@ -0,0 +1,80 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: +{ + name = "swap-random-encryption"; + + nodes.machine = + { config, pkgs, lib, ... }: + { + environment.systemPackages = [ pkgs.cryptsetup ]; + + virtualisation.useDefaultFilesystems = false; + + virtualisation.rootDevice = "/dev/vda1"; + + boot.initrd.postDeviceCommands = '' + if ! test -b /dev/vda1; then + ${pkgs.parted}/bin/parted --script /dev/vda -- mklabel msdos + ${pkgs.parted}/bin/parted --script /dev/vda -- mkpart primary 1MiB -250MiB + ${pkgs.parted}/bin/parted --script /dev/vda -- mkpart primary -250MiB 100% + sync + fi + + FSTYPE=$(blkid -o value -s TYPE /dev/vda1 || true) + if test -z "$FSTYPE"; then + ${pkgs.e2fsprogs}/bin/mke2fs -t ext4 -L root /dev/vda1 + fi + ''; + + virtualisation.fileSystems = { + "/" = { + device = "/dev/disk/by-label/root"; + fsType = "ext4"; + }; + }; + + swapDevices = [ + { + device = "/dev/vda2"; + + randomEncryption = { + enable = true; + cipher = "aes-xts-plain64"; + keySize = 512; + sectorSize = 4096; + }; + } + ]; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + + with subtest("Swap is active"): + # Doesn't matter if the numbers reported by `free` are slightly off due to unit conversions. + machine.succeed("free -h | grep -E 'Swap:\s+2[45][0-9]Mi'") + + with subtest("Swap device has 4k sector size"): + import json + result = json.loads(machine.succeed("lsblk -Jo PHY-SEC,LOG-SEC /dev/mapper/dev-vda2")) + block_devices = result["blockdevices"] + if len(block_devices) != 1: + raise Exception ("lsblk output did not report exactly one block device") + + swapDevice = block_devices[0]; + if not (swapDevice["phy-sec"] == 4096 and swapDevice["log-sec"] == 4096): + raise Exception ("swap device does not have the sector size specified in the configuration") + + with subtest("Swap encrypt has assigned cipher and keysize"): + import re + + results = machine.succeed("cryptsetup status dev-vda2").splitlines() + + cipher_pattern = re.compile(r"\s*cipher:\s+aes-xts-plain64\s*") + if not any(cipher_pattern.fullmatch(line) for line in results): + raise Exception ("swap device encryption does not use the cipher specified in the configuration") + + key_size_pattern = re.compile(r"\s*keysize:\s+512\s+bits\s*") + if not any(key_size_pattern.fullmatch(line) for line in results): + raise Exception ("swap device encryption does not use the key size specified in the configuration") + ''; +}) |