Ext4 encryption

From Gentoo Wiki
Jump to: navigation, search

This article provides instructions on encrypting files in a home partition using the ext4 filesystem's built-in file based encryption.

Overview

ext4 supports file based encryption. Encrypting files on an individual basis may be more suitable than full disk encryption (such as DM-Crypt) because of performance gains and the ability to exclude certain directories from encryption. For example, open-source project repositories or other 'public' files are not required to be encrypted.

This scenario will work only with single user computer (specified in systemd service file).

Note
Wayland is not supported since it won't run Xsession file before touching /home/${user} directory.

Basics

Decryption before login

Since ext4 uses the kernel keyring, which is divided into session keyring (every time a user logs into console, X, or Wayland) and user keyring (persist for user, but only as user keep logged in).

systemd

The systemd unit will need to run before login screens (impossible with systemd). So, I just cut tty6 for password prompt.

No need to use all 6 VT's.. So you need modify logind.conf and reduce number of reserved VTs.

FILE /etc/systemd/logind.conf
...
[Login]
NAutoVTs=3
ReserveVT=1
...

Create systemd service file:

FILE /etc/systemd/system/decrypt.service
[Unit]
Description=Decrypt
Wants=multi-user.target

[Service]
Type=oneshot
User=REPLACE_BY_YOUR_USERNAME
ExecStartPre=/usr/bin/sleep 6
ExecStartPre=/usr/bin/chvt 6
ExecStart=/bin/bash /usr/local/sbin/decrypt.sh
ExecStartPost=/usr/bin/sleep infinity
KeyringMode=inherit
StandardInput=tty-force
TTYPath=/dev/tty6
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

and script - wait for display manager loads itself, then switch to VT 6, ask password and save it to @s (session), set permissions to allow link it to @u (user keyring) and change back to VT 7 (display manager). Sleep infinity, because at moment, when this script ends, user keyring is wiped and it has no point.

Into script you have to fill number, which you'll get after you run /usr/sbin/e4crypt add_key under normal circumstances and then run keyctl list @s.

FILE /usr/local/sbin/decrypt.sh
systemd-ask-password | /usr/sbin/e4crypt add_key -k @us
keyctl setperm `keyctl search @us logon ext4:OUTPUT_KEY_FROM_E4CRYPT_ADD_KEY` 0x3f3f3f3f
FILE /usr/local/sbin/decrypt_link.sh
#!/bin/sh
sudo -u $PAM_USER /bin/keyctl link @us @s

Last thing, you need link from @u (user keyring) to @s (session keyring), because otherwise ext4 is not able to detect key (no idea why). For this case is best use PAM.

Search for files which has pam_keyinit.so inside, grep it and put line after with

CODE
session optional pam_exec.so /usr/local/sbin/decrypt_link.sh

Issues

  • When e4crypt is issued with -k @u (user keyring), the kernel is not able to decrypt content.