<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://wiki.lustre.org/index.php?action=history&amp;feed=atom&amp;title=Lustre_Client_Encryption</id>
	<title>Lustre Client Encryption - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.lustre.org/index.php?action=history&amp;feed=atom&amp;title=Lustre_Client_Encryption"/>
	<link rel="alternate" type="text/html" href="http://wiki.lustre.org/index.php?title=Lustre_Client_Encryption&amp;action=history"/>
	<updated>2026-10-28T09:26:09Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>http://wiki.lustre.org/index.php?title=Lustre_Client_Encryption&amp;diff=5759&amp;oldid=prev</id>
		<title>Elliswilson: Created page with &quot;__TOC__  == Overview ==  Lustre supports &#039;&#039;&#039;client-side encryption&#039;&#039;&#039; of file data, built on the Linux &#039;&#039;&#039;fscrypt&#039;&#039;&#039; framework. Encryption and decryption happen only on Lustre clients. Keys are never sent to servers, servers never encrypt or decrypt, and bulk RPCs carry ciphertext that servers write to disk as-is. File contents are therefore protected both &#039;&#039;&#039;in transit&#039;&#039;&#039; between clients and servers and &#039;&#039;&#039;at rest&#039;&#039;&#039; on the OSTs.  The feature is designed to give users a...&quot;</title>
		<link rel="alternate" type="text/html" href="http://wiki.lustre.org/index.php?title=Lustre_Client_Encryption&amp;diff=5759&amp;oldid=prev"/>
		<updated>2026-10-12T15:07:24Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;__TOC__  == Overview ==  Lustre supports &amp;#039;&amp;#039;&amp;#039;client-side encryption&amp;#039;&amp;#039;&amp;#039; of file data, built on the Linux &amp;#039;&amp;#039;&amp;#039;fscrypt&amp;#039;&amp;#039;&amp;#039; framework. Encryption and decryption happen only on Lustre clients. Keys are never sent to servers, servers never encrypt or decrypt, and bulk RPCs carry ciphertext that servers write to disk as-is. File contents are therefore protected both &amp;#039;&amp;#039;&amp;#039;in transit&amp;#039;&amp;#039;&amp;#039; between clients and servers and &amp;#039;&amp;#039;&amp;#039;at rest&amp;#039;&amp;#039;&amp;#039; on the OSTs.  The feature is designed to give users a...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Lustre supports &amp;#039;&amp;#039;&amp;#039;client-side encryption&amp;#039;&amp;#039;&amp;#039; of file data, built on the Linux &amp;#039;&amp;#039;&amp;#039;fscrypt&amp;#039;&amp;#039;&amp;#039; framework. Encryption and decryption happen only on Lustre clients. Keys are never sent to servers, servers never encrypt or decrypt, and bulk RPCs carry ciphertext that servers write to disk as-is. File contents are therefore protected both &amp;#039;&amp;#039;&amp;#039;in transit&amp;#039;&amp;#039;&amp;#039; between clients and servers and &amp;#039;&amp;#039;&amp;#039;at rest&amp;#039;&amp;#039;&amp;#039; on the OSTs.&lt;br /&gt;
&lt;br /&gt;
The feature is designed to give users a private directory for sensitive files. Users manage it per directory with the standard fscrypt tools; no server-side configuration or key material is needed.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Release !! Change&lt;br /&gt;
|-&lt;br /&gt;
| 2.14 || Client-side encryption introduced ([https://jira.whamcloud.com/browse/LU-12275 LU-12275]). File &amp;#039;&amp;#039;&amp;#039;contents&amp;#039;&amp;#039;&amp;#039; only; file and directory names stay in clear text.&lt;br /&gt;
|-&lt;br /&gt;
| 2.15 || Filename encryption added ([https://jira.whamcloud.com/browse/LU-13717 LU-13717]). See [[#Filename Encryption|Filename Encryption]] for when names are actually encrypted.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The authoritative references are the &amp;#039;&amp;#039;Managing Security&amp;#039;&amp;#039; chapter of the [https://doc.lustre.org/lustre_manual.xhtml Lustre Operations Manual] and the &amp;lt;code&amp;gt;Documentation/client_side_encryption/&amp;lt;/code&amp;gt; directory in the Lustre source tree. For other security features, see [[Setting up Lustre Security]].&lt;br /&gt;
&lt;br /&gt;
== What Is and Is Not Protected ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Protected !! Not protected&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
* File contents, on the wire and on disk&lt;br /&gt;
* File and directory names, and symlink targets (2.15+, see [[#Filename Encryption|Filename Encryption]])&lt;br /&gt;
|&lt;br /&gt;
* File sizes, permissions, ownership, and timestamps&lt;br /&gt;
* Extended attributes&lt;br /&gt;
* The existence and location of holes in sparse files&lt;br /&gt;
* Plaintext on a client while the key is loaded. Other users on that client are kept out only by normal permissions, ACLs, and LSMs.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Because servers never hold keys, an attacker who compromises a Lustre server, even to the point of reading arbitrary memory, cannot recover file contents. An attacker who compromises a &amp;#039;&amp;#039;&amp;#039;client&amp;#039;&amp;#039;&amp;#039; while a key is loaded can.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! Requirement&lt;br /&gt;
|-&lt;br /&gt;
| Client Lustre version || 2.14 or later&lt;br /&gt;
|-&lt;br /&gt;
| Client kernel || Linux 5.4 or later uses the in-kernel fscrypt library. Older distribution kernels with basic encryption support use an fscrypt library embedded in Lustre: RHEL/CentOS 8.1 and later, Ubuntu 18.04 and later, SLES 15 SP2 and later.&lt;br /&gt;
|-&lt;br /&gt;
| Client build || Encryption support is built by default. Clients built with &amp;lt;code&amp;gt;--enable-crypto=no&amp;lt;/code&amp;gt; are &amp;#039;&amp;#039;encryption-unaware&amp;#039;&amp;#039; (see [[#Limitations|Limitations]]).&lt;br /&gt;
|-&lt;br /&gt;
| Userspace tool || &amp;lt;code&amp;gt;fscrypt&amp;lt;/code&amp;gt; ([https://github.com/google/fscrypt github.com/google/fscrypt]) on every client that will manage or unlock encrypted directories&lt;br /&gt;
|-&lt;br /&gt;
| Servers || No configuration and no keys. Servers store and serve ciphertext.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Encryption is &amp;#039;&amp;#039;&amp;#039;enabled by default&amp;#039;&amp;#039;&amp;#039; on Lustre clients. There is no server-side feature flag to turn on.&lt;br /&gt;
&lt;br /&gt;
== Setting Up fscrypt ==&lt;br /&gt;
&lt;br /&gt;
Two one-time steps need root.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;On every client that will use encryption&amp;#039;&amp;#039;&amp;#039;, create the global fscrypt configuration:&lt;br /&gt;
&lt;br /&gt;
 # fscrypt setup&lt;br /&gt;
 Customizing passphrase hashing difficulty for this system...&lt;br /&gt;
 Created global config file at &amp;quot;/etc/fscrypt.conf&amp;quot;.&lt;br /&gt;
 Metadata directories created at &amp;quot;/.fscrypt&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Then edit &amp;lt;code&amp;gt;/etc/fscrypt.conf&amp;lt;/code&amp;gt; and set &amp;lt;code&amp;gt;policy_version&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;2&amp;lt;/code&amp;gt;. With version 2 policies, locking a directory also wipes its cached plaintext from memory.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;On one client only&amp;#039;&amp;#039;&amp;#039;, create the fscrypt metadata directory on the Lustre filesystem:&lt;br /&gt;
&lt;br /&gt;
 # fscrypt setup /mnt/lustre&lt;br /&gt;
 Metadata directories created at &amp;quot;/mnt/lustre/.fscrypt&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Encrypting a Directory ==&lt;br /&gt;
&lt;br /&gt;
Any user can then encrypt an &amp;#039;&amp;#039;&amp;#039;empty&amp;#039;&amp;#039;&amp;#039; directory that they own:&lt;br /&gt;
&lt;br /&gt;
 $ mkdir /mnt/lustre/vault&lt;br /&gt;
 $ fscrypt encrypt /mnt/lustre/vault&lt;br /&gt;
 The following protector sources are available:&lt;br /&gt;
 1 - Your login passphrase (pam_passphrase)&lt;br /&gt;
 2 - A custom passphrase (custom_passphrase)&lt;br /&gt;
 3 - A raw 256-bit key (raw_key)&lt;br /&gt;
 Enter the source number for the new protector [2 - custom_passphrase]: 2&lt;br /&gt;
 Enter a name for the new protector: shield&lt;br /&gt;
 Enter custom passphrase for protector &amp;quot;shield&amp;quot;:&lt;br /&gt;
 Confirm passphrase:&lt;br /&gt;
 &amp;quot;/mnt/lustre/vault&amp;quot; is now encrypted, unlocked, and ready for use.&lt;br /&gt;
&lt;br /&gt;
Every file, directory, and symlink created under &amp;lt;code&amp;gt;/mnt/lustre/vault&amp;lt;/code&amp;gt; afterwards inherits the encryption policy. The policy cannot be changed for a subdirectory, and it cannot be removed once set. To decrypt data, copy it out to an unencrypted directory while the directory is unlocked.&lt;br /&gt;
&lt;br /&gt;
=== Locking and Unlocking ===&lt;br /&gt;
&lt;br /&gt;
 $ fscrypt lock /mnt/lustre/vault&lt;br /&gt;
 &amp;quot;/mnt/lustre/vault&amp;quot; is now locked.&lt;br /&gt;
&lt;br /&gt;
 $ fscrypt unlock /mnt/lustre/vault&lt;br /&gt;
 Enter custom passphrase for protector &amp;quot;shield&amp;quot;:&lt;br /&gt;
 &amp;quot;/mnt/lustre/vault&amp;quot; is now unlocked and ready for use.&lt;br /&gt;
&lt;br /&gt;
Locking removes the master key from kernel memory. With version 2 policies it also evicts cached inodes, so files that are not open revert to their locked, encrypted form. Non-root users can remove their own keys.&lt;br /&gt;
&lt;br /&gt;
Keys are loaded &amp;#039;&amp;#039;&amp;#039;per client&amp;#039;&amp;#039;&amp;#039;. Unlocking a directory on one client does not unlock it anywhere else; each client that needs the data must unlock it.&lt;br /&gt;
&lt;br /&gt;
=== Protectors and Sharing ===&lt;br /&gt;
&lt;br /&gt;
fscrypt never exposes the master key directly. Each policy&amp;#039;s master key is wrapped by one or more &amp;#039;&amp;#039;protectors&amp;#039;&amp;#039; (a custom passphrase, a login passphrase, or a raw key). This lets a passphrase change without re-encrypting any data, and lets several users share an encrypted directory without sharing a secret:&lt;br /&gt;
&lt;br /&gt;
 # Change a protector&amp;#039;s passphrase&lt;br /&gt;
 $ fscrypt metadata change-passphrase --protector=/mnt/lustre:deacab807bf0e788&lt;br /&gt;
&lt;br /&gt;
 # Create a second protector and attach it to an existing policy&lt;br /&gt;
 $ fscrypt metadata create protector /mnt/lustre&lt;br /&gt;
 $ fscrypt metadata add-protector-to-policy \&lt;br /&gt;
       --protector=/mnt/lustre:f3cc1b5cf9b8f41c \&lt;br /&gt;
       --policy=/mnt/lustre:52b2b5aff0e59d8e0d58f962e715862e&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;fscrypt status /mnt/lustre&amp;lt;/code&amp;gt; lists all protectors and policies. &amp;lt;code&amp;gt;fscrypt status /mnt/lustre/vault&amp;lt;/code&amp;gt; shows a directory&amp;#039;s policy, its options, and whether it is unlocked.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Keep protector secrets safe.&amp;#039;&amp;#039;&amp;#039; If every protector for a policy is lost, the data under it cannot be recovered.&lt;br /&gt;
&lt;br /&gt;
== Encryption Modes ==&lt;br /&gt;
&lt;br /&gt;
fscrypt uses one mode for file contents and one for filenames. Lustre supports:&lt;br /&gt;
&lt;br /&gt;
* AES-256-XTS for contents with AES-256-CTS-CBC for filenames (recommended)&lt;br /&gt;
* AES-128-CBC for contents with AES-128-CTS-CBC for filenames&lt;br /&gt;
&lt;br /&gt;
== Filename Encryption ==&lt;br /&gt;
&lt;br /&gt;
Whether names are encrypted depends on how the client was built and which Lustre version created the directory:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Situation !! Names encrypted?&lt;br /&gt;
|-&lt;br /&gt;
| Directory created by a 2.14 client || &amp;#039;&amp;#039;&amp;#039;No&amp;#039;&amp;#039;&amp;#039;, contents only. Files and directories created under it later, by any version, also keep clear-text names.&lt;br /&gt;
|-&lt;br /&gt;
| 2.15+ client using the in-kernel fscrypt library || &amp;#039;&amp;#039;&amp;#039;Yes&amp;#039;&amp;#039;&amp;#039;, always. These clients do not have the &amp;lt;code&amp;gt;enable_filename_encryption&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
|-&lt;br /&gt;
| 2.15+ client using the embedded fscrypt library || Only if &amp;lt;code&amp;gt;llite.*.enable_filename_encryption=1&amp;lt;/code&amp;gt; when the directory is created. &amp;#039;&amp;#039;&amp;#039;Defaults to 0&amp;#039;&amp;#039;&amp;#039; (contents only).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
To turn on filename encryption for every client that uses the embedded library, run on the MGS:&lt;br /&gt;
&lt;br /&gt;
 mgs# lctl set_param -P llite.*.enable_filename_encryption=1&lt;br /&gt;
&lt;br /&gt;
This applies to &amp;#039;&amp;#039;&amp;#039;new&amp;#039;&amp;#039;&amp;#039; encrypted directories only. To get encrypted names for an existing directory: create a new encrypted directory (it can reuse an existing protector), unlock the old one, copy everything across, then remove the old directory.&lt;br /&gt;
&lt;br /&gt;
== Access Without the Key ==&lt;br /&gt;
&lt;br /&gt;
With the key loaded, encrypted files behave like ordinary files. On a client where the key is &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; loaded:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;stat()&amp;lt;/code&amp;gt; works, and directories can be listed. Encrypted names appear in an encoded form that is at most &amp;lt;code&amp;gt;NAME_MAX&amp;lt;/code&amp;gt; bytes and never contains &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; or NUL.&lt;br /&gt;
* Files and empty directories can be deleted, so &amp;lt;code&amp;gt;rm -r&amp;lt;/code&amp;gt; works.&lt;br /&gt;
* Opening or truncating a regular file fails with &amp;lt;code&amp;gt;ENOKEY&amp;lt;/code&amp;gt; (&amp;quot;Required key not available&amp;quot;). So does creating, linking, or renaming anything inside an encrypted directory.&lt;br /&gt;
&lt;br /&gt;
== Striping and Layouts ==&lt;br /&gt;
&lt;br /&gt;
The client encrypts file pages before sending them in bulk RPCs, so encryption is independent of the file layout. Striping, PFL, and OST pools work normally on encrypted files:&lt;br /&gt;
&lt;br /&gt;
 lfs setstripe -c 4 -S 4M /mnt/lustre/vault&lt;br /&gt;
&lt;br /&gt;
== Administrative Controls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Control !! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;noencrypt&amp;lt;/code&amp;gt; client mount option || Prevents that mount from using encryption.&lt;br /&gt;
|-&lt;br /&gt;
| Nodemap property &amp;lt;code&amp;gt;forbid_encryption=1&amp;lt;/code&amp;gt; || Enforced from the server side: clients in the nodemap cannot use encryption. See [[Lustre Multi Tenancy]].&lt;br /&gt;
|-&lt;br /&gt;
| Nodemap &amp;lt;code&amp;gt;rbac&amp;lt;/code&amp;gt; role &amp;lt;code&amp;gt;fscrypt_admin&amp;lt;/code&amp;gt; || Needed to create or modify fscrypt protectors and policies. Without it, users can still lock and unlock existing encrypted directories.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 mgs# lctl nodemap_modify --name tenantA --property forbid_encryption --value 1&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;No backup or restore without the key.&amp;#039;&amp;#039;&amp;#039; No API yet exists to back up or restore ciphertext. Back up from a client where the directory is unlocked, and protect those backups, because they contain plaintext.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Encryption-unaware clients&amp;#039;&amp;#039;&amp;#039; are clients older than 2.14, clients built with &amp;lt;code&amp;gt;--enable-crypto=no&amp;lt;/code&amp;gt;, and clients on kernels without the needed support. To prevent corruption, they get &amp;lt;code&amp;gt;ENOKEY&amp;lt;/code&amp;gt; when they try to open, create, link, rename, or migrate encrypted files. They can still list, stat, and remove them, using the encoded names.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Moving data in.&amp;#039;&amp;#039;&amp;#039; Unencrypted files, and files under a different policy, cannot be renamed or hard-linked into an encrypted directory. &amp;lt;code&amp;gt;mv&amp;lt;/code&amp;gt; falls back to copy-and-delete, and the original plaintext may stay recoverable from free space on the OSTs. Encrypt directories before you put data in them.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;fallocate()&amp;#039;&amp;#039;&amp;#039; modes &amp;lt;code&amp;gt;FALLOC_FL_COLLAPSE_RANGE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;FALLOC_FL_INSERT_RANGE&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;FALLOC_FL_ZERO_RANGE&amp;lt;/code&amp;gt; fail with &amp;lt;code&amp;gt;EOPNOTSUPP&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;DAX&amp;#039;&amp;#039;&amp;#039; is not supported. Direct I/O and &amp;lt;code&amp;gt;mmap&amp;lt;/code&amp;gt; are supported.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Symlinks.&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;st_size&amp;lt;/code&amp;gt; reports the ciphertext length, and the maximum target length is 2 bytes shorter than for an unencrypted symlink.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Special files&amp;#039;&amp;#039;&amp;#039; (named pipes, device nodes, and UNIX sockets) are not encrypted.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;CPU cost.&amp;#039;&amp;#039;&amp;#039; Encryption runs on client CPUs. Hardware AES acceleration (for example, AES-NI) greatly reduces the overhead; benchmark your own workload.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Setting up Lustre Security]]&lt;br /&gt;
* [[Lustre Multi Tenancy]] — nodemaps, including &amp;lt;code&amp;gt;forbid_encryption&amp;lt;/code&amp;gt;&lt;br /&gt;
* [[Lustre Kerberos SSK Authentication]] — encrypting all RPC traffic on the wire&lt;br /&gt;
&lt;br /&gt;
[[Category:Administration]]&lt;br /&gt;
[[Category:Security]]&lt;/div&gt;</summary>
		<author><name>Elliswilson</name></author>
	</entry>
</feed>