diff --git a/Dockerfile b/Dockerfile index cdec1a01..95188af6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,9 @@ RUN go mod download # Copy the go source COPY cmd/main.go cmd/main.go COPY api/ api/ -COPY pkg/ pkg/ +COPY pkg/exporter/ pkg/exporter/ +COPY pkg/processor/ pkg/processor/ +COPY pkg/receiver/ pkg/receiver/ # Build # the GOARCH has not a default value to allow the binary be built according to the host where the command diff --git a/Makefile b/Makefile index cfe1de19..5b7c8759 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and Cust .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./pkg/..." + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./api/..." .PHONY: fmt fmt: ## Run go fmt against code. diff --git a/api/v1/nimbuspolicy_types.go b/api/v1/nimbuspolicy_types.go index 4fd31af0..a560f5fe 100644 --- a/api/v1/nimbuspolicy_types.go +++ b/api/v1/nimbuspolicy_types.go @@ -33,7 +33,7 @@ type NimbusRules struct { Id string `json:"id"` Type string `json:"type,omitempty"` Description string `json:"description,omitempty"` - Rule []Rule `json:"rule"` + Rule Rule `json:"rule"` } type Rule struct { diff --git a/api/v1/securityintent_types.go b/api/v1/securityintent_types.go index 12fce719..64d72b1e 100644 --- a/api/v1/securityintent_types.go +++ b/api/v1/securityintent_types.go @@ -20,13 +20,14 @@ type SecurityIntentSpec struct { // Intent defines the security policy details type Intent struct { + // +kubebuilder:validation:Pattern:="^[a-zA-Z0-9]*$" Id string `json:"id"` Description string `json:"description,omitempty"` Action string `json:"action"` Mode string `json:"mode"` Severity int `json:"severity,omitempty"` Tags []string `json:"tags,omitempty"` - Params []SecurityIntentParams `json:"params"` + Params []SecurityIntentParams `json:"params,omitempty"` } // Resource defines the resources that the security policy applies to @@ -110,7 +111,7 @@ type SecurityIntentStatus struct { // SecurityIntent is the Schema for the securityintents API // +kubebuilder:object:root=true -// +kubebuilder:resource: shortName="sit" +// +kubebuilder:resource: shortName="si" // +kubebuilder:subresource:status // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 23f5b6cf..51ad1446 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -283,13 +283,7 @@ func (in *NimbusPolicyStatus) DeepCopy() *NimbusPolicyStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NimbusRules) DeepCopyInto(out *NimbusRules) { *out = *in - if in.Rule != nil { - in, out := &in.Rule, &out.Rule - *out = make([]Rule, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + in.Rule.DeepCopyInto(&out.Rule) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NimbusRules. diff --git a/config/crd/bases/intent.security.nimbus.com_nimbuspolicies.yaml b/config/crd/bases/intent.security.nimbus.com_nimbuspolicies.yaml index f98d8afb..9dfb3461 100644 --- a/config/crd/bases/intent.security.nimbus.com_nimbuspolicies.yaml +++ b/config/crd/bases/intent.security.nimbus.com_nimbuspolicies.yaml @@ -48,111 +48,108 @@ spec: id: type: string rule: - items: - properties: - action: - type: string - fromCIDRSet: - items: - description: CIDRSet defines CIDR ranges for network - policies - properties: - cidr: + properties: + action: + type: string + fromCIDRSet: + items: + description: CIDRSet defines CIDR ranges for network policies + properties: + cidr: + type: string + type: object + type: array + matchCapabilities: + description: 'Capabilities: MatchCapabilities' + items: + description: MatchCapability defines a capability for + capabilities policies + properties: + capability: + type: string + type: object + type: array + matchDirectories: + items: + description: MatchDirectory defines a directory for process + or file policies + properties: + dir: + type: string + fromSource: + items: + description: FromSource defines a source path for + directory-based policies + properties: + path: + type: string + type: object + type: array + type: object + type: array + matchPaths: + description: 'Process: MatchPaths, MatchDirectories, MatchPatterns + File: MatchPaths, MatchDirectories' + items: + description: MatchPath defines a path for process or file + policies + properties: + path: + type: string + type: object + type: array + matchPatterns: + items: + description: MatchPattern defines a pattern for process + policies + properties: + pattern: + type: string + type: object + type: array + matchProtocols: + description: 'Network: MatchProtocols' + items: + description: MatchProtocol defines a protocol for network + policies + properties: + protocol: + type: string + type: object + type: array + matchSyscalls: + description: 'Syscalls: MatchSyscalls' + items: + description: MatchSyscall defines a syscall for syscall + policies + properties: + syscalls: + items: type: string - type: object - type: array - matchCapabilities: - description: 'Capabilities: MatchCapabilities' - items: - description: MatchCapability defines a capability for - capabilities policies - properties: - capability: - type: string - type: object - type: array - matchDirectories: - items: - description: MatchDirectory defines a directory for - process or file policies - properties: - dir: - type: string - fromSource: - items: - description: FromSource defines a source path - for directory-based policies - properties: - path: - type: string - type: object - type: array - type: object - type: array - matchPaths: - description: 'Process: MatchPaths, MatchDirectories, MatchPatterns - File: MatchPaths, MatchDirectories' - items: - description: MatchPath defines a path for process or - file policies - properties: - path: - type: string - type: object - type: array - matchPatterns: - items: - description: MatchPattern defines a pattern for process - policies - properties: - pattern: - type: string - type: object - type: array - matchProtocols: - description: 'Network: MatchProtocols' - items: - description: MatchProtocol defines a protocol for network - policies - properties: - protocol: - type: string - type: object - type: array - matchSyscalls: - description: 'Syscalls: MatchSyscalls' - items: - description: MatchSyscall defines a syscall for syscall - policies - properties: - syscalls: - items: - type: string - type: array - type: object - type: array - toPorts: - items: - description: ToPort defines ports and protocols for - network policies - properties: - ports: - items: - description: Port defines a network port and its - protocol - properties: - port: - type: string - protocol: - type: string - type: object - type: array - type: object - type: array - required: - - action - type: object - type: array + type: array + type: object + type: array + toPorts: + items: + description: ToPort defines ports and protocols for network + policies + properties: + ports: + items: + description: Port defines a network port and its + protocol + properties: + port: + type: string + protocol: + type: string + type: object + type: array + type: object + type: array + required: + - action + type: object type: type: string required: diff --git a/config/crd/bases/intent.security.nimbus.com_securityintents.yaml b/config/crd/bases/intent.security.nimbus.com_securityintents.yaml index b0439195..8e684a44 100644 --- a/config/crd/bases/intent.security.nimbus.com_securityintents.yaml +++ b/config/crd/bases/intent.security.nimbus.com_securityintents.yaml @@ -12,7 +12,7 @@ spec: listKind: SecurityIntentList plural: securityintents shortNames: - - sit + - si singular: securityintent scope: Namespaced versions: @@ -44,6 +44,7 @@ spec: description: type: string id: + pattern: ^[a-zA-Z0-9]*$ type: string mode: type: string @@ -158,7 +159,6 @@ spec: - action - id - mode - - params type: object required: - intent diff --git a/pkg/adapter/adapter.go b/pkg/adapter/adapter.go new file mode 100644 index 00000000..648c72e1 --- /dev/null +++ b/pkg/adapter/adapter.go @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +// Package adapter provides security engine adapters to use with nimbus. +package adapter + +import ( + "context" + + v1 "github.com/5GSEC/nimbus/api/v1" +) + +// The Adapters currently supported by nimbus. +var Adapters = []string{"kubearmor"} + +// Adapter knows how to create/update and delete security-engine policies. +type Adapter interface { + ApplyPolicy(ctx context.Context, np v1.NimbusPolicy) error + DeletePolicy(ctx context.Context, np v1.NimbusPolicy) error +} diff --git a/pkg/adapter/exporter/exporter.go b/pkg/adapter/exporter/exporter.go new file mode 100644 index 00000000..c578b3be --- /dev/null +++ b/pkg/adapter/exporter/exporter.go @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package exporter + +import ( + "context" + + "go.uber.org/zap" + + v1 "github.com/5GSEC/nimbus/api/v1" + "github.com/5GSEC/nimbus/pkg/adapter" + "github.com/5GSEC/nimbus/pkg/adapter/k8s" + "github.com/5GSEC/nimbus/pkg/adapter/kubearmor" +) + +// ExportNpToAdapters export nimbus policy to security-engine adapters. +func ExportNpToAdapters(loggr *zap.SugaredLogger, nimbusPolicy v1.NimbusPolicy) { + for _, adptr := range adapter.Adapters { + loggr.Infof("Exporting '%s' NimbusPolicy to %s security engine", nimbusPolicy.Name, adptr) + err := sendNpTo(loggr, nimbusPolicy, adptr) + if err != nil { + loggr.Warnf("%v", err) + } + } +} + +func sendNpTo(loggr *zap.SugaredLogger, nimbusPolicy v1.NimbusPolicy, adptr string) error { + var securityEngineClient adapter.Adapter + k8sClient := k8s.NewClient(loggr) + switch adptr { + case "kubearmor": + securityEngineClient = kubearmor.NewKubeArmorClient(loggr, k8sClient) + err := securityEngineClient.ApplyPolicy(context.Background(), nimbusPolicy) + return err + default: + return nil + } +} diff --git a/pkg/adapter/idpool/idpool.go b/pkg/adapter/idpool/idpool.go new file mode 100644 index 00000000..5e5b1dc1 --- /dev/null +++ b/pkg/adapter/idpool/idpool.go @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +// Package idpool manages a pool of IDs for use by adapters. +package idpool + +import ( + "strings" +) + +const ( + SwDeploymentTools = "swDeploymentTools" + UnAuthorizedNEFAccess = "unAuthorizedNEFAccess" + NFServiceDiscovery = "nfServiceDiscovery" + DNSManipulation = "dnsManipulation" + NetPortExec = "netPortExec" + SysPathExec = "sysPathExec" +) + +// KaIds are IDs supported by KubeArmor security engine. +var KaIds = []string{ + SwDeploymentTools, +} + +// IdSupportedBy determines whether a given ID is supported by a security engine. +func IdSupportedBy(id, securityEngine string) bool { + switch strings.ToLower(securityEngine) { + case "kubearmor": + return in(id, KaIds) + default: + return false + } +} + +func in(id string, securityEngineIds []string) bool { + for _, currId := range securityEngineIds { + if currId == id { + return true + } + } + return false +} diff --git a/pkg/adapter/k8s/client.go b/pkg/adapter/k8s/client.go new file mode 100644 index 00000000..654cfca3 --- /dev/null +++ b/pkg/adapter/k8s/client.go @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package k8s + +import ( + "errors" + "os" + "path/filepath" + + "github.com/go-logr/logr" + kspAPI "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1" + "go.uber.org/zap" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +// NewClient creates a new Kubernetes client to perform CRUD operations. +func NewClient(logger *zap.SugaredLogger) client.Client { + err := registerScheme() + if err != nil { + logger.Errorf("failed to register scheme, error: %v", err) + } + config, err := rest.InClusterConfig() + if err != nil && errors.Is(err, rest.ErrNotInCluster) { + kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config") + config, err = clientcmd.BuildConfigFromFlags("", kubeconfig) + if err != nil { + logger.Errorf("failed to load kubeconfig, error: %v", err) + } + } + k8sClient, err := client.New(config, client.Options{}) + if err != nil { + logger.Fatalf("failed to create client, error: %v", err) + } + + // Temporary fix for 👇 error + // [controller-runtime] log.SetLogger(...) was never called; logs will not be displayed. + log.SetLogger(logr.Logger{}) + return k8sClient +} + +func registerScheme() error { + // Add a new scheme when adding a new Adapter + err := kspAPI.AddToScheme(scheme.Scheme) + return err +} diff --git a/pkg/adapter/kubearmor/client.go b/pkg/adapter/kubearmor/client.go new file mode 100644 index 00000000..9a53ca76 --- /dev/null +++ b/pkg/adapter/kubearmor/client.go @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package kubearmor + +import ( + "context" + "fmt" + "strings" + + kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1" + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + + v1 "github.com/5GSEC/nimbus/api/v1" + "github.com/5GSEC/nimbus/pkg/adapter/idpool" + "github.com/5GSEC/nimbus/pkg/adapter/kubearmor/processor" +) + +type Client struct { + Logger *zap.SugaredLogger + k8sClient client.Client +} + +func NewKubeArmorClient(logger *zap.SugaredLogger, client client.Client) *Client { + return &Client{ + Logger: logger, + k8sClient: client, + } +} + +func (c *Client) ApplyPolicy(ctx context.Context, np v1.NimbusPolicy) error { + // Build KSPs based on given IDs + var ksps []kubearmorv1.KubeArmorPolicy + for _, nimbusRule := range np.Spec.NimbusRules { + id := nimbusRule.Id + if idpool.IdSupportedBy(id, "kubearmor") { + ksp := processor.BuildKspFor(id) + ksp.Name = np.Name + "-" + strings.ToLower(id) + ksp.Namespace = np.Namespace + ksp.Spec.Message = nimbusRule.Description + ksp.Spec.Selector.MatchLabels = np.Spec.Selector.MatchLabels + ksp.Spec.Action = kubearmorv1.ActionType(nimbusRule.Rule.RuleAction) + processor.ProcessRuleParams(&ksp, nimbusRule.Rule) + ksps = append(ksps, ksp) + } else { + c.Logger.Warnf("KubeArmor does not support '%s' ID", id) + } + } + + for _, ksp := range ksps { + var existingKsp kubearmorv1.KubeArmorPolicy + err := c.k8sClient.Get(ctx, types.NamespacedName{Name: ksp.Name, Namespace: ksp.Namespace}, &existingKsp) + if err != nil && !errors.IsNotFound(err) { + return fmt.Errorf("failed to get existing '%s' KubeArmorPolicy, error: %v", ksp.Name, err) + } + if errors.IsNotFound(err) { + if err = c.k8sClient.Create(ctx, &ksp); err != nil { + return fmt.Errorf("failed to create '%s' KubeArmorPolicy, error: %v", ksp.Name, err) + } + c.Logger.Infof("Created KubeArmorPolicy %s", ksp.Name) + } else { + if err = c.k8sClient.Update(ctx, &ksp); err != nil { + return fmt.Errorf("failed to apply existing '%s' KubeArmorPolicy, error: %v", ksp.Name, err) + } + c.Logger.Infof("Configured KubeArmorPolicy %s", ksp.Name) + } + } + return nil +} + +func (c *Client) DeletePolicy(ctx context.Context, np v1.NimbusPolicy) error { + for _, nimbusRule := range np.Spec.NimbusRules { + id := nimbusRule.Id + if idpool.IdSupportedBy(id, "kubearmor") { + var ksp kubearmorv1.KubeArmorPolicy + ksp.SetName(np.Name + "-" + strings.ToLower(id)) + ksp.SetNamespace(np.Namespace) + if err := c.k8sClient.Delete(ctx, &ksp); err != nil && !errors.IsNotFound(err) { + return fmt.Errorf("failed to delete '%s' KubeArmorPolicy, error: %v", ksp.Name, err) + } + c.Logger.Infof("Deleted KubeArmorPolicy %s", ksp.Name) + } + } + return nil +} diff --git a/pkg/adapter/kubearmor/processor/ksp_processor.go b/pkg/adapter/kubearmor/processor/ksp_processor.go new file mode 100644 index 00000000..19c0076d --- /dev/null +++ b/pkg/adapter/kubearmor/processor/ksp_processor.go @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package processor + +import ( + "io" + "net/http" + + kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1" + "k8s.io/apimachinery/pkg/util/yaml" + + v1 "github.com/5GSEC/nimbus/api/v1" + "github.com/5GSEC/nimbus/pkg/adapter/idpool" +) + +// ProcessRuleParams processes the given nimbus policy rules, generating corresponding KubeArmorPolicy rules. +func ProcessRuleParams(ksp *kubearmorv1.KubeArmorPolicy, rule v1.Rule) { + // Process + // Why only process rules? Nimbus Policy has only process rules that's why we're processing only those rules. + for _, matchPath := range rule.MatchPaths { + ksp.Spec.Process.MatchPaths = append(ksp.Spec.Process.MatchPaths, kubearmorv1.ProcessPathType{ + Path: kubearmorv1.MatchPathType(matchPath.Path), + }) + } + + for idx, matchDir := range rule.MatchDirectories { + ksp.Spec.Process.MatchDirectories = append(ksp.Spec.Process.MatchDirectories, kubearmorv1.ProcessDirectoryType{ + Directory: kubearmorv1.MatchDirectoryType(matchDir.Directory), + }) + var fromSources []kubearmorv1.MatchSourceType + for _, fromSource := range matchDir.FromSource { + fromSources = append(fromSources, kubearmorv1.MatchSourceType{ + Path: kubearmorv1.MatchPathType(fromSource.Path), + }) + } + ksp.Spec.Process.MatchDirectories[idx].FromSource = fromSources + } + + for _, matchPattern := range rule.MatchPatterns { + ksp.Spec.Process.MatchPatterns = append(ksp.Spec.Process.MatchPatterns, kubearmorv1.ProcessPatternType{ + Pattern: matchPattern.Pattern, + }) + } + + // Network + for _, matchProtocol := range rule.MatchProtocols { + ksp.Spec.Network.MatchProtocols = append(ksp.Spec.Network.MatchProtocols, kubearmorv1.MatchNetworkProtocolType{ + Protocol: kubearmorv1.MatchNetworkProtocolStringType(matchProtocol.Protocol), + }) + } + // Ignoring SysCalls and Capabilities +} + +// BuildKspFor builds a KubeArmorPolicy based on intent ID supported by KubeArmor Security Engine. +func BuildKspFor(id string) kubearmorv1.KubeArmorPolicy { + switch id { + case idpool.SwDeploymentTools: + return buildSwDeploymentToolsKsp() + default: + return kubearmorv1.KubeArmorPolicy{} + } +} + +func buildSwDeploymentToolsKsp() kubearmorv1.KubeArmorPolicy { + var ksp kubearmorv1.KubeArmorPolicy + fileUrl := "https://raw.githubusercontent.com/kubearmor/policy-templates/main/nist/system/ksp-nist-si-4-execute-package-management-process-in-container.yaml" + response, err := http.Get(fileUrl) + + if err != nil { + return ksp + } + defer func() { + err = response.Body.Close() + if err != nil { + return + } + }() + + data, err := io.ReadAll(response.Body) + if err != nil { + return ksp + } + _ = yaml.Unmarshal(data, &ksp) + + // remove explicit action + ksp.Spec.Process.Action = "" + return ksp +} diff --git a/pkg/nimbus-kubearmor/receiver/server/server.go b/pkg/nimbus-kubearmor/receiver/server/server.go index f58d5285..a0557af9 100644 --- a/pkg/nimbus-kubearmor/receiver/server/server.go +++ b/pkg/nimbus-kubearmor/receiver/server/server.go @@ -5,12 +5,15 @@ package main import ( "encoding/json" - "fmt" "io" - "log" "net/http" "sync" "time" + + "go.uber.org/zap" + + v1 "github.com/5GSEC/nimbus/api/v1" + "github.com/5GSEC/nimbus/pkg/adapter/exporter" ) var ( @@ -20,6 +23,10 @@ var ( ) func main() { + logger, _ := zap.NewProduction() + defer logger.Sync() + log := logger.Sugar() + // Handler for exporting Nimbus Policies http.HandleFunc("/api/v1/nimbus/export", func(w http.ResponseWriter, r *http.Request) { if r.Method != "POST" { @@ -36,8 +43,8 @@ func main() { defer r.Body.Close() // Unmarshal the JSON data from the request - var data interface{} - err = json.Unmarshal(body, &data) + var nimbusPolicy v1.NimbusPolicy + err = json.Unmarshal(body, &nimbusPolicy) if err != nil { http.Error(w, "Error unmarshalling request body", http.StatusBadRequest) return @@ -45,11 +52,10 @@ func main() { // Store the received Nimbus Policy lock.Lock() - nimbusPolicies = append(nimbusPolicies, data) + nimbusPolicies = append(nimbusPolicies, nimbusPolicy) lock.Unlock() - - // Log the received policy - fmt.Printf("Received Nimbus Policy: %+v\n", data) + log.Infof("Exporting '%s' NimbusPolicy to security engines", nimbusPolicy.Name) + exporter.ExportNpToAdapters(log, nimbusPolicy) w.WriteHeader(http.StatusOK) }) @@ -77,6 +83,6 @@ func main() { } // Start the server - log.Println("Server starting on port 13000...") + log.Info("Starting server on port 13000...") log.Fatal(server.ListenAndServe()) } diff --git a/pkg/processor/nimbuspolicybuilder/nimbuspolicy_builder.go b/pkg/processor/nimbuspolicybuilder/nimbuspolicy_builder.go index 01384862..d2dd80da 100644 --- a/pkg/processor/nimbuspolicybuilder/nimbuspolicy_builder.go +++ b/pkg/processor/nimbuspolicybuilder/nimbuspolicy_builder.go @@ -9,14 +9,14 @@ import ( "github.com/google/cel-go/cel" "github.com/google/cel-go/checker/decls" - ctrl "sigs.k8s.io/controller-runtime" - - v1 "github.com/5GSEC/nimbus/api/v1" - "github.com/5GSEC/nimbus/pkg/processor/intentbinder" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" + + v1 "github.com/5GSEC/nimbus/api/v1" + "github.com/5GSEC/nimbus/pkg/processor/intentbinder" ) // BuildNimbusPolicy generates a NimbusPolicy based on SecurityIntent and SecurityIntentBinding. @@ -34,11 +34,6 @@ func BuildNimbusPolicy(ctx context.Context, client client.Client, req ctrl.Reque // Iterate over intent names to build rules. for i, intentName := range bindingInfo.IntentNames { - // Checks for array length consistency. - if i >= len(bindingInfo.IntentNamespaces) || i >= len(bindingInfo.BindingNames) || - i >= len(bindingInfo.BindingNamespaces) { - return nil, fmt.Errorf("index out of range in bindingInfo arrays") - } intentNamespace := bindingInfo.IntentNamespaces[i] intent, err := fetchIntentByName(ctx, client, intentName, intentNamespace) @@ -52,9 +47,6 @@ func BuildNimbusPolicy(ctx context.Context, client client.Client, req ctrl.Reque return nil, fmt.Errorf("no intents or bindings to process") } - var rules []v1.Rule - - // Constructs a rule from the intent parameters. rule := v1.Rule{ RuleAction: intent.Spec.Intent.Action, MatchProtocols: []v1.MatchProtocol{}, @@ -70,13 +62,12 @@ func BuildNimbusPolicy(ctx context.Context, client client.Client, req ctrl.Reque for _, param := range intent.Spec.Intent.Params { processSecurityIntentParams(&rule, param) } - rules = append(rules, rule) nimbusRule := v1.NimbusRules{ Id: intent.Spec.Intent.Id, Type: "", // Set Type if necessary Description: intent.Spec.Intent.Description, - Rule: rules, + Rule: rule, } nimbusRulesList = append(nimbusRulesList, nimbusRule) } diff --git a/test/v2/bindings/system/pkg-mgr-exec.yaml b/test/v2/bindings/system/pkg-mgr-exec.yaml new file mode 100644 index 00000000..fdcbae9d --- /dev/null +++ b/test/v2/bindings/system/pkg-mgr-exec.yaml @@ -0,0 +1,14 @@ +apiVersion: intent.security.nimbus.com/v1 +kind: SecurityIntentBinding +metadata: + name: pkg-mgr-exec +spec: + intents: + - name: pkg-mgr-exec + selector: + any: + - resources: + kind: Pod + namespace: default + matchLabels: + app: nginx diff --git a/test/v2/intents/network/intent-redis.yaml b/test/v2/intents/network/intent-redis.yaml index 487ddd12..e2e25ba2 100644 --- a/test/v2/intents/network/intent-redis.yaml +++ b/test/v2/intents/network/intent-redis.yaml @@ -5,7 +5,7 @@ metadata: namespace: default spec: intent: - id: net-port-exec + id: netPortExec description: "Don’t allow any outside traffic to the Redis port" action: Block mode: Strict diff --git a/test/v2/intents/system/intent-path-block.yaml b/test/v2/intents/system/intent-path-block.yaml index 451ca150..0df55918 100644 --- a/test/v2/intents/system/intent-path-block.yaml +++ b/test/v2/intents/system/intent-path-block.yaml @@ -5,7 +5,7 @@ metadata: namespace: multiubuntu spec: intent: - id: sys-path-exec + id: sysPathExec description: "block the execution of '/bin/sleep'" action: Block mode: Strict diff --git a/test/v2/intents/system/pkg-mgr-exec.yaml b/test/v2/intents/system/pkg-mgr-exec.yaml new file mode 100644 index 00000000..86dea90a --- /dev/null +++ b/test/v2/intents/system/pkg-mgr-exec.yaml @@ -0,0 +1,10 @@ +apiVersion: intent.security.nimbus.com/v1 +kind: SecurityIntent +metadata: + name: pkg-mgr-exec +spec: + intent: + id: swDeploymentTools + description: "block the execution of package managers inside the containers" + action: Block + mode: Strict