systemd-homed
systemd-homed(8) 是一个 systemd 服务,提供独立于当前系统配置的可移植用户账户。
它通过将所有用户相关信息移动到存储介质(可选加密)并创建一个 ~/.identity 文件来实现可移植性,该文件包含关于用户的签名信息、密码、所属组、UID/GID 以及通常分散在 / 中多个文件中的其他信息。
这种方法不仅允许主目录的可移植性,还可以通过在登录时自动管理主目录加密并在系统暂停时锁定它来提供安全性。
安装
systemd-homed 是 systemd 的一部分并与其一起打包。 pambase 包从版本 20200721.1-2 开始附带必要的 PAM 配置,以允许 systemd-homed 用户会话。
用法
启动/启用 systemd-homed.service 服务。
工具
homectl
homectl 是您将用于 homed 的主要实用程序。使用它可以创建、更新和检查由 systemd-homed(8) 服务控制的用户、他们的主目录以及他们的 ~/.identity 文件。
homectl(1) 的最简单用法是
# homectl create username
此命令将创建一个具有指定用户名的用户,一个免费的 UID 范围在 60001–60513 之间,创建一个同名的组,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 token 字段。此 token 的 JSON 数据必须有一个
record字段,其中包含一个带有 base64 编码数据的字符串。这些数据是 JSON 用户记录,与~/.identity中的序列化方式相同,但已加密。此 token 的 JSON 数据还必须有一个iv字段,其中包含用于加密的 base64 编码的二进制初始化向量。使用的加密与 LUKS2 卷本身使用的加密相同,由相同的卷密钥解锁,但基于其自己的 IV。 - 在此 LUKS2 卷内部必须有一个 Linux 文件系统,可以是 ext4、btrfs 和 XFS 之一。文件系统标签必须是用户名。
- 此文件系统应包含一个以用户命名的一个目录。当激活时,该目录将成为用户的家目录。它包含用户记录的第二个副本,位于
~/.identity文件中,与其他存储机制相同。
- 在发生强制或意外关机或断电的情况下,回环文件可能会处于脏状态,这可能会永久锁定用户。有关详细信息,请参阅 #Home directory in a dirty state。
- systemd-homed 在4Kn 驱动器和扇区大小为 4096 字节的 LUKS 上无法正常工作。请参阅 systemd 问题 30393 和 30394。
fscrypt 目录
用户主目录的存储方式与使用上述方法时相同,但这次使用的是本机文件系统加密。要使用此机制,请向 homectl 提供 --storage=fscrypt。
目录或 Btrfs 子卷
用户主目录存储在 /home/username.homedir 中,并在解锁时使用 bind 挂载到 /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 中列出的之一。删除 (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
暂停时忘记密钥
可以在 /etc/pam.d/ 中的文件的 pam_systemd_home.so 条目中使用 suspend 选项来启用暂停时忘记密钥。目前没有会话管理器支持此功能。此外,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/loop0p1mappername是您决定为映射设备采用的任何别名,例如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 之外,还可以仅要求用户存在,这需要触摸安全设备。目前,homectl 还要求用户设置一个密码作为备用登录,该密码也作为备份密钥。
故障排除
Plasma 注销后主目录仍保持活动状态
注销 Plasma 后,可能仍有活动的用户进程(例如 dbus-daemon)阻止主目录的停用。
可以通过启用 Plasma 的 systemd 启动来解决此问题。
用户 umask 被忽略
/etc/login.defs 中始终设置了 umask,因此用户通过 homectl 设置的自己的 umask 当前被忽略。请参阅 systemd issue 23007。
要解决此问题,请在您的登录 shell 的启动文件中设置 umask,例如 ~/.bash_profile 或 ~/.zprofile。
主目录处于脏状态
在发生强制或意外关机或断电的情况下,主目录可能会处于脏状态。在这种情况下,用户将被锁定,并且进行主目录身份验证可能需要手动干预。以下步骤假定使用 LUKS2 加密的回环文件存储机制,并且 fsck 可用于底层文件系统进行修复。
首先,确认回环文件的状态是脏的,并确定用户回环文件的路径
$ homectl inspect username
接下来,使用回环文件的路径,按照 #Mounting encrypted home directory for rescue 中的步骤进行操作。
最后,尝试使用 fsck 在已打开的 LUKS2 设备上修复文件系统
# fsck /dev/mapper/mappername
/dev/mapper/mappername 没有挂载点。此时,如果修复成功,请关闭 LUKS2 容器,卸载回环设备,然后尝试通过 systemd-homed 服务正常重新进行身份验证。