summaryrefslogtreecommitdiff
path: root/contractor.md
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-03-01 11:41:55 +0200
committerLars Wirzenius <liw@liw.fi>2020-03-01 11:41:55 +0200
commit525a8f69ec31e158fe4a4ab5dbfbe5ffba8c75ee (patch)
treed0ae64aaf9b4312629295de3acb88bac8bcd6fe2 /contractor.md
parentf024ab392c8bc82bb3496b04c13c4bd68b06cc05 (diff)
downloadick-contractor-525a8f69ec31e158fe4a4ab5dbfbe5ffba8c75ee.tar.gz
Change: flesh out contractor.md more
Diffstat (limited to 'contractor.md')
-rw-r--r--contractor.md266
1 files changed, 266 insertions, 0 deletions
diff --git a/contractor.md b/contractor.md
index 5dd5883..f5bc869 100644
--- a/contractor.md
+++ b/contractor.md
@@ -3,7 +3,273 @@ title: "Contractor: running CI builds securely"
author: "Lars Wirzenius"
...
+
+# Status of this document
+
+This document is in its very early stages, as is the whole Contractor
+project.
+
# Introduction
+
+A continuous integration engine (CI) takes the source code for a
+software project and ensures it works. In less abstract terms, it
+builds it, and runs any automated tests it may have. The exact steps
+for that depend heavily on the CI engine and the project, but can be
+thought of as follows (with concrete examples of possible commands):
+
+* retrieve the desired revision of the source code (git clone, git
+ checkout)
+* install build dependencies (dpkg-checkbuilddeps, apt install)
+* build (./configure, make)
+* test (make check)
+
+This is dangerous, risky stuff. In the specific case of an open,
+hosted CI service, it's especially dangerous: anyone can submit any
+build, and that build can do anything, including attack computers
+anywhere on the Internet. However, even in a CI engine that only
+builds projects for in-house developers, it's risky: most attacks on
+IT are done by insiders.
+
+Apart from actual attacks, building software is dangerous also due to
+accidents: a mistake in the way software is built, or automatically
+tested, can result in what looks and behaves like an attack. An
+infinite loop can use excessive amounts of CPU resources, or block
+other projects from getting built.
+
+## Threat model
+
+This section collects a list of specific threats to consider.
+
+* excessive use build host resources
+ * e.g., CPU, GPU, RAM, disk, etc
+* excessive use of network bandwidth
+* attack on a networked target via a denial of service attack
+ * e.g., build joins a DDoS swarm, or sends fabricated SYN packets to
+ prevent target from working
+* attack on build host, or other host, via network intrusion
+ * e.g., port scanning, probing for known vulnerabilities
+* attack build host directly without network
+ * e.g., by breaching security isolation using build host kernel or
+ hardware vulnerabilities, or CI engine vulnerabilities
+ * this includes eavesdropping on the host, and stealing secrets
+
# Requirements
+
+This chapter discusses the requirements for the Contractor solution.
+The requirements are divided into two sections: one that presents a
+threat model, and another for requirements that aren't about security.
+
+## Non-security requirements
+
+* **AnyBuildOS**: Builds should be able to run in any operating system
+ that can be run as a virtual machine guest of the host operating
+ system. The host is likely to be Linux, using Qemu and KVM for
+ virtualization.
+
+* **NoRoot**: Running the Contractor should not require root
+ privileges. It's OK to require sufficient privileges to use
+ virtualisation.
+
+* **DefaultBuilder**: The Contractor should be easy to set up and to
+ use. It should not require extensive configuration. Running a build
+ should be as easy as running **make**(1) on the commadnd line. It
+ should be feasible to expect developers to use the Contractor for
+ their normal development work.
+
+## Security requirements
+
+[RFC 2119]: https://tools.ietf.org/html/rfc2119
+
+These requirements stem from the threat model above.
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+document are to be interpreted as described in [RFC 2119][].
+
+* The Contractor MUST prevent the build from using more than the
+ user-specified amount of CPU time (**HardCPULimit**), disk space
+ (**HardDiskLimit**), or network bandwidth (**HardBandwidthLimit**).
+ Any attempt by the build to use more should fail. The Contractor
+ MUST fail the build if the limits are exceeded.
+
+* **HardRAMLimit**: The Contractor MUST prevent the build from using
+ more than the user-specified amount of RAM. The Contractor MAY fail
+ to build if the limit is exceeded, but is not required to do so.
+
+* **ConstrainNetworkAccess**: The Contractor MUST prevent the build
+ from accessing the network ourside the build environment in ways
+ that haven't been specifically allowed by the user. The contractor
+ SHOULD fail the build if it makes an attempt at such access. The
+ user MUST be able to specify which hosts to access, and using which
+ protocols.
+
+* **HostProtection**: The Contractor SHOULD attempt to protect the
+ host its running on from non-networked attacks performed by the
+ build. This includes vulnerabilities of the host's operating system
+ kernel, virtualisation solution, and hardware.
+
+
# Architecture
+
+This chapter discusses the architecture of the solution, with
+particular emphasis on threat mitigation.
+
+The overall solution is use of nested virtual machines, running on a
+developer's host. The outer VM runs the Contractor itself. The inner
+VM runs the build. The outer VM controls the inner VM, proxies its
+external access, and prevents it from doing anything nefarious. The
+outer VM is managed by a command line tool. Developers only interact
+directly with the command line tool.
+
+~~~dot
+digraph "arch" {
+ labelloc=b;
+ labeljust=l;
+ git [shape=tab];
+ apt [shape=tab];
+ npm [shape=tab];
+ subgraph cluster_host {
+ label="Host system \n (the vulnerable bit)";
+ contractor;
+ artifacts [shape=tab];
+ subgraph cluster_contractor {
+ label="Contractor VM \n (defence force)";
+ manager;
+ subgraph cluster_builder {
+ label="Build VM \n (here be dragons)";
+ style=filled;
+ fillcolor="#dd0000";
+ guestos [label="Guest OS"];
+ }
+ }
+ }
+ contractor -> manager;
+ git -> manager;
+ npm -> manager;
+ apt -> manager;
+ manager -> guestos;
+ guestos -> manager;
+ manager -> artifacts;
+}
+~~~
+
+This high-level design is chosen for the following reasons:
+
+* it allows the build to happen in any operating system
+ (**AnyBuildOS**)
+* the Contractor is a VM and running it doesn't require root
+ privileges; it has root inside the VM if needed (**NoRoot**)
+* the command line tool for using the Contractor can be made to be as
+ easy as any build tool so that developer actually use it by default
+ (**DefaultBuilder**)
+* the manager in the outer VM can monitor and control the build
+ (**HardCPULimit**, **HardBandwidthLimit**)
+* the manager can supply the inner VM with only a specified amount of
+ RAM and disk space (**HardRAMLimit**, **HardDiskLimit**)
+* the manager can set up routing and firewalls so that the inner VM
+ cannot access the network, except via proxies provided by the outer
+ VM (**ConstrainNetworkAccess**)
+* the nested VMs provide a smaller attack surface than the Linux
+ kernel API, and this protects the host better than Linux container
+ technologies, although it doesn't do much to protect against
+ virtualisation or hardware vulnerabilities (**HostProtection**)
+
+## Build process
+
+The architecture leads to a build process that would work like this:
+
+* developer runs command line tool to do a build
+* command line tool boots the outer VM, which starts any services and
+ proxies running in the outer VM, and configures networking and
+ firewalls
+* command line tool copies the source code and build recipe into the
+ outer VM
+* outer VM retrieves the system image for the inner VM
+* outer VM boots inner VM
+* outer VM provides source code to inner VM
+* outer VM instructs inner VM to perform each build step in the build
+ recipe, while monitoring network access and CPU use; if the outer VM
+ notices any limits being exceeded, or attempts to access network
+ resources other than ones allowed by developer, it will stop the
+ inner VM, and report failur to the developer
+* outer VM will retrieve build artifacts from the inner VM and put
+ them in an artifact directory so the developer can access them
+* command line tool reports to the developer build success or failure
+ and where build log and build artifacts are
+
+
# Acceptance criteria
+
+This chapter specifies acceptance criteria for the Contractor, as
+*scenarios*, which also define how the criteria are automatically
+verified.
+
+## Smoke tests
+
+These scenarios build a simple "hello, world" C application on a
+variety of guest systems, and verify the resulting binaries output the
+desired greeting. The goal of these scenarios is to ensure the various
+Contractor components fit together at least in the very basic case.
+
+### Debian smoke test
+
+### Ubuntu smoke test
+
+### FreeBSD smoke test
+
+## User-specified limits
+
+These scenarios verify that the Contractor fails builds that exceed
+specified limits.
+
+### Build fails if CPU time limit is exceeded
+
+### Build fails if bandwidth limit is exceeded
+
+### User can specify RAM limit of inner VM
+
+### User can specify disk size of inner VM
+
+## Forbidden network access
+
+These scenarios verify that the Contractor prevents the build from
+accessing network resources other than what is allowed.
+
+### Build fails if forbidden host is accessed
+
+### Build cannot ping external hosts
+
+### Build cannot ping outer VM
+
+### Build cannot send UCP packets outside inner VM
+
+### Build cannot TCP connect outside inner VM
+
+## Allowed network access
+
+These scenarios verify that the build can access allowed network
+resources. We need to verify that every supported kind of network
+operation works, whether that's git, HTTP, Debian package installs,
+language specific package management, or more.
+
+### Build can git clone from an allowed git server using git protocol
+
+### Build can make an HTTP GET request to an allowed host
+
+### Build can do an apt install from Debian
+
+### Build can do an apt install from CI repository
+
+### Build can use cargo to install Rust dependencies
+
+## Build scenarios
+
+### Can build a Debian package
+
+### Can build a Rust program
+
+### Can build a Debian guest VM image
+
+### Can build an Ubuntu guest VM image
+
+### Can build a FreeBSD guest VM image