强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

systemd 教程 / Home 目录管理(systemd-homed)

Home 目录管理(systemd-homed)

systemd-homed 是 systemd 234+ 引入的用户主目录管理服务,旨在提供便携、安全、自包含的用户主目录解决方案。每个用户的主目录作为一个独立的单元进行管理,支持加密、跨机器携带等特性。


1. systemd-homed 概念

设计理念

传统 Linux 用户管理存在以下问题:

问题传统方式homed 方式
用户信息分散/etc/passwd, /etc/shadow, /etc/group用户记录自包含在主目录中
主目录不可移动依赖本地磁盘路径支持导出和导入
加密依赖外部工具LUKS + dm-crypt 手动配置内置加密支持
用户空间有限无法动态扩展支持在线扩展

核心特性

  • 自包含:用户的所有信息(UID、GID、密码、SSH 密钥等)都存储在主目录中
  • 便携性:用户主目录可以存储在 USB 设备、网络存储上
  • 加密:默认支持 LUKS2 加密
  • 动态分配:按需分配和释放空间

2. homectl 命令

2.1 创建用户

# 创建基本用户
sudo homectl create username

# 创建用户并设置密码
sudo homectl create username --real-name="张三" --password=secret

# 指定存储格式和大小
sudo homectl create username \
    --storage=luks \
    --disk-size=5G \
    --shell=/bin/bash

# 创建用户并分配管理员权限
sudo homectl create adminuser \
    --member-of=wheel \
    --shell=/bin/bash

2.2 查看用户信息

# 查看所有 homed 管理的用户
homectl list

# 查看用户详细信息
homectl inspect username

# 输出 JSON 格式
homectl inspect --json=username

# 查看用户磁盘使用情况
homectl inspect username | grep -i disk

2.3 修改用户属性

# 修改密码
passwd username

# 修改用户属性
sudo homectl update username --real-name="李四"

# 调整磁盘大小
sudo homectl resize username 10G

# 设置过期时间
sudo homectl update username --expires="2027-01-01"

# 添加到组
sudo homectl update username --member-of=docker,wheel

2.4 激活与停用

# 激活用户主目录(挂载并就绪)
sudo homectl activate username

# 停用用户主目录(卸载)
sudo homectl deactivate username

# 锁定用户
sudo homectl lock username

# 解锁用户
sudo homectl unlock username

2.5 删除用户

# 删除用户(保留数据)
sudo homectl remove username

# 强制删除
sudo homectl remove username --force

⚠️ 注意:删除用户会同时删除其主目录数据,请确保已备份重要文件。


3. 用户目录格式

systemd-homed 支持多种存储后端:

3.1 存储格式对比

格式参数加密便携性性能适用场景
LUKS--storage=luks笔记本/工作站
btrfs subvolume--storage=subvolume服务器
directory--storage=directory开发环境
fscrypt--storage=fscryptSSD 设备
cifs--storage=cifs可选网络存储

3.2 LUKS 格式详解

# 创建 LUKS 格式用户
sudo homectl create secureuser \
    --storage=luks \
    --disk-size=10G \
    --fs-type=ext4

# LUKS 容器位于:
# /home/secureuser.home
# 或 /dev/loopX (loop device)

LUKS 格式的主目录结构:

/home/secureuser.home          # LUKS 容器文件
  └── /dev/mapper/home-secureuser  # 解密后的块设备
        └── ext4 文件系统
              └── /home/secureuser  # 挂载点

3.3 btrfs subvolume

# 创建 btrfs subvolume 格式
sudo homectl create fastuser \
    --storage=subvolume \
    --fs-type=btrfs

# 子卷位于:
# /home/fastuser.home (目录,btrfs 子卷)

4. 迁移现有用户到 homed

4.1 迁移步骤

# 1. 备份现有用户数据
sudo cp -a /home/existinguser /home/existinguser.bak

# 2. 确保用户已注销
sudo pkill -u existinguser

# 3. 创建 homed 用户(不创建数据)
sudo homectl create existinguser \
    --uid=$(id -u existinguser) \
    --gid=$(id -g existinguser) \
    --storage=luks \
    --disk-size=20G \
    --real-name="$(getent passwd existinguser | cut -d: -f5)"

# 4. 激活用户
sudo homectl activate existinguser

# 5. 恢复数据
sudo cp -a /home/existinguser.bak/. /home/existinguser/
sudo chown -R existinguser:existinguser /home/existinguser

# 6. 清理备份
sudo rm -rf /home/existinguser.bak

4.2 设置密码

# 为迁移用户设置密码
sudo homectl passwd existinguser

⚠️ 注意:迁移前必须确保 /etc/passwd/etc/shadow 中的用户条目已移除,否则会冲突。


5. 用户目录加密

5.1 加密机制

systemd-homed 使用用户密码作为 LUKS 密钥的一部分:

用户密码 → PBKDF2/Argon2 派生 → LUKS 主密钥 → 加密文件系统

5.2 双因素认证

# 配置 FIDO2 安全密钥
sudo homectl update username \
    --fido2-device=auto \
    --fido2-with-client-pin=yes \
    --fido2-with-user-presence=yes

# 配置 TPM2
sudo homectl update username \
    --tpm2-device=auto \
    --tpm2-with-pin=yes

5.3 恢复密钥

# 查看恢复密钥
sudo homectl inspect username | grep -i recovery

# 使用恢复密钥解锁
sudo homectl unlock username --recovery-key=ABCD-EFGH-IJKL-MNOP

💡 提示:务必安全保存恢复密钥,它是密码丢失后的唯一恢复手段。


6. 跨机器携带用户目录

6.1 导出用户主目录

# 导出为可移植格式
sudo homectl export username > /tmp/username.home

# 或直接复制 LUKS 容器文件
sudo cp /home/username.home /media/usb/

6.2 导入到新机器

# 在新机器上导入
sudo homectl import /media/usb/username.home

# 激活用户
sudo homectl activate username

6.3 USB 设备自动挂载

将 LUKS 容器放在 USB 设备上:

# 创建基于 USB 的用户
sudo homectl create portableuser \
    --storage=luks \
    --disk-size=5G \
    --home-dir=/media/usb/portableuser.home

当插入 USB 设备时,homed 会自动检测并提示激活。


7. homed.conf 配置

7.1 主配置文件

# /etc/systemd/homed.conf
[Home]
# 默认存储格式
DefaultStorage=luks

# 默认文件系统类型
DefaultFileSystemType=ext4

# 默认磁盘大小限制
DefaultDiskSize=10G

# 默认加密算法
DefaultEncryption=aes-xts-plain64

# 用户名限制(正则表达式)
UserNamePattern=[a-z][a-z0-9_-]*

# 自动挂载延迟(秒)
AutoLoginDelay=5

7.2 全局默认值

参数说明默认值
DefaultStorage默认存储格式luks
DefaultFileSystemType文件系统类型ext4
DefaultDiskSize默认磁盘大小5G
UserNamePattern用户名正则[a-z][a-z0-9_-]*

8. 实际场景

8.1 便携用户环境

场景:开发人员需要在多台工作站之间切换工作环境。

# 在工作站 A 创建用户
sudo homectl create developer \
    --storage=luks \
    --disk-size=50G \
    --member-of=wheel,docker \
    --shell=/bin/bash

# 导出到便携设备
sudo homectl export developer > /mnt/nas/developer.home

# 在工作站 B 导入
sudo homectl import /mnt/nas/developer.home
sudo homectl activate developer

8.2 企业环境

场景:企业统一管理用户,支持桌面和笔记本的漫游。

# 在 LDAP 中创建用户(外部系统)

# 创建本地 homed 用户映射
sudo homectl create employee123 \
    --storage=luks \
    --disk-size=20G \
    --member-of=employees \
    --realm=corp.example.com

# 配置自动锁定策略
sudo homectl update employee123 \
    --stop-delay=1800 \
    --kill-proces

9. homed 与 LDAP 集成

9.1 基本集成

systemd-homed 可以与 LDAP 配合使用:

# 安装 SSSD
sudo dnf install sssd sssd-ldap

# 配置 SSSD
# /etc/sssd/sssd.conf
[sssd]
services = nss, pam
domains = corp.example.com

[domain/corp.example.com]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldap://ldap.corp.example.com
ldap_search_base = dc=corp,dc=example,dc=com

9.2 创建映射用户

# 创建本地 homed 用户并映射到 LDAP
sudo homectl create ldapuser \
    --uid=10001 \
    --storage=luks \
    --disk-size=10G

# homed 会自动与 LDAP 同步密码

⚠️ 注意:homed 与 LDAP 的集成目前仍在发展中,建议在测试环境验证后再投入生产。


⚠️ 注意事项

  1. systemd 版本:需要 systemd 234 或更高版本
  2. 内核要求:需要内核支持 loop 设备和 dm-crypt
  3. 兼容性:homed 管理的用户不会出现在 /etc/passwd
  4. 密码复杂度:LUKS 加密强度取决于用户密码的复杂度
  5. 备份:定期备份 LUKS 容器文件
  6. 磁盘空间:LUKS 格式的容器会预分配全部空间

💡 提示

  • 使用 homectl inspect --json=username | jq . 获取结构化输出
  • LUKS 容器位于 /home/username.home,定期备份此文件
  • 使用 homectl resize 可以在线扩展用户主目录大小
  • homectl with username -- command args 可以在用户环境中执行命令

扩展阅读