sanebox: make it more obvious what we substitute at build-time

This commit is contained in:
2024-05-17 22:27:55 +00:00
parent 0698d4be24
commit 76434b6970
2 changed files with 48 additions and 53 deletions

View File

@@ -7,55 +7,42 @@
, substituteAll , substituteAll
, profileDir ? "/share/sanebox/profiles" , profileDir ? "/share/sanebox/profiles"
}: }:
stdenv.mkDerivation {
pname = "sanebox";
version = "0.1";
let src = ./sanebox;
sanebox = substituteAll { dontUnpack = true;
src = ./sanebox;
inherit bash bubblewrap firejail libcap;
landlockSandboxer = landlock-sandboxer;
firejailProfileDirs = "/run/current-system/sw/etc/firejail /etc/firejail ${firejail}/etc/firejail";
};
self = stdenv.mkDerivation {
pname = "sanebox";
version = "0.1";
src = sanebox; buildInputs = [
dontUnpack = true; bash # for cross builds, to ensure #!/bin/sh is substituted
];
buildPhase = '' buildPhase = ''
runHook preBuild runHook preBuild
substituteAll "$src" sanebox \ substitute $src sanebox \
--replace-fail '@out@' "$out" --replace-fail '@bwrap@' '${lib.getExe bubblewrap}' \
runHook postBuild --replace-fail '@firejail@' '${lib.getExe' firejail "firejail"}' \
--replace-fail '@landlockSandboxer@' '${lib.getExe landlock-sandboxer}' \
--replace-fail '@capsh@' '${lib.getExe' libcap "capsh"}'
runHook postBuild
'';
installPhase = ''
runHook preInstall
install -d "$out"
install -d "$out/bin"
install -m 755 sanebox $out/bin/sanebox
runHook postInstall
'';
meta = {
description = ''
helper program to run some other program in a sandbox.
factoring this out allows:
1. to abstract over the particular sandbox implementation (bwrap, firejail, ...).
2. to modify sandbox settings without forcing a rebuild of the sandboxed package.
''; '';
mainProgram = "sanebox";
installPhase = ''
runHook preInstall
install -d "$out"
install -d "$out/bin"
install -m 755 sanebox $out/bin/sanebox
runHook postInstall
'';
passthru = {
inherit landlock-sandboxer;
withProfiles = profiles: self.overrideAttrs (base: {
inherit profiles;
postInstall = (base.postInstall or "") + ''
install -d $out/share/sanebox
ln -s "${profiles}/${profileDir}" "$out/${profileDir}"
'';
});
};
meta = {
description = ''
helper program to run some other program in a sandbox.
factoring this out allows:
1. to abstract over the particular sandbox implementation (bwrap, firejail, ...).
2. to modify sandbox settings without forcing a rebuild of the sandboxed package.
'';
mainProgram = "sanebox";
};
}; };
in self }

20
pkgs/additional/sanebox/sanebox Normal file → Executable file
View File

@@ -1,4 +1,12 @@
#!@bash@/bin/bash #!/bin/sh
## BUILD-TIME SUBSTITUTIONS
### <bin>_FALLBACK: if `<bin>` isn't on PATH, then use this instead
FIREJAIL_FALLBACK='@firejail@'
BWRAP_FALLBACK='@bwrap@'
LANDLOCK_SANDBOXER_FALLBACK='@landlockSandboxer@'
CAPSH_FALLBACK='@capsh@'
## EARLY DEBUG HOOKS ## EARLY DEBUG HOOKS
@@ -552,7 +560,7 @@ firejailIngestKeepNamespace() {
} }
firejailGetCli() { firejailGetCli() {
locate _firejail "firejail" "@firejail@/bin/firejail" locate _firejail "firejail" "$FIREJAIL_FALLBACK"
cliArgs=( cliArgs=(
"$_firejail" "${firejailFlags[@]}" -- "$_firejail" "${firejailFlags[@]}" --
env "${portalEnv[@]}" "${cliArgs[@]}" env "${portalEnv[@]}" "${cliArgs[@]}"
@@ -645,7 +653,7 @@ bwrapGetCli() {
# --unshare-cgroup # --unshare-cgroup
# --unshare-uts # --unshare-uts
# --unshare-user (implicit to every non-suid call to bwrap) # --unshare-user (implicit to every non-suid call to bwrap)
locate _bwrap "bwrap" "@bubblewrap@/bin/bwrap" locate _bwrap "bwrap" "$BWRAP_FALLBACK"
cliArgs=( cliArgs=(
"$_bwrap" "${bwrapUnshareCgroup[@]}" "${bwrapUnshareIpc[@]}" "$_bwrap" "${bwrapUnshareCgroup[@]}" "${bwrapUnshareIpc[@]}"
"${bwrapUnshareNet[@]}" "${bwrapUnsharePid[@]}" "${bwrapUnshareNet[@]}" "${bwrapUnsharePid[@]}"
@@ -713,8 +721,8 @@ landlockGetCli() {
# so trampoline through `capsh` as well, to drop privs. # so trampoline through `capsh` as well, to drop privs.
# N.B: capsh passes its arg to bash (via /nix/store/.../bash), which means you have to `-c "my command"` to # N.B: capsh passes its arg to bash (via /nix/store/.../bash), which means you have to `-c "my command"` to
# invoke the actual user command. # invoke the actual user command.
locate _sandboxer "sandboxer" "@landlockSandboxer@/bin/sandboxer" locate _sandboxer "sandboxer" "$LANDLOCK_SANDBOXER_FALLBACK"
locate _capsh "capsh" "@libcap@/bin/capsh" locate _capsh "capsh" "$CAPSH_FALLBACK"
cliArgs=(env LL_FS_RO= LL_FS_RW="$landlockPaths" cliArgs=(env LL_FS_RO= LL_FS_RW="$landlockPaths"
"$_sandboxer" "$_sandboxer"
"$_capsh" "--caps=$capshCapsArg" --no-new-privs --shell="/usr/bin/env" -- "${portalEnv[@]}" "${cliArgs[@]}" "$_capsh" "--caps=$capshCapsArg" --no-new-privs --shell="/usr/bin/env" -- "${portalEnv[@]}" "${cliArgs[@]}"
@@ -762,7 +770,7 @@ capshonlyIngestCapability() {
} }
capshonlyGetCli() { capshonlyGetCli() {
locate _capsh "capsh" "@libcap@/bin/capsh" locate _capsh "capsh" "$CAPSH_FALLBACK"
cliArgs=( cliArgs=(
"$_capsh" "--caps=$capshCapsArg" --no-new-privs --shell="/usr/bin/env" -- "${portalEnv[@]}" "${cliArgs[@]}" "$_capsh" "--caps=$capshCapsArg" --no-new-privs --shell="/usr/bin/env" -- "${portalEnv[@]}" "${cliArgs[@]}"
) )