Occlum原理解析及使用说明

2024-05-06 13:04

本文主要是介绍Occlum原理解析及使用说明,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、设计初衷

二、背景知识

1.什么是可信计算

2.什么是TEE

3.传统SGX SDK的问题

三、Occlum

1.如何使用

2.特点

3.如何使用

1.Docker部署

1 硬件支持

2 环境

3 拉取镜像创建虚机

4 简单验证

4.Occlum中gcc编译

1 交叉编译

2 初始化Occlum实例

3 Occlum构建

4 运行

5.Occlum中go编译

6.Occlum中python编译


一、设计初衷

降低SGX使用门槛,打造一款小白也易于上手的可信执行环境框架。

二、背景知识

1.什么是可信计算

在许多现实环境中,比如公有云、边缘计算、区块链中,用户和服务器提供方扮演两个不同的利益主体,而用户想要保护自身应用程序和应用数据的隐私的同时能借助第三方服务器完成数据计算。而可信计算就解决了这个问题,即用户即使不相信第三方服务器也能保护应用的隐私性。

在另一个角度思考,数据的存储和数据传输在现实场景中都通过加密的方式解决,但是数据使用过程中的安全如何保护,这是可信计算主要解决的问题。

2.什么是TEE

普通的linux是左图的rich环境,将所有执行代码放在非可信区域,而TEE会将应用发放在可信区域,这些可信区域由硬件隔离、cpu加密等技术保护。

进程会自己启动一个enclave,相当于一个安全的隔离区,其基于cpu加密保护,也就是只要cpu层面安全就意味着恶意者无法获取enclave内部的相关数据。  

创建流程:

        1.用户在服务器上创建一个可信的enclave。
        2.非可信函数通过特殊的入口进入enclava,enclave进行可信检查。
        3.enclave内部程序进行计算,并返回计算结果到非可信区域。
        4.非可信区继续执行外部代码。

3.传统SGX SDK的问题

  • 开发难度较大,需要自身进行可信区和非可信的执行代码区分。
  • 语言支持性差,比如微软仅支持c++和go,百度的rust仅支持rust。
  • 语言支持不够全面,比如可信区域不支持调度非可信区的内容,语言的sys代码均不能使用,系统调用内容都不能使用。

三、Occlum

1.如何使用

用户提供执行内容,黄色部分,通过occlum build会将这些内容建立为 可信镜像,这个镜像即使放在非可信的环境上跑,也可以跑出可信的结果。相当于这是一个可信镜像,镜像内部所有数据都是被hash过不可被篡改。

用户上传镜像到部署环境,调用run命令即可,自动启动一个enclave,并将镜像中的执行程序读取到可信区域,并在内部安全执行。 并且所有的文件读写都是基于加密I/O保证读写安全。

2.特点

  • 高效的多任务处理。Occlum提供轻量级的LibOS进程:它们是轻量级的,因为所有LibOS进程共享相同的SGX飞地。与重量较重的每个飞地的LibOS进程相比,Occlum的轻量级LibOS进程在启动时快1000倍,在IPC上快3倍。此外,如果需要,Occlum提供了可选的PKU(用户空间保护密钥)功能,以增强Occlum的LibOS和用户空间进程之间的故障隔离。
  • 支持多个文件系统。Occlum支持各种类型的文件系统,例如只读散列FS(用于完整性保护)、可写加密FS(用于机密性保护)和不可信主机FS(用于LibOS和主机OS之间的方便数据交换)。
  • 记忆安全。Occlum是第一个使用内存安全编程语言(Rust)编写的SGX LibOS。因此,Occlum不太可能包含低级别的内存安全漏洞,并且更值得托管安全关键应用程序。
  • 易于使用。Occlum提供用户友好的构建和命令行工具。在SGX包围区内的Occlum上运行应用程序非常简单,只需键入几个shell命令即可(请参阅下一节)。

3.如何使用

1.Docker部署
1 硬件支持

首先,请确保裸机或虚拟机支持SGX。否则,用户只能尝试SW仿真模式。
为了更好地用户体验,要求带有FLC的SGX1或SGX2,用户可以使用cpuid命令检测硬件是否满足Occlum要求。

#SGX2
cpuid | grep SGX2
#FLC
cpuid | grep SGX_LC

注:暂无硬件支持,我们以仿真模式为例。

2 环境

实验环境:Ubuntu 22.04.3 LTS
Docker version 20.10.10, build b4856D36

3 拉取镜像创建虚机
# 1. Create softlinks on host
mkdir -p /dev/sgx
ln -sf ../sgx_enclave /dev/sgx/enclave
ln -sf ../sgx_provision /dev/sgx/provision
# 2. Create container in two methods:
# (1) With privileged mode特权模式
docker run -it --privileged -v /dev/sgx:/dev/sgx occlum/occlum:latest-ubuntu20.04
# (2) With non-privileged mode非特权模式
docker run -it --device /dev/sgx/enclave --device /dev/sgx/provision occlum/occlum:latest-ubuntu20.04
4 简单验证

SGX SDK提供了简单的样例来简单验证SGX是否正常工作。

cd /opt/intel/sgxsdk/SampleCode/SampleEnclave 

仿真模式下,需要将该目录下的Makefile中第35行SGX_MODE修改为SIM。

#Makefile中
35 SGX_MODE ?= SIM
make && ./app


到此,验证ok。Occlum自带的demo位置在/root/demos。

4.Occlum中gcc编译

以Hello World为例,展示如何在Occlum中编译SGX APP。

#include <stdio.h>int main() {printf("Hello World\n");return 0;
}
1 交叉编译
occlum-gcc -o hello_world hello_world.c
./hello_world

使用occlum-gcc编译时,生成的二进制文件将基于musl-libc库。
请注意,Occlum工具链并非传统意义上的交叉编译:Occlum工具链构建的二进制文件也可在Linux上运行。此属性使得编译、调试和测试用于Occlum的用户程序变得更加方便。

2 初始化Occlum实例
mkdir occlum_instance && cd occlum_instance
occlum init

或者

occlum new occlum_instance

occlum init命令在当前工作目录中创建Occlum的编译时和运行时状态。
occlum new命令基本上做了同样的事情,但是在一个新的实例目录中。
每个Occlum实例目录应用于应用程序的单个实例;多个应用程序或单个应用程序的不同实例应使用不同的Occlum实例。

3 Occlum构建
cp ../hello_world image/bin/
#仿真模式需要加参数 --sgx-mode SIM
occlum build --sgx-mode SIM

image目录的内容由occlum init命令初始化。镜像目录的结构模仿普通的UNIX FS,包含/bin、/lib、/root、/tmp等目录。将用户程序hello_world复制到镜像/bin/后,通过occlum build命令打包镜像目录,以生成安全的Occlum FS镜像以及Occlum SGX enclave。

4 运行
occlum run /bin/hello_world

occlum run命令启动一个Occlum SGX enclave,在幕后验证并加载相关的Occlum FS镜像,产生一个新的LibOS进程来执行/bin/hello_world,最终打印出消息。

5.Occlum中go编译

以Hello World为例,展示如何在Occlum中编译SGX APP。我们需要go_hello.go(源码)、go_hello.yaml(配置文件)和run_go_hello.sh(运行脚本)。

go_hello.go

package mainimport ("fmt"_ "go-sqlite3"
)func main() {fmt.Println("Hello World")
}

go_hello.yaml

includes:- base.yaml
targets:- target: /bincopy:- files:- ../go_hello

run_go_hello.sh

#!/bin/bash
set -eBLUE='\033[1;34m'
NC='\033[0m'rm -f go.mod  && occlum-go mod init go_hello_instanceocclum-go build -o go_hello go_hello.go# Init Occlum Workspace
rm -rf go_hello_instance && mkdir go_hello_instance
cd go_hello_instance
occlum init
new_json="$(jq '.resource_limits.user_space_size = "2560MB" |.resource_limits.kernel_space_heap_size="320MB" |.resource_limits.kernel_space_stack_size="10MB" |.process.default_stack_size = "40MB" |.process.default_heap_size = "320MB" ' Occlum.json)" && \
echo "${new_json}" > Occlum.json# Copy program into Occlum Workspace and build
rm -rf image && \
copy_bom -f ../go_hello.yaml --root image --include-dir /opt/occlum/etc/template && \
occlum build --sgx-mode SIMecho -e "${BLUE}occlum run /bin/go_hello${NC}"
time occlum run /bin/go_hello                              

运行脚本之后,效果如下:



注:go-sqlite3这个包需要导入。

6.Occlum中python编译

以Hello World为例,展示如何在Occlum中编译SGX APP。我们需要
hello.py

#!/usr/bin/python
# -*- coding: UTF-8 -*-print("hello world!")

python-hello.yaml

includes:- base.yaml
targets:- target: /bincreatelinks:- src: /opt/python-occlum/bin/python3linkname: python3# python packages- target: /optcopy:- dirs:- ../python-occlum# below are python code and data- target: /copy:- from: ..files:- hello.py                

run_python_hello.sh

#!/bin/bash
set -eBLUE='\033[1;34m'
NC='\033[0m'script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}"  )" >/dev/null 2>&1 && pwd )"
python_dir="$script_dir/occlum_instance/image/opt/python-occlum"[ -d occlum_instance ] || occlum new occlum_instancecd occlum_instance && rm -rf image
copy_bom -f ../python-hello.yaml --root image --include-dir /opt/occlum/etc/templateif [ ! -d $python_dir ];thenecho "Error: cannot stat '$python_dir' directory"exit 1
finew_json="$(jq '.resource_limits.user_space_size = "640MB" |.resource_limits.kernel_space_heap_size = "300MB" |.env.default += ["PYTHONHOME=/opt/python-occlum"]' Occlum.json)" && \
echo "${new_json}" > Occlum.json
occlum build --sgx-mode SIM# Run the python demo
echo -e "${BLUE}occlum run /bin/python3 hello.py${NC}"
occlum run /bin/python3 hello.py

执行脚本之后,效果如下:

参考文献:

1.GitHub - occlum/occlum: Occlum is a memory-safe, multi-process library OS for Intel SGX

2.Occlum: Secure and Efficient Multitasking Inside a Single Enclave of Intel SGX

3.SOFAChannel#18:零门槛的机密计算:Occlum使用入门与技术解密_哔哩哔哩_bilibili

4.使用手册

这篇关于Occlum原理解析及使用说明的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/964430

相关文章

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

一文解析C#中的StringSplitOptions枚举

《一文解析C#中的StringSplitOptions枚举》StringSplitOptions是C#中的一个枚举类型,用于控制string.Split()方法分割字符串时的行为,核心作用是处理分割后... 目录C#的StringSplitOptions枚举1.StringSplitOptions枚举的常用

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

MyBatis延迟加载与多级缓存全解析

《MyBatis延迟加载与多级缓存全解析》文章介绍MyBatis的延迟加载与多级缓存机制,延迟加载按需加载关联数据提升性能,一级缓存会话级默认开启,二级缓存工厂级支持跨会话共享,增删改操作会清空对应缓... 目录MyBATis延迟加载策略一对多示例一对多示例MyBatis框架的缓存一级缓存二级缓存MyBat

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他