Skip to content

Node

We provide Node 8.9.4 image that runs inside of an enclave:

docker pull sconecuratedimages/apps:node-8.9.4-alpine

Example

Let's look at a little hello world program. First, we need to start a node container:

docker run -it --device=/dev/isgx -p3000:3000 sconecuratedimages/apps:node-8.9.4-alpine sh

In case you have no sgx driver installed, you can drop option --device=/dev/isgx for testing. The programs will then run in simulation mode, i.e., the SCONE software runs but in native mode and not inside an enclave.

Inside of the container, we first add npm:

apk add --no-cache nodejs-npm

Ensure we can run even in a resource-constrainted VM by setting the maximum heap size to a reasonable value of 1GB:

export SCONE_HEAP=1G

We create a new application myapp:

mkdir myapp
cd myapp
cat > package.json << EOF
{
  "name": "myapp",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
EOF

We install express with the help of npm:

npm install express --save

Let's store the hello world code:

cat > app.js << EOF
var express = require('express');
var app = express();
app.get('/', function (req, res) {
  res.send('Hello World!');
});
app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});
EOF

We can run this application inside of an enclave with node. We can also enable some debug messages by setting environment variable SCONE_VERSION=1 to print that we run inside of an enclave:

SCONE_VERSION=1 node app.js

This results in an output like this:

export SCONE_QUEUES=4
export SCONE_SLOTS=256
export SCONE_SIGPIPE=0
export SCONE_MMAP32BIT=0
export SCONE_SSPINS=100
export SCONE_SSLEEP=4000
export SCONE_KERNEL=0
export SCONE_HEAP=4294967296
export SCONE_STACK=4194304
export SCONE_CONFIG=/etc/sgx-musl.conf
export SCONE_MODE=hw
export SCONE_SGXBOUNDS=no
export SCONE_VARYS=no
export SCONE_ALLOW_DLOPEN=yes (unprotected)
export SCONE_MPROTECT=no
Revision: e349ed6e4821f0cbfe895413c616409848216173 (Wed Feb 28 19:28:04 2018 +0100)
Branch: master
Configure options: --enable-shared --enable-debug --prefix=/builds/scone/subtree-scone/built/cross-compiler/x86_64-linux-musl

Enclave hash: 28cf4f0953ba54af02b9d042fa2ec88a832d749ae4e5395cabd50369e72a5dcb
Example app listening on port 3000!

You can now try to send a request to myapp from another shell in the container. Assuming that you did not start a new container in meantime, execute in another shell of your host:

docker exec -it $(docker ps -l -q) sh

Inside of the container, first install curl and then query myapp:

apk add --no-cache curl
curl localhost:3000/

This results in an output like this:

Hello World!/ #

Potential error messages:

Could not create enclave: Error opening SGX device

Your machine / container does not support SGX. Set mode to automatic via SCONE_MODE=AUTO: in AUTO mode, SCONE will use SGX enclaves when available and emulation mode otherwise.

Killed

Your machine / container has most likely too little memory: the Linux OOM (Out Of Memory) killer, terminated your program. Try to reduce memory size by reducing environment variable SCONE_HEAP appropriately.

errno ENOSYS

SCONE does not yet support the fork system call (- this will happen later this year). If you spawn processes, there will be some error message like: npm ERR! spawn ENOSYS

Environment variables

SGXv1 cannot dynamically increase the memory of an enclave. Hence, we have to determine the maximum heap (and stack) size at program start: you can increase the heap by setting environment variable SCONE_HEAP, e.g., SCONE_HEAP=8G. In case you run out of memory inside the enclave, increase the heap size. In case your program gets killed by the OS, you might have selected a too large heap that is not supported by your VM or your host.

Similarily, you can increase the stack size of threads running inside of enclaves by setting environment variable SCONE_STACK.

Environment variable SCONE_VERSION=1 prints debug messages - to show that the program runs inside of an enclave.

SCONE_MODE=hw enforce that program runs in hardware enclave. By default, we set SCONE_MODE=auto which uses hardware enclave if available and software emulation otherwise.

Dockerfile

The above example, you could more easily put the following text in a Dockerfile:

FROM sconecuratedimages/apps:node-8.9.4-alpine
ENV SCONE_HEAP=1G
EXPOSE 3000
RUN apk add --no-cache nodejs-npm \
  && mkdir myapp \
  && cd myapp \
  && echo "{" > package.json \
  && echo '"name": "myapp",' >> package.json \
  && echo '"version": "1.0.0",' >> package.json \
  && echo '"description": "",' >> package.json \
  && echo '"main": "app.js",' >> package.json \
  && echo '"scripts":' >> package.json { \
  && echo '  "test": "echo \"Error: no test specified\" && exit 1"' >> package.json \
  && echo '},' >> package.json \
  && echo '"author": "",' >> package.json \
  && echo '"license": "ISC"' >> package.json \
  && echo '}' >> package.json \
  && npm install express --save \
  && echo "var express = require('express');" > app.js \
  && echo "var app = express();" >> app.js \
  && echo "app.get('/', function (req, res) {" >> app.js \
  && echo "  res.send('Hello World!');" >> app.js \
  && echo "});" >> app.js \
  && echo "app.listen(3000, function () {" >> app.js \
  && echo "  console.log('Example app listening on port 3000!');" >> app.js \
  && echo "});" >> app.js 

CMD SCONE_VERSION=1 node /myapp/app.js

Now create an image myapp as follows:

docker build -t myapp .

You can run a container of this image as a daemon as follows:

docker run -d -p 3000:3000 myapp

You can now query myapp as follows:

curl localhost:3000

This results in an output like this:

Hello World!

© scontain.com, March 2018. Questions or Suggestions?