rgw数据加密
rgw网关收到客户端的数据后,先对数据进行加密,然后再存到rados集群里面。同理,读取数据的时候,rgw先进行解密,然后再发送给客户端。数据加解密的过程都是在rgw里面完成,此时rgw需要加解密的密钥和对应的算法。
ceph rgw(v12.2.12)里面按保存加密密钥的方式,分为两种情况:
1、由客户端负责指定加密密钥,当前仅支持AES256加密算法;
2、由rgw网关负责指定加密密钥,所有网关实例共用此密钥;
如果客户端上传、下载时指定了密钥的同时,rgw网关也配置了加密密钥,优先使用客户端指定的密钥进行数据加解密。
加密密钥保存在客户端
也就是客户端自己负责密钥的管理,rgw不负责保存。每次上传、下载数据的时候都需要指定加密密钥和加密算法。
上传下载对象例子
[root@ceph03 ~]# cat put.py
import boto3
import os
BUCKET = 'bk01'
KEY = os.urandom(32)
s3 = boto3.client('s3', endpoint_url="[http://192.168.10.20:7480](http://192.168.10.20:7480)")
s3.put_object(Bucket=BUCKET,
Key='foobar', Body=b'foobar',
SSECustomerKey=KEY,
SSECustomerAlgorithm='AES256')
print("put done")
print("getting object")
response = s3.get_object(Bucket=BUCKET, Key='foobar', SSECustomerKey=KEY, SSECustomerAlgorithm='AES256') print(response['Body'].read())
加密密钥保存在rgw
在集群配置文件/etc/ceph/ceph.conf里面,通过rgw crypt default encryption key来指定,缺点就是暴露了加密密钥。
[client.rgw.rgw1]
...
rgw crypt default encryption key = 4YSmvJtBv0aZ7geVgAsdpRnLBEwWSWlMIGnRS8a9TSA=
rgw_crypt_require_ssl = false
然后客户端和正常的使用方式一样,上传数据时,rgw会对数据进行加密保存。
持久化客户端的密钥
rgw客户端上传数据时,可以指定密钥,但后面如果忘记了这个密钥,就会无法读取数据了。这个时候我们存储系统需要保证客户端能够在忘记密钥的时候,也能读取数据。
实现思路就是客户端在上传数据时,把指定的密钥保存在应用数据对象的head对象的xattr里面。这样就算客户端忘记密钥了,也可以通过rados getxattr来获取密钥。
当然也可以增加配置项,来让用户决定是否开启该功能。
修改代码
rgw_crypt.cc文件:
int rgw_s3_prepare_decrypt(...){
...
std::string key_bin;
try {
key_bin = from_base64(s->info.env->get("HTTP_X_AMZ_SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY", ""));
// save user custom encrypt key to attr. start dyp
string custom_key = to_base64(key_bin);
bufferlist custom_key_bl;
custom_key_bl.append(custom_key.c_str(), custom_key.size() + 1);
attrs.emplace(std::move(RGW_ATTR_USER_CUSTOM_KEY), std::move(custom_key_bl));
// save user custom encrypt key to attr. end dyp
}
...
}
rgw_common.h 文件:
#define RGW_ATTR_X_ROBOTS_TAG RGW_ATTR_PREFIX "x-robots-tag"
// save user custom encrypt key to attr. start dyp
\#define RGW_ATTR_USER_CUSTOM_KEY RGW_ATTR_PREFIX "user_custom_key"
// save user custom encrypt key to attr. end dyp
测试
rgw客户端对数据加密存储的时候,其head对象增加了名为rgw_user_custom_key的xattr:
获取该rgw_user_custom_key的值,就可以拿到用户指定的加密密钥:
正常上传对象时,则不需要保存该xattr。