Skip to content

Commit

Permalink
feat: add support to add and drop linux capabilities
Browse files Browse the repository at this point in the history
This commit adds the configuration to add and drop
Linux capabilies to the container for bubblewrap and docker
runners, enabling a declarative way to do least privilege
at both build and test time. Furthermore, the minimum set
of process capabilities in Bubblewrap container is now
the same of Docker default capabilities.

Signed-off-by: Massimiliano Giovagnoli <massimiliano.giovagnoli@chainguard.dev>
  • Loading branch information
maxgio92 committed Dec 19, 2024
1 parent 53a5317 commit 8e46080
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 2 deletions.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
github.com/klauspost/compress v1.17.11
github.com/klauspost/pgzip v1.2.6
github.com/kubescape/go-git-url v0.0.30
github.com/moby/moby v27.4.0+incompatible
github.com/opencontainers/image-spec v1.1.0
github.com/package-url/packageurl-go v0.1.3
github.com/pkg/errors v0.9.1
Expand Down Expand Up @@ -93,6 +94,8 @@ require (
github.com/cloudflare/circl v1.5.0 // indirect
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
github.com/containerd/containerd v1.7.24 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.16.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8E
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ=
github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
github.com/containerd/containerd v1.7.24 h1:zxszGrGjrra1yYJW/6rhm9cJ1ZQ8rkKBR48brqsa7nA=
github.com/containerd/containerd v1.7.24/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/stargz-snapshotter/estargz v0.16.2 h1:DMcqm1rd1ak2hFghkyHlquacSo+zRe+cysRR3CmSpGk=
Expand Down Expand Up @@ -349,6 +351,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/moby v27.4.0+incompatible h1:jGXXZCMAmFZS9pKsQqUt9yAPHOC450PM9lbQYPSQnuc=
github.com/moby/moby v27.4.0+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
Expand Down
6 changes: 6 additions & 0 deletions pkg/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,12 @@ func (b *Build) buildWorkspaceConfig(ctx context.Context) *container.Config {
cfg.Memory = b.Configuration.Package.Resources.Memory
cfg.Disk = b.Configuration.Package.Resources.Disk
}
if b.Configuration.Capabilities.Add != nil {
cfg.Capabilities.CapAdd = b.Configuration.Capabilities.Add
}
if b.Configuration.Capabilities.Drop != nil {
cfg.Capabilities.CapDrop = b.Configuration.Capabilities.Drop
}

for k, v := range b.Configuration.Environment.Environment {
cfg.Environment[k] = v
Expand Down
6 changes: 6 additions & 0 deletions pkg/build/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,12 @@ func (t *Test) buildWorkspaceConfig(ctx context.Context, imgRef, pkgName string,
Environment: map[string]string{},
RunAs: imgcfg.Accounts.RunAs,
}
if t.Configuration.Capabilities.Add != nil {
cfg.Capabilities.CapAdd = t.Configuration.Capabilities.Add
}
if t.Configuration.Capabilities.Drop != nil {
cfg.Capabilities.CapDrop = t.Configuration.Capabilities.Drop
}

for k, v := range imgcfg.Environment {
cfg.Environment[k] = v
Expand Down
12 changes: 11 additions & 1 deletion pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,12 +595,22 @@ type Input struct {
Required bool `json:"required,omitempty"`
}

// The root melange configuration
type Capabilities struct {
// Linux process capabilities to add to the pipeline container.
Add []string `json:"add,omitempty" yaml:"add,omitempty"`
// Linux process capabilities to drop from the pipeline container.
Drop []string `json:"drop,omitempty" yaml:"drop,omitempty"`
}

// Configuration is the root melange configuration.
type Configuration struct {
// Package metadata
Package Package `json:"package" yaml:"package"`
// The specification for the packages build environment
Environment apko_types.ImageConfiguration `json:"environment" yaml:"environment"`
// Optional: Linux capabilities configuration to apply to the melange runner.
Capabilities Capabilities `json:"capabilities,omitempty" yaml:"capabilities,omitempty"`

// Required: The list of pipelines that produce the package.
Pipeline []Pipeline `json:"pipeline,omitempty" yaml:"pipeline,omitempty"`
// Optional: The list of subpackages that this package also produces.
Expand Down
21 changes: 20 additions & 1 deletion pkg/container/bubblewrap_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ import (
"path/filepath"
"strings"

"chainguard.dev/melange/internal/logwriter"

apko_build "chainguard.dev/apko/pkg/build"
apko_types "chainguard.dev/apko/pkg/build/types"
"chainguard.dev/melange/internal/logwriter"
"github.com/chainguard-dev/clog"
v1 "github.com/google/go-containerregistry/pkg/v1"
moby "github.com/moby/moby/oci/caps"
"go.opentelemetry.io/otel"
)

Expand Down Expand Up @@ -126,6 +128,23 @@ func (bw *bubblewrap) cmd(ctx context.Context, cfg *Config, debug bool, envOverr
baseargs = append(baseargs, "--gid", buildUserID)
}

// Add Docker runner-parity kernel capabilities to the container.
for _, c := range moby.DefaultCapabilities() {
baseargs = append(baseargs, "--cap-add", c)
}
// Add additional process kernel capabilities to the container as configured.
if cfg.Capabilities.CapAdd != nil {
for _, c := range cfg.Capabilities.CapAdd {
baseargs = append(baseargs, "--cap-add", c)
}
}
// Drop process kernel capabilities from the container as configured.
if cfg.Capabilities.CapDrop != nil {
for _, c := range cfg.Capabilities.CapDrop {
baseargs = append(baseargs, "--cap-drop", c)
}
}

if !debug {
// This flag breaks job control, which we only care about for --interactive debugging.
// So we usually include it, but if we're about to debug, don't set it.
Expand Down
2 changes: 2 additions & 0 deletions pkg/container/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type BindMount struct {

type Capabilities struct {
Networking bool
CapAdd []string // List of kernel capabilities to add to the container.
CapDrop []string // List of kernel capabilities to drop from the container.
}

type Config struct {
Expand Down
8 changes: 8 additions & 0 deletions pkg/container/docker/docker_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ func (dk *docker) StartPod(ctx context.Context, cfg *mcontainer.Config) error {
hostConfig := &container.HostConfig{
Mounts: mounts,
}
// Add process kernel capabilities to the container if configured.
if len(cfg.Capabilities.CapAdd) > 0 {
hostConfig.CapAdd = cfg.Capabilities.CapAdd
}
// Drop process kernel capabilities from the container if configured.
if len(cfg.Capabilities.CapDrop) > 0 {
hostConfig.CapDrop = cfg.Capabilities.CapDrop
}

platform := &image_spec.Platform{
Architecture: cfg.Arch.String(),
Expand Down

0 comments on commit 8e46080

Please sign in to comment.