加密

加密目前基于Encrypt-then-MAC结构,只支持经过身份验证的加密方案。

根据所选模式使用不同的原语:

  • 目前始终是CTR模式下的AES-256。计数器以明文添加,因为需要解密,并且客户端本地也跟踪,以避免计数器重复使用。

  • 密钥模式下的身份验证原语是HMAC-SHA-256或BLAKE2b-256。

  • 用于身份验证的原语总是与用于推导块ID的原始原语相同。

256位密钥加密密钥(KEK)来自使用PBKDF2-HMAC-SHA256的密码,带有随机的256位盐,然后用于同AES-256-CTR的密钥、初始化为0的向量一起Encrypt-and-MAC打包。明文的HMAC-SHA256使用相同的KEK生成,并存储在密文旁边,密文全文转换为base64。

然后,这个base64 blob(通常称为keyblob)存储在密钥文件或存储库配置中(分别为keyfile和repokey模式)。

主要通过openssl的libcrypto,python的hashlib、hmac库实现。

压缩

Borg支持以下压缩方法,每个方法由两个字节标识:

  • none(无压缩),标识为\x00\x00

  • lz4(低压缩,但超快),标识为\x01\x00

  • zstd(1-22级:1级是较低的压缩和高速,22级是较高的压缩和较低的速度)标识为\x03\x00

  • zlib(0-9级,0级没有压缩,1级低压缩,9级高压缩),由zlib头(\x.8\x..)标识

  • lzma(0-9级,0级低压缩,9级高压缩),标识为\x02\x00。

速度:none > lz4 > zlib > lzma, lz4 > zstd

压缩率:lzma > zlib > lz4 > none, zstd > lz4

压缩是在重复数据删除后应用的,因此在一个repo中使用不同的压缩方法不会影响重复数据删除。

重删

Borg支持这些重删分块:

  • “固定”:固定块大小的分块器,可选择支持不同大小的头块。

  • “buzhash”:变量,内容定义的块大小,使用由Buzhash算法计算的滚动散列。

id/key用于数据重删,是固定长度(32字节)的字节字符串,通过 id_hash(unencrypted_data) 得到,并且通过hashindex的块缓存管理。

块缓存存储在cache/chunks,用于确定我们是否已经有一个特定的块,计算对它的引用,也用于统计。

块缓存是一个键->值映射,并包含:

  • 键:块id_hash

  • 值:

    • 计数

    • 大小

    • 加密/压缩大小

此外文件缓存存储在cache/files,并在备份时用于快速确定给定文件是否未更改,并且我们拥有其所有块。

文件缓存是一个键->值映射的python字典:

  • 键:编码的绝对文件路径的id_hash

  • 值:

    • 文件inode编号

    • 文件大小

    • 文件mtime_ns

    • 年龄(0 [最新],1,2,3,…,BORG_FILES_CACHE_TTL - 1)

    • 文件内容的块ID列表