mirror of
https://github.com/matter-labs/nixsgx.git
synced 2025-07-21 15:33:56 +02:00

the custom `recursiveMerge` function was not working as expected. Signed-off-by: Harald Hoyer <harald@matterlabs.dev>
215 lines
6.9 KiB
Nix
215 lines
6.9 KiB
Nix
# SPDX-License-Identifier: Apache-2.0
|
|
# Copyright (c) 2024 Matter Labs
|
|
_:
|
|
{
|
|
mkSGXContainer =
|
|
{ lib
|
|
, pkgs
|
|
, coreutils
|
|
, curl
|
|
, nixsgx
|
|
, openssl
|
|
, packages
|
|
, entrypoint
|
|
, name
|
|
, tag ? null
|
|
, keyfile ? ./test-enclave-key.pem
|
|
, isAzure ? false
|
|
, manifest ? { }
|
|
, sgx_default_qcnl_conf ? null
|
|
, extraCmd ? ":"
|
|
, extraPostBuild ? ""
|
|
, extraChrootCommands ? ""
|
|
, appDir ? "/app"
|
|
, sigFile ? null
|
|
, extendedPackages ? [ ]
|
|
, customRecursiveMerge ? null
|
|
}:
|
|
assert lib.assertMsg (!(isAzure && sgx_default_qcnl_conf != null)) "sgx_default_qcnl_conf can't be set for Azure";
|
|
let
|
|
manifest_base = {
|
|
libos = { inherit entrypoint; };
|
|
fs = {
|
|
mounts = [
|
|
{ path = "/var/tmp"; type = "tmpfs"; }
|
|
{ path = "/tmp"; type = "tmpfs"; }
|
|
{ path = "${appDir}/.dcap-qcnl"; type = "tmpfs"; }
|
|
{ path = "${appDir}/.az-dcap-client"; type = "tmpfs"; }
|
|
];
|
|
root = { uri = "file:/"; };
|
|
start_dir = "${appDir}";
|
|
};
|
|
loader = {
|
|
argv = [ entrypoint ];
|
|
entrypoint = "file:{{ gramine.libos }}";
|
|
env = {
|
|
AZDCAP_COLLATERAL_VERSION = "v4";
|
|
AZDCAP_DEBUG_LOG_LEVEL = "ignore";
|
|
HOME = "${appDir}";
|
|
LD_LIBRARY_PATH = (lib.makeLibraryPath [
|
|
(if isAzure then nixsgx.azure-dcap-client.out else nixsgx.sgx-dcap.default_qpl)
|
|
pkgs.curl.out
|
|
]) + ":{{ gramine.runtimedir() }}:/lib";
|
|
MALLOC_ARENA_MAX = "1";
|
|
PATH = "/bin";
|
|
SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt";
|
|
};
|
|
log_level = "error";
|
|
};
|
|
sgx = {
|
|
remote_attestation = "dcap";
|
|
trusted_files = [
|
|
"file:${appDir}/"
|
|
"file:/bin/"
|
|
"file:/etc/gai.conf"
|
|
"file:/etc/ssl/certs/ca-bundle.crt"
|
|
"file:/lib/"
|
|
"file:/nix/"
|
|
"file:{{ gramine.libos }}"
|
|
"file:{{ gramine.runtimedir() }}/"
|
|
] ++ (if !isAzure then [
|
|
"file:/etc/sgx_default_qcnl.conf"
|
|
] else [ ]);
|
|
};
|
|
sys = {
|
|
enable_extra_runtime_domain_names_conf = true;
|
|
enable_sigterm_injection = true;
|
|
};
|
|
};
|
|
|
|
mergedManifest = (if customRecursiveMerge == null then lib.recursiveUpdate else customRecursiveMerge) manifest_base manifest;
|
|
|
|
tomlFormat = pkgs.formats.toml { };
|
|
manifestFile = tomlFormat.generate "${name}.manifest.toml" mergedManifest;
|
|
|
|
contents = pkgs.buildEnv {
|
|
name = "image-root";
|
|
|
|
paths = with pkgs.dockerTools; with nixsgx;[
|
|
openssl.out
|
|
curl.out
|
|
gramine
|
|
sgx-dcap.quote_verify
|
|
caCertificates
|
|
]
|
|
++ (if isAzure then [
|
|
azure-dcap-client
|
|
] else [
|
|
sgx-dcap.default_qpl
|
|
])
|
|
++ packages;
|
|
|
|
pathsToLink = [ "/bin" "/lib" "/etc" "/share" "${appDir}" ];
|
|
postBuild = ''
|
|
(
|
|
set -e
|
|
mkdir -p $out/{etc,var/run}
|
|
mkdir -p $out/${appDir}/{.dcap-qcnl,.az-dcap-client}
|
|
ln -s ${manifestFile} $out/${appDir}/${name}.manifest.toml
|
|
# Increase IPv4 address priority
|
|
printf "precedence ::ffff:0:0/96 100\n" > $out/etc/gai.conf
|
|
${
|
|
if sgx_default_qcnl_conf != null then
|
|
"rm -f $out/etc/sgx_default_qcnl.conf; ln -s ${sgx_default_qcnl_conf} $out/etc/sgx_default_qcnl.conf;"
|
|
else ""
|
|
}
|
|
eval "${extraPostBuild}"
|
|
)
|
|
'';
|
|
};
|
|
|
|
extendedContents = pkgs.buildEnv {
|
|
name = "extended-root";
|
|
|
|
paths = with pkgs.dockerTools; with nixsgx;[
|
|
coreutils
|
|
restart-aesmd
|
|
sgx-psw
|
|
usrBinEnv
|
|
binSh
|
|
fakeNss
|
|
] ++ extendedPackages;
|
|
|
|
pathsToLink = [ "/bin" "/lib" "/etc" "/share" ];
|
|
|
|
postBuild =
|
|
if sgx_default_qcnl_conf != null then ''
|
|
(
|
|
set -e
|
|
mkdir -p $out/etc
|
|
rm -f $out/etc/sgx_default_qcnl.conf
|
|
ln -s ${sgx_default_qcnl_conf} $out/etc/sgx_default_qcnl.conf
|
|
)
|
|
'' else null;
|
|
};
|
|
|
|
config = {
|
|
Env = [
|
|
"SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt"
|
|
"HOME=${appDir}"
|
|
"LD_LIBRARY_PATH=${lib.makeLibraryPath [ pkgs.curl.out (if isAzure then nixsgx.azure-dcap-client.out else nixsgx.sgx-dcap.default_qpl)]}"
|
|
];
|
|
Entrypoint = [ "/bin/sh" "-c" ];
|
|
Cmd = [ "${extraCmd}; [[ -r /var/run/aesmd/aesm.socket ]] || restart-aesmd >&2; exec gramine-sgx ${name}" ];
|
|
WorkingDir = "${appDir}";
|
|
};
|
|
|
|
|
|
# create a base image with the nix store included, because the derived image
|
|
# will run gramine-sgx-sign and has does not include store paths,
|
|
# otherwise all store paths from the `fakeRootCommands` will be included.
|
|
appImage = pkgs.dockerTools.buildLayeredImage { name = "${name}-app"; inherit contents; };
|
|
|
|
addGramineManifest = fromImage:
|
|
pkgs.dockerTools.buildLayeredImage
|
|
{
|
|
name = "${name}-manifest";
|
|
inherit tag;
|
|
inherit contents;
|
|
inherit fromImage;
|
|
|
|
includeStorePaths = false;
|
|
enableFakechroot = true;
|
|
fakeRootCommands = ''
|
|
(
|
|
set -e
|
|
cd ${appDir}
|
|
HOME=${appDir} ${nixsgx.gramine}/bin/gramine-manifest ${manifestFile} ${name}.manifest;
|
|
${nixsgx.gramine}/bin/gramine-sgx-sign \
|
|
--manifest ${name}.manifest \
|
|
--output ${name}.manifest.sgx \
|
|
--key ${keyfile};
|
|
eval "${extraChrootCommands}"
|
|
)
|
|
'';
|
|
};
|
|
|
|
injectSigFile = fromImage:
|
|
if sigFile != null then
|
|
pkgs.dockerTools.buildLayeredImage
|
|
{
|
|
inherit name;
|
|
inherit config;
|
|
inherit tag;
|
|
inherit fromImage;
|
|
|
|
includeStorePaths = false;
|
|
extraCommands = ''
|
|
mkdir -p app
|
|
cp ${sigFile} app/nixsgx-test-sgx-azure.sig
|
|
'';
|
|
}
|
|
else fromImage;
|
|
|
|
extendImage = fromImage:
|
|
pkgs.dockerTools.buildLayeredImage
|
|
{
|
|
inherit name;
|
|
inherit tag;
|
|
inherit config;
|
|
inherit fromImage;
|
|
contents = extendedContents;
|
|
};
|
|
in
|
|
injectSigFile (extendImage (addGramineManifest appImage));
|
|
}
|