Este tópico descreve como compilar uma aplicação Intel Software Guard Extensions (SGX) 2.0 com o SDK de ambiente de execução confiável (TEE), empacotá-la e implantá-la em um cluster de computação confidencial do ACK. A aplicação de exemplo, helloworld, executa dentro de um enclave, gera mensagens periodicamente e as exibe no terminal.
Pré-requisitos
Antes de começar, verifique se você tem:
Um cluster gerenciado ACK para computação confidencial. Consulte Crie um cluster de computação criptografada e pool de nós
Acesso via SSH ou Cloud Assistant a uma instância compatível com computação confidencial
Git instalado ou permissão para instalá-lo com
sudo yum install gitDocker instalado. Consulte Instale e use o Docker em uma instância Linux
kubectlconfigurado para se conectar ao cluster ACK
Como funciona
Uma aplicação Intel SGX 2.0 tem dois componentes:
Componente não confiável: memória não criptografada que contém a função de entrada
main()e implementações de OCALL (chamada externa). No diagrama,main()ebar()executam no componente não confiável.Componente confiável (enclave): memória criptografada criada e protegida pela CPU. Somente a CPU acessa o código e os dados internos. No diagrama,
helloworld()efoo()executam dentro do enclave.
Para chamar funções do enclave a partir de código não confiável, a aplicação usa ECALL (chamada de enclave). Para invocar funções não confiáveis de dentro do enclave, usa OCALL. Ambas as chamadas são declaradas em arquivos EDL (Enclave Definition Language).
Código de exemplo e estrutura de diretórios
O código-fonte do helloworld está disponível no GitHub. Ele inclui o source da aplicação, Makefile e Dockerfile.
Estrutura de nível superior:
sgx-device-plugin/samples/hello_world/
├── Dockerfile
├── Makefile
├── README.md
└── src
├── App
│ ├── App.cpp
│ └── App.h
├── Enclave
│ ├── Enclave.config.xml
│ ├── Enclave.cpp
│ ├── Enclave.edl
│ ├── Enclave.h
│ ├── Enclave.lds
│ └── Enclave_private.pem
└── Makefile
O diretório src contém dois subdiretórios:
|
Diretório |
Descrição |
Arquivos principais |
|
|
Código não confiável: função de entrada |
|
|
|
Código confiável executado dentro do enclave |
|
Arquivos-fonte principais
Enclave/Enclave.edl — declara a interface ECALL e OCALL. Toda aplicação SGX deve declarar pelo menos um bloco trusted {} (ECALLs) ou um bloco untrusted {} (OCALLs) no arquivo EDL.
Neste exemplo, a aplicação precisa apenas de um ECALL: ecall_hello_from_enclave. Essa chamada cria um buffer dentro do enclave, grava "Hello world" nele e copia o conteúdo para um buffer não confiável, permitindo que o componente não confiável chame printf.
enclave {
trusted {
public void ecall_hello_from_enclave([out, size=len] char* buf, size_t len);
};
};
Enclave/Enclave.config.xml — controla os limites de recursos de tempo de execução do enclave. Três grupos de parâmetros determinam o comportamento de memória e threads:
Parâmetros TCS (
TCSNum,TCSPolicy):TCSNumdefine o número de Thread Control Structures e determina quantas threads podem executar simultaneamente dentro do enclave.TCSPolicycontrola se os slots TCS são vinculados a threads do SO ou se podem ser reutilizados.Parâmetros de pilha (
StackMaxSize): tamanho máximo de pilha disponível para cada thread do enclave. Se o enclave utilizar pilhas de chamadas profundas ou variáveis locais grandes, aumente este valor.Parâmetros de heap (
HeapMaxSize): tamanho máximo de heap disponível para o enclave. Defina este valor com base na quantidade de memória dinâmica alocada pelo código do enclave.
Para builds de produção, altere DisableDebug de 0 para 1 para impedir que depuradores se anexem ao enclave.
<EnclaveConfiguration>
<ProdID>0</ProdID>
<ISVSVN>0</ISVSVN>
<StackMaxSize>0x40000</StackMaxSize>
<HeapMaxSize>0x100000</HeapMaxSize>
<TCSNum>10</TCSNum>
<TCSPolicy>1</TCSPolicy>
<!-- Change 'DisableDebug' to 1 before release to prevent debugger access -->
<DisableDebug>0</DisableDebug>
<MiscSelect>0</MiscSelect>
<MiscMask>0xFFFFFFFF</MiscMask>
</EnclaveConfiguration>
Enclave/Enclave_private.pem — chave privada RSA usada para assinar enclave.so. Gerada com:
openssl genrsa -out Enclave/Enclave_private.pem -3 3072
Etapa 1: Compilar a aplicação hello_world
-
Instale o Git:
sudo yum install git -
Clone o repositório e compile:
git clone https://github.com/AliyunContainerService/sgx-device-plugin cd sgx-device-plugin/samples/hello_world SGX_SDK=/opt/alibaba/teesdk/intel/sgxsdk make buildO build executa seis etapas:
sgx_edger8re a função ECALLsgx_ecallgeram código stub não confiável (Enclave_u.c,Enclave_u.h) no diretórioApp.Compilação dos arquivos binários não confiáveis em
App.sgx_edger8rgera código confiável (Enclave_t.c,Enclave_t.h) no diretórioEnclave.Compilação de
enclave.socomo biblioteca de vínculo dinâmico confiável.sgx_signassinaenclave.soe produzenclave.signed.so.Vinculação do binário final
hello_world.
Um build bem-sucedido termina com uma saída semelhante a:
GEN => App/Enclave_u.h CC <= App/Enclave_u.c CXX <= App/App.cpp LINK => app GEN => Enclave/Enclave_t.h CC <= Enclave/Enclave_t.c CXX <= Enclave/Enclave.cpp LINK => enclave.so ... tcs_num 10, tcs_max_num 10, tcs_min_pool 1 The required memory is 3960832B. The required memory is 0x3c7000, 3868 KB. Succeed. SIGN => enclave.signed.so The project has been built in debug hardware modeVerifique se a última linha exibe
The project has been built in debug hardware mode. Isso confirma que o build utilizou hardware SGX real (não modo de simulação) e que a assinatura foi concluída com êxito. A árvore de saída compilada:sgx-device-plugin/samples/hello_world/src/ ├── hello_world #[generated] ├── App │ ├── App.cpp │ ├── App.h │ ├── App.o #[generated] │ ├── Enclave_u.c #[generated] │ ├── Enclave_u.h #[generated] │ └── Enclave_u.o #[generated] ├── Enclave │ ├── Enclave.config.xml │ ├── Enclave.cpp │ ├── Enclave.edl │ ├── Enclave.h │ ├── Enclave.lds │ ├── Enclave.o #[generated] │ ├── Enclave_private.pem │ ├── Enclave_t.c #[generated] │ ├── Enclave_t.h #[generated] │ └── Enclave_t.o #[generated] ├── enclave.signed.so #[generated] ├── enclave.so #[generated] └── Makefile -
Execute a aplicação em uma instância compatível com SGX para verificar seu funcionamento:
cd src/ ./hello_worldSaída esperada:
Wed May 6 06:53:33 2020 Hello world From SGX Enclave! Wed May 6 06:53:34 2020 Hello world From SGX Enclave! ...
Etapa 2: Compilar e implantar a aplicação helloworld
Use uma imagem base Alibaba Cloud Linux e instale o SGX SDK mais recente. Atualize o SDK periodicamente para obter correções de segurança.
Dockerfile de exemplo
FROM registry.cn-hangzhou.aliyuncs.com/alinux/alinux3
ARG REGION_ID=cn-hangzhou
RUN yum install -y curl && \
repo_url=https://enclave-${REGION_ID}.oss-${REGION_ID}.aliyuncs.com/repo/alinux/enclave-expr.repo && \
yum install -y yum-utils && \
yum-config-manager --add-repo ${repo_url} && \
yum install -y libsgx-urts libsgx-uae-service # Add more SGX runtime dependencies on demand.
WORKDIR /src
COPY src/hello_world src/enclave.signed.so /src
ENTRYPOINT ["/src/hello_world"]
O Dockerfile instala dois pacotes de runtime SGX obrigatórios:
libsgx-urts: sistema de runtime não confiável do SGX, necessário para carregar e executar enclaves.libsgx-uae-service: biblioteca de serviços de plataforma para atestação remota e operações relacionadas.
Compilar e enviar a imagem de contêiner
-
Compile e envie a imagem de contêiner. Substitua
${IMAGE_URL}pelo endereço do seu registro de imagens:cd sgx-device-plugin/samples/hello_world TARGET_IMAGE=${IMAGE_URL} SGX_SDK=/opt/alibaba/teesdk/intel/sgxsdk make image docker push ${IMAGE_URL} -
Implante a aplicação
helloworldno cluster ACK. Substitua${IMAGE_URL}pelo endereço da imagem obtido na etapa anterior:cat <<EOF | kubectl create -f - apiVersion: apps/v1 kind: Deployment metadata: name: helloworld namespace: default spec: replicas: 2 selector: matchLabels: app: helloworld template: metadata: labels: app: helloworld spec: containers: - image: ${IMAGE_URL} imagePullPolicy: Always name: helloworld resources: limits: cpu: 250m memory: 512Mi alibabacloud.com/sgx_epc_MiB: 2 EOF