docs/zh_cn/security/encryption.md
在数据安全方面,JuiceFS 提供两个方面的数据加密保护:
JuiceFS 的架构决定了它的运行通常涉及与数据库和对象存储之间的网络连接,只要这些服务支持加密连接,JuiceFS 就可以通过其提供的加密通道进行访问。
公有云对象存储一般会同时支持 HTTP 和 HTTPS,在创建文件系统时如果没有指定协议头,JuiceFS 会默认使用 HTTPS 协议头。例如:
juicefs format --storage s3 \
--bucket myjfs.s3.ap-southeast-1.amazonaws.com \
...
以上命令,客户端会默认将 bucket 识别为 https://myjfs.s3.ap-southeast-1.amazonaws.com。
对于服务器和对象存储运行在相同 VPC 网络的情况,如果不需要加密连接,可以明确指定要使用的协议头,例如:--bucket http://myjfs.s3.ap-southeast-1.amazonaws.com。
对于所有支持的元数据引擎,只要数据库本身支持并配置了 TLS/SSL 等加密链接,JuiceFS 即可通过其加密通道进行连接。例如,配置了 TLS 加密的 Redis 数据库可以使用 rediss:// 协议头进行链接:
juicefs format --storage s3 \
--bucket myjfs.s3.ap-southeast-1.amazonaws.com \
"rediss://myredis.ap-southeast-1.amazonaws.com:6379/1" myjfs
JuiceFS 提供静态数据加密支持,即先加密,再上传。所有存入 JuiceFS 的文件都会在本地完成加密后再上传到对象存储,这可以在对象存储本身被破坏时有效地防止数据泄露。
JuiceFS 的静态数据加密采用混合加密架构:对称加密负责数据加密,非对称加密负责密钥保护。只需在创建文件系统时提供一个私钥即可启用数据加密功能,通过 JFS_RSA_PASSPHRASE 环境变量提供私钥密码。在使用上,挂载点对应用程序完全透明,即加密和解密过程对文件系统的访问不会产生影响。
JuiceFS 采用混合加密架构,包含两个加密层次:
数据加密层(对称加密 - AES-256-GCM 或 ChaCha20-Poly1305 或 SM4-GCM)
S + 随机种子 N(均使用 256 位密钥)密钥保护层(非对称加密)
M 加密每个数据块的对称密钥 S需要用户预先为文件系统创建一个全局私钥 M。在对象存储中保存的每个对象都将有自己的随机对称密钥 S。
符号说明:
M 代表用户自行创建的私钥S 代表 JuiceFS 客户端为每个文件对象生成的 256 位对称密钥N 代表 JuiceFS 客户端为每个文件对象生成的随机种子K 代表 M 加密 S 得到的密文S 和一个随机种子 N。S 和 N 对每个数据块进行加密得到 encrypted_data。S 在网络上明文传输,使用 RSA 私钥 M 对对称密钥 S 进行加密得到密文 K 。encrypted_data、密文 K 和随机种子 N 组合成对象,然后写入对象存储。K、随机种子 N 和被加密的数据 encrypted_data。K,得到对称密钥 S。S 和 N 解密数据 encrypted_data 得到数据块明文。:::note 注意 静态数据加密功能必须在创建文件系统时启用,已创建的文件系统无法再启用数据加密。 :::
启用静态加密功能的步骤为:
私钥是静态数据加密的关键,一般使用 OpenSSL 手动生成。以下命令将使用 aes256 算法在当前目录生成长度为 2048 位,文件名为 my-priv-key.pem 的 RSA 私钥:
openssl genrsa -out my-priv-key.pem -aes256 2048
由于使用了 aes256 加密算法,命令行会要求必须为该私钥提供一个至少 4 位的 Passphrase,可以简单地把它理解为一个用于加密 RSA 私钥文件本身的密码,它也是 RSA 私钥文件的最后一道安全保障。
:::caution 特别注意 私钥的安全极其重要,需要特别注意以下几点:
建议专注于保护 Passphrase 的安全,并通过环境变量方式传递,避免在命令行历史中泄露。 :::
创建加密的文件系统需要使用 --encrypt-rsa-key 选项指定私钥,提供的私钥内容将写入元数据引擎。需要用环境变量 JFS_RSA_PASSPHRASE 来指定私钥的 Passphrase。
JuiceFS 支持三种加密算法组合,可以通过 --encrypt-algo 选项指定:
aes256gcm-rsa(默认):使用 AES-256-GCM + RSA(或其他私钥)chacha20-rsa:使用 ChaCha20-Poly1305 + RSA(或其他私钥)sm4gcm: 使用 SM4-GCM + SM2(或其他私钥)用环境变量设置 Passphrase
export JFS_RSA_PASSPHRASE=the-passwd-for-rsa
创建文件系统(使用默认的 AES-256-GCM 加密)
juicefs format --storage s3 \
--encrypt-rsa-key my-priv-key.pem \
...
或者明确指定使用 ChaCha20-Poly1305 加密:
juicefs format --storage s3 \
--encrypt-rsa-key my-priv-key.pem \
--encrypt-algo chacha20-rsa \
...
(可选)删除本地私钥文件
JuiceFS 在格式化文件系统时会将私钥的内容安全地存储在元数据引擎中。因此,在完成文件系统创建后(除非有特殊的合规性要求),建议您删除本地的私钥文件:
rm my-priv-key.pem
这样只需确保 JFS_RSA_PASSPHRASE 环境变量的安全,后续的文件系统挂载和访问只需要提供正确的 Passphrase 即可。
如果由于合规性要求或其他原因需要保留私钥文件,请务必将私钥文件存储在安全位置,设置严格的访问权限,并确保私钥文件和 Passphrase 分开保管。
挂载加密的文件系统无需指定额外的选项,但在挂载之前需要通先过环境变量设置私钥的 Passphrase。
用环境变量设置 Passphrase
export JFS_RSA_PASSPHRASE=the-passwd-for-rsa
挂载文件系统
juicefs mount redis://127.0.0.1:6379/1 /mnt/myjfs
启用加密功能确实会带来一定的性能开销,但现代硬件技术已经让这种影响变得相当可控。具体的性能影响取决于工作负载类型、硬件配置(特别是 CPU 的加密指令集支持)和数据访问模式。
现代 CPU 中 TLS、HTTPS 和 AES-256 这些加密技术都有专门的硬件优化。特别是 Intel 和 AMD 的现代处理器都内置了 AES-NI 指令集,能够以接近原生的速度执行 AES 加密操作,这让数据加密的性能损耗大大降低。
AES-256-GCM(默认选择):
ChaCha20-Poly1305:
在选择加密密钥时,推荐使用 RSA-2048 密钥,它在安全强度和性能表现之间有较好的平衡。RSA-4096 提供更高的安全性,但其解密操作会更慢,在高并发读取场景下可能影响性能。
值得一提的是,加密后的数据会比原始数据稍大一些,主要是因为 AES-256-GCM 和 ChaCha20-Poly1305 加密算法需要添加认证标签(16 字节)和其他加密元数据。
加密方案的安全性不仅取决于算法本身,更在于如何正确地管理和使用加密密钥。以下是一些重要的安全实践建议:
密钥管理是安全的核心。私钥的密码应该足够强大——建议使用至少 16 个字符的组合,包含大小写字母、数字和特殊符号。建议通过环境变量传递密码,避免在命令行历史中泄露。
虽然定期更换私钥是个好习惯,但需要注意的是,更换私钥意味着需要重新格式化整个文件系统。因此,在规划私钥轮换策略时,要权衡安全需求和业务连续性。
访问控制同样重要。确保您的元数据引擎(无论是 Redis、MySQL 还是其他数据库)都配置了适当的认证和授权机制。对象存储的访问权限也应该遵循最小权限原则,只授予必要的操作权限。
在网络层面,尽量使用 VPC 或私有网络来隔离元数据引擎和对象存储之间的通信流量,减少被中间人攻击的风险。
监控和审计能帮助您及时发现异常情况。建议记录所有与加密相关的操作日志,定期检查密钥的使用模式,建立异常访问的检测机制。这样即使发生安全事件,您也能快速响应并采取应对措施。
在使用 JuiceFS 加密功能时,有几个重要的技术限制需要了解:
首先,客户端本地缓存的数据是不加密的。虽然只有 root 用户或文件所有者能够访问这些缓存数据,但如果您的使用场景要求端到端的完全加密,就需要考虑额外的保护措施,比如将缓存目录放在加密的文件系统或块存储上。
其次,加密功能有一些固有的限制。文件元数据(如文件名、大小、权限等信息)是不加密的,解密后的数据在内存中也是明文状态。最重要的是,一旦为文件系统启用了加密,就无法再关闭这个功能——加密是不可逆的操作。
在部署规划时,请考虑到加密会带来额外的 CPU 和内存开销。为了确保最佳的兼容性和稳定性,建议所有访问加密文件系统的客户端使用相同或兼容版本的 JuiceFS。
JuiceFS 的加密功能特别适合这些场景:保护云端对象存储中的敏感数据、满足 GDPR、HIPAA 等合规性要求、长期安全存储重要业务数据,以及在多租户环境中实现数据隔离。
不过,如果您需要客户端本地缓存也加密,或者想要为现有的文件系统后期添加加密功能,这个方案可能就不太适合。同样,对于性能要求极其苛刻的应用,或者需要频繁更换密钥但又不能接受重新格式化的场景,也需要慎重考虑。