diff options
author | Lars Wirzenius <liw@liw.fi> | 2020-03-01 11:41:55 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2020-03-01 11:41:55 +0200 |
commit | 525a8f69ec31e158fe4a4ab5dbfbe5ffba8c75ee (patch) | |
tree | d0ae64aaf9b4312629295de3acb88bac8bcd6fe2 /contractor.md | |
parent | f024ab392c8bc82bb3496b04c13c4bd68b06cc05 (diff) | |
download | ick-contractor-525a8f69ec31e158fe4a4ab5dbfbe5ffba8c75ee.tar.gz |
Change: flesh out contractor.md more
Diffstat (limited to 'contractor.md')
-rw-r--r-- | contractor.md | 266 |
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 |