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