CMTAB(5)

🌸 CMTAB(5) β€” User commands 🌸

okay so bestie, welcome to CMTAB(5) β€” the manual page for cmtab, and it's literally the blueprint for all the encrypted filesystems that cryptmount manages. no cap, this file is the group chat where every target spills its secrets. πŸ’…


✨ NAME ✨

cmtab - static information about filesystems managed by cryptmount


πŸ’– DESCRIPTION πŸ’–

okay so here's the tea: info about the encrypted filesystems managed by cryptmount lives in /etc/cryptmount/cmtab. each filesystem gets a target name, and that name is what you pass as an argument to cryptmount. it also shows up in /etc/cryptmount/cmtab in front of a list of parameters that describe where that filesystem is stored and how it's encrypted. 🫢

The format of the cmtab is flexible, with the description of each target being delimited by braces, parameters being specified by KEY=VALUE pairs, and white-space being freely usable. Comments are prefixed by a '#' character, and can start at any point in a line, lasting to the end of the line. The backslash character '\' can be used to ignore any special significance of the following character, for example to include a space in a filename.

/etc/cryptmount/cmtab contains entries of the following form:

TARGET_NAME {
    dev=DEVICE                      # REQUIRED
    flags=FLAG,FLAG,...
    startsector=STARTSECTOR
    numsectors=NUMSECTORS
    loop=LOOPDEV
    dir=MOUNT_POINT                 # REQUIRED
    fstype=TYPE                     # REQUIRED
    mountoptions=MOPT,MOPT,...
    fsckoptions=FOPT;FOPT;...
    supath=SUPATH
    bootaction=BOOTACTION
    cipher=CIPHER
    ivoffset=IVOFFSET
    keyformat=KEYMANAGER
    keyfile=KEYFILE                 # REQUIRED
    keyhash=KEYHASH
    keycipher=KEYCIPHER
    keymaxlen=KEYMAXLEN
    passwdretries=NUMATTEMPTS
}

Some fields, such as 'dev' and 'fstype' are mandatory, although many fields have sensible default values. Depending on the choice of KEYMANAGER, fields such as 'keyhash', 'keycipher', 'keymaxlen' may need to be set explicitly.

Any field which contains non-numerical values (e.g. not 'startsector', 'ivoffset' etc.) can contain references to environmental variables of the form $(HOME). The following variables are recognized, all based on the characteristics of the user currently running cryptmount:

  • $(HOME) β€” the home directory, as obtained from /etc/passwd
  • $(UID) β€” the numerical identifier of the user
  • $(USERNAME) β€” the printable name of the user
  • $(GID) β€” the numerical identifier of the user's current group
  • $(GROUPNAME) β€” the printable name of the user's current group

πŸ¦‹ TARGET DEFINITIONS πŸ¦‹

The components in each target definition have the following meaning:

  • TARGET_NAME { ... } β€” specifies the name that cryptmount uses to refer to a particular filesystem, with configuration options for that filesystem contained within the matching braces. The special name "_DEFAULTS_" may be used to set default values in subsequent targets for various parameters such as 'flags', 'fstype', 'mountoptions', 'cipher', 'keyformat', 'keyhash', 'keycipher', 'keymaxlen', 'passwdretries'. Note that if the "_DEFAULTS_" target appears more than once, each will undo the effects of previous default values - i.e. this pseudo-target does not operate incrementally.
  • dev=DEVICE β€” (required) sets the name of the raw device (e.g. /dev/sdb63) or ordinary file (e.g. /home/secretiveuser/private.fs) that contains the encrypted filesystem. Note that it may be useful to use a symbolic name based on an entry beneath /dev/disk/by-id, /dev/disk/by-path, to reduce the risk of device nodes being renamed when new disks are added to the system, etc.
  • flags=FLAG,FLAG,... β€” sets configuration switches, such as
    • "user" (any user can mount),
    • "nouser" (only root can mount),
    • "fsck" (automatically check filesystem before mounting),
    • "nofsck" (don't check filesystem before mounting),
    • "mkswap" (format swap partition before use),
    • "nomkswap" (don't format swap partition)
    • "trim" (enable TRIM/discard support on solid-state disks),
    • "notrim" (disable SSD TRIM/discard support)

This parameter is optional and defaults to "user,fsck,nomkswap,notrim".

  • startsector=STARTSECTOR β€” gives the number of sectors (512-byte blocks) into DEVICE at which the filesystem is to start. This parameter is optional, and defaults to zero.
  • numsectors=NUMSECTORS β€” gives the total length of the filesystem in sectors (512-byte blocks). This parameter is optional, and defaults to -1 which is shorthand for the total available length of DEVICE.
  • loop=LOOPDEV β€” can be used to specify a particular loopback device (e.g. /dev/loop0) to be used when DEVICE is an ordinary file. This parameter is optional and defaults to "auto".
  • dir=MOUNT_POINT β€” (required) specifies the directory onto which the encrypted filesystem will be mounted.
  • fstype=TYPE β€” (required) sets the filesystem type (as used by mount (8)). This must be set to "swap" if the device is to be used as an encrypted swap partition.
  • mountoptions=MOPT,MOPT,... β€” sets filesystem mounting options, as used by mount (8). MOPT can typically be "default", "noatime", "noexec", "nosuid", "ro", "sync" etc.
  • fsckoptions=FOPT;FOPT;... β€” sets filesystem-checking options understood by fsck (8). FOPT can typically be "-C", "-V" etc. Note that the list of fsck options uses semicolons as a separator to allow passing options that themselves contain commas.
  • supath=SUPATH β€” sets the PATH environment variable when running subprocesses as the super-user. This may be necessary when commands such as fsck and mount need to run subcommands (e.g. fsck.ext4). By default, this PATH is set to /sbin:/bin:/usr/sbin:/usr/bin.
  • bootaction=BOOTACTION β€” indicates what action, if any, should be taken for this target on system bootup. BOOTACTION can be one of "none", "mount", "swap" or "prepare", with the default being "none".
  • cipher=CIPHER β€” sets the encryption algorithm used on the DEVICE. The available algorithms are determined by the system kernel. This parameter is optional and defaults to "aes-cbc-plain".
  • keyformat=KEYMANAGER β€” specifies the key management scheme used to interact with the KEYFILE, as discussed in the CHOICE OF KEYMANAGER section below. The set of available key management schemes is determined when cryptmount is built, but may include "libgcrypt", "luks", and "openssl-compat", in addition to "builtin" and "raw". This parameter is optional: if absent, "builtin" will be used on first generating the key, with an automatic choice being made when reading a pre-existing key.
  • keyfile=KEYFILE β€” (required) gives the name of an ordinary file that contains the key used by the CIPHER algorithm to decrypt the filesystem. This key is itself encrypted in a way specified by the KEYHASH and KEYCIPHER
  • ivoffset=IVOFFSET β€” sets the offset added to the sector-number used in constructing the cipher algorithm's initialization vector. This parameter is optional, and defaults to 0.
  • keyhash=KEYHASH β€” is the hashing algorithm used to turn the user's password into the decryption key used by the KEYCIPHER algorithm. The available hashing algorithms are determined by the chosen key-encryption engine specified by KEYMANAGER. This parameter is optional and the default depends on the value of KEYMANAGER.
  • keycipher=KEYCIPHER β€” is the encryption algorithm used to secure the decryption key of the filesystem itself. The available key-encryption algorithms are determined by the chosen key-encryption engine specified by KEYMANAGER. This parameter is optional and the default depends on the value of KEYMANAGER.
  • keymaxlen=KEYMAXLEN β€” is the maximum number of bytes of the decryption key that will be read from KEYFILE. This parameter is optional, and defaults to 0, indicating that the full length of KEYFILE should be read.
  • passwdretries=NUMATTEMPTS β€” is the number of password-entry attempts that can be made before cryptmount will exit with an error-code when trying to mount or configure the target.

πŸ’… CHOICE OF KEYMANAGER πŸ’…

okay bestie so cryptmount does NOT have just one way to protect the access key sitting next to each encrypted filesystem β€” it's got a whole lil' roster. For most of y'all, the default builtin keymanager is gonna be chef's kiss: good security, good flexibility, no notes. But the alternative keymanagers are out here offering a wider menu of password-hashing schemes and playing nice with other encryption tools. Let's do the strengths-and-weaknesses rundown, shall we? πŸŽ€

🧸 builtin

This one needs cryptmount-2.0 or later, and it uses a separate key-file. A password-based key derivation function (PBKDF) using the SHA1 hashing algorithm, together with blowfish-cbc encryption, is what protects the filesystem key. ✨

Now β€” that key-derivation function got a glow-up in cryptmount-4.0 to make new keyfiles more secure, while still keeping compatibility with existing keyfiles (we don't abandon our old ones, that's rude). If you ever do need to write keyfiles in the old format, just say keyformat=builtin:0. The KEYHASH and KEYCIPHER parameters? Ignored. They don't get a seat at this table. πŸ’€

πŸ” libgcrypt

Supported since cryptmount-1.1 or later, and yeah, it also uses a separate key-file. A PBKDF protects the filesystem key, and here's the slay part: any hashing or cipher algorithm supported by the installed version of the libgcrypt library is available to you. Whatever your libgcrypt can do, you can do. Iconic. πŸ‘‘

πŸ¦‹ luks

This keymanager needs cryptmount-3.1 or later, and it's the one that brought compatibility with the Linux Unified Key Setup (LUKS) disk-format. 🫢

By default, LUKS uses a header inside the encrypted filesystem itself, instead of a separate keyfile. In that case, it's advisable to pick the same value for both the dev and keyfile parameters β€” or just leave keyfile unspecified and vibe. Alternatively, LUKS can be set up with a "detached header", and then the keyfile parameter should be the detached header file.

Just like every other cryptmount filesystem, dev can point to either a raw disk partition or an ordinary file. BUT (and this is the important bit, don't skip it πŸ™ˆ) β€” because of the filesystem structure that LUKS assumes, it is strongly recommended that you do not use either the startsector or numsector parameters. Like, at all.

🌸 openssl / openssl-compat

This keymanager has been around since the earliest release of cryptmount, and it uses a separate keyfile that's compatible with the format used by the openssl command-line encryption tool. Since cryptmount-3.0, that file-format has been provided via the libgcrypt library β€” and it's preferably specified as keyformat=openssl-compat. πŸ’–

A PBKDF protects the filesystem key, and you get a choice of hashing or cipher algorithms. Most algorithms supported by the openssl command-line tool should be available to you, provided the underlying algorithms are present within libgcrypt. So like… usually yes, but check your libgcrypt first, bestie. πŸŽ€

πŸŽ€ password

Needs cryptmount-4.0 or later. This one is wild β€” it doesn't want a separate keyfile at ALL. Instead it derives the filesystem key directly from the user's password. 🌈

The catch (and it's a big one 😭): it is not possible to change the access password without re-encrypting the entire filesystem. So choose wisely. Also, the keyhash and keycipher parameters are ignored here.

✨ raw

Supported since cryptmount-1.1 or later. It uses a separate keyfile where the access key is stored directly and without any encryption. 🫣

Where's this actually useful? Managing encrypted swap partitions β€” you can choose the keyfile as /dev/random, which means the access key will be different every single time it's read. That's the whole point, and honestly? kind of iconic for that use case. πŸ’…

But if the keyfile is an ordinary file, it offers minimal security, and it should preferably be stored separately from the disk that contains the encrypted filesystem β€” think a USB flash disk. Keep it away from the thing it protects, ok?? πŸ¦‹


πŸ›‘οΈ SECURITY πŸ›‘οΈ

Bestie, listen. Because cryptmount needs to run with setuid privileges, keeping its configuration file secure is not optional. Ideally, /etc/cryptmount/cmtab is managed only by the system administrator, and all key-files should be readable only by their owner. That's the dream, that's the goal. ✨

cryptmount does basic security checks on /etc/cryptmount/cmtab every single time it runs, and it will flat-out refuse to operate unless the following are all true:

  • cmtab must be owned by root
  • cmtab must be a regular file
  • cmtab must not be globally writable
  • the directory containing cmtab must be owned by root
  • the directory containing cmtab must not be globally writable

And on top of all that: for each target within /etc/cryptmount/cmtab, all paths must be absolute (i.e. starting with '/'). No sneaky relative paths, we see you. πŸ‘€

When you're using unencrypted keyfiles (that's when KEYMANAGER is "raw"), it is recommended that the KEYFILE is stored with access permissions no less restrictive than 0600, or on a removable device such as a USB flash-disk. (And with recent versions of cryptmount, the "builtin" key-format should be portable between different installations and vastly more secure than "raw" keyfiles. Just saying. πŸ’…)
🚨 DO NOT lose or damage the KEYFILE. This file is essential to providing access to your encrypted filesystem β€” lose it and you're locked out, no cap, fr fr. You are strongly advised to consider keeping a backup of your KEYFILE in some form. Back. It. Up. 😭

πŸ”„ ENCRYPTED SWAP PARTITIONS & AUTO-FORMATTING πŸ”„

When the mkswap option is selected for a particular target within /etc/cryptmount/cmtab, cryptmount will try to automatically format an encrypted swap partition every time you run:

cryptmount --swapon <target>

This is often super useful when there's no need to preserve swap data between reboots β€” you know, like when you're not using the kernel's hibernation features. Fresh swap every time, so clean, so refreshing. 🌸

But here's the tea: because reformatting will destroy any existing data on the chosen swap partition, cryptmount does some basic checking on the first megabyte of the partition, based on the degree of randomness (entropy) in the current contents. 🧚

  • If the partition looks like it contains pure noise, or has been zeroed, then it'll be formatted automatically. πŸ‘
  • If cryptmount determines the partition may contain non-random data, then it will ask you to run mkswap manually. βœ‹
There is no fool-proof way of determining whether a partition (especially after encryption) contains valuable data. So be very careful about the raw device you choose for any target where you select the mkswap option. This is a vibe check you do NOT want to fail. 🫣

πŸ“ EXAMPLE FILE πŸ“

Here's a whole /etc/cryptmount/cmtab example with five targets, using a variety of encryption algorithms and storing their filesystems in different ways β€” including a target representing an encrypted swap partition. Feast your eyes. πŸ‘‘

# /etc/cryptmount/cmtab
# example file - please modify before use

_DEFAULTS_ {
    passwdretries=3     # allow 3 password attempts by default
}

luks {                          # partition created by cryptsetup-luks
    dev=/dev/sdb63
    dir=/mnt/luks-partition-$(USERNAME)
    keyformat=luks
    fstype=ext3
}

basic {
    dev=/home/secretiveuser/crypt.fs
    dir=/home/secretiveuser/crypt           # where to mount
    loop=auto                               # find free loop-device
    fstype=ext3     mountoptions=default
    cipher=aes-cbc-plain                    # filesystem encryption
    keyfile=/home/secretiveuser/crypt.key
    # use default sha1/blowfish key-encryption:
    keyformat=builtin
}

partition {
    dev=/dev/sdb62                      # use whole disk partition
    dir=/mnt/crypt62
    fstype=ext3     mountoptions=nosuid,noexec
    cipher=serpent-cbc-plain

    # information about file used to store decryption key:
    keyfile=/etc/cryptmount/crypt_sdb62.key
    keyformat=openssl                   # use OpenSSL key-encryption
    keyhash=md5 keycipher=bf-cbc        # encryption of key file
}

subset {
    dev=/dev/sdb63
    startsector=512 numsectors=16384    # use subset of partition
    dir=/mnt/encrypted\ subset\ of\ sdb
    fstype=reiserfs     mountoptions=defaults
    cipher=twofish-cbc-plain            # filesystem encryption

    # information about file used to store decryption key:
    keyfile=/etc/cryptmount/crypt_sdb63.key
    keyformat=libgcrypt
    keyhash=md5 keycipher=blowfish-cbc # encryption of key file
}

encswap {                               # encrypted swap partition
    bootaction=swap
    dev=/dev/disk/by-id/scsi-SATA_ST500_ABCDEFG-part37
    startsector=16896 numsectors=1024   # use subset of partition
    fstype=swap        flags=mkswap       cipher=twofish-cbc-plain

    # read fresh 16-byte key from /dev/random whenever used:
    keyfile=/dev/random        keymaxlen=16     keyformat=raw
}

# end of cmtab

Okay so let's walk through the cast of characters, bestie πŸ’œ

The basic target uses an ordinary file "/home/secretiveuser/crypt.fs" to store the encrypted filesystem β€” maybe inside a normal user's home directory, very cozy. A loopback device gets automatically allocated (because of the "loop=auto") by cryptmount to turn that into a block-special device, before mounting. And the decryption key for the filesystem is also stored in this user's home directory, which makes it easier for them to change the password protecting the key. Convenient! πŸŽ€

The partition target uses a whole disk partition to store the encrypted filesystem, with the decryption key stored in the main cryptmount configuration directory. Classic.

The subset target is like partition's cousin, except it does not use a whole disk partition. That means other groups of blocks within that partition can be used for other filesystems managed via cryptmount or dmsetup. Sharing is caring. πŸ¦‹

The encswap target uses a subset of blocks within a disk partition to form an encrypted swap device. A brand-new encryption key is read from the system random-number generator /dev/random every time the target is used. Fresh key, who dis. ✨

And the luks target gives you access to an encrypted partition created by the cryptsetup-luks utility. By using the environmental variable $(USERNAME), the filesystem's mount-point varies depending on which user invokes cryptmount. So user 'joe' would find the filesystem mounted below /mnt/luks-partition-joe. Cute, personalized, slay. cryptmount will be able to mount and unmount the partition, but heads up β€” various advanced LUKS features must be accessed through cryptsetup. πŸ”₯


πŸ“‚ FILES πŸ“‚

  • /etc/cryptmount/cmtab β€” main configuration file

πŸ‘€ SEE ALSO πŸ‘€

cryptmount(8), cryptmount-setup(8), cryptsetup(8), dmsetup(8), openssl(1)


cryptmount is (C)Copyright 2005-2026, RW Penney and is supplied with NO WARRANTY. Licencing terms are as described in the file "COPYING" within the cryptmount source distribution.


and that's the whole page, bestie!! πŸ’– this is cryptmount 6.4.0, dated 2024-07-28, and it's the CMTAB(5) manual page β€” go forth and encrypt responsibly, ily, mwah πŸ«Άβœ¨πŸŽ€

πŸ“¦ where this page comes from