Deck is very simple, but its a bit hard to explain. Basically its a
high-level interface to overlays with a couple of tricks up its
sleeve.

The problem
===========

The impetus for inventing deck was to come up with a better way to
create and configure chroot overlays. Doing it by hand created a few
problems: 

1) too many long arcane command line options

2) you had to create your overlay and mount points by hand

3) having the overlay in-your-face besides the mount point (and the
   original readonly branch) is messy::

	$ ls /chroot/
	rootfs
	rootfs-tmp
	rootfs-tmp.overlay

   FYI, rootfs is the original debootstrap chroot I created and rootfs-tmp
   is the overlay in which I setup my development environment.

4) after I created the overlay I would have redo the various mounts
   inside rootfs-tmp (e.g., /proc /sys /dev/pts /turnkey). These
   sub=mounts don't carry over from a branch of the union to the union
   mount point, so I had to redo them by hand every time I rebooted. I
   eventually wrote a small script to do this.

5) I couldn't branch from a given chroot (not easily anyhow). For
   example, say I wanted to branch off rootfs-tmp-dirty from rootfs-tmp and
   try a dirty operation there, which I could then throw away. Theres no
   easy way to do that.

   Ideally, I wanted chroots to be as flexible as vmware snapshots.

Terminology
===========

deck
    a virtual filesystem branch derived from a directory or another
    deck

stack
    a stack of filesystem levels a deck is comprised of

levels
    behind the scenes, decks are a union of multiple filesystem levels

The solution
============

Deck solves all of the above problems in a very elegant way. The most
clever part is how it supports arbitrary branching, by structuring the
'deck' as a stack of unioned overlays.

In principle, to branch 'deck-b' from 'deck-a', you copy the stack
structure for 'deck-a' into the new 'deck-b' and then add another
overlay layer to each of the decks, so that post-branching writes go
to the separate branches. This way the decks remain independent
following the branching (changes to deck-a don't effect deck-b and
vice versa). Since the stack structure is really an ordered list of
*pointers* to the overlay levels, the branching operation does not
need to copy/replicate any actual files during the branching so the
operation is very fast and efficient.

Note that deck isn't specific to chroots. Thats just the original
application that got the ball rolling. Since its built on top of
useraufs, regular users can use it to branch their own
directories. However, deck only takes care of sub-mounts for you if
you are root, as this requires special privileges.

Usage
=====

Note, that the cli is designed to resemble a simplified mount. (not a
toolkit)

Syntax: deck /path/to/dir/or/deck /path/to/new/deck Syntax: deck [
-options ] /path/to/existing/deck Deck a filesystem

Options:

  -m mounts deck (the default)
  -u unmount deck (also refresh's the deck's fstab)
  -r refresh the deck's fstab (without unmounting)
  -d delete the deck

Usage examples::

    cd /chroot

    # create a new deck, branching rootfs.1 from rootfs will replicate any
    # mounts in rootfs to rootfs.1 deck rootfs rootfs.1

    # branch rootfs.1.1 from rootfs.1 deck rootfs.1 rootfs.1.1

    # unmount rootfs.1 deck -u rootfs.1

    # remount rootfs.1 (reconstructs the various mounts we had) deck rootfs.1

    # delete rootfs.1 deck -d rootfs.1

    # refresh mounts

    cd rootfs.1.1 mount --bind /mnt/archive/repository
    rootfs.1.1/turnkey/repository

    # refresh mounts (without unmounting) deck -r rootfs.1.1

    # when you unmount it also updates the fstab deck rootfs.1.1 mount
    # --bind /home/z rootfs.1.1/home/z deck -u rootfs.1.1 deck rootfs.1.1

    # sure enough, deck has saved the state of your mounts for you ls -la
    # rootfs.1.1/home/z

File structure
==============

Deck internals are stored in '.deck' inside the same directory as the
deck we created is located. One caveat is that you can't branch from
decks in another directory, only in the same directory.

Here's a snapshot of the contents of the .deck directory::

    .deck/
        levels.refs/ # references to overlay levels
            <level-id>/
                <name> -> ../stacks/<name>
        
        levels # overlay levels
            <level-id>/ # <level-id> is a random hash
                
        stacks/ # stack structure of decks (which levels in what order)
            <name>/
                0 -> /base
                1 -> ../../levels/3902bf6c37bdd2d16d92731ed76400ab
                2 -> ../../levels/0944b20f5eceec96a2da758182e8516e
        
            <name-derivative>/
                0 -> /base
                1 -> ../../levels/3902bf6c37bdd2d16d92731ed76400ab
                2 -> ../../levels/5b04f8c439460a60b200393c1604d5cc

        mounts/ # pointers to a record of mounts for this deck (if we're
        root)
            <name>
            <name-derivative>

Security considerations
=======================

In high risk applications, Deck is potentially a security risk. It is
dangerous to allow arbitrary mounts as this can be used to subvert the
security policy. For example, an attacker could use mount --bind /etc
to a location of his choosing, and the security policy will not apply
to the new location, only the location of the old files.

Overlays are dangerous because they are sort of a more powerful
equivalent of mount --bind, and they can be used to compromise the MAC
policy just as well, but an even greater risk is deck's automatic
support for sub-mounts.

I've built a few countermeasures into deck to reduce the risk: 

1) We rely on useraufs's configuration to allow the administrator to
   configure: which users are allowed to use the system which
   directories is the system allowed to operate on

   Since useraufs makes these decisions, its important to make sure we
   are running a good version of it, and not some spoofed version that
   never fails. To prevent these tricks, I fixed that project's
   execproxy so that it cleans the environment regardless of whether we
   are running as suid or not.

   This however, is not enough, since a malicious root user can
   potentially trick deck into making arbitrary mounts by tampering with
   the fstab file. So...

2) To prevent tampering, fstabs are not stored inside the local .deck
   sub-directory, but rather in a global location (/etc/deck/mounts).
   This directory can be protected by the MAC policy, such that only the
   deck process itself can access it.
