#yubi-key #zfs #encryption #security #home-dir #encryption-key

shavee_core

shavee 是一个程序,用于使用 Yubikey HMAC 作为双重认证或任何支持 PAM 的 USB 驱动器来自动解密和挂载 ZFS 数据集。

5 个版本 (2 个稳定版本)

1.0.1 2024 年 1 月 7 日
1.0.0 2023 年 12 月 21 日
0.7.5 2023 年 11 月 23 日
0.7.4 2023 年 11 月 23 日
0.7.3 2023 年 11 月 23 日

#1484文件系统


2 crates 中使用

MIT 许可证

105KB
1.5K SLoC

shavee

GitHub license

shavee 是一个简单的程序和一个 pam 模块,用于使用 Rust 编写的 Yubikey HMAC 或简单 USB 驱动器作为双重认证来自动解密和挂载加密的 ZFS 用户主目录。

注意:Shavee v1.0.0 及更高版本与使用早期版本创建的数据集不兼容。请参阅 迁移指南。

支持的方法

此程序目前支持两种双重认证方法

1. Yubikey

Yubikeys 是我们用作强第二因素的安全的身份验证 USB 设备。

Yubikey 在槽位 2 上预编程了一个 HMAC 密钥,可以与我们的密码一起用于推导最终加密密钥。

一旦在 Yubikey 中编程,程序化的 HMAC 秘密就无法提取。

如果您想在同一数据集中使用多个密钥(例如备份密钥),则需要在所有这些密钥上编程相同的新的 HMAC 秘密。

注意:如果您想使用不同的密钥,则需要使用手动解锁选项,因为自动模式通过序列号查找密钥。

Yubikey 模式通过 -y 标志设置。

如果您需要为不同的数据集使用不同的密钥,可以将它们全部连接在一起。

在此模式下,程序在登录时寻找 Yubikey,并使用其 HMAC 模式以及您的密码来推导最终加密密钥。

可以通过 -s 标志设置 Yubikey HMAC 槽位,默认为 SLOT 2

2. 文件/HTTP(S)/SFTP

在此模式下,程序寻找一个文件(可以是任何文件),并使用该文件以及您的密码来推导最终加密。

使用 -f <文件路径> 选项设置文件模式。

文件可以是本地文件、http(s) 或 sftp 位置

示例 HTTPS

shavee -f https://foo.org/secret.png

示例 SFTP

shavee -f sftp://[email protected]/mnt/secretfile -P 4242

-P 为 HTTP 和 SFTP 设置选项集端口。

示例本地文件

shavee -f /mnt/usb/secret.png

这种方法的想法是将文件存储在 USB 存储设备或您控制的网络位置,并在登录期间提供该文件以生成最终加密密钥。

您可以使用任何您选择的现有文件。

或使用以下方式创建一个:

dd if=/dev/uranson of=./secretfile bs=4096 count=4096

注意:由于文件成为您加密密钥的一部分,并且其安全性无法像 Yubikey 那样得到保证,因此您有责任保持其安全。与 Yubikey 不同,您需要负责保持其安全。

3. 仅密码

如果没有指定第二个因素,则程序将仅使用密码作为单一因素。

构建和安装

  1. 安装 Rust
  2. 使用以下命令克隆仓库
git clone https://github.com/ashuio/shavee.git
  • [可选] 通过修改 shavee-bin Cargo.toml 以包含或删除这些功能,启用或禁用 yubikeyfile 功能。
  • [可选] 通过修改 shavee-core Cargo.toml 以包含或删除该功能,启用或禁用详细调试 trace 日志。
    • 如果启用了 trace 日志功能,则必须设置 RUST_LOG=trace 环境变量以生成日志。否则,不会生成日志。注意:启用跟踪日志将增加二进制文件大小,并可能在输出日志中暴露密码短语。仅用于调试目的,在最终二进制文件中禁用它!
  1. 使用二进制文件进行构建
cargo build --release
  1. 使用以下命令将二进制文件放置在您的 bin 目录中
sudo cp target/release/shavee /usr/bin
  1. 使用以下命令将 Pam 模块放置在您的模块目录中
 sudo cp target/release/libshavee_pam.so /usr/lib/security/

模式

  • Shavee PAM 模块:Shavee PAM 模块用于在登录时解锁主目录
  • Shavee 二进制文件:Shavee 的管理功能,用于使用 Shavee 管理数据集

标志/选项

  • -y:使用 Yubikey 进行 2FA。可选地接受 yubikey 序列号或使用第一个密钥
  • -f:使用任何文件作为 2FA,需要文件路径或 HTTP(S) 位置作为参数。
  • -p:打印出密钥
  • -d:将数据集名称添加到打印输出。
  • -P:设置 HTTP 和 SFTP 请求的端口(大写 P)
  • -s:设置 Yubikey HMAC 插槽(可以是 1 或 2)
  • -c:使用派生的加密密钥创建/更改 ZFS 数据集的密钥
  • -m:解锁并挂载 ZFS 数据集。
  • -r:递归地对所有子数据集执行操作。
  • -a:自动检测数据集解锁属性(只能与 PrintMount 一起使用)
  • -z:要操作 ZFS 数据集(可以接受多个选项)

注意:-y(Yubikey 模式)标志和 -f <path to file>(文件模式)选项可以互换。

建议在版本更新后再次运行更改数据集密钥的命令。

配置 ZFS 数据集

注意:如果与PAM一起使用,您的数据集密码应与您的用户账户密码相同,才能自动工作。

注意:如果您更新了密码,请记得也更新加密密钥。


您可以通过运行以下命令来更改/更新现有ZFS数据集的密钥:

shavee -c -z <zfs dataset path>

示例

shavee -y -c -z zroot/data/home/hunter zroot/data/home/hunter2

或者,要使用特定密钥,请输入其序列号

shavee -y 12345678 -c -z zroot/data/home/hunter zroot/data/home/hunter2

在此,我们使用Yubikey作为我们的第二因素。(对于仅密码认证可以省略)并且同时操作两个数据集。

注意:如果数据集不是由shavee创建的,则必须已启用加密并加载密钥才能更改现有数据集的密钥。

创建新数据集

要使用我们推导出的加密密钥创建新数据集,只需运行以下命令:

sudo shavee -c -z <Desired dataset>

示例

sudo shavee -f /mnt/usb/secretfile -c -z zroot/data/home/hunter

在此,我们使用一个文件作为我们的第二因素(仅密码认证时可以省略)

使用shavee解锁和挂载任何zfs分区

只需使用选项 -m 来解锁任何zfs数据集

示例

shavee -y -m -z zroot/data/home/hunter/secrets

备份密钥

要备份密钥,只需使用选项 -p 将密钥打印到stdout

示例

shavee -p -y -z zroot/data/home/hunter/secrets

注意:即使您为多个数据集使用相同的密码,密钥也是唯一的。

在脚本中使用

您也可以直接将密码管道到shavee中,用于脚本

示例

echo "hunter2" | shavee -y -m -z zroot/data/home/hunter/secrets

在此,“hunter2”将被视为密码

使用USB驱动器代替Yubikey

您可以使用选项 -f 而不是使用 -y 标志来用任何USB驱动器替换Yubikey。

自动挂载USB驱动器,以便shavee在登录时可以找到所需的密钥文件

我们可以使用 udev 来实现这一点,只需创建并将以下内容添加到 /etc/udev/rules.d/99-usb-automount.rules

ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_UUID}=="<UUID of partition>", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode <Desired Mount point>"

示例

ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_UUID}=="ADB0-DA9C", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media/usb"

在此,我们将USB磁盘的第一个分区挂载到 /media/usb

您可以通过运行以下命令来获取UUID:

udevadm info --query=all --name=<Target disk> | grep ID_FS_UUID=

示例

udevadm info --query=all --name=/dev/sdb1 | grep ID_FS_UUID=

运行 udevadm control --reload-rules 以确保新规则被加载。

使用shavee与PAM自动解锁home目录

此程序附带一个pam模块,在登录过程中执行。

只需将以下行添加到您想要的pam登录方法文件中。

在我们的示例中,我们将将其添加到 /etc/pam.d/sddm 以处理图形登录,以及 /etc/pam.d/login 以处理CLI登录。

将以下行添加到您的pam配置文件中

auth       optional    libshavee_pam.so <Base home Dataset>
session    optional    libshavee_pam.so <Base home Dataset>

示例

auth       optional    libshavee_pam.so zroot/data/home
session    optional    libshavee_pam.so zroot/data/home

其中 zroot/data/home 挂载到 /home

注意:PAM模块递归地解锁和挂载数据集,任何数据集的失败都将导致认证失败。如果PAM模块设置为 optional,则不应阻止您登录。

要强制在数据集挂载失败时失败认证,请将 optional 更改为 required

ZFS中的双主目录

由于ZFS在现有目录之上挂载数据集,并且我们在PAM中将其定义为可选,因此即使我们的数据集未解密(例如,因为未插入Yubikey),我们仍然可以使用密码进行认证。

我们可以利用这一点,实际上拥有两个主目录。

第一个是您正常的加密主目录,当您的Yubikey在登录时存在时将解锁和挂载。

第二个目录已经存在,将在解密失败时加载,即在登录时未插入Yubikey。

如果您感兴趣,请告知,我也许可以编写更详细的指南。

依赖关系

~16–26MB
~403K SLoC