Add SELinux support to OCID

Signed-off-by: Dan Walsh <dwalsh@redhat.com>
This commit is contained in:
Dan Walsh 2016-10-05 09:29:30 -04:00
parent 308cc4a3b5
commit be77b841fa
5 changed files with 84 additions and 44 deletions

View file

@ -11,6 +11,7 @@ PREFIX ?= ${DESTDIR}/usr
INSTALLDIR=${PREFIX}/bin
GO_MD2MAN ?= $(shell which go-md2man)
export GOPATH := ${CURDIR}/vendor
BUILDTAGS := selinux
default: help
@ -38,7 +39,7 @@ pause:
make -C $@
ocid: ${OCID_LINK}
go build -o ocid ./cmd/server/
go build --tags "$(BUILDTAGS)" -o ocid ./cmd/server/
ocic: ${OCID_LINK}
go build -o ocic ./cmd/client/

View file

@ -8,6 +8,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/cri-o/server"
"github.com/opencontainers/runc/libcontainer/selinux"
"github.com/urfave/cli"
"google.golang.org/grpc"
"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
@ -65,6 +66,10 @@ func main() {
Name: "debug",
Usage: "enable debug output for logging",
},
cli.BoolFlag{
Name: "selinux-enabled",
Usage: "enable selinux support",
},
cli.StringFlag{
Name: "log",
Value: "",
@ -81,6 +86,9 @@ func main() {
if c.GlobalBool("debug") {
logrus.SetLevel(logrus.DebugLevel)
}
if !c.GlobalBool("selinux-enabled") {
selinux.SetDisabled()
}
if path := c.GlobalString("log"); path != "" {
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0666)
if err != nil {

View file

@ -5,11 +5,13 @@ import (
"fmt"
"os"
"path/filepath"
"syscall"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/stringid"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/kubernetes-incubator/cri-o/utils"
"github.com/opencontainers/runc/libcontainer/label"
"github.com/opencontainers/runtime-tools/generate"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
@ -161,8 +163,12 @@ func (s *Server) createSandboxContainer(containerID string, containerName string
options = "ro"
}
//TODO(hmeng): how to use this info? Do we need to handle relabel a FS with Selinux?
//selinuxRelabel := mount.GetSelinuxRelabel()
if mount.GetSelinuxRelabel() {
// Need a way in kubernetes to determine if the volume is shared or private
if err := label.Relabel(src, sb.mountLabel, true); err != nil && err != syscall.ENOTSUP {
return nil, fmt.Errorf("relabel failed %s: %v", src, err)
}
}
specgen.AddBindMount(src, dest, options)
@ -240,30 +246,8 @@ func (s *Server) createSandboxContainer(containerID string, containerName string
}
}
selinuxOptions := linux.GetSelinuxOptions()
if selinuxOptions != nil {
user := selinuxOptions.GetUser()
if user == "" {
return nil, fmt.Errorf("SELinuxOption.User is empty")
}
role := selinuxOptions.GetRole()
if role == "" {
return nil, fmt.Errorf("SELinuxOption.Role is empty")
}
t := selinuxOptions.GetType()
if t == "" {
return nil, fmt.Errorf("SELinuxOption.Type is empty")
}
level := selinuxOptions.GetLevel()
if level == "" {
return nil, fmt.Errorf("SELinuxOption.Level is empty")
}
specgen.SetProcessSelinuxLabel(fmt.Sprintf("%s:%s:%s:%s", user, role, t, level))
}
specgen.SetProcessSelinuxLabel(sb.processLabel)
specgen.SetLinuxMountLabel(sb.mountLabel)
user := linux.GetUser()
if user != nil {

View file

@ -10,6 +10,7 @@ import (
"github.com/docker/docker/pkg/stringid"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/kubernetes-incubator/cri-o/utils"
"github.com/opencontainers/runc/libcontainer/label"
"github.com/opencontainers/runtime-tools/generate"
"golang.org/x/net/context"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
@ -22,6 +23,8 @@ type sandbox struct {
labels map[string]string
annotations map[string]string
containers oci.Store
processLabel string
mountLabel string
}
const (
@ -58,6 +61,7 @@ func (s *Server) generatePodIDandName(name string, namespace string, attempt uin
// RunPodSandbox creates and runs a pod-level sandbox.
func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest) (*pb.RunPodSandboxResponse, error) {
var processLabel, mountLabel string
// process req.Name
name := req.GetConfig().GetMetadata().GetName()
if name == "" {
@ -140,6 +144,11 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
return nil, err
}
processLabel, mountLabel, err = getSELinuxLabels(nil)
if err != nil {
return nil, err
}
containerID, containerName, err := s.generateContainerIDandName(name, "infra", 0)
g.AddAnnotation("ocid/labels", string(labelsJSON))
g.AddAnnotation("ocid/annotations", string(annotationsJSON))
@ -154,6 +163,8 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
labels: labels,
annotations: annotations,
containers: oci.NewMemoryStore(),
processLabel: processLabel,
mountLabel: mountLabel,
})
for k, v := range annotations {
@ -442,3 +453,30 @@ func (s *Server) ListPodSandbox(context.Context, *pb.ListPodSandboxRequest) (*pb
Items: pods,
}, nil
}
func getSELinuxLabels(selinuxOptions *pb.SELinuxOption) (processLabel string, mountLabel string, err error) {
processLabel = ""
if selinuxOptions != nil {
user := selinuxOptions.GetUser()
if user == "" {
return "", "", fmt.Errorf("SELinuxOption.User is empty")
}
role := selinuxOptions.GetRole()
if role == "" {
return "", "", fmt.Errorf("SELinuxOption.Role is empty")
}
t := selinuxOptions.GetType()
if t == "" {
return "", "", fmt.Errorf("SELinuxOption.Type is empty")
}
level := selinuxOptions.GetLevel()
if level == "" {
return "", "", fmt.Errorf("SELinuxOption.Level is empty")
}
processLabel = fmt.Sprintf("%s:%s:%s:%s", user, role, t, level)
}
return label.InitLabels(label.DupSecOpt(processLabel))
}

View file

@ -13,6 +13,7 @@ import (
"github.com/docker/docker/pkg/truncindex"
"github.com/kubernetes-incubator/cri-o/oci"
"github.com/kubernetes-incubator/cri-o/utils"
"github.com/opencontainers/runc/libcontainer/label"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/rajatchopra/ocicni"
)
@ -55,14 +56,22 @@ func (s *Server) loadSandbox(id string) error {
if err != nil {
return err
}
processLabel, mountLabel, err := label.InitLabels(label.DupSecOpt(m.Process.SelinuxLabel))
if err != nil {
return err
}
s.addSandbox(&sandbox{
id: id,
name: name,
logDir: m.Annotations["ocid/log_path"],
labels: labels,
containers: oci.NewMemoryStore(),
processLabel: processLabel,
mountLabel: mountLabel,
})
sandboxPath := filepath.Join(s.sandboxDir, id)
scontainer, err := oci.NewContainer(m.Annotations["ocid/container_id"], m.Annotations["ocid/container_name"], sandboxPath, sandboxPath, labels, id, false)
if err != nil {
return err