Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support to add and drop linux capabilities #1702

Merged
merged 3 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions e2e-tests/capabilities-add-drop-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package:
name: busybox
description: Capabilities add-drop feature test
version: 0.1.0
epoch: 0

capabilities:
add:
- CAP_NET_ADMIN
drop:
- CAP_SYS_ADMIN
- CAP_SYS_CHROOT

environment:
contents:
packages:
- busybox
- cmd:capsh

pipeline:
- name: Test default effective capability
runs: |
capsh --decode=$(grep CapEff /proc/self/status | cut -d ':' -f2 | xargs) | grep -i cap_dac_override

- name: Test added non-default effective capability
runs: |
capsh --decode=$(grep CapEff /proc/self/status | cut -d ':' -f2 | xargs) | grep -i cap_net_admin

- name: Test dropped default effective capability
runs: |
capsh --decode=$(grep CapEff /proc/self/status | cut -d ':' -f2 | xargs) | grep -vi cap_sys_chroot
33 changes: 33 additions & 0 deletions e2e-tests/capabilities-add-drop-nopkg-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package:
name: busybox
description: Capabilities add-drop feature test
version: 0.1.0
epoch: 0

capabilities:
add:
- CAP_NET_ADMIN
drop:
- CAP_SYS_ADMIN
- CAP_SYS_CHROOT

pipeline:

test:
environment:
contents:
packages:
- busybox
- cmd:capsh
pipeline:
- name: Test default effective capability
runs: |
capsh --decode=$(grep CapEff /proc/self/status | cut -d ':' -f2 | xargs) | grep -i cap_dac_override

- name: Test added non-default effective capability
runs: |
capsh --decode=$(grep CapEff /proc/self/status | cut -d ':' -f2 | xargs) | grep -i cap_net_admin

- name: Test dropped default effective capability
runs: |
capsh --decode=$(grep CapEff /proc/self/status | cut -d ':' -f2 | xargs) | grep -vi cap_sys_chroot
27 changes: 27 additions & 0 deletions examples/capabilities-add-drop.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package:
name: busybox
version: 0.1.0
epoch: 0

capabilities:
add:
- CAP_NET_ADMIN
drop:
- CAP_SYS_ADMIN

pipeline:
# Here your build pipeline.
# Capabilities are added/dropped to both build and test pipelines.

test:
environment:
contents:
packages:
- busybox
- iproute2
pipeline:
# Note: you can't do it with bubblewrap runner,
# as it shares the host network namespace.
- name: Simulate a test attempting to create network interfaces
runs: |
ip link add dev myinterface type dummy
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
Copy link
Contributor Author

@maxgio92 maxgio92 Dec 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the cost of tracking and aligning to Docker default capabilities.

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.Add = b.Configuration.Capabilities.Add
}
if b.Configuration.Capabilities.Drop != nil {
cfg.Capabilities.Drop = 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.Add = t.Configuration.Capabilities.Add
}
if t.Configuration.Capabilities.Drop != nil {
cfg.Capabilities.Drop = t.Configuration.Capabilities.Drop
}

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

// The root melange configuration
// Capabilities is the configuration for Linux capabilities for the runner.
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.Add != nil {
for _, c := range cfg.Capabilities.Add {
baseargs = append(baseargs, "--cap-add", c)
}
}
// Drop process kernel capabilities from the container as configured.
if cfg.Capabilities.Drop != nil {
for _, c := range cfg.Capabilities.Drop {
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
Add []string // List of kernel capabilities to add to the container.
Drop []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.Add) > 0 {
hostConfig.CapAdd = cfg.Capabilities.Add
}
// Drop process kernel capabilities from the container if configured.
if len(cfg.Capabilities.Drop) > 0 {
hostConfig.CapDrop = cfg.Capabilities.Drop
}

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