Last weekend, I spent a bit of time improving a set of scripts I developed while at the Ubuntu Developer Summit in Orlando.
This script, now a small C program, is a proof of concept of desktop application container/sandbox using the same kernel features as LXC (a set of tools to manage containers on Linux) uses.
It basically does the following:
- Mount your / in a copy-on-write directory using aufs.
- Mount-bind your /home inside the copy-on-write environment.
- Switch to another UTS, “””PID” ” ” , IPC and NS context (keeping current network namespace)
- Mount a new /proc in the copy-on-write environment
- Chroot to the copy-on-write environment and switch user to your current user
At this point, the user will be in what looks like their home directory, though “ps” will only show a single process making it impossible to list or trace any process running outside this environment. Any change happening on the file system (outside of /home) will be recorded in a “cow” directory and be lost whenever the user exists the chroot.
This can be used to install an untrusted application in the chroot, test it, see exactly what it’s modifying on the filesystem without much risk for your actual system.
Current (known) limitations are:
- A GUI application will still be able to listen to events from any other X client (including key strokes)
- Change within /home aren’t stored in the copy-on-write as it’s bind-mounted.
- aufs doesn’t let you mount / in copy-on-write mode inside a directory that’s itself on / (to avoid loops), that’s why the current code requires a separate /home which will be bind-mounted (looking forward to btrfs for this).
- Running something as root in the container isn’t perfectly secure as access to /proc and /sys aren’t filtered. Though, it’s still a big improvement vs running the software directly on your system.
- The code is a proof of concept so it’s not meant for any serious usage, feel free to look at it, improve and propose patches 🙂
You can grab the code with bzr: bzr get lp:~stgraber/+junk/sandbox
or directly on Launchpad: https://code.launchpad.net/~stgraber/+junk/sandbox
could something like this be used to allow a non admin user to install a .deb package? maybe writing changes to a persistence file (like on the livecd).
Yes, it could. The long term goal is to use something similar to the code I wrote for Ubuntu as part of the application sandboxing effort.
It’d allow users to install software and use them without doing any real change on the system. The biggest issue with that so far is that /proc and /sys aren’t properly “virtualized” so something can “escape” the container. That’s why it’s safe when running software as a user but not entirely safe when running something as root (still a lot better than regular chroots though).
The initial use case, at least for me, is to run untrusted binaries, including installers and easily find which files they are trying to modify.
I always thought that this should be the default: I mean an application should have very limited access of hw/kernel/OS/whatever resources, only things exactly which are needed for their work. However then I can’t see clearly the difference about creating a sandbox with the steps you have mentioned above compared to “sendboxes” created with SELinux or apparmor, or whatever: sure the implementation details are different but the goal of their usage can be common.
The goal is definitely the same, as in restrict what a binary can do on your system.
I see them as covering slightly different areas though and both can probably do the other’s job with a lot of tweaking.
Apparmor is really good at restrict what a “trusted” binary on the system can do, as in restrict the files it’s allowed to access and the devices it can work with. If I remember well, it assumes the binary is going to be at a certain path on the filesystem and is therefore more suited for softwares shipped within a distribution.
sandbox is meant to be used for all these other cases where you get binaries (Windows softwares in wine, untrusted packages, weird RPMs you receive from manufacturers, …) that you don’t trust but still “need” to run and want to know what they’d do on your system.
For that, sandbox is great as it’ll run the application within something that looks like your real system, will let it do pretty much everything it wants but nothing will actually happen on your system.
So you can actually “study” the application and see if it’s harmful or not, instead of the Apparmor/SELinux way which would have required a profile to be written and then the application to simply fail should it not do what it’s supposed to.
Both solutions make a lot of sense and both should be used as much as possible, I just don’t see them as competitors.