Skip to content

Commit

Permalink
feat(adapter): Add core(converter, enforcer)
Browse files Browse the repository at this point in the history
  • Loading branch information
b0m313 committed Jan 9, 2024
1 parent 665ec93 commit 169e905
Show file tree
Hide file tree
Showing 13 changed files with 292 additions and 977 deletions.
23 changes: 5 additions & 18 deletions pkg/exporter/nimbuspolicy/nimbuspolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"

v1 "github.com/5GSEC/nimbus/api/v1"
"github.com/5GSEC/nimbus/pkg/exporter/httpexporter"
"github.com/5GSEC/nimbus/pkg/receiver/watcher"
)

Expand All @@ -34,7 +33,7 @@ func NewNimbusPolicyReconciler(client client.Client, scheme *runtime.Scheme) *Ni

watcherNimbusPolicy, err := watcher.NewWatcherNimbusPolicy(client)
if err != nil {
fmt.Println("NimbusPolicyReconciler: Failed to initialize WatcherNimbusPolicy:", err)
fmt.Println("NimbusPolicyReconciler: Failed to initialize WatcherNimbusPolicy", err)
return nil
}

Expand Down Expand Up @@ -62,31 +61,19 @@ func (r *NimbusPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request
log := log.FromContext(ctx)

if r.WatcherNimbusPolicy == nil {
fmt.Println("NimbusPolicyReconciler: WatcherNimbusPolicy is nil")
return ctrl.Result{}, fmt.Errorf("WatcherNimbusPolicy is not properly initialized")
return ctrl.Result{}, fmt.Errorf("NimbusPolicyReconciler: WatcherNimbusPolicy is nil")
}

nimPol, err := r.WatcherNimbusPolicy.Reconcile(ctx, req)
if err != nil {
log.Error(err, "Error in WatcherNimbusPolicy.Reconcile", "Request", req.NamespacedName)
log.Error(err, "NimbusPolicyReconciler: WatcherNimbusPolicy is error")
return ctrl.Result{}, err
}

if nimPol != nil {
log.Info("NimbusPolicy resource found", "Name", req.Name, "Namespace", req.Namespace)
log.Info("Found: NimbusPolicy", "Name", req.Name, "Namespace", req.Namespace)
} else {
log.Info("NimbusPolicy resource not found", "Name", req.Name, "Namespace", req.Namespace)
}

// Exporting the NimbusPolicy if it is found.
if nimPol != nil {
exporter := httpexporter.NewHttpNimbusExporter("http://localhost:13000/api/v1/nimbus/export") // Update the URL as needed.
err := exporter.ExportNimbusPolicy(ctx, nimPol)
if err != nil {
log.Error(err, "Failed to export NimbusPolicy")
return ctrl.Result{}, err
}
log.Info("NimbusPolicy exported successfully")
log.Info("Not Found: NimbusPolicy")
}

return ctrl.Result{}, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,22 @@ import (
"strings"

v1 "github.com/5GSEC/nimbus/api/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"

kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type PolicyTransformer struct {
type PolicyConverter struct {
Client client.Client
}

func NewPolicyTransformer(client client.Client) *PolicyTransformer {
return &PolicyTransformer{Client: client}
func NewPolicyConverter(client client.Client) *PolicyConverter {
return &PolicyConverter{Client: client}
}

func (pt *PolicyTransformer) Transform(ctx context.Context, nimbusPolicy v1.NimbusPolicy) (*kubearmorv1.KubeArmorPolicy, error) {
func (pt *PolicyConverter) Converter(ctx context.Context, nimbusPolicy v1.NimbusPolicy) (*kubearmorv1.KubeArmorPolicy, error) {
log := log.FromContext(ctx)
log.Info("Start Converting a NimbusPolicy", "PolicyName", nimbusPolicy.Name)

Expand Down Expand Up @@ -114,34 +112,3 @@ func (pt *PolicyTransformer) Transform(ctx context.Context, nimbusPolicy v1.Nimb

return kubeArmorPolicy, nil
}

func (pt *PolicyTransformer) ApplyPolicy(ctx context.Context, kubeArmorPolicy *kubearmorv1.KubeArmorPolicy) error {
log := log.FromContext(ctx)
log.Info("Apply KubeArmorPolicy", "PolicyName", kubeArmorPolicy.Name)

existingPolicy := &kubearmorv1.KubeArmorPolicy{}
err := pt.Client.Get(ctx, types.NamespacedName{Name: kubeArmorPolicy.Name, Namespace: kubeArmorPolicy.Namespace}, existingPolicy)
if err != nil && !errors.IsNotFound(err) {
log.Error(err, "Existing KubeArmorPolicy lookup failed", "PolicyName", kubeArmorPolicy.Name)
return err
}

if errors.IsNotFound(err) {
log.Info("Create a KubeArmorPolicy", "PolicyName", kubeArmorPolicy.Name)
err := pt.Client.Create(ctx, kubeArmorPolicy)
if err != nil {
log.Error(err, "KubeArmorPolicy Creation Failed", "PolicyName", kubeArmorPolicy.Name)
return err
}
} else {
log.Info("Update the KubeArmorPolicy", "PolicyName", kubeArmorPolicy.Name)
existingPolicy.Spec = kubeArmorPolicy.Spec
err := pt.Client.Update(ctx, existingPolicy)
if err != nil {
log.Error(err, "KubeArmorPolicy Update Failed", "PolicyName", kubeArmorPolicy.Name)
return err
}
}

return nil
}
209 changes: 209 additions & 0 deletions pkg/nimbus-kubearmor/core/converter/converthelper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2023 Authors of Nimbus

package transformer

import (
v1 "github.com/5GSEC/nimbus/api/v1"

kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1"
)

func handleProcessPolicy(rule v1.Rule, category string) (kubearmorv1.ProcessType, error) {
processType := kubearmorv1.ProcessType{
MatchPaths: []kubearmorv1.ProcessPathType{},
MatchDirectories: []kubearmorv1.ProcessDirectoryType{},
MatchPatterns: []kubearmorv1.ProcessPatternType{},
}

switch category {
case "paths":
for _, matchPath := range rule.MatchPaths {
if matchPath.Path != "" {
processType.MatchPaths = append(processType.MatchPaths, kubearmorv1.ProcessPathType{
Path: kubearmorv1.MatchPathType(matchPath.Path),
})
}
}

case "dirs":
for _, matchDir := range rule.MatchDirectories {
var fromSources []kubearmorv1.MatchSourceType
for _, source := range matchDir.FromSource {
fromSources = append(fromSources, kubearmorv1.MatchSourceType{
Path: kubearmorv1.MatchPathType(source.Path),
})
}
if matchDir.Directory != "" || len(fromSources) > 0 {
processType.MatchDirectories = append(processType.MatchDirectories, kubearmorv1.ProcessDirectoryType{
Directory: kubearmorv1.MatchDirectoryType(matchDir.Directory),
FromSource: fromSources,
})
}
}

case "patterns":
for _, matchPattern := range rule.MatchPatterns {
if matchPattern.Pattern != "" {
processType.MatchPatterns = append(processType.MatchPatterns, kubearmorv1.ProcessPatternType{
Pattern: matchPattern.Pattern,
})
}
}
}

// Set empty slices if fields are empty
if len(processType.MatchPaths) == 0 {
processType.MatchPaths = []kubearmorv1.ProcessPathType{}
}
if len(processType.MatchDirectories) == 0 {
processType.MatchDirectories = []kubearmorv1.ProcessDirectoryType{}
}
if len(processType.MatchPatterns) == 0 {
processType.MatchPatterns = []kubearmorv1.ProcessPatternType{}
}

return processType, nil
}

func handleFilePolicy(rule v1.Rule, category string) (kubearmorv1.FileType, error) {
fileType := kubearmorv1.FileType{
MatchPaths: []kubearmorv1.FilePathType{},
MatchDirectories: []kubearmorv1.FileDirectoryType{},
MatchPatterns: []kubearmorv1.FilePatternType{},
}

switch category {
case "paths":
for _, matchPath := range rule.MatchPaths {
if matchPath.Path != "" {
fileType.MatchPaths = append(fileType.MatchPaths, kubearmorv1.FilePathType{
Path: kubearmorv1.MatchPathType(matchPath.Path),
})
}
}
case "dirs":
for _, matchDir := range rule.MatchDirectories {
var fromSources []kubearmorv1.MatchSourceType
for _, source := range matchDir.FromSource {
fromSources = append(fromSources, kubearmorv1.MatchSourceType{
Path: kubearmorv1.MatchPathType(source.Path),
})
}
if matchDir.Directory != "" || len(fromSources) > 0 {
fileType.MatchDirectories = append(fileType.MatchDirectories, kubearmorv1.FileDirectoryType{
Directory: kubearmorv1.MatchDirectoryType(matchDir.Directory),
FromSource: fromSources,
})
}
}
case "patterns":
for _, matchPattern := range rule.MatchPatterns {
if matchPattern.Pattern != "" {
fileType.MatchPatterns = append(fileType.MatchPatterns, kubearmorv1.FilePatternType{
Pattern: matchPattern.Pattern,
})
}
}
}

// Set empty slices if fields are empty
if len(fileType.MatchPaths) == 0 {
fileType.MatchPaths = []kubearmorv1.FilePathType{}
}
if len(fileType.MatchDirectories) == 0 {
fileType.MatchDirectories = []kubearmorv1.FileDirectoryType{}
}
if len(fileType.MatchPatterns) == 0 {
fileType.MatchPatterns = []kubearmorv1.FilePatternType{}
}

return fileType, nil
}

func handleNetworkPolicy(rule v1.Rule) (kubearmorv1.NetworkType, error) {
networkType := kubearmorv1.NetworkType{
MatchProtocols: []kubearmorv1.MatchNetworkProtocolType{},
}

for _, matchProtocol := range rule.MatchProtocols {
if matchProtocol.Protocol != "" {
networkType.MatchProtocols = append(networkType.MatchProtocols, kubearmorv1.MatchNetworkProtocolType{
Protocol: kubearmorv1.MatchNetworkProtocolStringType(matchProtocol.Protocol),
})
}
}
return networkType, nil
}

func handleSyscallPolicy(rule v1.Rule, category string) (kubearmorv1.SyscallsType, error) {
// Initialize syscallType with default values
syscallType := kubearmorv1.SyscallsType{
MatchSyscalls: []kubearmorv1.SyscallMatchType{},
MatchPaths: []kubearmorv1.SyscallMatchPathType{},
}

switch category {
case "syscalls":
for _, matchSyscall := range rule.MatchSyscalls {
syscallMatch := kubearmorv1.SyscallMatchType{
Syscalls: []kubearmorv1.Syscall{},
}
for _, syscall := range matchSyscall.Syscalls {
if syscall != "" {
syscallMatch.Syscalls = append(syscallMatch.Syscalls, kubearmorv1.Syscall(syscall))
}
}
syscallType.MatchSyscalls = append(syscallType.MatchSyscalls, syscallMatch)
}

case "paths":
for _, matchSyscallPath := range rule.MatchSyscallPaths {
syscallMatchPath := kubearmorv1.SyscallMatchPathType{
Path: kubearmorv1.MatchSyscallPathType(matchSyscallPath.Path),
Recursive: matchSyscallPath.Recursive,
Syscalls: []kubearmorv1.Syscall{},
FromSource: []kubearmorv1.SyscallFromSourceType{},
}
for _, syscall := range matchSyscallPath.Syscalls {
if syscall != "" {
syscallMatchPath.Syscalls = append(syscallMatchPath.Syscalls, kubearmorv1.Syscall(syscall))
}
}
for _, fromSource := range matchSyscallPath.FromSource {
syscallFromSource := kubearmorv1.SyscallFromSourceType{
Path: kubearmorv1.MatchPathType(fromSource.Path),
Dir: fromSource.Dir,
}
syscallMatchPath.FromSource = append(syscallMatchPath.FromSource, syscallFromSource)
}
syscallType.MatchPaths = append(syscallType.MatchPaths, syscallMatchPath)
}
}

// Set empty slices if fields are empty
if len(syscallType.MatchSyscalls) == 0 {
syscallType.MatchSyscalls = []kubearmorv1.SyscallMatchType{}
}
// Set empty slices if fields are empty
if len(syscallType.MatchPaths) == 0 {
syscallType.MatchPaths = []kubearmorv1.SyscallMatchPathType{}
}

return syscallType, nil
}

func handleCapabilityPolicy(rule v1.Rule) (kubearmorv1.CapabilitiesType, error) {
capabilityType := kubearmorv1.CapabilitiesType{
MatchCapabilities: []kubearmorv1.MatchCapabilitiesType{},
}

for _, matchCapability := range rule.MatchCapabilities {
if matchCapability.Capability != "" {
capabilityType.MatchCapabilities = append(capabilityType.MatchCapabilities, kubearmorv1.MatchCapabilitiesType{
Capability: kubearmorv1.MatchCapabilitiesStringType(matchCapability.Capability),
})
}
}
return capabilityType, nil
}
40 changes: 40 additions & 0 deletions pkg/nimbus-kubearmor/core/enforcer/enforcer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2023 Authors of Nimbus

package enforcer

import (
"context"

v1 "github.com/5GSEC/nimbus/api/v1"
"github.com/5GSEC/nimbus/pkg/nimbus-kubearmor/core/applier"
"github.com/5GSEC/nimbus/pkg/nimbus-kubearmor/core/converter"

"sigs.k8s.io/controller-runtime/pkg/client"
)

// PolicyEnforcer manages the conversion and enforcement of Nimbus policies.
type PolicyEnforcer struct {
converter *converter.PolicyConverter
applier *applier.Applier
}

// NewPolicyEnforcer creates a new PolicyEnforcer instance.
func NewPolicyEnforcer(client client.Client) *PolicyEnforcer {
return &PolicyEnforcer{
converter: converter.NewPolicyConverter(client),
applier: applier.NewApplier(client),
}
}

// ExportAndApplyPolicy converts a NimbusPolicy to a KubeArmorPolicy and applies it.
func (pe *PolicyEnforcer) Enforcer(ctx context.Context, nimbusPolicy v1.NimbusPolicy) error {
// Convert NimbusPolicy to KubeArmorPolicy
kubeArmorPolicy, err := pe.converter.Converter(ctx, nimbusPolicy)
if err != nil {
return err
}

// Apply the converted KubeArmorPolicy
return pe.applier.ApplyPolicy(ctx, kubeArmorPolicy)
}
Loading

0 comments on commit 169e905

Please sign in to comment.