systemd-homed
systemd-homed(8) 是一个 systemd 服务,提供不依赖于当前系统配置的便携式用户账户。
它通过将所有与用户相关的信息移动到存储介质(可选加密)中,并创建一个包含签名信息(关于用户、密码、所属组、UID/GID 以及通常散布在 / 中多个文件里的其他信息)的 ~/.identity 文件,来实现可移植性。
这种方法不仅实现了主目录的可移植性,还通过在登录时自动管理主目录加密并在系统挂起时锁定主目录来提供安全性。
安装
systemd-homed 是 systemd 的一部分并与之打包发布。自 20200721.1-2 版本起,pambase 软件包附带了支持 systemd-homed 用户会话所需的 PAM 配置。
用法
启动/启用 systemd-homed.service 服务。
工具
homectl
homectl 是用于 homed 的主要工具。使用它,您可以创建、更新和检查用户;及其主目录;以及由 systemd-homed(8) 服务控制的 ~/.identity 文件。
homectl(1) 最简单的用法是
# homectl create username
此命令将创建一个具有指定用户名的用户,在 60001–60513 范围内分配一个空闲的 UID,创建一个同名且 GID 与 UID 相同的组,将指定用户设为该组成员,并将用户的默认 shell 设置为 /bin/bash。
主目录的挂载点设置为 /home/username。存储机制的选择顺序如下:
- 如果支持则使用
luks; - 如果不支持 LUKS 但支持子卷,则使用
subvolume; - 如果上述均不支持且未指定其他手动选项,则使用
directory。
LUKS 机制的映像路径设置为 /home/username.home。目录机制的目录路径设置为 /home/username.homedir。
~/.identity 文件是经过签名的,严禁直接使用文本编辑器进行编辑,否则会破坏签名导致其无效。请使用 homectl update --identity=/path/to/.identity 进行修改。userdbctl
一种查询工具,用于检查由传统 UNIX 机制和 systemd-homed 提供的用户、组及组成员资格。
存储机制
LUKS 主目录
用户主目录存储在 Linux 文件系统中,该文件系统位于环回文件或任何可移动介质内的加密 LUKS (Linux Unified Key Setup) 卷中。要使用此机制,请向 homectl 提供 --storage=luks。
如果您使用的是环回文件,为了节省空间,可以使 LUKS2 卷透明地丢弃已删除的数据。要使用此机制,请向 homectl 提供 --luks-discard=true 和 --luks-offline-discard=true。然而,这样做可能会在特定情况下降低安全性。
如果您使用的是可移动介质,请确保满足以下条件:
- 映像包含一个 GPT 分区表。目前它应该只包含一个分区,并且该分区的类型 UUID 必须为
773f91ef-66d4-49b5-bd83-d683bf40ad16。其分区标签必须是用户名。 - 此分区必须包含一个 LUKS2 卷,其标签必须是用户名。该 LUKS2 卷必须包含一个 systemd-homed 类型的 LUKS2 令牌字段。此令牌的 JSON 数据必须有一个 record 字段,包含一个 base64 编码数据的字符串。这些数据是 JSON 用户记录,序列化方式与
~/.identity相同,但经过了加密。此令牌的 JSON 数据还必须有一个 iv 字段,包含加密所需的 base64 编码的二进制初始化向量。使用的加密方式与 LUKS2 卷本身使用的相同,由同一个卷密钥解锁,但基于其自己的 IV。 - 在此 LUKS2 卷内必须是一个 Linux 文件系统,可以是 ext4、btrfs 或 XFS 之一。文件系统标签必须是用户名。
- 此文件系统应包含一个以用户名命名的单个目录。激活后,该目录将成为用户的主目录。它在
~/.identity文件中包含用户记录的第二个副本,就像其他存储机制一样。
在强制关闭、意外关机或停电的情况下,如果是环回文件,可能会导致其处于脏状态,这可能会永久锁定用户。详细信息请参阅 #主目录处于脏状态。
fscrypt 目录
用户主目录的存储方式与上述方法相同,但使用的是原生文件系统加密。要使用此机制,请向 homectl 提供 --storage=fscrypt。
目录或 Btrfs 子卷
用户主目录存储在 /home/username.homedir 中,并在解锁时通过绑定 挂载到 /home/username。使用此方法时不提供加密。要使用此机制,请向 homectl 提供 --storage=directory 或 --storage=subvolume。
CIFS 服务器
在这种情况下,主目录在登录时从 CIFS (Common Internet File System) 服务器挂载。请注意,CIFS 是通过 Samba 协议实现的。在 homectl 命令行中使用 --storage=cifs。用户的本地密码用于登录 CIFS 服务。
用户记录属性
您可以使用以下命令查看完整的用户记录:
# homectl inspect username
您可以使用以下命令修改或添加用户记录:
# homectl update username --property=VALUE
更多选项请参阅 homectl(1)。
管理用户
创建
创建具有 LUKS 加密的用户:
# homectl create username --storage=luks
创建具有 fscrypt 加密的用户(确保文件系统已 启用 fscrypt):
# homectl create username --storage=fscrypt
创建具有特定 UID、Shell 和组的用户:
# homectl create username --shell=/usr/bin/zsh --uid=60100 --member-of=wheel,adm,uucp
其他选项可以在 homectl(1) § USER RECORD PROPERTIES 中找到。
/etc/shells 中列出的 shell 之一。激活与去激活
默认情况下,用户的主目录在登录时自动激活。
# homectl activate username # homectl deactivate username
删除 (Deletion)
可以同时删除多个用户:
# homectl remove username username2
技巧与提示
LUKS 后端的默认挂载选项
默认情况下,主目录将以 compress=zstd:1 和 noacl 挂载。参见 [2]。
您可以使用 --luks-extra-mount-options 覆盖此设置和/或添加额外选项。例如,要启用 ACL,使用标准 3 级 zstd 压缩级别,并允许普通用户删除子卷,可以使用:
$ homectl update user --luks-extra-mount-options acl,compress=zstd,user_subvol_rm_allowed
挂起时清除密钥
suspend 选项可以与 /etc/pam.d/ 文件中的 pam_systemd_home.so 条目一起使用,以启用挂起时清除密钥的功能。目前尚无会话管理器支持此功能。此外,TTY 会话不支持重新认证机制。因此,当会话管理器开始支持此功能时,仅应为它们启用 suspend 选项。阅读 pam_systemd_home(8) 和 Linux-PAM 系统管理员指南以获取更多详细信息。
SSH 远程解锁
systemd-homed 使用您的密码加密您的主目录,因此配置为公钥认证的 SSH 无法挂载它或读取 authorized_keys。一种可能的解决方案是将授权密钥添加到您的用户记录中,并要求同时使用公钥和密码进行认证。将以下内容添加到 /etc/ssh/sshd_config 中:
/etc/ssh/sshd_config
PasswordAuthentication yes PubkeyAuthentication yes AuthenticationMethods publickey,password
在用户处于解锁状态时,使用以下命令更新包含授权密钥的用户记录:
# homectl update username --ssh-authorized-keys=@/path/to/mounted/home/.ssh/authorized_keys
从现在起,SSH 将在完成基于密钥的认证后要求您输入密码。systemd-homed 将使用它来解锁和挂载您的主目录。
为救援模式挂载加密主目录
如果您需要从救援盘或其他机器挂载 systemd-homed 加密的目录,则需要在 systemd-homed 框架之外解密该目录。您可能希望将论坛中的此解决方案的文本文件或脚本保存在救援盘上以备不时之需:
# losetup -fP --show username.home # cryptsetup open /dev/loopXpY mappername # mount /dev/mapper/mappername /mnt/mountpoint
其中:
username.home是/home目录中以您的用户名和 .home 为后缀的文件;loopXpY是/dev目录中具有前一步创建的环回设备环路号和相关分区号的设备,可能是/dev/loop0p1;mappername是您决定为映射设备采用的任何别名,例如user_oldhome;/mnt/mountpoint是您想要挂载解密后主目录的位置。
使用 FIDO2 hmac-secret 设置用户认证与加密
此设置需要 FIDO2 安全设备,并在登录和解密主目录时需要输入 PIN 码。
# homectl create username --storage=fscrypt --fido2-device=auto --fido2-with-client-pin=yes --fido2-with-user-presence=no --recovery-key=yes
建议设置恢复密钥,以防设备丢失或损坏。恢复密钥将像密码一样用于访问用户和文件。除了使用设备 PIN 码外,还可以仅要求用户在场(user presence),这需要触摸安全设备。目前,homectl 还要求用户设置密码作为替代登录方式,该密码同时也充当备份密钥。
故障排除
注销 Plasma 后主目录仍处于活动状态
从 Plasma 注销后,可能仍有活动的用户进程(例如 dbus-daemon)阻止主目录去激活。
可以通过 启用 Plasma 的 systemd 启动 来解决此问题。
用户 umask 被忽略
/etc/login.defs 中始终设置了 umask,因此目前通过 homectl 设置的用户自己的 umask 会被忽略。参见 systemd 问题 23007。
要解决此问题,请在您的 登录 shell 的启动文件中(例如 ~/.bash_profile 或 ~/.zprofile)设置 umask。
主目录处于脏状态
在强制关闭、意外关机或停电的情况下,主目录可能会处于脏状态。在这种情况下,用户将被锁定,对主目录的认证可能需要手动干预。以下步骤假设使用了 LUKS2 加密环回文件存储机制,并且可以使用 fsck 在底层文件系统上对其进行修复。
首先,确认环回文件的状态为 dirty,并确定用户的环回文件路径:
$ homectl inspect username
接下来,使用环回文件的路径,按照 #为救援模式挂载加密主目录 中的步骤操作。
最后,尝试在打开的 LUKS2 设备上使用 fsck 修复文件系统:
# fsck /dev/mapper/mappername
/dev/mapper/mappername 不存在任何挂载点。此时,如果修复成功,请关闭 LUKS2 容器,卸载环回设备,然后尝试通过 systemd-homed 服务正常重新认证。