So on Saturday I blogged about a piece of code I wrote to easily create containers on a recent Linux desktop. I have now spent a few more hours improving the code a bit with two main new features:
- Support for turning on/off network access
- Support for mounting /home as aufs too
The on/off switch for network access is done by putting (or not) the spawned shell in another network namespace. This means that if network is disabled for the container, the software running in the container will only see a loopback device. This loopback device itself is separate from the one available outside the container, so a contained software won’t be able to access anything that listens on the loopback interface outside of the container.
I also switched to creating a “mount” directory that’s a tmpfs and which in turn contains the various mount points for the container. This workarounds the fact that you can’t mount an aufs filesystem in a sub-directory of its base filesystem (or it’d create a loop).
I updated the README in the branch accordingly and added basic getopt support for the two options.
Code can be found in a bzr branch: bzr get lp:~stgraber/+junk/sandbox
Or from: https://code.launchpad.net/~stgraber/+junk/sandbox
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