Because of how Git tracks history, it's better suited for tracking a
series of small repositories, as opposed to one large one
- [#]_. Furthermore, most pre-existing tools and techniques for
- dealing with Debian packages in Git repositories (such as
- git-buildpackage_ or `VCS location information`_) are designed
- exclusively for this case.
+ [#]_. Furthermore, most preexisting tools and techniques for dealing
+ with Debian packages in Git repositories (such as git-buildpackage_
+ or `VCS location information`_) are designed exclusively for this
+ case.
* Synchronization between Git and APT repositories.
For the Invirt_ project's use of the Invirtibuilder, we adapted our
existing configuration mechanism. Our configuration file consists of a
-singls YAML_ file. Here is the snippet of configuration we use for our
+single YAML_ file. Here is the snippet of configuration we use for our
build configuration::
build:
using Git directly. However, we realized that what we actually wanted
was a separate build queue where each build request was handled and
processed independently of any requests before or after it. It's not
-possible to have these semantics using Git as a signalling mechanism
+possible to have these semantics using Git as a signaling mechanism
without breaking standard assumptions about how remote Git
repositories work.
Git repository. The remctl daemon then calls a script which validates
the build and adds it to the build queue. Because of the structure of
remctl's ACLs, we are able to have different ACLs depending on which
-pocket the build is destined for. This allows us to fulfil our design
+pocket the build is destined for. This allows us to fulfill our design
goal of having different ACLs for different pockets.
For simplicity, the queue itself is maintained as a directory of
could contain scripts to publish the results of the build in whatever
way is deemed useful by the developers.
+Security
+========
+
+As noted above, our intent was for a single instance of the
+Invirtibuilder to be used for both our trusted production environment
+and our untrusted development environment. In order to be trusted for
+the production environment, the Invirtibuilder needs to run in the
+production environment as well. However, it would be disastrous if
+access to the development environment allowed a developer to insert
+malicious packages into the production apt repository.
+
+In terms of policy, we enforce this distinction using the remctl ACL
+mechanism described in `The Build Queue`_. But is that mechanism on
+its own actually secure?
+
+Only mostly, it turns out.
+
+While actual package builds run unprivileged (with the help of the
+fakeroot_ tool), packages can declare arbitrary build dependencies
+that must be installed for the package build to run. Packages'
+maintainer scripts (post-install, pre-install, pre-removal, and
+post-removal scripts) run as root. This means that by uploading a
+malicious package that another package build-depends on, then
+triggering a build of the second package, it is possible to gain root
+privileges. Since breaking out of the build chroot as root is trivial
+[#], it is theoretically possible for developers with any level of
+access to the APT repositories to root the build server.
+
+One minor protection from this problem is the Invirtibuilder's
+reporting mechanism. A single independent malicious build can't
+compromise the build server on its own. Even if a second build
+compromises the build server, the first build will have already been
+reported through the hook mechanism described in `Build Failures`_. We
+encourage users of the Invirtibuilder to include hooks that send
+notifications of builds over e-mail or some other mechanism such that
+there are off-site records. The server will still be compromised, but
+there will be an audit trail.
+
+Such a vulnerability will always be a concern so long as builds are
+isolated using chroots. It is possible to protect against this sort of
+attack by strengthening the chroot mechanism (e.g. with grsecurity_)
+or by using a more isolated build mechanism
+(e.g. qemubuilder_). However, we decided that the security risk didn't
+justify the additional implementation effort or runtime overhead.
+
+Future Directions
+=================
+
+While the Invirtibuilder was written as a tool for the Invirt_
+project, taking advantage of infrastructure specific to Invirt, it was
+designed with the hope that it could one day be expanded to be useful
+outside of our infrastructure. Here we outline what we believe the
+next steps for development of the Invirtibuilder are.
+
+One deficiency that affects Invirt_ development already is the
+assumption that all packages are Debian-native [#]. Even for packages
+which have a non-native version number, the Invirtibuilder will create
+a Debian-native source package when the package is exported from Git
+as part of the `Build Execution`_. Correcting this requires a means to
+find and extract the upstream tarball from the Git repository. This
+could probably be done by involving the pristine-tar_ tool.
+
+The Invirtibuilder is currently tied to the configuration framework
+developed for the Invirt_ project. To be useful outside of Invirt, the
+Invirtibuilder needs its own, separate mechanism for providing and
+parsing configuration. It should not be difficult to use a separate
+configuration file but a similar YAML configuration mechanism for the
+Invirtibuilder. And of course, as part of that process, filesystem
+paths and the like that are currently hard-coded should be replaced
+with configuration options.
+
+The Invirtibuilder additionally relies on the authentication and
+authorization mechanisms used for Invirt_. Our RPC protocol of choice,
+remctl_, requires a functional Kerberos environment for
+authentication, limiting its usefulness for one-off projects not
+associated with an already existing Kerberos realm. We would like to
+provide support for some alternative RPC mechanism—possibly
+ssh. Additionally, there needs to be some way to expand the build ACLs
+for each pocket that isn't tied to Invirt's authorization
+framework. One option would be providing an executable in the
+configuration that, when passed a pocket as a command-line argument,
+prints out all of the principals that should have access to that
+pocket.
+
.. _config-package-dev: http://debathena.mit.edu/config-packages
+.. _fakeroot: http://fakeroot.alioth.debian.org/
.. _git-buildpackage: https://honk.sigxcpu.org/piki/projects/git-buildpackage/
+.. _grsecurity: http://www.grsecurity.net/
.. _Invirt: http://invirt.mit.edu
+.. _pristine-tar: http://joey.kitenet.net/code/pristine-tar/
+.. _qemubuilder: http://wiki.debian.org/qemubuilder
.. _remctl: http://www.eyrie.org/~eagle/software/remctl/
.. _SIPB: http://sipb.mit.edu
.. _VCS location information: http://www.debian.org/doc/developers-reference/best-pkging-practices.html#bpp-vcs
pockets with ``allow_backtracking`` set to ``True``, we don't
create new tags for builds on pockets with
``allow_backtracking`` set to ``True`` either.
+.. [#] http://kerneltrap.org/Linux/Abusing_chroot
+.. [#] http://people.debian.org/~mpalmer/debian-mentors_FAQ.html#native_vs_non_native