-
Notifications
You must be signed in to change notification settings - Fork 0
/
jail
executable file
·89 lines (76 loc) · 2.47 KB
/
jail
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env -S unshare -rm --map-auto sh
# Copyright (C) 2022, Sol Boucher
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
# Lesser General Public License as published by the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along with this program.
# If not, see <https://www.gnu.org/licenses/>.
if [ "$#" -eq "0" ]
then
cat <<-tac
USAGE: $0 <mountpoint> [cmdline]...
Enters a container at <mountpoint>---which can be an empty/nonexistent directory or
a template root "filesystem" (in which case it will be write protected)---and
executes the specified [cmdline] if provided (or otherwise spawns an instance of the
current shell).
Note that while most resources are isolated from the rest of the system, notable
exceptions include interprocess communication, networking, and the abstract sockets
namespace. The container is intended for use on a headless system, since otherwise
its contents could break out via the X Window System.
Once a directory tree has been write protected by this command, one must manually
reverse this operation in order to remove it. This can be done via the accompanying
unprotect script.
tac
exit 1
fi
dir="$1"
shift
[ -e "$dir" ] || mkdir "$dir"
if [ -n "`ls "$dir"`" ]
then
# Workaround so mount -M will not be a no-op.
mount -B "$dir" "$dir"
[ -e "$dir/home" ] || chown -R nobody: "$dir"
nonempty="true"
else
mount -t tmpfs none "$dir"
nonempty="false"
fi
cd "$dir"
ln -sf lib/x86_64-linux-gnu lib64
if [ -d bin ]
then
ln -sf ../usr/bin/sh bin
ln -sf "../usr/bin/`basename "$SHELL"`" bin
else
ln -sf usr/bin .
fi
mkdir -p dev
mkdir -p etc
mkdir -p lib
mkdir -p proc
mkdir -p usr
mount -R /dev dev
mount -Bo ro /etc etc
mount -Bo ro /lib lib
mount -R /proc proc
mount -Bo ro,nosuid /usr usr
mkdir -p home/nobody
mkdir -p tmp
mount -t tmpfs none home/nobody
mount -t tmpfs none tmp
cp -r etc/skel/. home/nobody
if "$nonempty"
then
chown nobody: home
else
mount -o remount,ro none .
fi
# Allow unshare within unshare -R.
mount -M . / 2>/dev/null
exec env -i HOME=/home/nobody PATH="$PATH" SHELL="$SHELL" TERM="$TERM" unshare -R. unshare -Upf --mount-proc --kill-child "$@"