Skip to content

Commit 0a3eeb8

Browse files
rjd22jaapmarcus
andauthored
Add a bubblewrap jail that allows to create a sandboxed environment (hestiacp#4687)
* Add a bubblewrap jail that allows to create a sandboxed environment * Rebase and format --------- Co-authored-by: Jaap Marcus <9754650+jaapmarcus@users.noreply.github.com>
1 parent dbba10c commit 0a3eeb8

File tree

9 files changed

+173
-4
lines changed

9 files changed

+173
-4
lines changed

bin/v-add-sys-ssh-jail

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,32 @@ if [ ! -x /sbin/jk_init ]; then
2929
exit
3030
fi
3131

32+
# Checking if bubblewrap is installed
33+
if [ ! -x /bin/bwrap ]; then
34+
exit
35+
fi
36+
3237
# Perform verification if read-only mode is enabled
3338
check_hestia_demo_mode
3439

3540
#----------------------------------------------------------#
3641
# Action #
3742
#----------------------------------------------------------#
3843

44+
# Move jailbash to /usr/sbin
45+
if [ ! -x /usr/sbin/jailbash ]; then
46+
cp -f $HESTIA_COMMON_DIR/bubblewrap/jailbash /usr/sbin/jailbash
47+
cp -f $HESTIA_COMMON_DIR/bubblewrap/bwrap-userns-restrict /etc/apparmor.d/bwrap-userns-restrict
48+
chmod +x /usr/sbin/jailbash
49+
50+
service apparmor reload > /dev/null 2>&1
51+
fi
52+
53+
# Register /usr/sbin/jailbash
54+
if [ -z "$(grep ^/usr/sbin/jailbash /etc/shells)" ]; then
55+
echo "/usr/sbin/jailbash" >> /etc/shells
56+
fi
57+
3958
# Checking sshd directives
4059
config='/etc/ssh/sshd_config'
4160
ssh_i=$(grep -n "^# Hestia SSH Chroot" $config)

bin/v-delete-sys-ssh-jail

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ check_hestia_demo_mode
2929
# Action #
3030
#----------------------------------------------------------#
3131

32+
# Unregister /usr/sbin/jailbash
33+
sed -i "/\/usr\/sbin\/jailbash/d" /etc/shells
34+
35+
# Remove jailbash from /usr/sbin
36+
if [ -x /usr/sbin/jailbash ]; then
37+
rm -f /usr/sbin/jailbash
38+
rm -f /etc/apparmor.d/bwrap-userns-restrict
39+
40+
service apparmor reload > /dev/null 2>&1
41+
fi
42+
3243
# Checking sshd directives
3344
config='/etc/ssh/sshd_config'
3445
ssh_i=$(grep -n "^# Hestia SSH Chroot" $config)
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# This profile allows almost everything and only exists to allow bwrap
2+
# to work on a system with user namespace restrictions being enforced.
3+
# bwrap is allowed access to user namespaces and capabilities within
4+
# the user namespace, but its children do not have capabilities,
5+
# blocking bwrap from being able to be used to arbitrarily by-pass the
6+
# user namespace restrictions.
7+
8+
# Note: the bwrap child is stacked against the bwrap profile due to
9+
# bwraps use of no-new-privs.
10+
11+
abi <abi/4.0>,
12+
13+
include <tunables/global>
14+
15+
profile bwrap /usr/bin/bwrap flags=(attach_disconnected,mediate_deleted) {
16+
allow capability,
17+
# not allow all, to allow for pix stack on systems that don't support
18+
# rule priority.
19+
#
20+
# sadly we have to allow 'm' every where to allow children to work under
21+
# profile stacking atm.
22+
allow file rwlkm /{**,},
23+
allow network,
24+
allow unix,
25+
allow ptrace,
26+
allow signal,
27+
allow mqueue,
28+
allow io_uring,
29+
allow userns,
30+
allow mount,
31+
allow umount,
32+
allow pivot_root,
33+
allow dbus,
34+
35+
# stacked like this due to no-new-privs restriction
36+
# this will stack a target profile against bwrap and unpriv_bwrap
37+
# Ideally
38+
# - there would be a transition at userns creation first. This would allow
39+
# for the bwrap profile to be tighter, and looser within the user
40+
# ns. bwrap will still have to fairly loose until a transition at
41+
# namespacing in general (not just user ns) is available.
42+
# - there would be an independent second target as fallback
43+
# This would allow for select target profiles to be used, and not
44+
# necessarily stack the unpriv_bwrap in cases where this is desired
45+
#
46+
# the ix works here because stack will apply to ix fallback
47+
# Ideally we would sanitize the environment across a privilege boundry
48+
# (leaving bwarp into application) but flatpak etc use environment glibc
49+
# sanitized environment variables as part of the sandbox setup.
50+
allow pix /** -> &bwrap//&unpriv_bwrap,
51+
52+
# the local include should not be used without understanding the userns
53+
# restriction.
54+
# Site-specific additions and overrides. See local/README for details.
55+
include if exists <local/bwrap-userns-restrict>
56+
}
57+
58+
# The unpriv_bwrap profile is used to strip capabilities within the userns
59+
profile unpriv_bwrap flags=(attach_disconnected,mediate_deleted) {
60+
# not allow all, to allow for pix stack
61+
allow file rwlkm /{**,},
62+
allow network,
63+
allow unix,
64+
allow ptrace,
65+
allow signal,
66+
allow mqueue,
67+
allow io_uring,
68+
allow userns,
69+
allow mount,
70+
allow umount,
71+
allow pivot_root,
72+
allow dbus,
73+
74+
# bwrap profile does stacking against itself this will keep the target
75+
# profile from having elevated privileges in the container.
76+
# If done recursively the stack will remove any duplicate
77+
allow pix /** -> &unpriv_bwrap,
78+
79+
audit deny capability,
80+
81+
# the local include should not be used without understanding the userns
82+
# restriction.
83+
# Site-specific additions and overrides. See local/README for details.
84+
include if exists <local/unpriv_bwrap>
85+
}

install/common/bubblewrap/jailbash

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env bash
2+
3+
# Use bubblewrap to run /bin/bash reusing the host OS binaries (/usr), but with
4+
# separate /tmp, /home, /var, /run, and /etc. For /etc we just inherit the
5+
# host's resolv.conf, and set up "stub" passwd/group files.
6+
7+
set -euo pipefail
8+
(exec -a jailbash bwrap --ro-bind /usr /usr \
9+
--ro-bind /lib /lib \
10+
--ro-bind-try /lib64 /lib64 \
11+
--tmpfs /usr/lib/modules \
12+
--tmpfs /usr/lib/systemd \
13+
--ro-bind /bin /bin \
14+
--ro-bind /sbin /sbin \
15+
--dir /var \
16+
--dir /tmp \
17+
--symlink ../tmp var/tmp \
18+
--proc /proc \
19+
--dev /dev \
20+
--bind ${HOME} ${HOME} \
21+
--ro-bind-try /etc/profile /etc/profile \
22+
--ro-bind-try /etc/alternatives /etc/alternatives \
23+
--ro-bind-try /etc/localtime /etc/localtime \
24+
--ro-bind-try /etc/ld.so.cache /etc/ld.so.cache \
25+
--ro-bind-try /etc/resolv.conf /etc/resolv.conf \
26+
--ro-bind-try /etc/hosts /etc/hosts \
27+
--ro-bind-try /etc/nsswitch.conf /etc/nsswitch.conf \
28+
--ro-bind-try /etc/ssl /etc/ssl \
29+
--ro-bind-try /etc/pki /etc/pki \
30+
--ro-bind-try /etc/manpath.config /etc/manpath.config \
31+
--bind-try /run/mysqld/mysqld.sock /run/mysqld/mysqld.sock \
32+
--chdir ${HOME} \
33+
--unshare-all \
34+
--share-net \
35+
--die-with-parent \
36+
--dir /run/user/$(id -u) \
37+
--setenv XDG_RUNTIME_DIR "/run/user/$(id -u)" \
38+
--setenv PS1 "$(id -nu)$ " \
39+
--file 11 /etc/passwd \
40+
--file 12 /etc/group \
41+
/bin/bash -l "$@") \
42+
11< <(getent passwd $UID 65534) \
43+
12< <(getent group $(id -g) 65534)

install/hst-install-debian.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ software="acl apache2 apache2-suexec-custom apache2-suexec-pristine apache2-util
5252
php$fpm_v php$fpm_v-apcu php$fpm_v-bz2 php$fpm_v-cgi php$fpm_v-cli php$fpm_v-common php$fpm_v-curl php$fpm_v-gd
5353
php$fpm_v-imagick php$fpm_v-imap php$fpm_v-intl php$fpm_v-ldap php$fpm_v-mbstring php$fpm_v-mysql php$fpm_v-opcache
5454
php$fpm_v-pgsql php$fpm_v-pspell php$fpm_v-readline php$fpm_v-xml php$fpm_v-zip postgresql postgresql-contrib
55-
proftpd-basic quota rrdtool rsyslog spamd sysstat unrar-free unzip util-linux vim-common vsftpd xxd whois zip zstd jailkit restic"
55+
proftpd-basic quota rrdtool rsyslog spamd sysstat unrar-free unzip util-linux vim-common vsftpd xxd whois zip zstd jailkit bubblewrap restic"
5656

5757
installer_dependencies="apt-transport-https ca-certificates curl dirmngr gnupg openssl wget sudo"
5858

install/hst-install-ubuntu.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ software="acl apache2 apache2.2-common apache2-suexec-custom apache2-utils appar
5353
php$fpm_v-imagick php$fpm_v-imap php$fpm_v-intl php$fpm_v-ldap php$fpm_v-mbstring php$fpm_v-mysql php$fpm_v-opcache
5454
php$fpm_v-pgsql php$fpm_v-pspell php$fpm_v-readline php$fpm_v-xml php$fpm_v-zip postgresql postgresql-contrib
5555
proftpd-basic quota rrdtool rsyslog util-linux spamassassin
56-
sysstat unzip vim-common vsftpd whois zip zstd jailkit restic"
56+
sysstat unzip vim-common vsftpd whois zip zstd jailkit bubblewrap restic"
5757

5858
installer_dependencies="apt-transport-https ca-certificates curl dirmngr gnupg openssl software-properties-common wget sudo"
5959

src/deb/hestia/control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Section: admin
66
Maintainer: HestiaCP <info@hestiacp.com>
77
Homepage: https://www.hestiacp.com
88
Architecture: amd64
9-
Depends: bash, awk, sed, acl, sysstat, setpriv | util-linux (>= 2.33), zstd, lsb-release, idn2, jq, jailkit
9+
Depends: bash, awk, sed, acl, sysstat, setpriv | util-linux (>= 2.33), zstd, lsb-release, idn2, jq, jailkit, bubblewrap
1010
Description: hestia
1111
hestia is an open source hosting control panel.
1212
hestia has a clean and focused interface without the clutter.

src/rpm/hestia/hestia.spec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Source0: hestia-%{version}.tar.gz
1212
Source1: hestia.service
1313
Vendor: hestiacp.com
1414
Requires: redhat-release >= 8
15-
Requires: bash, chkconfig, gawk, sed, acl, sysstat, (setpriv or util-linux), zstd, jq, jailkit
15+
Requires: bash, chkconfig, gawk, sed, acl, sysstat, (setpriv or util-linux), zstd, jq, jailkit, bubblewrap
1616
Conflicts: vesta
1717
Provides: hestia = %{version}
1818
BuildRequires: systemd

test/test.bats

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,17 @@ function check_ip_not_banned(){
449449
assert_file_exist /etc/systemd/system/$mount_file
450450
}
451451

452+
@test "User: Change user bash with bubblewrap jail" {
453+
run v-change-user-shell $user jailbash no
454+
assert_success
455+
refute_output
456+
457+
run stat -c '%U' /home/$user
458+
assert_output --partial "$user"
459+
mount_file=$(systemd-escape -p --suffix=mount "/srv/jail/$user/home")
460+
assert_file_not_exist /etc/systemd/system/$mount_file
461+
}
462+
452463
@test "User: Change user default ns" {
453464
run v-change-user-ns $user ns0.com ns1.com ns2.com ns3.com
454465
assert_success

0 commit comments

Comments
 (0)