Skip to content

Instantly share code, notes, and snippets.

@bendlas
Last active August 21, 2022 06:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bendlas/a5eb77731d58eb9fbb051c958b3efa1f to your computer and use it in GitHub Desktop.
Save bendlas/a5eb77731d58eb9fbb051c958b3efa1f to your computer and use it in GitHub Desktop.
example for unshare from the shell / running nix commands in a /nix directory not at root
#!/usr/bin/env nix-shell
#! nix-shell -i sh -p nix
set -e
ROOT="$1"; shift
USER_MOUNTS=$(nix-build --no-out-link shell.nix -A user-mounts)
ZSH=$(nix-build --no-out-link "<nixpkgs>" -A zsh)
CU=$(nix-build --no-out-link "<nixpkgs>" -A coreutils)
UL=$(nix-build --no-out-link "<nixpkgs>" -A utillinux)
NIX=$(nix-build --no-out-link "<nixpkgs>" -A nix)
SUDO=$(nix-build --no-out-link "<nixpkgs>" -A sudo)
nix copy --no-check-sigs --to local?root=$ROOT $USER_MOUNTS $ZSH $NIX $CU $SUDO $UL
exec $USER_MOUNTS/bin/unshare-user-mounts "
mount --make-rprivate /
mount --rbind $ROOT/nix /nix
export PATH='$ZSH/bin:$NIX/bin:$CU/bin:$SUDO/bin:$UL/bin'
" "$@"
#define _GNU_SOURCE
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
void remap(const char *conf_path, const char *id) {
int fd;
fd=open(conf_path, O_WRONLY);
write(fd,id,strlen(id));
write(fd," 0 1",4);
close(fd);
}
int main(int argc, char *argv[]) {
int fd;
unshare(CLONE_NEWUSER);
fd=open("/proc/self/setgroups",O_WRONLY);
write(fd,"deny",4);
close(fd);
remap("/proc/self/uid_map", argv[1]);
remap("/proc/self/gid_map", argv[2]);
execvp(argv[3],argv+3);
}
with import <nixpkgs> {};
{
user-mounts = callPackage ./user-mounts.nix {};
}
#!/bin/sh
set -evx
SETUP="$1"; shift
U=$(id -u)
G=$(id -g)
exec unshare -rmU -- sh -evxc "
$SETUP
exec @out@/bin/revertuid $U $G $@
"
{ runCommand, gcc }:
runCommand "user-mount-tools" {
nativeBuildInputs = [
gcc
];
} ''
mkdir -p $out/bin
gcc -o $out/bin/revertuid ${./revertuid.c}
substituteAll ${./unshare-user-mounts.in} $out/bin/unshare-user-mounts
chmod +x $out/bin/unshare-user-mounts
fixupPhase
''
@bendlas
Copy link
Author

bendlas commented Feb 3, 2019

revertuid.c is necessary, because setgroups gid_maps and uid_maps must be written together in a way that can't be done from shell

@VerTiGoEtrex
Copy link

This looks closely related to a question I recently asked on Reddit - I'd be curious if you have any advice on this. It seems unshare is probably the/a key I'm missing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment