devxlogo

eCryptfs: Single-File Encryption in Linux

eCryptfs: Single-File Encryption in Linux

f you need to share data in a Linux environment, some basic encryption solutions and practices will allow you to do so in a very secure manner. Many tools enable data encryption in Linux, and each has its pros and cons. Yet many developers try to build their own cryptographic technology, which often gets them in trouble. A better approach is to employ tools that rely on proven cryptography techniques and algorithms. A great example of this approach is eCryptfs, a complete cryptographic file system for Linux that essentially is a robust implementation of mature cryptographic technology.

eCryptfs, which is embedded inside the Linux kernel, is a stackable solution for single-file encrypting. Stackable means that eCryptfs is a layer that works on top of other standard, lower file systems, such as ext3, FAT, FS, XFS, ReiserFS, and (since kernel version 2.6.24.X) NFS. eCryptfs delivers its encryption solution by using relevant existing kernel services such as keyring management.

This article steps you through the necessary operations for installing and using eCryptfs to allow secure data sharing in your Linux environment. (See the eCryptfs site for more details about how it works.)

Copy, Move, and Backup
One of the great advantages of eCryptfs is that the encryption is made at the single-file level and all the metadata needed for encryption/decryption are embedded in the file itself. This process makes each file a little larger than the decrypted version, but it enables:

  • Having under the same directory files encrypted by different users and with different encryption contexts, and each user can access only his/her files;
  • Moving individual files by copying them in encrypted form to another location where they will be accessible simply by using the right encryption context;
  • Using backup tools that allow incremental file transfer.

For backup tools, you can use rsync to mirror secret archives in an efficient way. Rsync will use secure connections as ssh sessions to transfer data on the network, even if this is a redundant feature when you transfer eCryptfs directories. You periodically can mirror the /data directory on the backup_server with this command:

rsync -a --delete /data backup_server:/backup/data

The option -a is equivalent to –rlptgoD. It means recurse into directories, copy symlinks as symlinks, preserve permissions, preserve modification times, preserve group, preserve owner, preserve device files (super-user only), and preserve special files.

The Server-Side Setup
To install eCryptfs, first you need to configure your Linux kernel suitably. The example for this article uses the most recent stable kernel available (2.6.26.3) and the Debian Linux distribution. The configuration begins with the following command:

General setup  --->    [*] Prompt for development and/or incomplete code/driversFile systems  --->    Miscellaneous file systems  --->         eCrypt file system layer support (EXPERIMENTAL)Security options  --->    [*] Enable access key retention support-*- Cryptographic API  --->    {M}   AES cipher algorithms       AES cipher algorithms (i586)

Notice that with key retention support, this snippet activates the key management service offered by the kernel since version 2.6.10.X. With the cryptographic API, it also implements the best digest, cipher, and compression algorithms available. When the configuration is complete, you compile, link, and install the kernel.

Next, you insert the necessary modules:

modprobe ecryptfsmodprobe aesmodprobe md5

eCryptfs needs helper programs to run in the user space and manage the communication with the kernel. For this purpose, you install two packages, ecryptfs-utils and keyutils, with this command:

apt-get install ecryptfs-utils keyutils

Before proceeding to mount the eCryptfs file system, run the keyctl utility to query the kernel key-retention system about the keyring status:

keyctl show    Session Keyring       -3 --alswrv      0    -1  keyring: _uid_ses.0279774249 --alswrv      0    -1   \_ keyring: _uid.0

Please keep this output in mind for future comparison.

For this example, the server directory /data contains all enterprise information that is shareable, with secret data relegated on /data/confidential subdirectory. Using the encryption features of eCryptfs means mounting the /data/confidential directory over a mount point, specifying the value ecryptfs as a file system type. Usually, you chose the source directory itself as a target mount point, but that is not mandatory. In this case, use the following mount operation:

mount -t ecryptfs /data/confidential /data/confidential

This operation kicks off a set of interactive questions that help to learn the details of the ecryptfs implementation. The first question asks about the key type, which is important for understanding the encryption method used. This example follows two possible choices: passphrase and openssl.

  • Passphrase encryption: This is the simplest but weakest way to protect your data. If you choose it, at least try to write down a long and complex passphrase.
    Select key type to use for newly created files: 1) pkcs11-helper 2) tspi 3) passphrase 4) opensslSelection: 3Passphrase:
  • openssl encryption: This choice is definitively better. It represents public key encryption, implemented here via the OpenSSL eCryptfs module. With OpenSSL encryption, you will have a passphrase that unlocks a key involved in file encryption operations. Typically, you must keep the passphrase (long but not too complex) in your mind and the key in your pocket.

Before mounting the eCryptfs file system, you have to create a pair of public/private keys. For this purpose, you run ecryptfs-manager, the user space utility that talks to the kernel key-management system:

ecryptfs-manager   eCryptfs key management menu-------------------------------        1. Add passphrase key to keyring        2. Add public key to keyring        3. Generate new public/private keypair        4. ExitMake selection: 3Select key type to use for newly created files:  1) opensslSelection: 1

As specified in several Remote Filesystem Checkers (RFCs), a PEM file may contain certificates or private keys enclosed between the appropriate BEGIN/END lines. You can save this file containing the private key on a USB pen drive mounted under /usb:

SSL key file path [/usb/key.pem]:Passphrase:

Now you can mount the eCryptfs file system as before:

  1. Choose openssl as the key type.
  2. Tell the system to read the private key from the USB pen drive.
  3. Input the passphrase to unlock it:
    Select key type to use for newly created files:  1) pkcs11-helper 2) tspi 3) passphrase 4) opensslSelection: 4PEM key file [/usb/key.pem]: /usb/key.pemMethod of providing the passphrase:  1) openssl_passwd: Enter on Console 2) openssl_passwd_file: File Containing Passphrase 3) openssl_passwd_fd: File Descriptor for File Containing PassphraseSelection [openssl_passwd]:Passphrase:

Regardless of the key type you choose, you must now select the algorithm to be used for encryption. AES could be the best option:

Select cipher: 1) aes: blocksize = 16; min keysize = 16; max keysize = 32 (not loaded)2) des3_ede: blocksize = 8; min keysize = 24; max keysize = 24 (loaded)3) des: blocksize = 8; min keysize = 8; max keysize = 8 (loaded)4) arc4: blocksize = 1; min keysize = 1; max keysize = 256 (loaded)Selection [aes]: aes

Thirty-two bytes is quite a good key size length for AES:

Select key bytes:  1) 16 2) 32 3) 24Selection [16]: 32

eCryptfs allows users to read unencrypted files that are under /data/confidential. Although this feature could be useful in some situations, you can pass on it for this example:

Enable plaintext passthrough (y/n) [n]: n

The system then tries to mount the file system and asks if it is the first time you have mounted the file system with such a key or if you mistyped the passphrase. Actually, the system keeps a hash of the passphrase in the file $HOME/.ecryptfs/sig-cache.txt, and if the file is missing or the hash on file doesn’t match with the hash of the typed passphrase, it warns the user. You can turn off this feature by answering no to the last question.

Attempting to mount with the following options:  ecryptfs_key_bytes=32  ecryptfs_cipher=aes  ecryptfs_sig=b866e7a3accdf162WARNING: Based on the contents of [/root/.ecryptfs/sig-cache.txt],it looks like you have never mounted with this key /before. This could mean that you have typed your passphrase wrong.Would you like to proceed with the mount (yes/no)? yesWould you like to append sig [b866e7a3accdf162] to[/root/.ecryptfs/sig-cache.txt] in order to avoid this warning in the future (yes/no)? noMounted eCryptfs

Now is a good time to introduce two commonly used cryptography terms that you should understand before continuing:

  • Cryptographic context: This term refers to all the choices you have made, including key type, algorithm, key size, and passphrases;
  • Authentication token: This term originally referred to hardware devices used by people in order to be identified and authorized. Now it includes software tokens such as passphrases and key files.

With the df command, you can now list the file systems mounted and see the /data/confidential directory mounted over itself. This means that the eCryptfs layer is working over the native /data file systems, and you can perform on-the-fly file encryption/decryption. All the typical operations on files and directories (create, modify, delete) are accomplished in a completely transparent way.

Note that the first mount of an eCryptfs file system, when the cryptographic context is going to be defined, has to be done as root. The next mount(s) could be issued by all the users who own the authorization token. After mounting all the file properties, the directories on an eCryptfs file system remain the same as those on the lower file system.

To make the protected directory inaccessible, you umount the eCryptfs file system:

umount /data/confidential

After unmounting, you continue to see all the files you previously created or edited. However, if you try to access them, you realize that their content is completely scrambled. Also, the sizes of the files are larger, because eCryptfs adds a header to each file to embed the metadata needed for encryption.

If you run the keyctl utility again to query the kernel keyring service, you get:

keyctl showSession Keyring       -3 --alswrv      0    -1  keyring: _uid_ses.0279774249 --alswrv      0    -1   \_ keyring: _uid.0344543112 --alswrv      0     0       \_ user: b866e7a3accdf162

This output compared with the previous one shows that eCryptfs has added a session key. This key, as its name suggests, remains valid during the user session. This means that if you unmount the eCryptfs and then mount it again without exiting from the session, you don’t need to type the passphrase again. To erase the session key from the kernel keyring, you must run:

keyctl clear @u 

USB Pen Drives for Passphrases
The previous section suggested using a USB pen drive to store the private key. The weakness of the passphrase method is its reliance on simplicity and brevity. On the other hand, it is very difficult to use a long, complex yet meaningless string unless you have hardware support. For example, mount a USB pen drive under /usb and edit a file inserting the row:

passphrase_passwd=875C9C9A385F72A4FAA7E6BAD02ED530A2084E959830E896D21B6B8A3B4F3FAA

Save it with any name (say, foo.txt) under /usb. Then mount the eCryptfs file system in non-interactive mode, assigning options accordingly:

mount -t ecryptfs –o key=passphrase:passfile=/usb/foo.txt, ecryptfs_cipher=aes, ecryptfs_key_bytes=32, ecryptfs_passthrough=no, 
o_sig_cache /data/confidential /data/confidential

With no further steps, the eCryptfs file system /data/confidential is mounted as before. You don’t need to remember the passphrase anymore. Of course it is crucial to keep the USB pen secure, otherwise you will not be able to access your data and the security of your files will be jeopardized.

When you finish with the confidential directory, run the small script edown.sh, which erases the session key from the kernel keyring:

#!/bin/shPEN_MOUNT_POINT=/usbCONFIDENTIAL_DIR=/data/confidential/bin/umount ${CONFIDENTIAL_DIR}/bin/umount ${PEN_MOUNT_POINT}keyctl clear @u

The Client-Side Setup
A portion of the eCryptfs FAQ page reads:

Changes in the 2.6.24 kernel make eCryptfs more functional on NFS and CIFS, although there is still a little more work to do in order to make eCryptfs function as well on networked file systems as it currently works on local file systems.

To try this out and allow a remote machine to mount a directory with NFS, export the /data directory containing the confidential data on the server. Edit the file /etc/exports by adding a row for each authorized machine:

/data client1_name(rw,sync,no_root_squash,no_subtree_check)/data client2_name(rw,sync,no_root_squash,no_subtree_check)...

Restart NFS server:

/etc/init.d/nfs-kernel-server restart

On the client side, you have to customize and build the kernel and then insert the modules as you did for the server. You need to mount the server /data directory under the local /remote_data directory via NFS:

mount server_name:/data /remote_data

In a very similar way as before, you can locally mount /remote_data /confidential over itself as an eCryptfs file system:

mount –t ecryptfs /remote_data/confidential /remote_data/confidential

This is valid for any key type chosen, and the command can be enriched with command-line options to avoid interaction. The system works even if you didn’t make an exhaustive test. ECryptfs’ usability will improve greatly as soon as NFS support becomes fully reliable.

Automating with UDEV
For further automation, you use the UDEV kernel implementation. UDEV is the new Linux system that dynamically allocates device files representing hardware peripherals under /dev. It is beyond the scope of this article to drill down into technical details about UDEV. Instead, this section describes all the steps to mount an eCryptfs file system automatically when you insert a USB pen drive (sdb) containing a passphrase in a file called foo.txt.

First, install the udev package that contains the user space utilities to manage the udev system and the lsscsi utility:

apt-get install udev lsscsi

The udevd daemon reads all the files under /etc/udev/rules.d in alphabetical order. These files dictate the rules for configuring devices after certain events occur. In this case, the event is the insertion of a specific USB pen drive. You have to retrieve its hardware peculiarities. With lsscsi, you can find the information about the device automatically assigned to your pen drive, in the following example sdb:

 [4:0:00]  disk  SanDisk Corporation	U3  Cruzer Micro  3.10	/dev/sdb

Then with the command:

udevadm info –attribute-walk –name sdb

You would retrieve the following information about the pen drive:

ATTRS{manufacturer}=="SanDisk Corporation"ATTRS{product}=="U3 Cruzer Micro"ATTRS{serial}=="0000186F6A623B0D"

Under /etc/udev/rules.d, you would write the file z21_passpen.rules (the z21 prefix forces the udevd daemon to execute the rule in the right order):

SUBSYSTEMS=="usb", ATTRS{manufacturer}=="SanDisk Corporation", ATTRS{product}=="U3 Cruzer Micro", ATTRS{serial}=="0000186F6A623B0D", NAME+="passpen%n", OPTIONS+="all_partitions"ACTION=="add", NAME=="passpen1", RUN="/usr/local/bin/eup.sh

In the first row, you see a set of conditions defined by a double equal sign. If the event related to the insertion of the USB pen drive and reported to the udevd daemon satisfy these conditions, then udev executes what is prescribed further (i.e., naming the devices file connected to the pen drive with /dev/passpenX).

The second row says that when a new /dev/passpen1 is added, the script /usr/local/bin/eup.sh has to be run:

#!/bin/shPEN_MOUNT_POINT=/usbFILE=foo.txtCONFIDENTIAL_DIR=/remote_data/confidential/bin/mount -t auto /dev/passpen1 ${PEN_MOUNT_POINT}modprobe aesmodprobe md5modprobe ecryptfs/bin/mount -t ecryptfs ${CONFIDENTIAL_DIR} ${CONFIDENTIAL_DIR} -o key=passphrase:passfile=${PEN_MOUNT_POINT}/${FILE},ecryptfs_cipher=aes,ecryptfs_key_bytes=32,ecryptfs_passthrough=no,
o_sig_cache

It is a best practice to restart the udevd daemon, which forces it to read the new rule:

/etc/init.d/udev restart

Some seconds after the insertion of the precious USB pen drive, the eCryptfs will be automatically mounted.

What you have learned so far is just a starting point for exploiting all the features offered by eCryptfs. For example, you can also:

Never Feel Secure
When an eCryptfs file system is mounted, access to the data it contains is available to all users and it is regulated by file and directory permissions only. Moreover, during and after editing eCryptfs files, decrypted copies of the file contents remain on the swap space (if it exists). To avoid this, you have to encrypt the swap space and a better technique for this kind of operation is dm-crypt, a kernel implementation that encrypts data at the block-device level.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist