Mount encrypted swap partitions via gpt-auto

If the auto-discovered swap partition is LUKS encrypted, decrypt it
automatically.

This aligns with the Discoverable Partitions Specification, though I've
also updated it to explicitly mention that LUKS is now supported here.

Since systemd retries any key already in the kernel keyring, if the swap
partition has the same passphrase as the root partition, the user won't
be prompted a second time for a second passphrase.

See https://github.com/systemd/systemd/issues/20019
This commit is contained in:
Hugo Osvaldo Barrera 2021-07-04 16:30:20 +02:00 committed by Lennart Poettering
parent 105a4245ff
commit 8859b8f77a
3 changed files with 19 additions and 10 deletions

View file

@ -73,7 +73,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| `3b8f8425-20e0-4f3b-907f-1a25a76f98e8` | _Server Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/srv/`. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/srv`. |
| `4d21b016-b534-45c2-a9fb-5c16e091fd2d` | _Variable Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/var/` — under the condition that its partition UUID matches the first 128 bit of `HMAC-SHA256(machine-id, 0x4d21b016b53445c2a9fb5c16e091fd2d)` (i.e. the SHA256 HMAC hash of the binary type UUID keyed by the machine ID as read from [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html). This special requirement is made because `/var/` (unlike the other partition types listed here) is inherently private to a specific installation and cannot possibly be shared between multiple OS installations on the same disk, and thus should be bound to a specific instance of the OS, identified by its machine ID. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/var`. |
| `7ec6f557-3bc5-4aca-b293-16ef5df639d1` | _Temporary Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/var/tmp/`. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/tmp`. Note that the intended mount point is indeed `/var/tmp/`, not `/tmp/`. The latter is typically maintained in memory via <tt>tmpfs</tt> and does not require a partition on disk. In some cases it might be desirable to make `/tmp/` persistent too, in which case it is recommended to make it a symlink or bind mount to `/var/tmp/`, thus not requiring its own partition type UUID. |
| `0657fd6d-a4ab-43c4-84e5-0933c84b4f4f` | _Swap_ | Swap | All swap partitions on the disk containing the root partition are automatically enabled. This partition type predates the Discoverable Partitions Specification. |
| `0657fd6d-a4ab-43c4-84e5-0933c84b4f4f` | _Swap_ | Swap, optionally in LUKS | All swap partitions on the disk containing the root partition are automatically enabled. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/swap`. This partition type predates the Discoverable Partitions Specification. |
| `0fc63daf-8483-4772-8e79-3d69d8477de4` | _Generic Linux Data Partitions_ | Any native, optionally in LUKS | No automatic mounting takes place for other Linux data partitions. This partition type should be used for all partitions that carry Linux file systems. The installer needs to mount them explicitly via entries in <tt>/etc/fstab</tt>. Optionally, these partitions may be encrypted with LUKS. This partition type predates the Discoverable Partitions Specification. |
| `c12a7328-f81f-11d2-ba4b-00a0c93ec93b` | _EFI System Partition_ | VFAT | The ESP used for the current boot is automatically mounted to `/efi/` (or `/boot/` as fallback), unless a different partition is mounted there (possibly via `/etc/fstab`, or because the Extended Boot Loader Partition — see below — exists) or the directory is non-empty on the root disk. This partition type is defined by the [UEFI Specification](http://www.uefi.org/specifications). |
| `bc13c2ff-59e6-4262-a352-b275fd6f7172` | _Extended Boot Loader Partition_ | Typically VFAT | The Extended Boot Loader Partition (XBOOTLDR) used for the current boot is automatically mounted to <tt>/boot/</tt>, unless a different partition is mounted there (possibly via <tt>/etc/fstab</tt>) or the directory is non-empty on the root disk. This partition type is defined by the [Boot Loader Specification](https://systemd.io/BOOT_LOADER_SPECIFICATION). |

View file

@ -338,12 +338,14 @@ static int add_partition_mount(
SPECIAL_LOCAL_FS_TARGET);
}
static int add_swap(const char *path) {
_cleanup_free_ char *name = NULL, *unit = NULL;
static int add_swap(DissectedPartition *p) {
const char *what;
_cleanup_free_ char *name = NULL, *unit = NULL, *crypto_what = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(path);
assert(p);
assert(p->node);
/* Disable the swap auto logic if at least one swap is defined in /etc/fstab, see #6192. */
r = fstab_has_fstype("swap");
@ -354,9 +356,17 @@ static int add_swap(const char *path) {
return 0;
}
log_debug("Adding swap: %s", path);
if (streq_ptr(p->fstype, "crypto_LUKS")) {
r = add_cryptsetup("swap", p->node, true, true, &crypto_what);
if (r < 0)
return r;
what = crypto_what;
} else
what = p->node;
r = unit_name_from_path(path, ".swap", &name);
log_debug("Adding swap: %s", what);
r = unit_name_from_path(what, ".swap", &name);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
@ -374,7 +384,7 @@ static int add_swap(const char *path) {
"Description=Swap Partition\n"
"Documentation=man:systemd-gpt-auto-generator(8)\n");
r = generator_write_blockdev_dependency(f, path);
r = generator_write_blockdev_dependency(f, what);
if (r < 0)
return r;
@ -382,7 +392,7 @@ static int add_swap(const char *path) {
"\n"
"[Swap]\n"
"What=%s\n",
path);
what);
r = fflush_and_check(f);
if (r < 0)
@ -703,7 +713,7 @@ static int enumerate_partitions(dev_t devnum) {
return log_error_errno(r, "Failed to dissect: %m");
if (m->partitions[PARTITION_SWAP].found) {
k = add_swap(m->partitions[PARTITION_SWAP].node);
k = add_swap(m->partitions + PARTITION_SWAP);
if (k < 0)
r = k;
}

View file

@ -1077,7 +1077,6 @@ int dissect_image(
continue;
designator = PARTITION_SWAP;
fstype = "swap";
} else if (sd_id128_equal(type_id, GPT_LINUX_GENERIC)) {