# Fatdog64 Sandbox Environment

## Introduction

Fatdog (since version 520) comes with a sandbox tool built-in. The tool is activated through terminal - there is no menu or GUI for this. The commands are:

1. sandbox.sh
2. rw-sandbox.sh
3. sb2dir.sh

sandbox.sh and rw-sandbox.sh are identical, except that sandbox.sh stores the content of the sandbox session in tmpfs (therefore it's not persistent), while rw-sandbox.sh stores the session in a file. An analogy with running Fatdog would be:

1. running sandbox.sh is analog to running with savefile=none
2. running rw-sandbox.sh is analog to running with a savefile.

In the following description, all references to sandbox.sh also means rw-sandbox.sh except when noted.

## Intended Purposes

The sandbox is meant for:

1. Testing foreign packages
2. Creating new packages
3. Isolate well-behaved applications

### 1. Testing Foreign Packages

When a new package is installed, it will install its files into the system. Other than package integrity, there is no checks done on what files are inside. If a package modifies system files and libraries (overwriting libraries with bad ones, or deleting necessary system files), the system could stop working (which could be "fixed" by rebooting without savefile and then create a new savefile, but it is still an unnecessary hassle).

Sandbox is the solution to this. The sandbox creates an environment which is similar to the currently running system, but is safely separated from it. Any changes made to the files inside the sandbox (with few exceptions) will not affect anything outside. One can thus start the sandbox, install any number of packages in it, test them, and when done, leave the sandbox - and everything will be restored.

### 2. Creating New Package

Most packages can be created by using the standard recipe of:

- configure & build the packages
- install the package, capturing the output on the way so that we can package it later.

The usual steps for packages that uses autoconf are:

- extract the source tarball
- ./configure && make && make DESTDIR=/tmp/pkgname install
- dir2pet /tmp/pkgname

Or

- extract the source tarball
- ./configure && make
- new2dir make install

But this has obvious limitations. For one, it only works with packages that uses autoconf as its build system. Secondly, not all packages act kindly with new2dir - they don't always work. For example, python packages can't be captured this way. Other build systems (cmake, jam, etc) also can't be captured this way.

Sandbox provides a solution to this. A package can be configured, built and installed in the sandbox - without any use of Puppy's specific tools. Once this is done and the package is confirmed to work, all that is left to do is to scrape the files that were changed and installed - and the sandbox makes this super easy. In fact, the third command in the sandbox package (sb2dir.sh - sandbox-to-directory) will do this automatically. Supply it with a directory name and it will look for all the changed files from the sandbox, copy them over to "/tmp/dir-name-that-you-give". All you need to do afterwards is to check the files inside, once you are happy with it, just run makepkg inside on that directory.

### 3. Isolate well-behaved applications

Application installation usually places files in many places in the filesystem. After the application is run, it also creates configuration and other files, in a way. If you need to install many applications, but they are only used very rarely, it is easy to grow your savefile to become very large and cluttered with all these applications. Some applications offer "portable" versions and can be installed in one directory, but many are not. Is there a way around this?

Or you may want to install an application but run it with different or multiple configurations, which isn't supported natively. You can switch config files back and forth to do this, but is there an easier way?

Of course: use the sandbox! Starting from version 622 onwards, multiple sandboxes can be run at the same time, making it an ideal way to isolate applications. Create an rw-sandbox for every application you want to isolate. Install the application from within the sandbox, and then run it. When you're done, close the sandbox. This way, you can have a rw-sandbox for each application. You can even have multiple sandboxes for the same application, each with different configuration. Need to configure and keep different versions of the same application? No problem too!

Note: This only works for "well-behaved" application - that is application which do not pose security risk to your system. The sandbox is not a security tool. It is still possible for malicious apps to create havoc on the system. It is possible for malicious application to "escape" from the sandbox. If you need to secure yourself from these, you need a stronger sandboxing: consider using Linux Container sandbox or User Mode Linux or other virtualisation solutions such as Qemu (with/without KVM), VirtualBox, or others.

## Usage

### Starting the sandbox

Start the sandbox by running sandbox.sh. A dialog box will be shown, showing all the currently mounted SFS (this includes Fatdog's save file, Fatdog's main sfs, and any other SFS currently mounted). One can choose which SFS will be loaded into the sandbox. If the SFS is not chosen, they won't be loaded and won't be visible. For example, for testing packages in pristine conditions, one can choose not to load the currently used save-file. The sandbox environment will then be almost identical to running Fatdog with savefile=none.

rw-sandbox.sh behaves identically - except that, first, it will ask the user where to store the permanent session file (="the savefile"). You can also pass the path to the "savefile" as the first parameter to rw-sandbox.

From Fatdog64 720 onwards, you can pass the command to be executed in sandbox by as an argument to sandbox.sh or rw-sandbox.sh.

### Inside the sandbox

Once inside the sandbox, one can do almost everything that one can do in the system itself. Running terminal commands obviously work. Running GUI programs will work.

In addition, the sandbox comes with a full desktop emulation environment - this can be started by typing xwin inside sandbox. A nested Xorg server (Xephyr), complete with its own instance of openbox, rox and lxpanel will launch.

Note: if one wishes to run "rox" without the full desktop emulation environment, one has to use "-n" parameter to start it, like this: rox -n.

### Leaving the sandbox

Once done, type "exit" inside the terminal that contains the sandbox. If one uses the full desktop emulation, close the window that contains the emulated Xorg or choose Exit to Terminal or Restart X server from inside the sandbox's desktop.

## Advanced notes

The sandbox is implemented using stackable union file system, aufs, just like the main Fatdog. All the files modified in sandbox is visible in /mnt/sb/sandbox (this mountpoint only exist when sandbox is running, it is also the sandbox-path you need to pass to sb2dir.sh). The sandbox's fake root, i.e. the top of the union seen from within the sandbox itself is mounted as /mnt/sb/fakeroot. If you run multiple sandboxes, the sandbox and the fakeroot will be /mnt/sb/sandbox.XXXXXX and /mnt/sb/fakeroot.XXXXXXX respectively, where XXXXXXX is a random string.

### Important Note: Sandbox is not a security tool

The sandbox is not a security tool, and is never intended to be. Some of the files changed in the sandbox do propagate to the system outside. For example, /tmp directory from the system is mapped to the sandbox. Any changes made to /tmp will be visible and have direct effect to the system outside.

The same can be said for /proc and /sys - thus all process currently running in the system can be seen within the sandbox. Running "wmreboot" from within the sandbox will shutdown the entire system, not just the sandbox (this is no longer true in version 622 onwards, but only because "wmreboot" script is overwritten. Running "reboot" will still reboot the entire system).

It is quite easy to "escape" from the sandbox, this document from 2002 shows how and it still works even today because that is what UNIX standard says (a somewhat cleare explanation is here).

### Improvements on Fatdog64 622 over previous versions:

1. In older versions, sb2dir.sh was previously known as pet4sand.sh and it will automatically run dir2pet for you. This was annoying because most of the time you still want to check whether the files are all right before running dir2pet/makepkg. Thus the changes. Also, sb2dir.sh is now capable of extracting files from multiple sandbox by passing the sandbox-path as the second parameter.
2. In previous versions, only one sandbox can run at one time (regardless of sandbox.sh or rw-sandbox.sh). In version 622 and newer, Fatdog64 can run multiple sandboxes at the same time and sb2dir.sh has been enhanced to allow selection of the sandbox to use.
3. Due to this, the location of sandbox and fakeroot mounts have changed. In previous versions they were located in /mnt/sandbox and /mnt/fakeroot; now they are located in /mnt/sb/sandbox and /mnt/sb/fakeroot.
4. In previous versions, one cannot use Exit to Terminal or Restart X server command from sandbox desktop - it would have shutdown the system's desktop instead. In version 622 onwards, this is the preferred method (although closing the Xephyr window will work, too).
5. From version 622 onwards, Fatdog64 also comes with Linux Container sandbox described below.

### Linux Container sandbox (sandbox-lxc)

Standard sandbox uses chroot as its isolation mechanism. sandbox-lxc is a sandbox that uses Linux Container instead of chroot. Linux Container (LXC) a process isolation mechanism, similar to FreeBSD jail (and Virtuozzo, OpenVZ (open-source version of Virtuozzo), as well as Linux-VServer). From Fatdog64 700 on-wards, suitable kernel is provided and the necessary CLI tools are included in the distribution. Older Fatdogs requires installation of supporting utilities and specially configured kernel.

sandbox-lxc provides more isolation than standard sandbox :

- Applications in sandbox-lxc can only interact with themselves, and cannot affect not anything in the system (or in other sandboxes)
- sandbox-lxc has its own hostname and network and do not share the system's IP address and hostname and thus by default has no network access.
- If you don't enable desktop emulation, there is no shared writable directory with the system (if you *do*, then /tmp is shared from the system).
- By default all character devices from the system is accessible in the sandbox, but none of the block devices. You can fine tune this after the sandbox has been running using lxc-cgroup.
- By default the memory and CPU usage are not restricted. If you wish you can limit the maximum allowable memory and CPU that a sandbox can use. This is also done using lxc-cgroup. Look here for more details of what can be managed and controlled.
- If your kernel supports it (from 3.9 onwards), you can optionally run with user namespaces separation - that is, "root" in the sandbox is just actually just a regular user in the system.

Differences from usage perspective:

1. use sandbox-lxc.sh instead of sandbox.sh
2. use rw-sandbox-lxc.sh instead of rw-sandbox.sh
3. sb2dir.sh works with both standard and sandbox-lxc.
4. Networking must be setup manually (both inside and outside the sandbox) either by using bridging or NAT.
5. /sys is not mounted by default.
6. Use poweroff command to leave sandbox, instead of exit.
7. If you detach the console from the sandbox accidentally (by pressing "Ctrl-G q"), you can re-attach by running lxc-console -e g -n XXXX where XXXX is the sandbox-lxc id (shown when you started the sandbox initially). If you don't know what it is, it would be in the form of sb.lxc.XXXXXX where XXXXXX would be the random string you see in /mnt/sb/sandbox.XXXXXX.
8. To run sandbox-lxc with user namespaces, add environment variable IDMAP=yes before starting sandbox, e.g. IDMAP=yes sandbox-lxc.sh. When started this way, sandbox's "root" user is actually a user with uid of 10000 in the system.

Please note that LXC is still in active development and there may be issues that affect isolation. If you really need even tighter security controls then please consider User Mode Linux or KVM/Qemu or other full-system virtualisation solution.

From Fatdog64 720 onwards, sandbox-lxc also supports running one-time command by passing the command as sandbox-lxc (and rw-sandbox-lxc) arguments. Unlike the normal sandbox, however, which runs the command and then quit, in sandbox-lxc the command is executed (after rc.sysinit.lxc has been executed) and then it returns to sandbox shell. If you want to explicitly terminate sandbox-lxc afterward, you must issue "poweroff" as one of the command sequence.