Disk encryption in linux debian. Encrypting your hard drive in Linux. Encryption using the loop-aes module

Home directory encryption provides reliable protection for data stored on your hard drive or other storage media. Encryption is especially important on laptops, on computers with multiple access, as well as in any other conditions. Home directory encryption is offered when installing Linux Mint.

The main catch with full encryption of the home directory is that you need to “move” the directory with the encrypted data beyond the mount point.

Performance decreases slightly, at least until SWAP is used. SWAP is a special disk partition or file into which the operating system moves individual blocks of RAM when there is not enough RAM to run applications. SWAP is also encrypted if you select encryption of the home directory in the installer, and sleep mode stops working.

Not encrypting SWAP when the home directory is encrypted is potentially dangerous, since data from encrypted files may end up there in clear text - the whole point of encryption is lost. Starting with version 14 of Linux Mint, during installation you can choose the option to encrypt the entire disk. This option is most suitable for storing personal data on portable devices (which typically have only one user).

1.3 Encryption in gnome – Seahorse

Linux Mint has a built-in Passwords and Keys utility, or Seahorse. Using its capabilities, the user can operate with all keys, passwords, as well as certificates that are available in this OS.

Essentially, Seahorse is an application for GNOME (GNOME is a free desktop environment for Unix-like operating systems), which is a frontend to GnuPG (a free program for encrypting information and creating electronic digital signatures) and is designed to manage encryption keys and passwords. It replaced GNOME Keyring, which was completely replaced in GNOME 2.22, although it was announced back in GNOME 2.18. Allows you to perform all operations that previously needed to be done on the command line and combining them under a single interface:

    manage the security of your work environment and OpenPGP and SSH keys;

    encrypt, expand and scan files and text;

    add and check digital signatures to documents;

    synchronize keys with key servers;

    create and publish keys;

    reserve key information;

    add to images in any supported GDK as an OpenGPG photo ID;

1.4 TrueCrypt

TrueCrypt has a fairly convenient graphical interface, but, unfortunately, the developers have hard-coded integration with the Nautilus file manager.

You can use different methods to encrypt data.

First you need to create a so-called container that will contain file folders intended for encryption. A container can be a file with an arbitrary name or even an entire disk partition. To access the container, you must specify a password, and you can also create a key file (optional) with which the information will be encrypted. Container size is limited.

Creating encrypted partitions/files

Creating a key file:

truecrypt -create-keyfile /home/user/test/file , where file is the name of the key file.

Creating a container, in this case a section:

sudo truecrypt -k /home/user/test/file -c /dev/sda9

Instead of the /dev/sda9 partition, you can also specify a file, for example /home/user/test/cryptofile, but in this case you will need to specify its size, this is done with the -size=5G parameter before the -c parameter. The example above will create a 5GB cryptofile. Sometimes TrueCrypt only accepts the size in bytes; for 5 GB you can either calculate the value in advance and specify -size=5368709120, or write it as follows: -size=`echo 1024^3*5 | bc`.

The already created key file will be used for encryption.

When creating, you will be prompted to select the container type (normal/hidden), file system (FAT, ext2/3/4 or without FS), in this example the mode without using FS was selected. You will also be offered a choice of encryption algorithm (for example, AES), as well as a hash algorithm (for example, SHA-1) for encrypting data streams.

TrueCrypt is used to encrypt data on the fly, that is, you can mount a container and work with the files in it as usual (open/edit/close/create/delete), which is very convenient.

The encrypted partition/file has been created. Now, if you need to format its internal file system (hereinafter referred to as FS), you should do the following.

Select the required section using Truecrypt:

truecrypt -k /home/user/test/file /dev/sda9

By default, the Truecrypt-created device /dev/mapper/truecrypt0 will be used. By accessing this device, you can change, for example, the FS in an encrypted container. In this case, this needs to be done.

sudo mkfs.ext4 -v /dev/mapper/truecrypt0

This is how the ext4 FS was created inside this encrypted container.

Next, since this container is already “attached” to the device /dev/mapper/truecrypt0, all that remains is to simply mount it to some directory. This mount directory must already exist on the system.

sudo mount /dev/mapper/truecrypt0 /mnt/crypto, where /mnt/crypto is the directory to which the encrypted container is mounted.

truecrypt -d

Now, without knowing the key file and password, no one will be able to read the hidden information.

In this article I will try to compare the performance various systems encryption for Linux. In theory, of course, we know which system is more productive, and attempts to calculate performance different systems were (). Truecrypt even contains a built-in benchmark (which, however, shows performance on RAM; it can only be used to evaluate the speed of different encryption algorithms). I’ll do something a little different - I’ll measure the speed of a file system encrypted by various means as a percentage compared to a regular unencrypted file system.


We will encrypt a separate partition on a separate HDD that does not contain the root file system, the algorithm used by default in each specific case. As a regular user, I don't understand the nuances of encryption standards (for example, how RIPEMD-160 hashing differs from Whirpool, which mode is faster, which provides better security), so we'll just rely on what the manufacturers of each software product We chose fairly secure default settings. This may not be entirely correct, since the performance of different encryption algorithms is not the same. If you wish, of course you can change the encryption type, but I’m not sure that all the tested products have an absolutely identical set of algorithms. We will test:

3) eCryptfs is the default system offered to Ubuntu users for encrypting home directories, which is why it is included in this test. Works on top of an existing file system. Encrypts each file separately, so everyone can see the rights, modification dates, and the number of encrypted files; By default, file names are also visible, although there is an option to encrypt them. The most ineffective product of the bunch.

4) EncFS is an approximate analogue of eCryptfs, but uses FUSE.

So, for testing, a separate machine of quite advanced age was allocated in the following configuration: CPU - Intel Celeron 2000Mhz, RAM - 512 Mb DDR PC2700, system HDD - WD Caviar SE 5400 RPM 80Gb, test HDD - WD Caviar SE 7200 RPM 80Gb.
OS - Ubuntu 12.04 LTS, versions of all software current for the repositories of this OS at the time of writing (Truecrypt 7.1a-linux-x86 not from the repositories).

We will test the default ext4 file system for most distributions. To test performance, we will use the iozone3 utility and a shell script written “on the knee” to measure the percentage difference in the tests.

Script for counting. No special attention was paid to the purity of the code; the only criterion when writing was the presence of the correct result.

#!/bin/sh gendifffile () ( #the procedure generates a file that is convenient to analyze. Firstly, lines #not subject to analysis are truncated; secondly, the first two numbers in each line are truncated, indicating #the file size and the record size, respectively ; thirdly, the entire file is output line by line - #one test result per line cat $1 | while read LINE | grep "^[[:space:]]*[[:digit:]]" | "(for (i=3;i<=NF;i++) {print $i}}" done > > $2 ) getline () ( #procedure prints line number $2 of file $1 head -n $2 "$1" | tail -n 1 ) compare () ( #procedure compares files $1 and $2 line by line, calculating the percentage difference of each pair of tests #then calculates the arithmetic average of how many percent faster or slower the #file containing the first group of tests is than the file containing the second group P=0 MAX=0 L1=`cat "$1" | "$2" | wc -l` if [ $L1 -ne $L2 ]; then #if the files contain different numbers of tests, then we will not compare them echo error return fi STEP=$(($L1*5/100)) J=0 for I in `seq 1 $L1`; do J=$(($J+1)) if [ $J -eq $STEP ]; then J=0 echo "$((100*$I/$ L1))% completed ($I of $L1)" fi A=`getline "$1" $I` B=`getline "$2" $I` if [ `echo $A \> $B|bc -l` - eq 1 ]; then D=`echo "100-($B*100/$A)"|bc -l` if [ `echo $D \> $MAX| bc -l` -eq "1" ]; MAX=$D sleep 5 fi else D=`echo "100-($A*100/$B)"|bc -l` if [ `echo $D \> $MAX| bc -l` -eq "1" ]; then MAX=$D sleep 5 fi D="-$D" #if the value has a "-" sign, then this test was executed faster #in the second file, not in the first fi P=`echo "$P+ $D"| bc -l` done P=`echo $P/$L1| bc -l` #calculate the arithmetic mean echo PERCENT=$P MAX_PERCENT=$MAX ) genaverage () ( #procedure for generating a file prepared for analysis, each line of which is #the arithmetic mean of the corresponding lines of all report files located in the analyzed directory AVG=` mktemp` F=`ls "$1"|wc -l` #number of files with reports in a given directory #provided that only such files are stored there and nothing else #we will not check the correctness of this assumption if [ -d " $1" -o $F -lt 2 ]; then echo error >/dev/stderr #in this procedure we will output all messages to stderr, because #stdout is substituted into another procedure rm -f $AVG exit fi TMP=` mktemp` find "$1" -type f| while read FILE; do #for each iozone report file located in the specified directory I=`mktemp` #generate a temporary file prepared for analysis gendifffile "$FILE" "$I" #names write all such files to "TMP" line by line echo "$I">>$TMP done L=`cat \`getline "$TMP" 1\`|wc -l` cat "$TMP"| while read LINE; do #a few checks wouldn't hurt L1=`cat "$LINE"| wc -l` #do all files contain the same number of tests if [ $L -ne $L1 ]; then echo error >/dev/stderr exit fi done STEP=$(($L*5/100)) J=0 for I in `seq 1 $L`; do J=$(($J+1)) if [ $J -eq $STEP ]; then J=0 echo "$((100*$I/$L))% completed ($I of $L)" >/dev/stderr fi SUMFILE=`mktemp` #this way I get the value of the SUM variable from the nested loop SUM=0 cat "$TMP"| while read LINE; do SUM=$((`getline "$LINE" $I`+$SUM)) echo $SUM > "$SUMFILE" done echo `tail -n 1 "$SUMFILE"`/$F|bc -l >> $ AVG #get the arithmetic average #and write it to the appropriate place in the AVG file rm -f "$SUMFILE" done cat "$TMP"| while read LINE; do #delete temporary files rm -f "$LINE" done rm -f "$TMP" echo $AVG ) printf %b "\\033-chainmode-ivmode[:ivopts]> [<#opt_params> ]

Step 02: Considering LUKS

As we have already seen in the previous step, the dm-crypt application can encrypt/decrypt data on its own. But it has a few drawbacks - if you use the dm-crypt application directly, it will not create metadata on disk, and this can be a serious problem if you want to ensure compatibility between different Linux distributions. In addition, the dm-crypt application does not support the use of multiple keys, whereas in real situations it is very important to use multiple keys.

It is for these reasons that the LUKS (Linux Unified Key Setup) technique was born. LUKS is the Linux hard drive encryption standard and standardization allows for compatibility between different distributions. The use of multiple keys and passphrases is also supported. As part of this standardization, a LUKS header is added to the encrypted data and this header contains all the information necessary for configuration. When there is such a header with data, users can easily switch to any other distribution. The dm-crypt project currently recommends using LUKS as the preferred way to configure disk encryption. Let's look at how to install the cryptsetup utility and how to use it to create LUKS-based volumes.

Step 03: Installation

The kernel-level functionality used in dm-crypt is already present in all Linux distributions; we only need an interface to them. We will use the cryptsetup utility, with which you can create volumes using dm-crypt, the LUKS standard, as well as the good old TrueCrypt application. To install cryptsetup on Debian/Ubuntu distributions, you can use the following commands:

$ sudo apt-get update $ sudo apt-get install cryptsetup

The first command synchronizes the rocket index files with the contents of their repositories: it obtains information about the latest versions of all available packages. The second command will download and install the cryptsetup package on your computer. If you are using a RHEL/Fedora/CentOS distribution, you can use the yum command to install the cryptsetup utility.

$ yum install cryptsetup-luks

Step 04: Creating a target file

Now that the cryptsetup utility has been successfully installed, we must create a target file that will store the LUKS container. Although there are many ways to create such a file, there are a number of conditions that must be met when creating it:

  • The file should not consist of several parts located in different places on the disk, i.e., when creating it, you should immediately allocate a sufficient amount of memory for it.
  • The entire file must be filled with random data so that no one can tell where the data used for encryption will be located.

The dd command can help us create a file that satisfies the above conditions, although it will be relatively slow. Just use it with a special device file /dev/random specified as input and a target file specified as output. An example command looks like this:

$ dd if=/dev/random of=/home/nitish/basefile bs=1M count=128

As a result, a file called basefile with a size of 128 MB will be created in the /home/nitish directory. However, please note that this command may take quite a long time to complete; in the system our expert used, this took an hour.

Step 05: Create dm-crypt LUKS

Once you have created the target file, you need to create a LUKS partition in that file. This section serves as the main layer on which all data encryption is built. In addition, the header of this section (LUKS header) contains all the information required for compatibility with other devices. To create a LUKS partition, use the cryptsetup command:

$ cryptsetup -y luksFormat /home/nitish/basefile

Once you agree that the data inside the basefile will be permanently deleted, enter the passphrase, and then confirm it, the LUKS partition will be created. You can check this with the following file command:

$file basefile

Please note that the phrase you enter here will be used to decrypt the data. It is very important to remember this and keep it in a safe place, because if you forget it, you will almost certainly lose all the data in the encrypted partition.

Step 06: Create and mount the file system

The LUKS container we created in the previous step is now available as a file. In our example, this is /home/nitish/basefile. The cryptsetup utility allows you to open the LUKS container as an independent device. To do this, first map the container file to the device name and then mount the device. The display command looks like this:

Once you successfully enter the passphrase you created in the previous step, the LUKS container will be mapped to volume1. What actually happens is that the file is opened as a local loopback device, so that the rest of the system can now treat the file as if it were a real device.

Step 07: File system - continued

The LUKS container file is now available on the system as a regular device. Before we can use it for normal operations, we must format it and create a file system on it. You can use any file system that is supported on your system. In my example, we used ext4 because it is the newest file system for Linux systems.

$ mkfs.ext4 -j /dev/mapper/volume1

Once the device is successfully formatted, the next step is to mount it. First you should create a mount point, preferably at /mnt (based on common sense).

$mkdir/mnt/files

Now let's mount:

To cross-check, use the df –h command - you will see the device "/dev/mapper/volume1" at the end of the list of mounted devices. It can be seen that the LUKS header already takes up some space in the device.

Thanks to this step, you can now use the LUKS device with ext4 file system. Just use this device to store files - everything you write to this device will be encrypted, and everything you read from it will be decrypted and shown to you.

Step 08: Using an encrypted drive

We followed several steps to achieve this result, and if you are not very clear on how it all works, you will most likely get confused about what you need to do only once (required for installation), and what needs to be done regularly when using encryption. Let's consider the following scenario: You have successfully completed all the steps above and then shut down your computer. The next day, when you start your computer, you are unable to find the mounted device - where did it go? To figure all this out, you need to keep in mind that after the system starts, you need to mount the LUKS container, and before stopping the computer, unmount it.

To access your LUKS file, do the following every time you turn on your computer, and then safely close the file before turning off your computer:

Open the LUKS file (i.e. /home/nitish/basefile) and enter the password. The command looks like this:

$ cryptsetup luksOpen /home/nitish/basefile volume1

Once the file is open, mount it (if it doesn't mount automatically):

$ mount /dev/mapper/volume1 /mnt/files

Now you can use the mounted device as a regular disk and read from or write data to it.

Once done, unmount the device as follows:

$ umount /mnt/files

After successful unmounting, close the LUKS file:

$cryptsetup luksClose volume1

Step 09: Backup

Most losses of data stored in a LUKS container are due to corruption of the LUKS header or key slots. In addition to the fact that even due to accidental rewriting of a header into memory, LUKS headers can be damaged, in real conditions a complete failure of the hard drive is also possible. The best way to protect yourself from such problems is to have backups. Let's see what backup options are available.

To create a backup of the LUKS header file, specify the luksHeaderBackup parameter in the command:

$ sudo cryptsetup luksHeaderBackup /home/nitish/basefile --header-backup-file /home/nitish/backupfile

Or, if you want to restore a file from a backup, then specify the luksHeaderRestore parameter in the command:

$ sudo cryptsetup luksHeaderRestore /home/nitish/basefile --header-backup-file /home/nitish/backupfile

To check the LUKS header file and ensure that the file you are dealing with corresponds to an actual LUKS device, you can use the isLuks parameter.

$ sudo cryptsetup -v isLuks /home/nitish/basefile

We've already seen how to backup LUKS header files, but a LUKS header backup won't actually protect against a complete disk failure, so you'll need to back up the entire partition using the following cat command:

$ cat /home/nitish/basefile > basefile.img

Step 10: Various settings

There are several other settings that may be useful when using dm-crypt LUKS encryption. Let's look at them.

To dump the LUKS header, the cryptsetup command has the luksDump option. It will allow you to take a snapshot of the LUKS header file of the device you are using. An example command looks like this:

$ cryptsetup luksDump /home/nitish/basefile

At the beginning of this article, we mentioned that LUKS supports multiple keys. Let's see this in action now by adding a new key slot ( Translator's note: key slot - key space):

$ cryptsetup luksAddKey --Key-slot 1 /home/nitish/basefile

This command adds a key to key slot number 1, but only after you enter the current password (the key present in key slot 0). There are a total of eight key slots, and you can decrypt data using any key. If you dump the header after adding the second key, you will see that the second key slot is occupied.

You can remove key slots like this:

$ cryptsetup luksRemoveKey /home/nitish/basefile

This will remove the key slot with the highest slot number. Be careful not to delete all slots, otherwise your data will be lost forever.

In this article I will tell you how to create a hidden crypto container using standard Linux OS tools (LUKS and cryptsetup). LUKS' built-in features (such as using external headers and placing real data at a given offset) allow the user to access data hidden inside an existing container, as well as deny the existence of such data.

UPD: Since this post was ready a month ago, then I could not even imagine such a strange and unexpected death of the project. Well, yes, perhaps he is not completely dead yet, we’ll see... However, in this text I decided to leave all references to TrueCrypt as they are.

What is "plausible deniability"?

You can find a very long and detailed description of this concept on Wikipedia: http://en.wikipedia.org/wiki/Plausible_deniability. In short, this means that you may have something (or could have done something), the presence of which cannot be suspected or proven by anyone (unless you admit it yourself, of course). And subsequently you can deny the existence (or fact of committing) this something if someone wants to accuse you, since (I repeat) this fact cannot be proven. Well, for example, if a child kicked his little brother in the butt, and the brother went to seek justice from his parents, what would happen in this case?

Well... As if nothing would happen. Because this dude will deny it, and his parents, formally speaking, will not be able to catch him in the hand (since, firstly, there are stupidly no witnesses, and secondly, the younger brother can play his dirty game). This way, no one will be punished. Well, or both of them will be punished just in case. This was just an example of the use of plausible deniability by a child prone to aggression. But you and I are, of course, white and fluffy, and we will use hidden containers solely to protect our personal data from the bad guys. Right? Of course, “what is “good” and what is “bad” is a separate question... However, closer to the point.

General idea of ​​implementation

Let's say we want to save some important data inside an encrypted file. In general, we will use some kind of crypto protection program that will do all the dirty work for us. We may want to treat the encrypted file as a virtual disk, and this greatly narrows down the number of potential candidates. However, there is one “but”. Almost all such programs work with the file as one piece of encrypted data. Let me explain: the user usually has one password (and maybe a few spare ones) for everyone data inside the container. This means there is at least one weak link: the container password. I don't want to mention that the password must be cryptographically strong, because this is a truism. What I mean is that if the user gives up this password for some reason (for example, under duress), all data will be read. And this fact seems sad and completely wrong to me...

Although, in general, there is hope. :) For example, there is such a program as, which is quite smart. The user can create two containers in one file: one “dummy” with a certain number of “forbidden” but relatively safe files, and the other is real, with data that should not be exposed under any circumstances. Thus, TrueCrypt asks for two different passwords when the user wants to create such a “double” container. When working, the user enters only one password for the “real” part and works with it. If, under pressure from external circumstances, the user is forced to disclose the contents of the container to third parties, he simply enters a different password, and TrueCrypt opens the “fake”. I emphasize (and this is really important) that there is no way to prove the presence of a hidden part if the researcher does not know the corresponding password.

Now let's quickly figure out how this stuff works... It's actually very simple. The software divides the container file into two (generally speaking, unequal) parts. The first part, which may be relatively small, contains specially prepared data; the second is real. Accordingly, the program must be able to work with two different headers (configurations) for two different parts, and also be able to choose which part to decrypt depending on the password entered by the user. And this, I must say, is not the most trivial part of the work. Well, simply because “officially” only one, “fake” configuration should be visible: if the container has a standard header, it should only be a “fake” header; if the container parameters are stored in a separate config, this config should allow only the “fake” part to be decrypted. And after deciphering the “fake” part, not a single hint of the presence of a real one should appear. They must be absolutely independent. Moreover, when the “fake” part is opened, the software should show the full capacity of the crypto container, even if the volume of this part is much smaller.

So what about LUKS?

Well, here we have good news and... um... even more good news.

The good news is that cryptsetup can decrypt and mount volumes created by TrueCrypt. Read-only, however, but this is nonsense. Because there is better news. Namely, we can create “hidden” containers exclusively using cryptsetup. . Moreover, this utility allows you to create any number of “hidden” parts. Naturally, within reasonable limits. And here's how you can do it.

But before we continue,

HUGE FAT SCARY WARNING!!!

  • Anything described below may cause irreversible data loss.
  • The use of strong cryptography may be prohibited in your country, so you may be imprisoned not for real information, but simply for having a crypto container that is found on your screw.
  • Cryptography may protect your data, but it will not protect you from torture. A hidden container can help preserve valuable information, but you cannot deny its presence in the event of betrayal or denunciation.
  • The guys who are interested in your encrypted data may not be as stupid as you expected. Even if they cannot prove the presence of a hidden part of the container, they may well lock you in the same cell with seasoned criminals, and in a couple of days you will remember all the passwords to all the hidden data.
  • If you have close people (girlfriend/boyfriend, relatives, friends), they can also become a target for harsh pressure. And this will certainly help you remember everything much faster, including what you didn’t even know.

So you better think twice about how much more valuable information is than your life and the lives of your loved ones. And make a backup. Just in case.

So, man cryptsetup can tell us a lot of interesting details about the command line parameters of this utility. Well, for example, let's look at the --header option:

Well, okay. This means that we may now have a volume of data filled with random garbage, completely without any meaningful signatures. The description of this option contains a little more information, cautions and warnings, but at the bottom line this is all that is required. However, I highly recommend reading this excellent guide.

Another very useful option is --align-payload, which allows you to position the actual data at a specific offset relative to the beginning of the volume:

And this is cool too, because now we can freely shift our data to any part of the volume. You get the idea, right?

  1. We initialize the volume for encryption: we completely overwrite it with random data.
  2. We make an “official” encrypted volume and throw a little money onto it infected warez, spiraled muzla, prona useful free programs, recordings of your amateur rock band, films about love, etc., in general, things for which you will be given no more than two years probation.
  3. Using the above esoteric cryptsetup options, we create a hidden volume (inside the “official” one) and transfer its header to external media. Here you can store truly dangerous information (such as your kindergarten photos or plans to conquer the world).

Actually, people, that's all. No magic. Naturally, you cannot fill the “official” encrypted disk to capacity for the simple reason that part of its space is given over to a hidden container. And as I said at the beginning, you can, if you want, create multiple hidden drives by following the same logic.

Here... And if you still need details, then especially for you -

Step by step guide

Attention!

The following commands will destroy your data if executed without using your brain. Lost information cannot be recovered because utilities like dd operate at a low level (that is, below the file system level). Therefore, it will not be possible to roll back changes or undo their effect, even if you interrupt execution immediately after launch.

In short, don't do it unless you can come up with a meaningful explanation for how each step relates to your goals. And make a backup. Now.

So, let's say we have a device with multiple partitions. Let it be, for example, /dev/sdb. And let /dev/sdb1 be a relatively small (8GB) partition intended for encryption. We'll split it 5 to 3, with the 5 GB portion being "official" and the 3 GB portion being hidden. Let’s also assume that we will keep the key for the encrypted disk in /etc/keys, and the header of the hidden container, respectively, on an external USB drive, which we will mount in /media/user/ExtUSBStick. I assume you already know what permissions need to be set on a key store, how to configure encfs/ecryptfs to securely store confidential data on insecure devices, and also that it makes sense to copy real secret keys and store them in several geographically separated safes.

That's it, okay, I'll stop muttering and get to the heart of the matter.

    Initializing device /dev/sdb1:

    Dd if=/dev/urandom of=/dev/sdb1 bs=16M

    We create a key for the encrypted volume. 512 bits (64 bytes) is through the roof for our purposes:

    Dd if=/dev/urandom bs=64 count=1 >/etc/keys/secret.key 2>/dev/null

    We encrypt the volume using the newly created key:

    Cryptsetup luksFormat /dev/sdb1 /etc/keys/secret.key

    Open the encrypted device and set up mapping in secretdata:

    Cryptsetup luksOpen --key-file /etc/keys/secret.key \ /dev/sdb1 secretdata

    We create a file system on the encrypted volume (for example, btrfs):

    Mkfs.btrfs -L SecretData /dev/mapper/secretdata

    ... and montage it:

    Mount /dev/mapper/secretdata /var/secretdata/

    Keeping in mind the 5 GB limit, set a quota for subvolumes:

    Btrfs quota enable /var/secretdata/

    Since btrfs quotas only apply to subvolumes, let's create one like this:

    Brfs subvolume create /var/secretdata/workingvolume

    ... and apply the specified quota to it (note that btrfs subvolumes can be mounted like regular file systems, so you may later find it more convenient to mount this particular subvolume instead of the entire fs):

    Btrfs qgroup limit 5G /var/secretdata/workingvolume

    We fill it with some data:

    Debootstrap --variant=buildd testing /var/secretdata/workingvolume

    That's it, now you can forget about this part:

    Umount /var/secretdata cryptsetup luksClose secretdata

    Now let’s create a “fish” for the title and stuff random garbage into it:

    Dd if=/dev/urandom of=/media/user/ExtUSBStick/hidden.head bs=4M count=1

    But now comes the very moment when the real magic begins. (What? Did I say there is no magic? So I lied.) We use the same secret key, however, not the whole one, but only half (from an offset of 32 bytes). However, the remaining 256 random bits are quite capable of becoming a good key. Then we will separate the header and put it on the flash drive. Finally, we'll tell cryptsetup that we want to offset our hidden container by 5GB (i.e. 10485760 512-byte blocks) from the beginning of the volume:

    Cryptsetup --keyfile-offset 32 ​​--header /media/user/ExtUSBStick/hidden.head \ --align-payload 10485760 luksFormat /dev/sdb1 /etc/keys/secret.key

    Yes, yes, it's that simple. Now let's open the new encrypted device:

    Cryptsetup luksOpen --key-file /etc/keys/secret.key --keyfile-offset 32 ​​\ --header /media/user/ExtUSBStick/hidden.head /dev/sdb1 realsecretdata

    Let's download any fs we want:

    Mkfs.btrfs /dev/mapper/realsecretdata

useful links

For those who want to know a little more, here are some additional sources of information:

  • Disk encryption, general information on disk encryption: https://wiki.archlinux.org/index.php/Disk_encryption
  • Negative encryption, a concept somewhat narrower than “plausible deniability”, which relates only to the field of cryptography: https://ru.wikipedia.org/wiki/Deniable_encryption
  • TrueCrypt