Posted to Infrastructure on

Convert an Encrypted Secondary SSD into Server Storage

Move an encrypted secondary SSD from desktop-style mounting into a stable server path using LUKS UUIDs, crypttab, fstab, nofail, and explicit reboot validation.

#fedora#linux#local-server#luks#storage#crypttab#fstab

Server Storage Should Behave Like Part of the Server

A secondary disk attached to Fedora Workstation often behaves like desktop storage: GNOME can unlock it, mount it below /run/media/<user>/..., and expose it as an ejectable device.

That is convenient on a workstation. It is a weak long-term model for storage that should behave like infrastructure.

A cleaner server-oriented layout is:

secondary SSD
    │
    └── LUKS container
          │
          └── /dev/mapper/server-storage
                │
                └── ext4
                      │
                      └── /srv/storage

This guide converts an existing LUKS + ext4 disk into system-managed storage without reformatting it.

Within this series, this guide assumes you completed the host and administration baseline through Private Remote Administration with Tailscale. The storage procedure itself does not depend on Tailscale, but it assumes the host is stable and recoverable before you change boot-time disk configuration.

Example values: Hostnames, usernames, addresses, interface names, device paths, and other identifiers are illustrative unless explicitly described as software defaults. Discover the values on your own systems before running commands.

Know Exactly Which Disk You Are About to Change

This guide assumes:

  • the secondary drive already has a LUKS container;
  • the filesystem inside that container is already ext4;
  • the drive is not the Fedora system disk.

The procedure preserves existing data. If the disk contains anything irreplaceable, back it up before you start.

The most dangerous mistake here is confusing the secondary disk with the encrypted system disk. Stable identifiers are preferable to raw kernel names such as sda or sdb for persistent configuration because those names can change across boots or hardware changes.1 Never infer the target of a disk command from drive order or a kernel name alone. Confirm size, model, and the existing LUKS signature first.

Start by inventorying the physical disks and filesystems:

lsblk -o NAME,SIZE,FSTYPE,LABEL,UUID,MOUNTPOINTS,MODEL
sudo blkid

For example:

sda              1T                               Secondary SSD
└─sda1           1T   crypto_LUKS  <LUKS_UUID>

nvme0n1          500G                             System NVMe
├─nvme0n1p1      ...
├─nvme0n1p2      ...
└─nvme0n1p3      ...  crypto_LUKS  <SYSTEM_LUKS_UUID>
  └─luks-...      ...  btrfs       Fedora root/home

Record the secondary disk's LUKS UUID separately from any filesystem UUID inside it. cryptsetup and systemd both support LUKS UUIDs so persistent configuration does not have to depend on a transient /dev/sdX name.2

Desktop Mount State Is a Clue, Not the Final Configuration

Inspect current mounts and device-mapper volumes:

findmnt | grep -E '/run/media|mapper'
lsblk -o NAME,FSTYPE,LABEL,UUID,MOUNTPOINTS

If GNOME already mounted the disk under /run/media/<user>/..., unmount it before changing the permanent configuration.

If the encrypted partition is already open under another mapper name, note that name and close it only after any mounted filesystem has been safely unmounted.

Give the LUKS Mapping a Name You Control

Assume for example purposes only that the encrypted partition is /dev/sda1. Unlock it as server-storage:

sudo cryptsetup open /dev/sda1 server-storage
lsblk -o NAME,SIZE,FSTYPE,LABEL,UUID,MOUNTPOINTS

cryptsetup open maps the decrypted device under /dev/mapper/<name>; that mapper name is an administrator choice.2:1

A successful mapping looks like:

sda1                    crypto_LUKS  <LUKS_UUID>
└─server-storage        ext4         <FILESYSTEM_UUID>

Inspect the inner filesystem directly:

sudo blkid /dev/mapper/server-storage

Keep the two identifiers straight:

outer LUKS UUID       → /etc/crypttab → identify/unlock encrypted container
inner filesystem UUID → /etc/fstab    → identify/mount filesystem

That distinction is the backbone of the permanent configuration.

Inspect Existing Data Before You Make Anything Persistent

Create a temporary inspection mount and look at the contents:

sudo mkdir -p /mnt/server-storage-check
sudo mount /dev/mapper/server-storage /mnt/server-storage-check
ls -la /mnt/server-storage-check
df -h /mnt/server-storage-check

If this is not the filesystem you expected, stop. Unmount it, close the mapping with sudo cryptsetup close server-storage, and correct the disk identification before going further. A mapping left open on the wrong disk makes the next cryptsetup open under the same name fail, and it invites configuration against the wrong UUIDs.

If it is the expected filesystem, unmount it and remove the temporary directory:

sudo umount /mnt/server-storage-check
sudo rmdir /mnt/server-storage-check

Leave /dev/mapper/server-storage open. The configuration test later in this guide mounts it through /etc/fstab without unlocking it again.

Choose a Stable Home for Server Data

The Filesystem Hierarchy Standard defines /srv for site-specific data served by the system, making /srv/storage a defensible location for server-owned data.3

Create it:

sudo mkdir -p /srv/storage

A future layout could become:

/srv/storage/
├── data/
├── backups/
├── archives/
├── media/
├── services/
└── vm-storage/

Do not create every directory preemptively. Add namespaces when real workloads need them.

Back Up the Files That Can Affect Boot

Before editing /etc/fstab or /etc/crypttab, preserve known-good copies:

sudo cp -a /etc/fstab "/etc/fstab.backup-$(date +%F-%H%M%S)"
sudo test -f /etc/crypttab && sudo cp -a /etc/crypttab "/etc/crypttab.backup-$(date +%F-%H%M%S)"

A typo in either file can make boot behavior confusing. Backups are cheap; recovering from a half-understood boot dependency is not.

Define the Encrypted Device Boundary

Edit /etc/crypttab as root, for example with sudoedit /etc/crypttab, and add a line using the outer LUKS UUID:

server-storage UUID=<SECONDARY_LUKS_UUID> none luks,nofail

crypttab entries are structured as volume name, encrypted device, key source, and options. When the key source is none and no matching key file is available, systemd falls back to asking for a passphrase during boot.4

The fields mean:

server-storage       mapper name created below /dev/mapper/
UUID=...             encrypted block device identity
none                 no explicit plaintext key-file path
luks,nofail          LUKS mapping; failure is non-fatal to boot

nofail matters because this is optional secondary storage. systemd documents that a crypttab device marked nofail is not a hard dependency of cryptsetup.target; boot may continue if the volume is unavailable or not unlocked.4:1

There is a second half to the rule: if an /etc/fstab mount depends on this encrypted device, the mount needs nofail too or the mount can still make boot fail.4:2

Define the Filesystem Mount Boundary

Edit /etc/fstab as root, for example with sudoedit /etc/fstab, and add a line using the inner filesystem UUID:

UUID=<EXT4_FILESYSTEM_UUID> /srv/storage ext4 defaults,nofail,x-gvfs-hide 0 2

The important options are:

  • defaults — ordinary ext4 mount defaults;
  • nofail — successful boot does not depend on this mount;
  • x-gvfs-hide — ask GVfs-aware desktop UI not to present the volume as ordinary removable storage;
  • final 2 — place this non-root ext filesystem in normal filesystem-check ordering.

systemd's mount documentation defines nofail as making the mount wanted rather than required by the normal filesystem targets.5

GNOME's GVfs volume-monitor documentation recognizes x-gvfs-hide for suppressing a device from the desktop UI and recommends stable /dev/disk/... identifiers over raw sda, sdb, and similar names for persistent entries.1:1

Test the Configuration Before You Reboot

The mapper is still open from the inspection step, so you can test the fstab entry without unlocking the disk again. If you closed it, reopen it with cryptsetup open first. Reload generated unit state, mount the configured filesystem, and validate the result:

sudo systemctl daemon-reload
sudo mount /srv/storage
findmnt /srv/storage
df -h /srv/storage
sudo mount -a

A successful mount shows /srv/storage with source /dev/mapper/server-storage and filesystem type ext4. No output from mount -a usually means there was no mount error, but findmnt is still the better proof that the intended target is live.

Keep the Mount Root System-Owned

Do not hand the entire filesystem to one interactive login user just because that user is doing the setup.

A simple starting point is to create workload directories beneath the mount:

sudo mkdir -p /srv/storage/data /srv/storage/backups

If a specific non-root account should write to those directories directly, delegate only them. admin is the example account; replace it with the intended real account before running the command:

sudo chown admin:admin /srv/storage/data /srv/storage/backups
ls -ld /srv/storage /srv/storage/data /srv/storage/backups

Keeping the mount root under system ownership leaves room for dedicated service accounts and tighter permissions later.

Prove Non-Root Read and Write Access

As the intended non-root user:

touch /srv/storage/data/server-storage-test
ls -l /srv/storage/data/server-storage-test
rm /srv/storage/data/server-storage-test

A configuration that mounts successfully but cannot support the intended workload is not finished.

The Boot Sequence Is the Design

With the crypttab and fstab configuration above, the secondary disk is not silently decrypted by itself.

A normal encrypted-root plus encrypted-secondary boot can look like:

power on
  ↓
unlock Fedora root LUKS volume (if root encryption was chosen)
  ↓
Fedora/systemd begins boot
  ↓
crypttab requests secondary-storage passphrase
  ↓
/dev/mapper/server-storage appears
  ↓
fstab mounts it at /srv/storage
  ↓
remaining services continue/start

If you skip or fail the secondary-storage unlock, nofail on both the crypt mapping and mount allows Fedora to continue booting.4:35:1

This is independent of desktop login. System services such as sshd, tailscaled, and libvirt should not depend on a GNOME session.

Optional Storage Can Be Unlocked Later

If you leave the secondary volume locked at boot, unlock it later and mount the configured target. Address the encrypted device by the LUKS UUID you recorded rather than assuming the kernel still calls it /dev/sda1:

sudo cryptsetup open /dev/disk/by-uuid/<SECONDARY_LUKS_UUID> server-storage
sudo mount /srv/storage
findmnt /srv/storage

Locking the Disk Starts with a Clean Unmount

Before locking the encrypted volume, make sure no process is using it:

sudo umount /srv/storage
sudo cryptsetup close server-storage
lsblk

The server-storage mapper should disappear. If umount refuses, find the process holding the filesystem open instead of forcing the mapper closed beneath active I/O.

A Reboot Proves the Permanent Path

Reboot and exercise the exact behavior you designed:

sudo reboot

If the Fedora root volume is encrypted, unlock it. When prompted for the secondary volume, enter its passphrase if you want /srv/storage immediately available.

After boot:

lsblk -o NAME,SIZE,FSTYPE,LABEL,UUID,MOUNTPOINTS
findmnt /srv/storage
df -h /srv/storage
systemctl --failed

When the secondary disk is unlocked, the chain looks like:

secondary disk
└── LUKS
    └── /dev/mapper/server-storage
        └── ext4
            └── /srv/storage

unexpected failed systemd units: 0

If you skipped the secondary unlock on purpose, /srv/storage being absent is not evidence of a failed Fedora boot.

Auto-Unlock Changes the Threat Model

A server can auto-unlock secondary LUKS volumes using approaches such as a key file protected by the already-encrypted root disk, TPM2, FIDO2, PKCS#11 hardware, or other supported systemd and cryptsetup mechanisms.

systemd-cryptenroll documents TPM2, FIDO2, PKCS#11, password, and recovery-key enrollment for LUKS2 volumes.6

Those mechanisms can be appropriate, but they change the security and recovery model. This baseline keeps the second passphrase explicit so you understand the dependency before automating it.

Encryption Recovery Includes the LUKS Header

LUKS metadata is necessary to interpret the encrypted volume. The cryptsetup project warns that header damage can make encrypted data unrecoverable even when the passphrase is still known, and it documents header-backup and restore operations.7

That does not mean you should paste a generic header-backup command from an article and call recovery solved. It means the recovery plan must account for passphrase or key recovery, LUKS metadata integrity, independent backups of important data, and tested restoration.

Encryption protects confidentiality. It does not replace data backup.

Keep VM Storage a Separate Decision

The existing libvirt default pool can remain under /var/lib/libvirt/images on the main system disk.

Moving VM disks to /srv/storage is a separate capacity, performance, and lifecycle decision. If you later do it, create a dedicated directory, apply the correct SELinux context, and define a libvirt storage pool deliberately.

Do not point libvirt at an arbitrary server-data directory and then disable SELinux when labels do not match expectations.

Footnotes

Scroll to article content with footnote reference 1

GNOME's GVfs source includes an explicit what-is-shown.txt policy reference for desktop-visible disks. It documents x-gvfs-hide/x-gvfs-show and recommends stable /dev/disk/... identifiers for persistent fstab configuration instead of raw kernel names such as sda and sdb.

Scroll to article content with footnote reference 1 Scroll to article content with footnote reference 1
Scroll to article content with footnote reference 2

The upstream cryptsetup(8) documentation defines LUKS open/close operations and UUID handling. The mapper name passed to cryptsetup open becomes the /dev/mapper/<name> device used by the decrypted filesystem.

Scroll to article content with footnote reference 2 Scroll to article content with footnote reference 2
Scroll to article content with footnote reference 3

The Filesystem Hierarchy Standard 3.0 defines /srv as the location for site-specific data served by the system. That makes /srv/storage a defensible convention, not a mandatory Linux mount point.

Scroll to article content with footnote reference 3
Scroll to article content with footnote reference 4

systemd's crypttab(5) documentation defines the volume-name encrypted-device key-file options fields, UUID device selection, passphrase fallback when no key file is available, and nofail. It also explicitly warns that a dependent fstab mount needs its own nofail if boot should continue when the encrypted device is not unlocked.

Scroll to article content with footnote reference 4 Scroll to article content with footnote reference 4 Scroll to article content with footnote reference 4 Scroll to article content with footnote reference 4
Scroll to article content with footnote reference 5

systemd's systemd.mount(5) documentation explains how /etc/fstab is translated into mount units and defines nofail as making a mount non-required by the normal filesystem target so boot may continue if it fails.

Scroll to article content with footnote reference 5 Scroll to article content with footnote reference 5
Scroll to article content with footnote reference 6

systemd-cryptenroll(1) documents supported enrollment mechanisms including TPM2, FIDO2, PKCS#11, passwords, and recovery keys for LUKS2 volumes.

Scroll to article content with footnote reference 6
Scroll to article content with footnote reference 7

The upstream cryptsetup FAQ emphasizes that LUKS metadata/header damage can make data unrecoverable and discusses header backup/restore and recovery limits. Treat a header backup as sensitive recovery material and store it independently from the disk it protects.

Scroll to article content with footnote reference 7

Down the rabbit hole

Fedora Local Server Guide

Posted to Infrastructure on

Maintenance, Validation, and the Known-Good Fedora Server Baseline

Posted to Infrastructure on
Browse all posts

Map the system you need

Describe the product, workflow, integration, or operation you are building—and where the current system loses power. Include the people, tools, boundaries, constraints, and outcome that matter.

Every message is reviewed. Responses are limited.

Press Escape to close preview popover.