EAS支持配置安全加密环境,允许加密后的模型进行安全部署和推理。该方式提供了多层次的安全保障,确保数据和模型在整个生命周期中的安全性。适用于对敏感数据要求较高的场景,例如金融服务、政府、企业级应用等。本文将详细介绍准备加密模型、进行加密部署以及安全推理的完整流程。
使用流程
本方案主要采用以下流程进行安全加密部署和推理:
加密模型:使用Gocryptfs或Sam对模型进行加密,并将加密后的模型上传到数据源中(例如对象存储OSS),方便后续在EAS中进行挂载部署。
存储解密密钥:目前,EAS支持阿里云托管的自建Trustee远程证明服务。在阿里云ACK Serverless中部署Trustee远程证明服务,用于对模型部署环境和推理环境进行安全验证,并使用阿里云密钥管理服务KMS作为解密密钥的存储后端。
在使用PAI-EAS部署加密模型时,系统会自动连接Trustee远程证明服务对部署环境进行验证。验证通过后,使用KMS中的密钥解密并挂载模型,然后将其部署为EAS服务。
部署完成后,启用可信网关代理容器,确保所有请求都经过安全检查。通过可信网关向服务发送请求进行安全推理,确保推理过程的安全性和可靠性。
步骤一:准备加密模型
在模型正式上云部署之前,您需要先对模型进行加密,然后将其上传到云存储。解密模型的密钥将由远程证明服务控制的KMS(密钥管理服务)负责托管。请在本地或可信环境中执行模型的加密操作。以部署Qwen2.5-3B-Instruct大模型为例,基于本地环境Alibaba Cloud Linux 3.2104 LTS 64(可访问公网),提供如下指导。
1.准备模型(可选)
如果您已有自己的模型,请跳过本章节,直接进入2.模型加密章节。
以使用modelscope工具下载Qwen2.5-3B-Instruct模型为例,在终端中执行如下命令下载模型。
pip3 install modelscope importlib-metadata
modelscope download --model Qwen/Qwen2.5-3B-Instruct
成功执行命令后,模型将被下载到~/.cache/modelscope/hub/models/Qwen/Qwen2.5-3B-Instruct/
目录下。
2.模型加密
PAI-EAS支持如下两种加密方式,本方案以Sam为例。
Gocryptfs:基于AES256-GCM,符合开源Gocryptfs标准的加密模式。
Sam:阿里云可信AI模型加密格式,保护模型机密性和License内容不被篡改和非法使用。
方案一:执行Sam加密
首先下载并解压Sam加密模块。
# 下载Sam加密模块压缩包 wget https://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/rai/RAI_SAM_SDK_2.1.0-20240731.tgz # 解压Sam加密模块 tar xvf RAI_SAM_SDK_2.1.0-20240731.tgz
使用Sam加密模块加密模型。
# 进入Sam加密模块的加密目录 cd RAI_SAM_SDK_2.1.0-20240731/tools # 加密模型 ./do_content_packager.sh <模型目录> <明文密钥> <密钥ID>
其中:
<模型目录>:待加密模型所在的目录,可以使用相对路径或绝对路径,例如
~/.cache/modelscope/hub/models/Qwen/Qwen2.5-3B-Instruct/
。<明文密钥>:自定义的加密密钥,有效长度为4 ~ 128字节,例如
alibaba@1688
。明文密钥是需要上传到远程证明服务(Trustee)的模型解密密钥。<密钥ID>:自定义的密钥标识,有效长度为8 ~ 48字节,例如
LD_Demo_0001
。
加密结束后,模型将以密文形式存储在当前路径的
<密钥ID>
目录中。
方案二:执行Gocryptfs加密
安装用于加密模型的工具Gocryptfs (目前只支持使用默认参数进行加密的Gocryptfs v2.4.0 版本)。您可以选择以下任意一种方式进行安装:
(推荐)方式一:直接下载预编译binary
# 下载预编译Gocryptfs压缩包 wget https://github.jobcher.com/gh/https://github.com/rfjakob/gocryptfs/releases/download/v2.4.0/gocryptfs_v2.4.0_linux-static_amd64.tar.gz # 解压并安装 tar xf gocryptfs_v2.4.0_linux-static_amd64.tar.gz sudo install -m 0755 ./gocryptfs /usr/local/bin
方式二:编译安装Gocryptfs
## 安装golang yum install go -y go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct ## 安装 Gocryptfs git clone https://github.com/rfjakob/gocryptfs.git cd gocryptfs git checkout -b v2.4.0 v2.4.0 ./build-without-openssl.bash sudo install -m 0755 ./gocryptfs /usr/local/bin
创建Gocryptfs密钥文件,作为模型加密的密钥。在后续步骤中,您需要将该密钥上传到远程证明服务(Trustee)进行托管。
在本方案中,使用
alibaba@1688
作为加密模型使用的密钥,密钥内容将存储在cachefs-password
文件中。您也可以自定义密钥。cat << EOF > ~/cachefs-password alibaba@1688 EOF
使用已创建的密钥对模型进行加密。
配置明文模型的路径。
说明在此处配置您刚才下载的明文模型所在路径,如果您有其他模型,请将其替换为目标模型的实际路径。
PLAINTEXT_MODEL_PATH=~/.cache/modelscope/hub/models/Qwen/Qwen2.5-3B-Instruct/
使用Gocryptfs对模型目录树进行加密。
加密完成后,模型将以密文形式存储在
./cipher
目录中。mkdir -p ~/mount cd ~/mount mkdir -p cipher plain # 安装Gocryptfs运行时依赖 sudo yum install -y fuse # initialize gocryptfs cat ~/cachefs-password | gocryptfs -init cipher # mount to plain cat ~/cachefs-password | gocryptfs cipher plain # move AI model to ~/mount/plain cp -r ${PLAINTEXT_MODEL_PATH} ~/mount/plain
3.上传模型
EAS支持将加密模型存储在多种存储后端,并在部署服务时,通过挂载的方式将解密后的模型加载到服务实例中。更多信息请参考服务存储挂载。
以对象存储OSS为例,请参考控制台快速入门创建一个存储空间(Bucket)和一个名为qwen-encrypted
的目录(例如oss://examplebucket/qwen-encrypted/
),然后使用ossutil工具将加密模型上传到该目录(您也可以使用自己的方法上传加密模型),以供推理服务挂载。以Sam加密为例,密文模型上传后的结果如下图所示。若采用Gocryptfs加密方式,模型文件的密文文件名将全部变成加密后的乱码。
4.搭建远程证明服务和上传密钥
将用于解密模型的密钥托管在远程证明服务中。远程证明服务是用户管理的验证服务,负责对模型和推理服务的运行环境做验证。只有当确认EAS模型部署环境的可信度符合预期条件时,才会注入模型解密密钥实现模型解密挂载。
目前,EAS支持阿里云托管的自建Trustee远程证明服务。您可以使用阿里云ACK Serverless来部署远程证明服务,对模型部署环境和推理环境进行验证。同时,利用阿里云KMS为模型解密密钥提供专业的安全保障。具体操作步骤如下:
ACK集群的地域不必与EAS部署服务的目标地域相同。
阿里云KMS实例必须和准备部署的阿里云Trustee远程证明服务所在的ACK集群处于相同地域。
在创建KMS实例和ACK集群之前,请先创建专有网络和2个交换机。具体操作,请参见创建和管理专有网络。
首先创建一个阿里云KMS实例作为密钥存储后端。
前往密钥管理服务控制台,在左侧导航栏选择 ,然后在软件密钥管理页签创建并启动实例。在启动实例时,请选择与ACK集群相同的专有网络。具体操作,请参见购买和启用KMS实例。
等待大约10分钟,即可启动完毕。
实例启动完成后,在左侧导航栏选择步骤一:创建软件密钥。
,然后在密钥管理页面为该实例创建一个用户主密钥。具体操作,请参见在左侧导航栏选择方式一:快速创建。
,然后在接入点页面为该实例创建应用接入点。其中作用域选择已创建的KMS实例。更多配置说明,请参见应用接入点创建成功后,浏览器会自动下载ClientKey***.zip文件,该zip文件解压后包含:
应用身份凭证内容(ClientKeyContent):文件名默认为
clientKey_****.json
。凭证口令(ClientKeyPassword):文件名默认为
clientKey_****_Password.txt
。
在
页面,单击KMS实例名称,然后在基础信息区域,单击实例CA证书后的下载,导出KMS实例的公钥证书文件PrivateKmsCA_***.pem
。
创建ACK服务集群并安装csi-provisioner组件。
前往创建集群页面,创建ACK Serverless集群,其中关键参数配置说明如下,更多配置说明,请参见创建集群。
集群配置:配置以下参数,完成后单击下一步:组件配置。
关键配置
描述
专有网络
选择使用已有,并勾选为专有网络配置SNAT,否则无法拉取Trustee镜像。
交换机
请确保在已有专有网络中创建至少两个虚拟交换机,否则无法暴露公网ALB。
组件配置:配置以下参数,完成后单击下一步:确认配置。
关键配置
描述
服务发现
选择CoreNDS。
Ingress
选择ALB Ingress,ALB云原生网关实例来源选择新建,并选择两个虚拟交换机。
确认配置:确认配置信息和使用须知,然后单击创建集群。
集群创建成功后,安装csi-provisioner(托管)组件。具体操作,请参见管理组件。
在ACK集群中部署Trustee远程证明服务。
首先通过公网或内网连接集群。具体操作,请参见连接集群。
将已下载的KMS实例的应用身份凭证(
clientKey_****.json
)、凭证口令(clientKey_****_Password.txt
)和CA证书(PrivateKmsCA_***.pem
),上传到连接ACK Serverless集群的环境中,并执行以下命令部署Trustee远程证明服务,使用阿里云KMS作为密钥存储后端。# 安装插件 helm plugin install https://github.com/AliyunContainerService/helm-acr helm repo add trustee acr://trustee-chart.cn-hangzhou.cr.aliyuncs.com/trustee/trustee helm repo update export DEPLOY_RELEASE_NAME=trustee export DEPLOY_NAMESPACE=default export TRUSTEE_CHART_VERSION=1.0.0 # 设置ACK集群所在的地域信息,比如cn-hangzhou export REGION_ID=cn-hangzhou # 刚才导出的KMS实例相关信息 # 替换为您的KMS实例ID export KMS_INSTANCE_ID=kst-hzz66a0*******e16pckc # 替换为您的KMS实例应用身份凭证所在路径 export KMS_CLIENT_KEY_FILE=/path/to/clientKey_KAAP.***.json # 替换为您的KMS实例凭证口令所在路径 export KMS_PASSWORD_FILE=/path/to/clientKey_KAAP.***_Password.txt # 替换为您的KMS实例CA证书所在路径 export KMS_CERT_FILE=/path/to/PrivateKmsCA_kst-***.pem helm install ${DEPLOY_RELEASE_NAME} trustee/trustee \ --version ${TRUSTEE_CHART_VERSION} \ --set regionId=${REGION_ID} \ --set kbs.aliyunKms.enabled=true \ --set kbs.aliyunKms.kmsIntanceId=${KMS_INSTANCE_ID} \ --set-file kbs.aliyunKms.clientKey=${KMS_CLIENT_KEY_FILE} \ --set-file kbs.aliyunKms.password=${KMS_PASSWORD_FILE} \ --set-file kbs.aliyunKms.certPem=${KMS_CERT_FILE} \ --namespace ${DEPLOY_NAMESPACE}
说明执行代码中第一条安装插件命令(
helm plugin install...
)可能需要较长时间。如果安装失败,可以先通过helm plugin uninstall cm-push
命令卸载该插件,然后重新执行插件安装命令。返回结果示例为:
NAME: trustee LAST DEPLOYED: Tue Feb 25 18:55:33 2025 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None
在连接ACK Serverless集群的环境中执行如下命令,来获取Trustee的访问地址。
export TRUSTEE_URL=http://$(kubectl get AlbConfig alb -o jsonpath='{.status.loadBalancer.dnsname}')/${DEPLOY_RELEASE_NAME} echo ${TRUSTEE_URL}
返回结果示例为
http://alb-ppams74szbwg2f****.cn-shanghai.alb.aliyuncsslb.com/trustee
。在连接ACK Serverless集群的环境中执行以下命令,测试Trustee服务的连通性。
cat << EOF | curl -k -X POST ${TRUSTEE_URL}/kbs/v0/auth -H 'Content-Type: application/json' -d @- { "version":"0.1.0", "tee": "tdx", "extra-params": "foo" } EOF
若Trustee服务运行状态正常,预期输出如下:
{"nonce":"PIDUjUxQdBMIXz***********IEysXFfUKgSwk=","extra-params":""}
配置Trustee网络白名单。
说明本项配置的目的是允许PAI-EAS模型部署环境主动访问远程证明服务,进行环境安全性检查。
前往阿里云ALB负载均衡控制台,创建访问控制策略组,并将访问Trustee权限的地址/地址段添加为IP条目。具体操作,请参见访问控制。其中,需要添加的地址段如下:
部署EAS服务时绑定的专有网络的公网IP地址。
推理客户端的出口IP地址。
使用如下命令获得集群上Trustee实例使用的ALB负载均衡实例ID。
kubectl get ing --namespace ${DEPLOY_NAMESPACE} kbs-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' | cut -d'.' -f1 | sed 's/[^a-zA-Z0-9-]//g'
预期输出如下结果:
alb-llcdzbw0qivhk0****
在阿里云ALB负载均衡控制台左侧导航栏,选择 ,在集群所在地域下搜索上一步获得的ALB实例,并单击实例ID进入实例详情页面。然后在页面最下方实例属性区域,单击关闭配置修改保护。
切换到监听页面,单击目标监听实例访问控制列下的启用,并配置白名单为上述步骤创建的访问控制策略组。
创建凭据来存储模型解密密钥。
Trustee托管的模型解密密钥实际上存储在KMS中,只有在远程证明服务验证目标环境后,密钥才能被访问。
前往密钥管理服务控制台,在左侧导航栏选择 ,然后在通用凭据页签,单击创建凭据。其中关键配置说明如下:
凭据名称:自定义凭据名称,用于索引该密钥,例如
model-decryption-key
。设置凭据值:填写加密模型时使用的密钥。例如
alibaba@1688
,您的密钥以实际为准。加密主密钥:选择上述步骤创建的主密钥。
步骤二:使用PAI-EAS部署加密模型
登录PAI控制台,在页面上方选择目标地域,并在右侧选择目标工作空间,然后单击进入EAS。
在模型在线服务(EAS)页面,单击部署服务,然后在自定义模型部署区域,单击自定义部署。
在自定义部署页面,配置以下关键参数,其他参数配置说明,请参见服务部署:控制台。
参数
描述
环境信息
部署方式
选择镜像部署。
镜像配置
选择镜像。在本方案示例场景中,选择官方镜像>chat-llm-webui:3.0-vllm。
模型配置
单击+OSS按钮,并配置以下参数:
OSS:请选择模型密文所在的目录。例如
oss://examplebucket/qwen-encrypted/
,您的路径以实际为准。挂载路径:配置为模型明文挂载的目录,例如
/mnt/model
。
运行命令
配置示例为
python webui/webui_server.py --port=8000 --model-path=/mnt/model --backend=vllm
。请注意,--model-path
需要与挂载路径保持一致,用于读取解密后的模型。端口号
本方案将端口号配置为8000。
环境变量
可添加环境变量,用于Trustee远程证明服务验证使用。本方案添加环境变量为:键
eas-test
:值123
。资源部署
部署资源
本方案资源规格选择ecs.gn7i-c8g1.2xlarge。
专有网络
专有网络(VPC)
配置专有网络并设置专有网络的SNAT公网出口IP,为EAS开通公网访问,以便能访问远程证明服务,并进行环境安全性检查。
交换机
安全组名称
服务功能
配置安全加密环境
打开配置安全加密环境开关,并配置以下参数:
文件加密方式:模型加密时使用的加密方式。支持Sam和Gocryptfs。本方案选择Sam。
系统信任管理服务地址:部署的Trustee服务地址。例如
http://alb-ppams74szbwg2f****.cn-shanghai.alb.aliyuncsslb.com/trustee
。解密密钥的KBS URI:使用的模型解密密钥的KBS URI,格式为
kbs:///default/aliyun/<密钥的凭据名称>
。请将<密钥的凭据名称>
替换为上述步骤已创建的凭据名称。
最终得到的JSON配置示例如下:
参数配置完成后,单击部署。
当服务状态为运行中时,表明服务已成功部署。此时,您可以在集群列表页面单击目标集群名称,然后在容器组页面按照下图操作指引,查看
attestation-service-*
容器日志。日志中会显示Trustee远程证明服务是否已对模型部署环境进行了验证,并详细展示执行环境信息等。
步骤三:调用服务进行安全推理
1.查看服务访问地址
在模型在线服务(EAS)页面,单击目标服务的服务方式列下的调用信息,获取服务访问地址和Token。
2.调用EAS服务
在终端中执行如下命令,启动可信网关代理容器。其中
${TRUSTEE_URL}
需要替换为Trustee地址(请参考4.搭建远程证明服务和上传密钥,查看Trustee地址)。说明目前可信网关代理服务仅支持容器部署,请在终端上安装Docker。
docker run -d \ --network=host \ confidential-ai-registry.cn-shanghai.cr.aliyuncs.com/product/tng:1.0.3 \ tng launch --config-content ' { "add_ingress": [ { "http_proxy": { "proxy_listen": { "host": "0.0.0.0", "port": 41000 }, "dst_filters": [ { "domain": "*.pai-eas.aliyuncs.com", "port": 80 } ] }, "encap_in_http": { "path_rewrites": [ { "match_regex": "^/api/predict/([^/]+)([/]?.*)$", "substitution": "/api/predict/\\1" } ] }, "verify": { "as_addr": "${TRUSTEE_URL}/as", "policy_ids": [ "default" ] } } ] } '
待可信网关代理容器启动完成后,您可以执行如下cURL命令,向推理服务发起推理请求。
重要请将推理客户端的出口IP添加到Trustee ALB的白名单中。具体操作,请参见4.配置Trustee网络白名单。若未添加,服务会调用失败。
export http_proxy=http://127.0.0.1:41000 curl <Service_URL> \ -H "Content-type: application/json" \ --data-binary @openai_chat_body.json \ -v \ -H "Connection: close" \ -H "Authorization: <Token>"
其中
<Service_URL>:配置为EAS服务访问地址。
<Token>:配置为EAS服务Token。
openai_chat_body.json为原始推理请求,请求内容示例如下:
{ "max_new_tokens": 4096, "use_stream_chat": false, "prompt": "What is the capital of Canada?", "system_prompt": "Act like you are a knowledgeable assistant who can provide information on geography and related topics.", "history": [ [ "Can you tell me what's the capital of France?", "The capital of France is Paris." ] ], "temperature": 0.8, "top_k": 10, "top_p": 0.8, "do_sample": true, "use_cache": true }
返回结果示例如下:
{ "response": "The capital of Canada is Ottawa.", "history": [ [ "Can you tell me what's the capital of France?", "The capital of France is Paris." ], [ "What is the capital of Canada?", "The capital of Canada is Ottawa." ] ] }