本文是关于我在这篇文章中创建的加密ZFS文件系统的日常管理的技术笔记。
更换加密ZFS文件系统的密钥
上次在处理密钥的时候有几次操作不够谨慎,导致密钥在一些磁盘上留下了痕迹(忘了使用shred
安全抹除),好在我们看到的密钥[并不是]()ZFS真正用来加密信息的encryption key,而是用于管理encryption key的wrapping key,因此只要换掉这个密钥就可以了,非常方便。
A wrapping key is used to encrypt the actual data encryption keys. A wrapping key is either in a file (in raw or hex format) or it is derived from a passphrase. ——Managing ZFS File Systems in Oracle® Solaris 11.3
更换密钥的过程非常简单,首先用dd
命令生成新key,然后:
# zfs change-key -o keyformat=raw -o keylocation=file:///etc/zfs/data.key data/mailserver
另外要提几点:
- 在ZoL的实现中,默认的加密方式是
aes-256-ccm
,这比Solaris ZFS里的默认值aes-128-ccm
安全了很多倍。在量子计算的时代背景下,256位的AES加密仍然被认为是安全的,而128位就不那么安全了。但是相比于gcm,ccm的安全性又要差一些。所以建议有能力的朋友上aes-256-gcm
! - ZoL里的wrapping key一定是256位,即使你用的加密方式是128位或192位的。
- encryption key也是允许更换的,但是新key只用于写入新数据,旧数据还是由旧key保护。
备份加密的ZFS文件系统
使用ZFS快照
ZFS快照是一种copy-on-write快照,也就是说创建之初是不额外占用磁盘空间的,我喜欢。
创建ZFS快照相当简单:
zfs snapshot data/mailserver@snapshot
其中后面的snapshot
是快照名。我更喜欢用时间命名快照:
zfs snapshot data/mailserver@`date +%Y%m%d-%H%M%S-%N
创建好后,就可以在/data/mailserver/.zfs/snapshot/(快照名)
中看到刚刚创建的快照了。里面的内容和/data/mailserver/
完全一样,不过是只读的。
这里的.zfs
是一个特殊的目录,它在ls -a /data/mailserver
中是看不见的,但是可以cd
进去。你可以通过zfs set snapdir=visible data/mailserver
来显示这个目录,然后就可以在ls -a
中看见它了。不过一直显示它不是一个好主意,因为会让find
等命令变得很 滑 稽 ( 滑 稽 )。把snapdir
属性设置成hidden
就可以重新隐藏.zfs
了。
注:ZFS提供了细致的权限管理,因此有一些命令并不需要在root环境下执行。我给了自己账户部分权限,一些不常用的命令没有给。你可以根据需要调节这些权限来避免每次都要sudo
。
ZFS快照是atomic的,不会给服务造成downtime,也不存在快照数据不consistent的风险,非常适合作为备份策略采用。
备份快照里的内容
ZFS原生有一个很棒的功能:zfs send
。这个命令可以把一整个ZFS文件系统导出成可以由zfs recv
命令接收的stream。其中-w
参数指定raw导出,保留ZFS的加密。zfs send
还可以通过-i
参数指定增量输出:指定两个快照,zfs send
会比较两个快照,输出有改动的部分。这个增量信息也可以由zfs recv
在较旧的快照基础上接收,从而将旧的快照更新为较新的版本。
这样一来,强大的ZFS帮我解决了三件大事:打包、加密、增量备份。接下来是实际操作,假设已经有了一个快照:
~ > zfs list -o name,mountpoint
NAME MOUNTPOINT
data /data
data/mailserver /data/mailserver
data/mailserver@20200217-141330-016045667 -
~ > zfs send -w data/mailserver@20200217-141330-016045667 |gzip >[email protected]
~ > ls
[email protected]
为了节省空间,我采用gzip
压缩备份文件。这个文件现在就可以在gzip
解压缩后由ZFS导入,我们来试一下:
~ > gzip -cd [email protected] | sudo zfs recv data/mailserver_recovered
~ > zfs list -o encryption,name,mountpoint
ENCRYPTION NAME MOUNTPOINT
off data /data
aes-256-ccm data/mailserver /data/mailserver
aes-256-ccm data/mailserver@20200217-141330-016045667 -
aes-256-ccm data/mailserver_recovered /data/mailserver_recovered
aes-256-ccm data/mailserver_recovered@20200217-141330-016045667 -
~ > ls /data
mailserver
~ > zfs load-key -a
Key load error: Cannot enter raw keys on the terminal
Key load error: Cannot enter raw keys on the terminal
Key load error: Cannot enter raw keys on the terminal
0 / 1 key(s) successfully loaded
~ > zfs get keyformat,keylocation data/mailserver_recovered
NAME PROPERTY VALUE SOURCE
data/mailserver_recovered keyformat raw -
data/mailserver_recovered keylocation prompt local
可以看到,第一条命令从备份文件新建了一个data/mailserver_recovered
文件系统,并且保留了原文件系统的加密。需要加载key才能挂载这个刚导入的文件系统,不过因为send过程没有保留keylocation
属性,需要自己设置一下。我临时把密钥文件放到了家目录下一份。
~ > sudo zfs set keylocation=file:///home/saltyfish/data.key data/mailserver_recovered
~ > sudo zfs load-key -a
1 / 1 key(s) successfully loaded
~ > sudo zfs mount -a
~ > ls /data
mailserver mailserver_recovered
挂载成功,检查一下可以确认mailserver_recovered
和mailserver
原来的内容完全一样。测试成功,# zfs destroy -r data/mailserver_recovered
,然后随手用随机数据覆写50次销毁密钥。
上传到云端
我有个用edu邮箱白嫖的Onedrive for Business,有如下特征:
- 5T空间,大!
- 不被神秘魔法影响
- 不要钱 不限速
- 数据安全没有保障
用来备份太合适了,毕竟备份不需要经常访问,加密储存不会不方便,可以很好地克服数据不安全的问题。
我最开始打算用duplicati
直接备份snapshot
目录,但是这样实现增量备份就比较麻烦,虽然duplicati
内置增量备份功能,但我要增量备份的不是snapshot
目录啊!把备份源改来改去,太麻烦;保持快照名不变,更麻烦。更重要的是,duplicati
里的SharePoint不好使,测试了很多版本都不行。据作者说是巨硬提供的接口有问题,那这咱没办法。另外,zfs send
它不香吗(滑稽)~
四处找了一圈,似乎用rclone
是一个不错的连接Onedrive for Business的方法。rclone
非常小巧,使用也简单,配置好后一句rclone copy
就能把文件上传到Onedrive for Business。首先安装rclone
,用apt install
就可以了。然后执行rclone config
,跟着提示走就可以了。其中授权步骤需要一个浏览器,不过rclone
很贴心地提供了在自己电脑上获取授权码并粘贴进terminal的方式,方便了配置headless机器的用户。
配置好之后,就可以使用rclone
上传备份了:
~ > rclone copy [email protected] 1drv:server_backups/mailserver/ -P
Transferred: 11.059M / 11.059 MBytes, 100%, 470.755 kBytes/s, ETA 0s
Transferred: 1 / 1, 100%
Elapsed time: 24.0s
其中-P
参数指定显示进度。当然,rclone copy
也可以从云端下载文件。目前还不是很方便,需要定期手动执行备份,大一点的文件可能就需要丢到screen
去挂着。过段时间可能会写个脚本实现自动备份(自挖大坑)。
网速较快的环境下,可以观察到rclone
会在10M处卡一段时间。我又做了一些测试,发现较大的文件会在每一个10M倍数处都卡一段时间。研究了一下发现有这样一个参数:--onedrive-chunk-size
,其默认值是10M。我把它调成了240M,上传速度得到了极大的提升。没有设成更大的值是因为我的Onedrive接受的最大请求只有250M。关于这个参数的细节,参见rclone
官网上的说明。
结语
本文探讨了加密ZFS文件系统的一些日常管理,包括修改密钥和完整的备份方案。很惭愧,就做了一点微小的工作,谢谢大家!