Skip to content
This repository has been archived by the owner on May 2, 2023. It is now read-only.

Commit

Permalink
Merge pull request #57 from brave/reproducible-example
Browse files Browse the repository at this point in the history
Make enclave application build reproducibly.
  • Loading branch information
Philipp Winter committed Apr 18, 2023
2 parents 07bc8d7 + d6c32ad commit cac319d
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 44 deletions.
2 changes: 1 addition & 1 deletion cmd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ lint:
golangci-lint run

$(binary): $(godeps)
CGO_ENABLED=0 go build -buildvcs=false -o $(binary)
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -buildvcs=false -o $(binary)

clean:
rm -f $(binary)
26 changes: 19 additions & 7 deletions example/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
FROM alpine:latest
# A Go base image is enough to build nitriding reproducibly.
# We use a specific instead of the latest image to ensure reproducibility.
FROM golang:1.20 as builder

RUN mkdir -p /lib64 && ln -sf /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
RUN apk add --no-cache py3-requests
WORKDIR /

COPY nitriding /
COPY service.py /
COPY start.sh /
# Clone the repository and build the stand-alone nitriding executable.
RUN git clone https://github.com/brave/nitriding.git
RUN make -C nitriding/cmd/ nitriding

CMD ["/start.sh"]
# Use the intermediate builder image to add our files. This is necessary to
# avoid intermediate layers that contain inconsistent file permissions.
COPY service.py start.sh /bin/
RUN chown root:root /bin/service.py /bin/start.sh
RUN chmod 0755 /bin/service.py /bin/start.sh

FROM python:3.11-slim-bullseye

# Copy all our files to the final image.
COPY --from=builder /nitriding/cmd/nitriding /bin/start.sh /bin/service.py /bin/

CMD ["start.sh"]
65 changes: 37 additions & 28 deletions example/Makefile
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
.PHONY: all docker enclave kill run clean

docker_image = python-test
enclave_image = $(docker_image).eif
godeps = ../cmd/*.go ../*.go ../go.mod ../go.sum
binary = nitriding

all: $(binary) docker enclave kill run

$(binary): $(godeps)
make -C ../cmd/
cp ../cmd/nitriding .

docker: Dockerfile
docker build -t $(docker_image):latest .

enclave:
nitro-cli build-enclave --docker-uri $(docker_image):latest --output-file $(enclave_image)

kill:
$(eval ENCLAVE_ID=$(shell nitro-cli describe-enclaves | jq -r '.[0].EnclaveID'))
@if [ "$(ENCLAVE_ID)" != "null" ]; then nitro-cli terminate-enclave --enclave-id $(ENCLAVE_ID); fi

run:
nitro-cli run-enclave --cpu-count 2 --memory 512 --enclave-cid 4 --eif-path $(enclave_image) --debug-mode
nitro-cli console --enclave-id $$(nitro-cli describe-enclaves | jq -r '.[0].EnclaveID')

prog := python-enclave
version := $(shell git describe --tag --dirty)
image_tag := $(prog):$(version)
image_tar := $(prog)-$(version)-kaniko.tar
image_eif := $(image_tar:%.tar=%.eif)

.PHONY: all
all: run

.PHONY: image
image: $(image_tar)

$(image_tar): Dockerfile service.py start.sh
docker run \
-v $(PWD):/workspace \
gcr.io/kaniko-project/executor:v1.9.2 \
--reproducible \
--no-push \
--tarPath $(image_tar) \
--destination $(image_tag) \
--custom-platform linux/amd64

$(image_eif): $(image_tar)
docker load -i $<
nitro-cli build-enclave \
--docker-uri $(image_tag) \
--output-file $(image_eif)

.PHONY: run
run: $(image_eif)
# Terminate already-running enclave.
nitro-cli terminate-enclave --all
# Start our proxy and the enclave.
./run-enclave.sh $(image_eif)

.PHONY: clean
clean:
rm -f $(binary)
rm -f $(image_tar) $(image_eif)
30 changes: 30 additions & 0 deletions example/run-enclave.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

if [ $# -ne 1 ]
then
echo >&2 "Usage: $0 IMAGE_EIF"
exit 1
fi
image_eif="$1"

# gvproxy is the untrusted proxy application that runs on the EC2 host. It
# acts as the bridge between the Internet and the enclave. The code is
# available here:
# https://github.com/brave-intl/bat-go/tree/master/nitro-shim/tools/gvproxy
echo "[ec2] Starting gvproxy."
sudo gvproxy -listen vsock://:1024 &
pid="$!"

# Run enclave in debug mode and attach console, to see what's going on
# inside. Note that this disables remote attestation.
echo "[ec2] Starting enclave."
nitro-cli run-enclave \
--cpu-count 2 \
--memory 600 \
--enclave-cid 4 \
--eif-path "$image_eif" \
--debug-mode \
--attach-console

echo "[ec2] Stopping gvproxy."
sudo pkill -INT -P "$pid"
12 changes: 6 additions & 6 deletions example/service.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#!/usr/bin/env python3

import time
import requests
import urllib.request

nitriding_url = "http://127.0.0.1:8080/enclave/ready"


def signal_ready():
r = requests.get(url=nitriding_url)
if r.status_code != requests.status_codes.codes.ok:
r = urllib.request.urlopen(nitriding_url)
if r.getcode() != 200:
raise Exception("Expected status code %d but got %d" %
(requests.status_codes.codes.ok, r.status_code))


def fetch_addr():
r = requests.get(url="https://ifconfig.me/ip")
r.raise_for_status()
print("[py] Our IP address is: %s" % r.text)
url = "https://raw.githubusercontent.com/brave/nitriding/master/README.md"
with urllib.request.urlopen(url) as f:
print("[py] Fetched %d bytes of README.md." % len(f.read(100)))


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions example/start.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/bin/sh

/nitriding -fqdn example.com -extport 443 -intport 8080 &
nitriding -fqdn example.com -extport 443 -intport 8080 &
echo "[sh] Started nitriding."

sleep 1

/service.py
service.py
echo "[sh] Ran Python script."

0 comments on commit cac319d

Please sign in to comment.