Add SELinux support to OCID
Signed-off-by: Dan Walsh <dwalsh@redhat.com>
This commit is contained in:
parent
308cc4a3b5
commit
be77b841fa
5 changed files with 84 additions and 44 deletions
3
Makefile
3
Makefile
|
@ -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/
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -10,18 +10,21 @@ 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"
|
||||
)
|
||||
|
||||
type sandbox struct {
|
||||
id string
|
||||
name string
|
||||
logDir string
|
||||
labels map[string]string
|
||||
annotations map[string]string
|
||||
containers oci.Store
|
||||
id string
|
||||
name string
|
||||
logDir string
|
||||
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))
|
||||
|
@ -148,12 +157,14 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
|
|||
g.AddAnnotation("ocid/container_name", containerName)
|
||||
g.AddAnnotation("ocid/container_id", containerID)
|
||||
s.addSandbox(&sandbox{
|
||||
id: id,
|
||||
name: name,
|
||||
logDir: logDir,
|
||||
labels: labels,
|
||||
annotations: annotations,
|
||||
containers: oci.NewMemoryStore(),
|
||||
id: id,
|
||||
name: name,
|
||||
logDir: logDir,
|
||||
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))
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue