# Building the manifest for Nginx: # # - make Building for Linux # - make DEBUG=1 Building for Linux, with Graphene debug output # - make SGX=1 Building for SGX # - make SGX=1 DEBUG=1 Building for SGX, with Graphene debug output # # Use `make clean` to remove Graphene-generated files. # # Use `make distclean` to further remove the Nginx tarball, source code, # and installation. THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) INSTALL_DIR ?= $(THIS_DIR)install NGINX_SRC ?= $(THIS_DIR)nginx-1.16.1 NGINX_CHECKSUM ?= f11c2a6dd1d3515736f0324857957db2de98be862461b5a542a3ac6188dbe32b # Mirrors for downloading the Nginx source code NGINX_MIRRORS ?= \ http://nginx.org/download/ # Address and port for the Nginx server to listen LISTEN_HOST ?= 127.0.0.1 LISTEN_PORT ?= 8002 # Relative path to Graphene root GRAPHENEDIR ?= $(THIS_DIR)../.. SGX_SIGNER_KEY ?= $(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem ifeq ($(DEBUG),1) GRAPHENEDEBUG = inline else GRAPHENEDEBUG = none endif .PHONY: all all: $(INSTALL_DIR)/sbin/nginx nginx.manifest pal_loader config testdata ifeq ($(SGX),1) all: nginx.manifest.sgx nginx.sig nginx.token endif include ../../Scripts/Makefile.configs # The make targets for downloading and compiling the Nginx source code, and # installing the binaries. # Note that Graphene doesn't support eventfd() and PR_SET_DUMPABLE, so we manually # overwrite these macros in the autogenerated configuration header of Nginx. $(INSTALL_DIR)/sbin/nginx: $(NGINX_SRC)/configure cd $(NGINX_SRC) && ./configure --prefix=$(abspath $(INSTALL_DIR)) sed -e "s|#define NGX_HAVE_EVENTFD[[:space:]]\+1|#define NGX_HAVE_EVENTFD 0|g" \ -e "s|#define NGX_HAVE_SYS_EVENTFD_H[[:space:]]\+1|#define NGX_HAVE_SYS_EVENTFD_H 0|g" \ -e "s|#define NGX_HAVE_PR_SET_DUMPABLE[[:space:]]\+1|#define NGX_HAVE_PR_SET_DUMPABLE 0|g" \ -i $(NGINX_SRC)/objs/ngx_auto_config.h cd $(NGINX_SRC) && $(MAKE) cd $(NGINX_SRC) && $(MAKE) install $(NGINX_SRC)/configure: $(NGINX_SRC).tar.gz tar -mxzf $< $(NGINX_SRC).tar.gz: $(GRAPHENEDIR)/Scripts/download --output $@ --sha256 $(NGINX_CHECKSUM) $(foreach mirror,$(NGINX_MIRRORS),--url $(mirror)/$(NGINX_SRC).tar.gz) # Nginx dependencies (generate from ldd): # # For SGX, the manifest needs to list all the libraries loaded during the # execution, so that the signer can include the file checksums. # # The dependencies are generated from the ldd results. # We need to replace Glibc dependencies with Graphene-specific Glibc. The Glibc # binaries are already listed in the manifest template, so we can skip them # from the ldd results GLIBC_DEPS = linux-vdso /lib64/ld-linux-x86-64 libc libm librt libdl libutil libpthread # Listing all the Nginx dependencies, besides Glibc libraries .INTERMEDIATE: nginx-ldd nginx-ldd: $(INSTALL_DIR)/sbin/nginx @for F in $(INSTALL_DIR)/sbin/nginx; do \ ldd $$F >> $@ || exit 1; done .INTERMEDIATE: nginx-deps nginx-deps: nginx-ldd @cat $< | awk '{if ($$2 =="=>") {split($$1,s,/\./); print s[1]}}' \ | sort | uniq | grep -v -x $(patsubst %,-e %,$(GLIBC_DEPS)) > $@ # Generating manifest rules for Nginx dependencies .INTERMEDIATE: nginx-trusted-libs nginx-trusted-libs: nginx-deps @HTTPD_LIBS="$(INSTALL_DIR)/sbin/nginx" && \ for F in `cat nginx-deps`; do \ P=`ldd $$HTTPD_LIBS | grep $$F | awk '{print $$3; exit}'`; \ N=`echo $$F | tr --delete '-'`; \ echo -n "sgx.trusted_files.$$N = file:$$P\\\\n"; \ done > $@ nginx.manifest: nginx.manifest.template nginx-trusted-libs sed -e 's|$$(GRAPHENEDIR)|'"$(GRAPHENEDIR)"'|g' \ -e 's|$$(GRAPHENEDEBUG)|'"$(GRAPHENEDEBUG)"'|g' \ -e 's|$$(INSTALL_DIR)|'"$(INSTALL_DIR)"'|g' \ -e 's|$$(INSTALL_DIR_ABSPATH)|'"$(abspath $(INSTALL_DIR))"'|g' \ -e 's|$$(NGINX_TRUSTED_LIBS)|'"`cat nginx-trusted-libs`"'|g' \ -e 's|$$(ARCH_LIBDIR)|'"$(ARCH_LIBDIR)"'|g' \ $< > $@ # Generating the SGX-specific manifest (nginx.manifest.sgx), the enclave signature, # and the token for enclave initialization. nginx.manifest.sgx: nginx.manifest $(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/pal-sgx-sign \ -libpal $(GRAPHENEDIR)/Runtime/libpal-Linux-SGX.so \ -key $(SGX_SIGNER_KEY) \ -manifest $< -output $@ nginx.sig: nginx.manifest.sgx nginx.token: nginx.sig $(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/pal-sgx-get-token \ -output nginx.token -sig nginx.sig # Extra executables pal_loader: ln -s $(GRAPHENEDIR)/Runtime/pal_loader $@ # Nginx configuration and test data # # The following changes are made in nginx.conf (copied as nginx-graphene.conf): # - Number of worker processes in increased from 1 to 4 # - Listening port is changed from 80 to LISTEN_PORT # - Listening host is changed from localhost to LISTEN_HOST # - Add `daemon off` to run Nginx in the foreground .PHONY: config config: $(INSTALL_DIR)/conf/nginx-graphene.conf $(INSTALL_DIR)/conf/nginx-graphene.conf: $(INSTALL_DIR)/conf/nginx.conf sed -e "s|^worker_processes[[:space:]]\+1;|worker_processes 4;|g" \ -e "s|listen[[:space:]]\+80;|listen $(LISTEN_PORT);|g" \ -e "s|server_name[[:space:]]\+localhost;|server_name $(LISTEN_HOST);|g" \ $< > $@ printf "\n\ndaemon off;\n" >> $@ # HTTP docs: # Generating random HTML files in $(INSTALL_DIR)/html/random RANDOM_DIR = $(INSTALL_DIR)/html/random RANDOM_FILES = \ $(foreach n,1 2 3 4 5 6 7 8 9 10,2K.$n.html) \ $(foreach n,1 2 3 4 5,10K.$n.html) \ $(foreach n,1 2 3 4 5,100K.$n.html) \ $(foreach n,1 2 3,1M.$n.html) \ $(foreach n,1 2 3,10M.$n.html) \ $(foreach n,1 2 3,100.$n.html) TEST_DATA = $(addprefix $(RANDOM_DIR)/,$(RANDOM_FILES)) $(RANDOM_DIR)/%.html: mkdir -p $(RANDOM_DIR) dd if=/dev/urandom of=$@ count=1 bs=$(basename $(basename $(notdir $@))) .PHONY: testdata testdata: $(TEST_DATA) # Targets to run Nginx .PHONY: start-native-server start-native-server: all $(INSTALL_DIR)/sbin/nginx -c conf/nginx-graphene.conf .PHONY: start-graphene-server start-graphene-server: all ./pal_loader nginx.manifest -c conf/nginx-graphene.conf .PHONY: clean clean: $(RM) *.manifest *.manifest.sgx *.token *.sig pal_loader OUTPUT result-* nginx-ldd tmp .PHONY: distclean distclean: clean $(RM) -r $(NGINX_SRC).tar.gz $(NGINX_SRC) $(INSTALL_DIR)