Add flask tls server demo
This commit is contained in:
parent
cba8689bf3
commit
97812967f1
31
.github/workflows/demo_test.yml
vendored
31
.github/workflows/demo_test.yml
vendored
@ -675,3 +675,34 @@ jobs:
|
|||||||
|
|
||||||
- name: Run gvisor syscall test
|
- name: Run gvisor syscall test
|
||||||
run: docker exec $gvisor_test bash -c "cd /root/gvisor/occlum && SGX_MODE=SIM ./run_occlum_passed_tests.sh"
|
run: docker exec $gvisor_test bash -c "cd /root/gvisor/occlum && SGX_MODE=SIM ./run_occlum_passed_tests.sh"
|
||||||
|
|
||||||
|
Flask_tls_test:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- uses: ./.github/workflows/composite_action/sim
|
||||||
|
with:
|
||||||
|
container-name: ${{ github.job }}
|
||||||
|
build-envs: 'OCCLUM_RELEASE_BUILD=1'
|
||||||
|
|
||||||
|
- name: Download conda and build python
|
||||||
|
run: docker exec ${{ github.job }} bash -c "cd /root/occlum/demos/python/flask; ./install_python_with_conda.sh"
|
||||||
|
|
||||||
|
- name: Generate sample cert/key
|
||||||
|
run: docker exec ${{ github.job }} bash -c "cd /root/occlum/demos/python/flask; ./gen-cert.sh"
|
||||||
|
|
||||||
|
- name: Prepare and start Flask Occlum instance
|
||||||
|
run: docker exec ${{ github.job }} bash -c "cd /root/occlum/demos/python/flask;
|
||||||
|
SGX_MODE=SIM ./build_occlum_instance.sh; ./run_flask_on_occlum.sh &"
|
||||||
|
|
||||||
|
- name: Test PUT
|
||||||
|
run: |
|
||||||
|
sleep ${{ env.nap_time }};
|
||||||
|
docker exec ${{ github.job }} bash -c "cd /root/occlum/demos/python/flask;
|
||||||
|
curl --cacert flask.crt -X PUT https://localhost:4996/customer/1 -d "data=Tom""
|
||||||
|
- name: Test Get
|
||||||
|
run: docker exec ${{ github.job }} bash -c "cd /root/occlum/demos/python/flask;
|
||||||
|
curl --cacert flask.crt -X GET https://localhost:4996/customer/1"
|
||||||
|
57
demos/python/flask/README.md
Normal file
57
demos/python/flask/README.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Flask TLS demo on Occlum
|
||||||
|
|
||||||
|
This project demonstrates how Occlum enables _unmodified_ [Python](https://www.python.org) program [`flask`](https://github.com/pallets/flask) running in SGX enclaves, which is based on glibc.
|
||||||
|
|
||||||
|
`Flask` is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications.
|
||||||
|
|
||||||
|
## Sample Code: Flask TLS demo in Python
|
||||||
|
|
||||||
|
To make the sample code more realistic, we choose to start a simple Flask TLS server by [`flask-restful`](https://flask-restful.readthedocs.io/en/latest/quickstart.html). The sample code can be found [here](rest_api.py).
|
||||||
|
|
||||||
|
## How to Run
|
||||||
|
|
||||||
|
This tutorial is written under the assumption that you have Docker installed and use Occlum in a Docker container.
|
||||||
|
|
||||||
|
* Step 1: Download miniconda and install python to prefix position.
|
||||||
|
```
|
||||||
|
bash ./install_python_with_conda.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
* Step 2: Generate sample cert/key
|
||||||
|
```
|
||||||
|
bash ./gen-cert.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
* Step 3: Build Flask TLS Occlum instance
|
||||||
|
```
|
||||||
|
bash ./build_occlum_instance.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
* Step 4: Start the Flask TLS server on Occlum
|
||||||
|
```
|
||||||
|
bash ./run_flask_on_occlum.sh
|
||||||
|
```
|
||||||
|
It starts a sample Flask server like below:
|
||||||
|
```
|
||||||
|
occlum run /bin/rest_api.py
|
||||||
|
* Serving Flask app "rest_api" (lazy loading)
|
||||||
|
* Environment: production
|
||||||
|
WARNING: This is a development server. Do not use it in a production deployment.
|
||||||
|
Use a production WSGI server instead.
|
||||||
|
* Debug mode: off
|
||||||
|
* Running on all addresses.
|
||||||
|
WARNING: This is a development server. Do not use it in a production deployment.
|
||||||
|
* Running on https://localhost:4996/ (Press CTRL+C to quit)
|
||||||
|
```
|
||||||
|
|
||||||
|
* Step 5: Write some customers' info, such as
|
||||||
|
```
|
||||||
|
# curl --cacert flask.crt -X PUT https://localhost:4996/customer/1 -d "data=Tom"
|
||||||
|
# curl --cacert flask.crt -X PUT https://localhost:4996/customer/2 -d "data=Jerry"
|
||||||
|
```
|
||||||
|
|
||||||
|
* Step 6: Read the customers' info back
|
||||||
|
```
|
||||||
|
# curl --cacert flask.crt -X GET https://localhost:4996/customer/1
|
||||||
|
# curl --cacert flask.crt -X GET https://localhost:4996/customer/2
|
||||||
|
```
|
25
demos/python/flask/build_occlum_instance.sh
Executable file
25
demos/python/flask/build_occlum_instance.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BLUE='\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"
|
||||||
|
|
||||||
|
rm -rf occlum_instance && occlum new occlum_instance
|
||||||
|
cd occlum_instance && rm -rf image
|
||||||
|
copy_bom -f ../flask.yaml --root image --include-dir /opt/occlum/etc/template
|
||||||
|
|
||||||
|
if [ ! -d $python_dir ];then
|
||||||
|
echo "Error: cannot stat '$python_dir' directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
new_json="$(jq '.resource_limits.user_space_size = "640MB" |
|
||||||
|
.resource_limits.kernel_space_heap_size = "256MB" |
|
||||||
|
.process.default_mmap_size = "512MB" |
|
||||||
|
.env.default += ["PYTHONHOME=/opt/python-occlum"]' Occlum.json)" && \
|
||||||
|
echo "${new_json}" > Occlum.json
|
||||||
|
occlum build
|
||||||
|
|
23
demos/python/flask/flask.yaml
Normal file
23
demos/python/flask/flask.yaml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
includes:
|
||||||
|
- base.yaml
|
||||||
|
targets:
|
||||||
|
- target: /usr/bin
|
||||||
|
createlinks:
|
||||||
|
- src: /opt/python-occlum/bin/python3
|
||||||
|
linkname: python3
|
||||||
|
# python packages
|
||||||
|
- target: /opt
|
||||||
|
copy:
|
||||||
|
- dirs:
|
||||||
|
- ../python-occlum
|
||||||
|
# below are python code and data
|
||||||
|
- target: /bin
|
||||||
|
copy:
|
||||||
|
- files:
|
||||||
|
- ../rest_api.py
|
||||||
|
# Flask server key/cert
|
||||||
|
- target: /etc
|
||||||
|
copy:
|
||||||
|
- files:
|
||||||
|
- ../flask.crt
|
||||||
|
- ../flask.key
|
16
demos/python/flask/gen-cert.sh
Executable file
16
demos/python/flask/gen-cert.sh
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
pushd ~
|
||||||
|
openssl rand -writerand .rnd
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Geneate self-signed key/cert
|
||||||
|
# Generate valid Flask server Key/Cert
|
||||||
|
openssl genrsa -out flask.key 2048
|
||||||
|
openssl req -nodes -new -key flask.key -subj "/CN=localhost" -out flask.csr
|
||||||
|
openssl x509 -req -sha256 -days 365 -in flask.csr -signkey flask.key -out flask.crt
|
||||||
|
|
||||||
|
# Remove passphrase from the Key
|
||||||
|
openssl rsa -in flask.key -out flask.key
|
||||||
|
|
||||||
|
|
11
demos/python/flask/install_python_with_conda.sh
Executable file
11
demos/python/flask/install_python_with_conda.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||||
|
|
||||||
|
# 1. Init occlum workspace
|
||||||
|
[ -d occlum_instance ] || occlum new occlum_instance
|
||||||
|
|
||||||
|
# 2. Install python and dependencies to specified position
|
||||||
|
[ -f Miniconda3-latest-Linux-x86_64.sh ] || wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||||
|
[ -d miniconda ] || bash ./Miniconda3-latest-Linux-x86_64.sh -b -p $script_dir/miniconda
|
||||||
|
$script_dir/miniconda/bin/conda create --prefix $script_dir/python-occlum -y python=3.8 flask=1.1.2 flask-restful=0.3.8
|
33
demos/python/flask/rest_api.py
Executable file
33
demos/python/flask/rest_api.py
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
from flask import Flask, request
|
||||||
|
from flask_restful import Resource, Api
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.dirname(__file__))
|
||||||
|
|
||||||
|
cert = '/etc/flask.crt'
|
||||||
|
cert_key = '/etc/flask.key'
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
api = Api(app)
|
||||||
|
|
||||||
|
customers = {}
|
||||||
|
|
||||||
|
class Customer(Resource):
|
||||||
|
def get(self, customer_id):
|
||||||
|
return {customer_id: customers[customer_id]}
|
||||||
|
|
||||||
|
def put(self, customer_id):
|
||||||
|
customers[customer_id] = request.form['data']
|
||||||
|
return {customer_id: customers[customer_id]}
|
||||||
|
|
||||||
|
api.add_resource(Customer, '/customer/<string:customer_id>')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.debug = False
|
||||||
|
ssl_context = (cert, cert_key)
|
||||||
|
app.run(host='0.0.0.0', port=4996, threaded=True, ssl_context=ssl_context)
|
||||||
|
#app.run(host='0.0.0.0', port=4996, threaded=True)
|
10
demos/python/flask/run_flask_on_occlum.sh
Executable file
10
demos/python/flask/run_flask_on_occlum.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BLUE='\033[1;34m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# Run the python demo
|
||||||
|
cd occlum_instance
|
||||||
|
echo -e "${BLUE}occlum run /bin/rest_api.py${NC}"
|
||||||
|
occlum run /bin/rest_api.py
|
Loading…
Reference in New Issue
Block a user