diff --git a/.travis.yml b/.travis.yml index ee3a108a4..aea15291c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,10 +42,6 @@ before_script: gcloud auth activate-service-account --key-file gcp-secret.json --project=k8s-cri-containerd; fi -env: - # Travis trusty has disabled apparmor, so disable enable in our test. - - CRI_CONTAINERD_FLAGS="--enable-apparmor=false" - jobs: include: - stage: Build diff --git a/Makefile b/Makefile index d95101bda..c724ac997 100644 --- a/Makefile +++ b/Makefile @@ -12,22 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -GO ?= go -EPOCH_TEST_COMMIT ?= f9e02affccd51702191e5312665a16045ffef8ab +GO := go +EPOCH_TEST_COMMIT := f9e02affccd51702191e5312665a16045ffef8ab PROJECT := github.com/kubernetes-incubator/cri-containerd -BINDIR ?= ${DESTDIR}/usr/local/bin -BUILD_DIR ?= _output +BINDIR := ${DESTDIR}/usr/local/bin +BUILD_DIR := _output # VERSION is derived from the current tag for HEAD plus amends. Version is used # to set/overide the criContainerdVersion variable in the verison package for # cri-containerd. VERSION := $(shell git describe --tags --dirty) # strip the first char of the tag if it's a `v` VERSION := $(VERSION:v%=%) -TARBALL ?= cri-containerd-$(VERSION).tar.gz -ifdef BUILD_TAGS -BUILD_TAGS := -tags $(BUILD_TAGS) -endif -GO_LDFLAGS := -ldflags '-X $(PROJECT)/pkg/version.criContainerdVersion=$(VERSION)' +TARBALL := cri-containerd-$(VERSION).tar.gz +BUILD_TAGS := apparmor +GO_LDFLAGS := -X $(PROJECT)/pkg/version.criContainerdVersion=$(VERSION) SOURCES := $(shell find . -name '*.go') all: binaries @@ -71,11 +69,16 @@ boiler: $(BUILD_DIR)/cri-containerd: $(SOURCES) $(GO) build -o $@ \ - $(BUILD_TAGS) $(GO_LDFLAGS) $(GO_GCFLAGS) \ - $(PROJECT)/cmd/cri-containerd + -tags '$(BUILD_TAGS)' \ + -ldflags '$(GO_LDFLAGS)' \ + -gcflags '$(GO_GCFLAGS)' \ + $(PROJECT)/cmd/cri-containerd test: - go test -timeout=10m -race ./pkg/... $(BUILD_TAGS) $(GO_LDFLAGS) $(GO_GCFLAGS) + go test -timeout=10m -race ./pkg/... \ + -tags '$(BUILD_TAGS)' \ + -ldflags '$(GO_LDFLAGS)' \ + -gcflags '$(GO_GCFLAGS)' test-cri: binaries @./hack/test-cri.sh @@ -88,7 +91,7 @@ clean: binaries: $(BUILD_DIR)/cri-containerd -static-binaries: GO_LDFLAGS += --ldflags '-extldflags "-fno-PIC -static"' +static-binaries: GO_LDFLAGS += -extldflags "-fno-PIC -static" static-binaries: $(BUILD_DIR)/cri-containerd install: binaries @@ -103,7 +106,7 @@ $(BUILD_DIR)/$(TARBALL): $(BUILD_DIR)/cri-containerd hack/versions release: $(BUILD_DIR)/$(TARBALL) push: $(BUILD_DIR)/$(TARBALL) - @@BUILD_DIR=$(BUILD_DIR) TARBALL=$(TARBALL) ./hack/push.sh + @BUILD_DIR=$(BUILD_DIR) TARBALL=$(TARBALL) ./hack/push.sh .PHONY: install.deps diff --git a/cmd/cri-containerd/cri_containerd.go b/cmd/cri-containerd/cri_containerd.go index 8ecc00d09..79e385942 100644 --- a/cmd/cri-containerd/cri_containerd.go +++ b/cmd/cri-containerd/cri_containerd.go @@ -51,9 +51,7 @@ func main() { os.Exit(0) } - if !o.EnableSelinux { - selinux.SetDisabled() - } + validateConfig(o) glog.V(2).Infof("Run cri-containerd grpc server on socket %q", o.SocketPath) s, err := server.NewCRIContainerdService(o.Config) @@ -68,3 +66,13 @@ func main() { glog.Exitf("Failed to run cri-containerd grpc server: %v", err) } } + +func validateConfig(o *options.CRIContainerdOptions) { + if o.EnableSelinux { + if !selinux.GetEnabled() { + glog.Warning("Selinux is not supported") + } + } else { + selinux.SetDisabled() + } +} diff --git a/cmd/cri-containerd/options/options.go b/cmd/cri-containerd/options/options.go index d43475090..097e12053 100644 --- a/cmd/cri-containerd/options/options.go +++ b/cmd/cri-containerd/options/options.go @@ -64,9 +64,6 @@ type Config struct { CgroupPath string `toml:"cgroup_path"` // EnableSelinux indicates to enable the selinux support. EnableSelinux bool `toml:"enable_selinux"` - // EnableAppArmor indicates to enable apparmor support. cri-containerd will - // apply default apparmor profile if apparmor is enabled. - EnableAppArmor bool `toml:"enable_apparmor"` // SandboxImage is the image used by sandbox container. SandboxImage string `toml:"sandbox_image"` } @@ -114,8 +111,6 @@ func (c *CRIContainerdOptions) AddFlags(fs *pflag.FlagSet) { "", "The cgroup that cri-containerd is part of. By default cri-containerd is not placed in a cgroup.") fs.BoolVar(&c.EnableSelinux, "enable-selinux", false, "Enable selinux support.") - fs.BoolVar(&c.EnableAppArmor, "enable-apparmor", - true, "Enable apparmor support. cri-containerd will apply default apparmor profile when apparmor is enabled.") fs.StringVar(&c.SandboxImage, "sandbox-image", "gcr.io/google_containers/pause:3.0", "The image used by sandbox container.") fs.BoolVar(&c.PrintDefaultConfig, "default-config", diff --git a/pkg/server/container_create.go b/pkg/server/container_create.go index e25e7052c..3be3d5ca3 100644 --- a/pkg/server/container_create.go +++ b/pkg/server/container_create.go @@ -30,6 +30,7 @@ import ( "github.com/docker/docker/pkg/mount" "github.com/golang/glog" imagespec "github.com/opencontainers/image-spec/specs-go/v1" + runcapparmor "github.com/opencontainers/runc/libcontainer/apparmor" "github.com/opencontainers/runc/libcontainer/devices" runtimespec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" @@ -201,8 +202,14 @@ func (c *criContainerdService) CreateContainer(ctx context.Context, r *runtime.C specOpts = append(specOpts, containerd.WithUsername(username)) } // Set apparmor profile, (privileged or not) if apparmor is enabled - if c.config.EnableAppArmor { - appArmorProf := securityContext.GetApparmorProfile() + appArmorProf := securityContext.GetApparmorProfile() + if !runcapparmor.IsEnabled() { + // Should fail loudly if user try to specify apparmor profile + // but we don't support it. + if appArmorProf != "" { + return nil, fmt.Errorf("apparmor is not supported") + } + } else { switch appArmorProf { case runtimeDefault: // TODO (mikebrow): delete created apparmor default profile diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go new file mode 100644 index 000000000..82ed1a68a --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor.go @@ -0,0 +1,39 @@ +// +build apparmor,linux + +package apparmor + +// #cgo LDFLAGS: -lapparmor +// #include +// #include +import "C" +import ( + "fmt" + "io/ioutil" + "os" + "unsafe" +) + +// IsEnabled returns true if apparmor is enabled for the host. +func IsEnabled() bool { + if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil && os.Getenv("container") == "" { + if _, err = os.Stat("/sbin/apparmor_parser"); err == nil { + buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled") + return err == nil && len(buf) > 1 && buf[0] == 'Y' + } + } + return false +} + +// ApplyProfile will apply the profile with the specified name to the process after +// the next exec. +func ApplyProfile(name string) error { + if name == "" { + return nil + } + cName := C.CString(name) + defer C.free(unsafe.Pointer(cName)) + if _, err := C.aa_change_onexec(cName); err != nil { + return fmt.Errorf("apparmor failed to apply profile: %s", err) + } + return nil +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go new file mode 100644 index 000000000..d4110cf0b --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/apparmor/apparmor_disabled.go @@ -0,0 +1,20 @@ +// +build !apparmor !linux + +package apparmor + +import ( + "errors" +) + +var ErrApparmorNotEnabled = errors.New("apparmor: config provided but apparmor not supported") + +func IsEnabled() bool { + return false +} + +func ApplyProfile(name string) error { + if name != "" { + return ErrApparmorNotEnabled + } + return nil +}