From eda419cb037dac409e942aaaed5d68b4949bd608 Mon Sep 17 00:00:00 2001 From: Linda Yu Date: Fri, 8 Dec 2023 15:29:25 +0800 Subject: [PATCH] kata-runtime: add set policy function to kata-runtime logging/debugging information might probably be disabled in production due to security consideration, but we'd better provide an approach for customer to get logging information during runtime, this PR implement setpolicy function in kata-runtime tools, although it can set whole policy other than logging. setpolicy would evokes remote attestation, which means before setting policy during runtime, user has to reconfigure new policy hash in KBS/AS. usage: kata-runtime policy set policy.rego --sandbox-id XXXXXXXX Fixes: #8797 Signed-off-by: Linda Yu --- src/runtime/cmd/kata-runtime/kata-policy.go | 73 +++++++++++++++++++ src/runtime/cmd/kata-runtime/main.go | 1 + .../pkg/containerd-shim-v2/shim_management.go | 28 +++++++ src/runtime/virtcontainers/interfaces.go | 1 + .../virtcontainers/pkg/vcmock/sandbox.go | 4 + src/runtime/virtcontainers/sandbox.go | 5 ++ 6 files changed, 112 insertions(+) create mode 100644 src/runtime/cmd/kata-runtime/kata-policy.go diff --git a/src/runtime/cmd/kata-runtime/kata-policy.go b/src/runtime/cmd/kata-runtime/kata-policy.go new file mode 100644 index 0000000000..1ca1779d8b --- /dev/null +++ b/src/runtime/cmd/kata-runtime/kata-policy.go @@ -0,0 +1,73 @@ +// Copyright (c) 2023 Intel Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package main + +import ( + "fmt" + "os" + + containerdshim "github.com/kata-containers/kata-containers/src/runtime/pkg/containerd-shim-v2" + "github.com/kata-containers/kata-containers/src/runtime/pkg/katautils" + "github.com/kata-containers/kata-containers/src/runtime/pkg/utils/shimclient" + "github.com/urfave/cli" +) + +var policySubCmds = []cli.Command{ + setPolicyCommand, +} + +var kataPolicyCommand = cli.Command{ + Name: "policy", + Usage: "set policy within the Kata Containers guest", + Subcommands: policySubCmds, + Action: func(context *cli.Context) { + cli.ShowSubcommandHelp(context) + }, +} + +var setPolicyCommand = cli.Command{ + Name: "set", + Usage: "set policy in a specifc Kata Containers guest based on file", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "sandbox-id", + Usage: "the target sandbox for setting the policy", + Required: true, + Destination: &sandboxID, + }, + }, + Action: func(c *cli.Context) error { + policyFile := c.Args().Get(0) + + // verify sandbox exists: + if err := katautils.VerifyContainerID(sandboxID); err != nil { + return err + } + + // verify policy were provided: + if policyFile == "" { + return fmt.Errorf("policy file not provided") + } + + if !katautils.FileExists(policyFile) { + return fmt.Errorf("policy file does not exist: %s", policyFile) + } + + // Read file into buffer, and make request to the appropriate shim + buf, err := os.ReadFile(policyFile) + if err != nil { + return err + } + + url := containerdshim.PolicyUrl + + if err = shimclient.DoPut(sandboxID, defaultTimeout, url, "application/octet-stream", buf); err != nil { + return fmt.Errorf("Error observed when making policy-set request(%s): %s", policyFile, err) + } + + return nil + }, +} diff --git a/src/runtime/cmd/kata-runtime/main.go b/src/runtime/cmd/kata-runtime/main.go index a722afd6be..2c89c1eaf1 100644 --- a/src/runtime/cmd/kata-runtime/main.go +++ b/src/runtime/cmd/kata-runtime/main.go @@ -126,6 +126,7 @@ var runtimeCommands = []cli.Command{ factoryCLICommand, kataVolumeCommand, kataIPTablesCommand, + kataPolicyCommand, } // runtimeBeforeSubcommands is the function to run before command-line diff --git a/src/runtime/pkg/containerd-shim-v2/shim_management.go b/src/runtime/pkg/containerd-shim-v2/shim_management.go index e83e54417a..4133e786e1 100644 --- a/src/runtime/pkg/containerd-shim-v2/shim_management.go +++ b/src/runtime/pkg/containerd-shim-v2/shim_management.go @@ -38,6 +38,7 @@ const ( DirectVolumeStatUrl = "/direct-volume/stats" DirectVolumeResizeUrl = "/direct-volume/resize" IPTablesUrl = "/iptables" + PolicyUrl = "/policy" IP6TablesUrl = "/ip6tables" MetricsUrl = "/metrics" ) @@ -199,6 +200,32 @@ func (s *service) serveVolumeResize(w http.ResponseWriter, r *http.Request) { w.Write([]byte("")) } +func (s *service) policyHandler(w http.ResponseWriter, r *http.Request) { + logger := shimMgtLog.WithFields(logrus.Fields{"handler": "policy"}) + + switch r.Method { + case http.MethodPut: + body, err := io.ReadAll(r.Body) + if err != nil { + logger.WithError(err).Error("failed to read request body") + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + + if err = s.sandbox.SetPolicy(context.Background(), string(body)); err != nil { + logger.WithError(err).Error("failed to set policy") + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + } + w.Write([]byte("")) + + default: + w.WriteHeader(http.StatusNotImplemented) + return + } +} + func (s *service) ip6TablesHandler(w http.ResponseWriter, r *http.Request) { s.genericIPTablesHandler(w, r, true) } @@ -266,6 +293,7 @@ func (s *service) startManagementServer(ctx context.Context, ociSpec *specs.Spec m.Handle(DirectVolumeStatUrl, http.HandlerFunc(s.serveVolumeStats)) m.Handle(DirectVolumeResizeUrl, http.HandlerFunc(s.serveVolumeResize)) m.Handle(IPTablesUrl, http.HandlerFunc(s.ipTablesHandler)) + m.Handle(PolicyUrl, http.HandlerFunc(s.policyHandler)) m.Handle(IP6TablesUrl, http.HandlerFunc(s.ip6TablesHandler)) s.mountPprofHandle(m, ociSpec) diff --git a/src/runtime/virtcontainers/interfaces.go b/src/runtime/virtcontainers/interfaces.go index 492d3f35a7..742156a6b5 100644 --- a/src/runtime/virtcontainers/interfaces.go +++ b/src/runtime/virtcontainers/interfaces.go @@ -82,6 +82,7 @@ type VCSandbox interface { GetIPTables(ctx context.Context, isIPv6 bool) ([]byte, error) SetIPTables(ctx context.Context, isIPv6 bool, data []byte) error + SetPolicy(ctx context.Context, policy string) error } // VCContainer is the Container interface diff --git a/src/runtime/virtcontainers/pkg/vcmock/sandbox.go b/src/runtime/virtcontainers/pkg/vcmock/sandbox.go index 77f56846a2..09ece4e765 100644 --- a/src/runtime/virtcontainers/pkg/vcmock/sandbox.go +++ b/src/runtime/virtcontainers/pkg/vcmock/sandbox.go @@ -269,3 +269,7 @@ func (s *Sandbox) GetIPTables(ctx context.Context, isIPv6 bool) ([]byte, error) func (s *Sandbox) SetIPTables(ctx context.Context, isIPv6 bool, data []byte) error { return nil } + +func (s *Sandbox) SetPolicy(ctx context.Context, policy string) error { + return nil +} diff --git a/src/runtime/virtcontainers/sandbox.go b/src/runtime/virtcontainers/sandbox.go index 548c6f8300..bff8b6b9b0 100644 --- a/src/runtime/virtcontainers/sandbox.go +++ b/src/runtime/virtcontainers/sandbox.go @@ -2607,6 +2607,11 @@ func (s *Sandbox) SetIPTables(ctx context.Context, isIPv6 bool, data []byte) err return s.agent.setIPTables(ctx, isIPv6, data) } +// SetPolicy will set the policy in the guest +func (s *Sandbox) SetPolicy(ctx context.Context, policy string) error { + return s.agent.setPolicy(ctx, policy) +} + // GuestVolumeStats return the filesystem stat of a given volume in the guest. func (s *Sandbox) GuestVolumeStats(ctx context.Context, volumePath string) ([]byte, error) { guestMountPath, err := s.guestMountPath(volumePath)