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=fscrypt | ✅ | 中 | 高 | SSD 设备 |
| 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 的集成目前仍在发展中,建议在测试环境验证后再投入生产。
⚠️ 注意事项
- systemd 版本:需要 systemd 234 或更高版本
- 内核要求:需要内核支持 loop 设备和 dm-crypt
- 兼容性:homed 管理的用户不会出现在
/etc/passwd中 - 密码复杂度:LUKS 加密强度取决于用户密码的复杂度
- 备份:定期备份 LUKS 容器文件
- 磁盘空间:LUKS 格式的容器会预分配全部空间
💡 提示
- 使用
homectl inspect --json=username | jq .获取结构化输出 - LUKS 容器位于
/home/username.home,定期备份此文件 - 使用
homectl resize可以在线扩展用户主目录大小 homectl with username -- command args可以在用户环境中执行命令