containers / bubblewrap

Low-level unprivileged sandboxing tool used by Flatpak and similar projects
Other
3.88k stars 236 forks source link

Maybe provide more sandbox examples #76

Open pothos opened 8 years ago

pothos commented 8 years ago

Just an idea, but people might find it interesting to use bwrap instead of firejail. Here is a quick example to contain Skype and even use Xephyr instead of the current X session.

#!/bin/sh
Xephyr :9 -screen 600x700 -reset -terminate -host-cursor -ac 2> /dev/null &
sleep 3
DISPLAY=:9 metacity 2> /dev/null &
mkdir /tmp/skypepulseclientconf
echo "enable-shm = no" > /tmp/skypepulseclientconf/client.conf
bwrap --ro-bind / / --tmpfs /home --bind /home/$USER/.Skype /home/$USER/.Skype --bind /home/$USER/.config/Skype /home/$USER/.config/Skype  --tmpfs /tmp --proc /proc --dev /dev --mqueue /dev/mqueue --chdir /home/$USER --unshare-pid --tmpfs /run --ro-bind /run/user/$(id -u) /run/user/$(id -u) --bind /tmp/skypepulseclientconf /home/$USER/.config/pulse --unshare-cgroup-try --setenv DISPLAY ":9" --tmpfs /run/user/$(id -u)/gdm skype
# using bwrap to make all read-only, make pulse work through new client.conf, hide home content except for skype dirs which are writable, new empty tmp, dev and proc, own pid namespace
# optionally use xephyr as display 9 and hide xauth cookie through tmpfs for /run/user/<id>/gdm
cgwalters commented 8 years ago

Yeah, we should have more examples. Though for desktop apps Flatpak already exists and uses bwrap.

pothos commented 8 years ago

Yes, for sure Flatpak is recommendable first. It was aimed to contain the (Debian) package provided by skype.com and might be helpful for people who have something installed already they want to run.

groks commented 8 years ago

Here are some problems which could be avoided with better examples and documentation:

https://news.ycombinator.com/item?id=12241971

sebix commented 7 years ago

@pothos With your suggestion I get this on tumbleweed:

Can't mount mqueue on /newroot/dev/mqueue: Operation not permitted

I also removed Xephyr for this test.

fff7d1bc commented 7 years ago

Isn't it so, that you have /dev/mqueue mounted, but then something else mounted on the top of /dev? I am pretty sure I had such issue. Can you show /proc/mounts?

sebix commented 7 years ago

Hi, thanks for your help! This is the content of the file /proc/mounts:

sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
devtmpfs /dev devtmpfs rw,nosuid,size=502664k,nr_inodes=125666,mode=755 0 0
securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /run tmpfs rw,nosuid,nodev,mode=755 0 0
tmpfs /sys/fs/cgroup tmpfs ro,nosuid,nodev,noexec,mode=755 0 0
cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0
pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0
cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_cls,net_prio 0 0
cgroup /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids 0 0
cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpu,cpuacct 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
cgroup /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
/dev/sda2 / ext4 rw,relatime,data=ordered 0 0
systemd-1 /proc/sys/fs/binfmt_misc autofs rw,relatime,fd=24,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=11852 0 0
debugfs /sys/kernel/debug debugfs rw,relatime 0 0
hugetlbfs /dev/hugepages hugetlbfs rw,relatime 0 0
mqueue /dev/mqueue mqueue rw,relatime 0 0
tmpfs /var/run tmpfs rw,nosuid,nodev,mode=755 0 0
shared /media/sf_shared vboxsf rw,nodev,relatime 0 0
tmpfs /run/user/1000 tmpfs rw,nosuid,nodev,relatime,size=101804k,mode=700,uid=1000,gid=100 0 0
tmpfs /var/run/user/1000 tmpfs rw,nosuid,nodev,relatime,size=101804k,mode=700,uid=1000,gid=100 0 0
fusectl /sys/fs/fuse/connections fusectl rw,relatime 0 0
gvfsd-fuse /run/user/1000/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=100 0 0
gvfsd-fuse /var/run/user/1000/gvfs fuse.gvfsd-fuse rw,nosuid,nodev,relatime,user_id=1000,group_id=100 0 0
tracefs /sys/kernel/debug/tracing tracefs rw,relatime 0 0
alexlarsson commented 7 years ago

The reason for this:

    Can't mount mqueue on /newroot/dev/mqueue: Operation not permitted

Is that mounting an mqueue is not allowed by the kernel in an unprivileged user namespace. It works with a setuid bwrap though.

Does skype really need mqueue?

Also, for the temp config, you shouldn't have to create such files on the host at all, as they will be left around if things go bad. Instead use --file FD DEST. See the bubblewrap-shell.sh example in the source for how to use this from a script.

pothos commented 7 years ago

Ah, nice, thanks for the hint :) It also seems to work without mqueue but some other application might need it if one tries to provide examples which cover most cases.

sebix commented 7 years ago

Ok, removing mqueue and replacing the pulse-part with --dir /home/$USER/.config/pulse (I hope this is correct?) now gives:

Can't mkdir /run/user/1000/gdm: Read-only file system

Using sudo I get this error:

Can't find source path /home/sebix/.config/Skype: Permission denied

The bubblewrap-shell.sh example fails for me too (Can't find bash).

alexlarsson commented 7 years ago

So, the operations are applied in order, and you do:

--tmpfs /run --ro-bind /run/user/$(id -u) /run/user/$(id -u) --tmpfs /run/user/$(id -u)/gdm skype

This means /run is a tmpfs, but /run/user/1000 is a read-only copy of the host one, then you try to mount a tmpfs on /run/user/1000/gdm. But this does not exist, so bubblewrap tries to create it and fails since it is in a directory mounted readonly.

I'm not sure exactly why you need the gdm thing, but you could create the dir before staring bubblewrap, then it should work.

pothos commented 7 years ago

With GNOME Wayland session I use this:

#!/usr/bin/env bash
set -euo pipefail
(exec bwrap --ro-bind / / --tmpfs /home --bind /home/$USER/.Skype /home/$USER/.Skype --bind /home/$USER/.config/Skype /home/$USER/.config/Skype  --tmpfs /tmp --proc /proc --dev /dev --chdir /home/$USER --unshare-pid --tmpfs /run --ro-bind /run/user/$(id -u) /run/user/$(id -u) --file 11 /home/$USER/.config/pulse/client.conf --unshare-cgroup-try skype) 11< <(printf "enable-shm = no\nenable-memfd=true\n")
pothos commented 7 years ago

(A bit off topic and by the way: Maybe this whole issue can be closed now?) For the record: It's not recommended to use the Skype client anyway since it's incompatible now. Consider rather using Skype Web which chromium in a new profile by e.g. creating this desktop file:

[Desktop Entry]
Name=Skype Web
Comment=Skype Web application in a Chromium profile
Exec=sh -c "mkdir -p $HOME/.local/share/skypeweb && GDK_BACKEND=x11 chromium --user-data-dir=$HOME/.local/share/skypeweb https://web.skype.com 1>/dev/null 2>/dev/null &"
Terminal=false
Type=Application
Encoding=UTF-8
Categories=Network;Application;