]>
Commit | Line | Data |
---|---|---|
a9dabd68 LP |
1 | --- |
2 | title: Home Directories | |
5fe63895 | 3 | category: Users, Groups and Home Directories |
a9dabd68 | 4 | layout: default |
0aff7b75 | 5 | SPDX-License-Identifier: LGPL-2.1-or-later |
a9dabd68 LP |
6 | --- |
7 | ||
8 | # Home Directories | |
9 | ||
10 | [`systemd-homed.service(8)`](https://www.freedesktop.org/software/systemd/man/systemd-homed.service.html) | |
abbfc39a | 11 | manages home directories of regular ("human") users. |
12 | Each directory it manages encapsulates both the data store and the user record of the user, | |
13 | so that it comprehensively describes the user account, and is thus naturally portable | |
14 | between systems without any further, external metadata. | |
15 | This document describes the format used by these home directories, in the context of the storage | |
fa16642f | 16 | mechanism used. |
a9dabd68 LP |
17 | |
18 | ## General Structure | |
19 | ||
20 | Inside of the home directory a file `~/.identity` contains the JSON formatted | |
abbfc39a | 21 | user record of the user. |
0d592a5e | 22 | It follows the format defined in [`JSON User Records`](/USER_RECORD). |
abbfc39a | 23 | It is recommended to bring the record into 'normalized' form(i.e. all objects should contain their fields |
24 | sorted alphabetically by their key) before storing it there, | |
25 | though this is not required nor enforced. | |
26 | Since the user record is cryptographically signed, the user cannot make modifications to the file on their own | |
27 | (at least not without corrupting it, or knowing the private key used for signing the record). | |
28 | Note that user records are stored here without their `binding`, `status` and | |
a9dabd68 LP |
29 | `secret` sections, i.e. only with the sections included in the signature plus |
30 | the signature section itself. | |
31 | ||
32 | ## Storage Mechanism: Plain Directory/`btrfs` Subvolume | |
33 | ||
34 | If the plain directory or `btrfs` subvolume storage mechanism of | |
35 | `systemd-homed` is used (i.e. `--storage=directory` or `--storage=subvolume` on | |
36 | the | |
37 | [`homectl(1)`](https://www.freedesktop.org/software/systemd/man/homectl.html) | |
fa16642f | 38 | command line) the home directory requires no special setup besides including |
a9dabd68 LP |
39 | the user record in the `~/.identity` file. |
40 | ||
41 | It is recommended to name home directories managed this way by | |
abbfc39a | 42 | `systemd-homed.service` by the user name, suffixed with `.homedir` |
43 | (example: `lennart.homedir` for a user `lennart`) but this is not enforced. | |
44 | When the user is logged in, the directory is generally mounted to `/home/$USER` | |
45 | (in our example: `/home/lennart`), thus dropping the suffix while the home directory is active. | |
46 | `systemd-homed` will automatically discover home directories named this | |
47 | way in `/home/*.homedir` and synthesize NSS user records for them as they show up. | |
a9dabd68 LP |
48 | |
49 | ## Storage Mechanism: `fscrypt` Directories | |
50 | ||
51 | This storage mechanism is mostly identical to the plain directory storage | |
abbfc39a | 52 | mechanism, except that the home directory is encrypted using `fscrypt`. |
53 | (Use `--storage=fscrypt` on the `homectl` command line.) | |
54 | Key management is implemented via extended attributes on the directory itself: | |
55 | for each password an extended attribute `trusted.fscrypt_slot0`, `trusted.fscrypt_slot1`, | |
56 | `trusted.fscrypt_slot2`, … is maintained. | |
57 | Its value contains a colon-separated pair of Base64 encoded data fields. | |
58 | The first field contains a salt value, the second field the encrypted volume key. | |
59 | The latter is encrypted using AES256 in counter mode, using a key derived from the password via PBKDF2-HMAC-SHA512, | |
60 | together with the salt value. | |
61 | The construction is similar to what LUKS does for`dm-crypt` encrypted volumes. | |
62 | Note that extended attributes are not encrypted by `fscrypt` and hence are suitable for carrying the key slots. | |
63 | Moreover, by using extended attributes, the slots are directly attached to the directory and | |
fa16642f | 64 | an independent sidecar key database is not required. |
a9dabd68 LP |
65 | |
66 | ## Storage Mechanism: `cifs` Home Directories | |
67 | ||
fa16642f | 68 | In this storage mechanism, the home directory is mounted from a CIFS server and |
abbfc39a | 69 | service at login, configured inside the user record. |
70 | (Use `--storage=cifs` on the `homectl` command line.) | |
71 | The local password of the user is used to log into the CIFS service. | |
72 | The directory share needs to contain the user record in `~/.identity` as well. | |
73 | Note that this means that the user record needs to be registered locally before it can be mounted for the first time, | |
74 | since CIFS domain and server information needs to be known *before* the mount. | |
75 | Note that for all other storage mechanisms it is entirely sufficient if the directories | |
a9dabd68 LP |
76 | or storage artifacts are placed at the right locations — all information to |
77 | activate them can be derived automatically from their mere availability. | |
78 | ||
79 | ## Storage Mechanism: `luks` Home Directories | |
80 | ||
81 | This is the most advanced and most secure storage mechanism and consists of a | |
abbfc39a | 82 | Linux file system inside a LUKS2 volume inside a loopback file (or on removable media). |
83 | (Use `--storage=luks` on the `homectl` command line.) Specifically: | |
84 | ||
85 | * The image contains a GPT partition table. | |
86 | For now it should only contain a single partition, | |
87 | and that partition must have the type UUID | |
88 | `773f91ef-66d4-49b5-bd83-d683bf40ad16`. | |
89 | Its partition label must be the user name. | |
90 | ||
91 | * This partition must contain a LUKS2 volume, whose label must be the user name. | |
92 | The LUKS2 volume must contain a LUKS2 token field of type `systemd-homed`. | |
93 | The JSON data of this token must have a `record` field, containing a string with base64-encoded data. | |
94 | This data is the JSON user record, in the same serialization as in `~/.identity`, though encrypted. | |
95 | The JSON data of this token must also have an `iv` field, which contains a | |
96 | base64-encoded binary initialization vector for the encryption. | |
97 | The encryption used is the same as the LUKS2 volume itself uses, unlocked by the | |
a9dabd68 LP |
98 | same volume key, but based on its own IV. |
99 | ||
abbfc39a | 100 | * Inside of this LUKS2 volume must be a Linux file system, one of `ext4`, `btrfs` and `xfs`. |
101 | The file system label must be the user name. | |
a9dabd68 | 102 | |
abbfc39a | 103 | * This file system should contain a single directory named after the user. |
104 | This directory will become the home directory of the user when activated. | |
105 | It contains a second copy of the user record in the `~/.identity` file, like in the other storage mechanisms. | |
a9dabd68 | 106 | |
fa16642f | 107 | The image file should reside in a directory `/home/` on the system, |
abbfc39a | 108 | named after the user, suffixed with `.home`. |
109 | When activated, the container home directory is mounted to the same path, | |
110 | though with the `.home` suffix dropped — unless a different mount point is defined in the user record. | |
111 | (e.g.: the loopback file `/home/waldo.home` is mounted to `/home/waldo` while activated.) | |
fa16642f | 112 | When the image is stored on removable media (such as a USB stick), the image |
abbfc39a | 113 | file can be directly `dd`'ed onto it; the format is unchanged. |
114 | The GPT envelope should ensure the image is properly recognizable as a home directory both when | |
115 | used in a loopback file and on a removable USB stick. | |
116 | (Note that when mounting a home directory from a USB stick, it too defaults to a directory in `/home/`, | |
a9dabd68 LP |
117 | named after the username, with no further suffix.) |
118 | ||
abbfc39a | 119 | Rationale for the GPT partition table envelope: |
120 | this way the image is nicely discoverable and recognizable already by partition managers as a home directory. | |
121 | Moreover, when copied onto a USB stick the GPT envelope makes sure | |
122 | the stick is properly recognizable as a portable home directory medium. | |
123 | (Moreover, it allows embedding additional partitions later on, for | |
124 | example on a multi-purpose USB stick that contains both a home directory and a generic storage volume.) | |
a9dabd68 | 125 | |
37b22b3b | 126 | Rationale for including the encrypted user record in the LUKS2 header: |
a9dabd68 LP |
127 | Linux kernel file system implementations are generally not robust towards |
128 | maliciously formatted file systems; there's a good chance that file system | |
abbfc39a | 129 | images can be used as attack vectors, exploiting the kernel. |
130 | Thus it is necessary to validate the home directory image *before* mounting it and establishing a minimal level of trust. | |
131 | Since the user record data is cryptographically signed and user records not signed with a recognized private | |
132 | key are not accepted, a minimal level of trust between the system and the homedirectory image is established. | |
a9dabd68 LP |
133 | |
134 | Rationale for storing the home directory one level below to root directory of | |
abbfc39a | 135 | the contained file system: |
136 | this way special directories such as `lost+found/` do not show up in the user's home directory. | |
a9dabd68 LP |
137 | |
138 | ## Algorithm | |
139 | ||
140 | Regardless of the storage mechanism used, an activated home directory | |
abbfc39a | 141 | necessarily involves a mount point to be established. |
142 | In case of the directory-based storage mechanisms (`directory`, `subvolume` and `fscrypt`) this is a bind mount. | |
143 | In case of `cifs` this is a CIFS network mount, and in case of the LUKS2 backend a regular block device mount of the file system | |
144 | contained in the LUKS2 image. | |
145 | By requiring a mount for all cases (even for those that already are a directory), | |
146 | a clear logic is defined to distinguish active and inactive home directories, | |
147 | so that the directories become inaccessible under their regular path the instant they are deactivated. | |
148 | Moreover, the `nosuid`, `nodev` and `noexec` flags configured in the user record are applied when the bind mount is established. | |
a9dabd68 LP |
149 | |
150 | During activation, the user records retained on the host, the user record | |
151 | stored in the LUKS2 header (in case of the LUKS2 storage mechanism) and the | |
abbfc39a | 152 | user record stored inside the home directory in `~/.identity` are compared. |
153 | Activation is only permitted if they match the same user and are signed by a recognized key. | |
154 | When the three instances differ in `lastChangeUSec` field, the newest record wins, and is propagated to the other two locations. | |
a9dabd68 | 155 | |
fa16642f | 156 | During activation, the file system checker (`fsck`) appropriate for the |
a9dabd68 LP |
157 | selected file system is automatically invoked, ensuring the file system is in a |
158 | healthy state before it is mounted. | |
159 | ||
160 | If the UID assigned to a user does not match the owner of the home directory in | |
161 | the file system, the home directory is automatically and recursively `chown()`ed | |
162 | to the correct UID. | |
163 | ||
fa16642f | 164 | Depending on the `luksDiscard` setting of the user record, either the backing |
a9dabd68 LP |
165 | loopback file is `fallocate()`ed during activation, or the mounted file system |
166 | is `FITRIM`ed after mounting, to ensure the setting is correctly enforced. | |
c0440512 LP |
167 | |
168 | When deactivating a home directory, the file system or block device is trimmed | |
169 | or extended as configured in the `luksOfflineDiscard` setting of the user | |
170 | record. |