systemd/systemd-homed

From Gentoo Wiki
Jump to:navigation Jump to:search

homed support became available in Gentoo around 2021-02-01[1].

The following article provides instructions to migrate home directories from their traditional structure into the encrypted by default, portable concept provided by systemd's homed. This article follows the upstream guide when possible. For continuity, it would be wise to read the upstream instructions before reading the instructions here.

Warning
There has only been two known 'test runs' of concerning a home directory for homed. All system administrators making this change proceed at your own risk! Be sure to create a second or third backup of the data before migration to ensure nothing is accidentally lost in the transition process!

Installation

Kernel

KERNEL Required kernel options
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_DM_CRYPT=y
CONFIG_CRYPTO_XTS=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA256_SSSE3=y
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_NI_INTEL=y
CONFIG_CRYPTO_USER_API_HASH=y
CONFIG_CRYPTO_USER_API_SKCIPHER=y

USE flags

Installation presumes sys-apps/systemd has already been installed and is presently running as the system and service manager.

Rebuild sys-auth/pambase and sys-apps/systemd with homed support. systemd will also require the cryptsetup USE flag as well, since LUKS is needed. Alternatively, add USE="cryptsetup homed" in /etc/portage/make.conf, which may help prevent additional USE flag maintenance in the future.

FILE /etc/portage/package.use/systemd-homedAdd homed support to pambase and systemd
sys-auth/pambase homed
sys-apps/systemd cryptsetup homed

Emerge

Update the @world set to account for the USE changes:

root #emerge --ask --update --changed-use --deep @world

Reload the systemd process for good measure:

root #systemctl daemon-reexec

Configuration

Service

Systemd

Enable the systemd-homed service:

root #systemctl enable --now systemd-homed

NSS

Tell the Name Service Switch to use systemd for authenticating users.

FILE /etc/nsswitch.conf
passwd:      files systemd
shadow:      files systemd
group:       files systemd

Usage

Invocation

user $homectl --help
homectl [OPTIONS...] COMMAND ...

Create, manipulate or inspect home directories.

Commands:
  list                         List home areas
  activate USER…               Activate a home area
  deactivate USER…             Deactivate a home area
  inspect USER…                Inspect a home area
  authenticate USER…           Authenticate a home area
  create USER                  Create a home area
  remove USER…                 Remove a home area
  update USER                  Update a home area
  passwd USER                  Change password of a home area
  resize USER SIZE             Resize a home area
  lock USER…                   Temporarily lock an active home area
  unlock USER…                 Unlock a temporarily locked home area
  lock-all                     Lock all suitable home areas
  deactivate-all               Deactivate all active home areas
  rebalance                    Rebalance free space between home areas
  with USER [COMMAND…]         Run shell or command with access to a home area

Options:
  -h --help                    Show this help
     --version                 Show package version
     --no-pager                Do not pipe output into a pager
     --no-legend               Do not show the headers and footers
     --no-ask-password         Do not ask for system passwords
  -H --host=[USER@]HOST        Operate on remote host
  -M --machine=CONTAINER       Operate on local container
     --identity=PATH           Read JSON identity from file
     --json=FORMAT             Output inspection data in JSON (takes one of
                               pretty, short, off)
  -j                           Equivalent to --json=pretty (on TTY) or
                               --json=short (otherwise)
     --export-format=          Strip JSON inspection data (full, stripped,
                               minimal)
  -E                           When specified once equals -j --export-format=
                               stripped, when specified twice equals
                               -j --export-format=minimal

General User Record Properties:
  -c --real-name=REALNAME      Real name for user
     --realm=REALM             Realm to create user in
     --email-address=EMAIL     Email address for user
     --location=LOCATION       Set location of user on earth
     --icon-name=NAME          Icon name for user
  -d --home-dir=PATH           Home directory
  -u --uid=UID                 Numeric UID for user
  -G --member-of=GROUP         Add user to group
     --skel=PATH               Skeleton directory to use
     --shell=PATH              Shell for account
     --setenv=VARIABLE[=VALUE] Set an environment variable at log-in
     --timezone=TIMEZONE       Set a time-zone
     --language=LOCALE         Set preferred language
     --ssh-authorized-keys=KEYS
                               Specify SSH public keys
     --pkcs11-token-uri=URI    URI to PKCS#11 security token containing
                               private key and matching X.509 certificate
     --fido2-device=PATH       Path to FIDO2 hidraw device with hmac-secret
                               extension
     --fido2-with-client-pin=BOOL
                               Whether to require entering a PIN to unlock the
                               account
     --fido2-with-user-presence=BOOL
                               Whether to require user presence to unlock the
                               account
     --fido2-with-user-verification=BOOL
                               Whether to require user verification to unlock
                               the account
     --recovery-key=BOOL       Add a recovery key

Account Management User  Record Properties:
     --locked=BOOL             Set locked account state
     --not-before=TIMESTAMP    Do not allow logins before
     --not-after=TIMESTAMP     Do not allow logins after
     --rate-limit-interval=SECS
                               Login rate-limit interval in seconds
     --rate-limit-burst=NUMBER
                               Login rate-limit attempts per interval

Password Policy User Record Properties:
     --password-hint=HINT      Set Password hint
     --enforce-password-policy=BOOL
                               Control whether to enforce system's password
                               policy for this user
  -P                           Same as --enforce-password-password=no
     --password-change-now=BOOL
                               Require the password to be changed on next login
     --password-change-min=TIME
                               Require minimum time between password changes
     --password-change-max=TIME
                               Require maximum time between password changes
     --password-change-warn=TIME
                               How much time to warn before password expiry
     --password-change-inactive=TIME
                               How much time to block password after expiry

Resource Management User Record Properties:
     --disk-size=BYTES         Size to assign the user on disk
     --access-mode=MODE        User home directory access mode
     --umask=MODE              Umask for user when logging in
     --nice=NICE               Nice level for user
     --rlimit=LIMIT=VALUE[:VALUE]
                               Set resource limits
     --tasks-max=MAX           Set maximum number of per-user tasks
     --memory-high=BYTES       Set high memory threshold in bytes
     --memory-max=BYTES        Set maximum memory limit
     --cpu-weight=WEIGHT       Set CPU weight
     --io-weight=WEIGHT        Set IO weight

Storage User Record Properties:
     --storage=STORAGE         Storage type to use (luks, fscrypt, directory,
                               subvolume, cifs)
     --image-path=PATH         Path to image file/directory
     --drop-caches=BOOL        Whether to automatically drop caches on logout

LUKS Storage User Record Properties:
     --fs-type=TYPE            File system type to use in case of luks
                               storage (btrfs, ext4, xfs)
     --luks-discard=BOOL       Whether to use 'discard' feature of file system
                               when activated (mounted)
     --luks-offline-discard=BOOL
                               Whether to trim file on logout
     --luks-cipher=CIPHER      Cipher to use for LUKS encryption
     --luks-cipher-mode=MODE   Cipher mode to use for LUKS encryption
     --luks-volume-key-size=BITS
                               Volume key size to use for LUKS encryption
     --luks-pbkdf-type=TYPE    Password-based Key Derivation Function to use
     --luks-pbkdf-hash-algorithm=ALGORITHM
                               PBKDF hash algorithm to use
     --luks-pbkdf-time-cost=SECS
                               Time cost for PBKDF in seconds
     --luks-pbkdf-memory-cost=BYTES
                               Memory cost for PBKDF in bytes
     --luks-pbkdf-parallel-threads=NUMBER
                               Number of parallel threads for PKBDF
     --luks-sector-size=BYTES
                               Sector size for LUKS encryption in bytes
     --luks-extra-mount-options=OPTIONS
                               LUKS extra mount options
     --auto-resize-mode=MODE   Automatically grow/shrink home on login/logout
     --rebalance-weight=WEIGHT Weight while rebalancing

Mounting User Record Properties:
     --nosuid=BOOL             Control the 'nosuid' flag of the home mount
     --nodev=BOOL              Control the 'nodev' flag of the home mount
     --noexec=BOOL             Control the 'noexec' flag of the home mount

CIFS User Record Properties:
     --cifs-domain=DOMAIN      CIFS (Windows) domain
     --cifs-user-name=USER     CIFS (Windows) user name
     --cifs-service=SERVICE    CIFS (Windows) service to mount as home area
     --cifs-extra-mount-options=OPTIONS
                               CIFS (Windows) extra mount options

Login Behaviour User Record Properties:
     --stop-delay=SECS         How long to leave user services running after
                               logout
     --kill-processes=BOOL     Whether to kill user processes when sessions
                               terminate
     --auto-login=BOOL         Try to log this user in automatically

See the homectl(1) man page for details.

Inspecting users

homectl(1) can be used to see information about user accounts:

user $homectl inspect larry
   User name: larry
       State: active
 Disposition: regular
 Last Change: Mon 2024-03-18 02:25:37 GMT
 Last Passw.: Fri 2024-02-23 18:20:33 GMT
    Login OK: yes
 Password OK: yes
         UID: 60183
         GID: 60183 (larry)
 Aux. Groups: adm
              larry
              wheel
   Real Name: Larry The Cow
   Directory: /home/larry
     Storage: luks (strong encryption)
  Image Path: /home/larry.home
   Removable: no
       Shell: /bin/bash
 Access Mode: 0701
LUKS Discard: online=no offline=yes
   LUKS UUID: 1cf006fb-daa8-45b3-b9f9-c539c210ee34
   Part UUID: 6ed84030-d48a-4e54-852d-db3092ef4a2b
     FS UUID: a337bb03-e09b-4864-880a-a9d90f1fb59c
 File System: btrfs
 LUKS Cipher: aes
 Cipher Mode: xts-plain64
  Volume Key: 256bit
 Mount Flags: nosuid nodev exec
   Disk Size: 1.1T
  Disk Usage: 18.2G (= 1.5%)
   Disk Free: 1.1T (= 98.5%)
  Disk Floor: 18.2G
Disk Ceiling: 1.6T
  Good Auth.: 356
   Last Good: Tue 2024-03-19 21:12:23 GMT
   Bad Auth.: 517
    Last Bad: Tue 2024-03-19 21:11:45 GMT
    Next Try: anytime
 Auth. Limit: 30 attempts per 1min
   Rebalance: off
   Passwords: 1
  Local Sig.: yes
     Service: io.systemd.Home

Creating new users

homectl(1) can be used to see create new user accounts. For a simple account larry using /bin/bash as the shell, and a home directory at /home/larry:

root #homectl new larry

Converting traditional home directories to systemd homed

Backup important data in /home

As mentioned in the warning above, all important data in existing /home directories should have at least one, but preferably two local copies of the data in order to be well protected against the case of accidental data loss. This should be the case for each home directory to be migrated. The 3-2-1 backup rule applies here.

As an extra measure, there is a 'backup' step below, but do not rely on that step for assurance of data safety.

Collect UIDs of users to be migrated

Unless specifically assigned at user creation time, most single user Gentoo systems will have the primary user's ID set to a value of 1000. Verify the UID of the primary system user by using the following commands (according to upstream), substituting larry for the appropriate username as necessary:

user $getent passwd larry
larry:x:1000:1000::/home/larry:/bin/bash
user $getent group 1000
larry:x:1000:

Mult-user systems go beyond the scope of these instructions. For multi-user systems proceed with each UID as necessary and proceed with caution.

Backup core files

Create backups of important core system files that will be modified:

root #cp /etc/passwd /etc/passwd.bak
root #cp /etc/shadow /etc/shadow.bak
root #cp /etc/gshadow /etc/gshadow.bak
root #cp /etc/passwd /etc/passwd.bak

Backup /home directories

Backup the user(s) home directories. Depending on the speed of the disk and the amount of data, this could take considerable time.

root #cp --archive --recursive /home/larry /home/larry.saved

Create homed directories

To (re)create the home directory for each user to be migrated, simply enter the same username and password that each user account had before the migration. If there should be changes made to the names of usernames, password, or groups, then it is possible to make the changes now, however it may be unwise. The safest option is to leave the values the way they are and adjust using homectl update later.

root #homectl create larry --uid=1000 --real-name="Larry the Cow" --member-of=wheel,audio,docker,kvm,video,plugdev,portage,users,vboxusers,libvirt
🔐 Please enter new password for user foobar:
🔐 Please enter new password for user foobar (repeat):

Move, then remove the files

Move the old home directory files into the new home directory:

root #homectl with larry -- rsync -aHAXv --remove-source-files /home/larry.saved/ .

When the rsync command finishes, all files will be moved into the new home directory; only empty directories will be left inside the /home/larry.saved location. It can be finally removed with:

user $rmdir /home/larry.saved

If the command fails on a certain directory, then not all files have been moved properly. Re-run the above command until the remove command successfully completes the removal of all directories.

Troubleshooting

There are various issues that homed can experience due to being an encrypted filesystem and not a traditional directory full of files.

Manual homed mount and repair

In case a homed filesystem is marked as dirty, which can happen due to disk corruption, the filesystem can be manually mounted and fsck'd. Using an alternate user account (typically root), use homectl inspect <username> in order to determine filesystem is dirty. Substitute larry in the above command with the appropriate username as necessary:

root #losetup -fP /home/larry.home
root #cryptsetup open /dev/loop0p1 home-larry
root #btrfs check /dev/mapper/home-larry

If the check completes successfully, then the device can be manually mounted:

root #mount /dev/mapper/home-larry /mnt/rescue

If everything works as expected, then the /mnt/rescue directory will contain the mounted home directory. Files can be moved out of the image, or removed as necessary.

Moving a homed home directory to a new system

TODO:

Todo:

  • Verify both private.local and public.local files are needed for proper home migration...


Once home directories are converted to the homed format, one of the advantages is their portability. They can be moved between computer systems.

  1. Copy the home directory file from the homed directory location (/home by default) on the old system to the homed directory location on the new system.
  2. Copy the private.local and public.local files found under the /var/lib/systemd/home directory on the old system to the new system.
  3. Restart the systemd-homed service on the new system.
    root #systemctl restart systemd-homed
  4. Login on the new system.
Note
Although moving home directories are portable with this approach, moving the /var/lib/portage/world file and Portage's configuration files under the /etc/portage directory may be needed to ensure all applications used and references in the moved users' home directory are available on the new system. Examples include broken shell aliases, commands called in systemd-timers, etc. Depending on the selected profile, custom USE flag selections, and other factors, this may be as simple as copying the world file from the old system to the new system and re-emerging the @world set, or it may be more complex.

Home directory fails to mount: not enough free space

When using a underlying filesystem such as btrfs and experiencing mount issues after filling the home directory with too many files, then files will either need removed from the image or a larger partition/disk will be necessary.

Activate luks discard offline support:

user $homectl update larry --luks-discard=true --luks-offline-discard=true

Now attempt to activate the home directory:

user $homectl activate larry

If this does not work as expected, then try the Manual homed mount and repair section.

Image on partition or LVM volume remains absent

Creating a home on a block device other than a whole device (like /dev/sda) is currently not officially supported.[2] Homed relies on a GPT partition table with a single partition with the appropriate type UUID set for a Linux Home. homectl create will appear to work just fine on a partition or LVM volume. However, nested partition tables are not automatically probed and made available.

Open systemd issue for partition support.

Example

If a LVM volume and user are created like:

root #lvcreate -L 20G -n test vg0
root #homectl create test --uid=1001 --storage=luks --image-path=/dev/vg0/test --fs-type=ext4

When activating, there will be an error:

root #homectl activate test
Home of user test is currently absent, please plug in the necessary storage device or backing file system.

The journal log will show:

root #journalctl -u systemd-homed.service
Jan 26 13:30:45 rog systemd-homework[5051]: Watching /dev/disk/by-uuid
Jan 26 13:30:45 rog systemd-homework[5051]: Device link /dev/disk/by-uuid/a72f39cf-9d6c-455d-b0dc-96f2aefdff45 still hasn't shown up, giving up.
Jan 26 13:30:45 rog systemd-homework[5051]: Creation completed.
Jan 26 13:30:45 rog systemd-homework[5051]: Image size is 20.0G, file system size is 19.9G, file system payload size is 19.4G, file system free is 19.4G.
Jan 26 13:30:45 rog systemd-homed[1353]: test: changing state creating → absent

Work-around

kpartx can be used to probe for nested partitions and make them available:[3]

root #kpartx -av /dev/vg0/test
add map vg0-test1 (253:10): 0 2091008 linear 253:9 2048

Now activation should work fine:

root #homectl activate test
🔐 Please enter password for user test: **************

Boot persistence can be achieved by running kpartx as pre-start hook for homed:

FILE /etc/systemd/system/systemd-homed.service.d/override.confhomed service override
[Service]
ExecStartPre=/usr/bin/kpartx -av /dev/vg0/test

ExecStartPre can be specified multiple times, if more user volumes / partitions need to be probed.

See also

  • systemd — a modern SysV-style init and rc replacement for Linux systems.

References