Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions configuration/ConfigurationFile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"services": [
{
"type": "sniffer",
"data": {
"ebpfEngine": {
"type": "falco",
"data": {
"kernelObjPath": "./resources/ebpf/kernel_obj.o",
"ebpfEngineLoaderPath": "./resources/ebpf/userspace_app"
}
},
"node": {
"name": "minikube"
},
"features": [
{
"Name": "relevantCVEs"
}
],
"containerSniffing": {
"sniffingTime": {
"sniffingMaxTime": "3600"
}
},
"outputDataStorage": {
"type": "server",
"data": {
"dataStorage": {
"URL": "blabla.com/v1/store"
}
},
"updateDataPeriod": "120"
}
}
}
]
}
2 changes: 1 addition & 1 deletion deps/install_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ cmake ..
make all
cd ../../../
cp deps/dependencies/kubescape_ebpf_engine_sc/deps/dependencies/falco-libs/build/driver/bpf/probe.o ../resources/ebpf/kernel_obj.o
cp deps/dependencies/kubescape_ebpf_engine_sc/build/main ../resources/ebpf/sniffer
cp deps/dependencies/kubescape_ebpf_engine_sc/build/main ../resources/ebpf/userspace_app
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this is the new name for sniffer?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, but this is our wrapper to the userspace application of falco that loaded and communicate with the kernel code. so I think the name is better

66 changes: 66 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package config

import (
"bytes"
"encoding/json"
"fmt"
"io"
"os"
v1 "sniffer/internal/config/v1"
)

const (
FALCO_EBPF_ENGINE = "falco"
CILIUM_EBPF_ENGINE = "cilium"
)

var c *Config

type Config struct {
data v1.ConfigData
}

func (cfg *Config) getConfigFilePath() (string, bool) {
return os.LookupEnv("SNIFFER_CONFIG")
}

func (cfg *Config) GetConfigurationData() (io.Reader, error) {
config := Config{}
c = &config
cfgPath, exist := cfg.getConfigFilePath()
if !exist {
return nil, fmt.Errorf("failed to find configuration file path")
}
data, err := os.ReadFile(cfgPath)
if err != nil {
return nil, fmt.Errorf("failed to read configuration file with error %v", err.Error())
}

return bytes.NewReader(data), nil
}

func (cfg *Config) ParseConfiguration(data io.Reader) error {
configData := v1.ConfigData{}

buf := new(bytes.Buffer)
_, err := buf.ReadFrom(data)
if err != nil {
return err
}
b := buf.Bytes()
err = json.Unmarshal(b, &configData)
if err != nil {
return err
}
cfg.data = configData

return nil
}

func IsFalcoEbpfEngine() bool {
return c.data.IsFalcoEbpfEngine()
}

func GetSyscallFilter() []string {
return c.data.GetFalcoSyscallFilter()
}
6 changes: 6 additions & 0 deletions internal/config/config_data_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package config

type ConfigDataInterface interface {
IsFalcoEbpfEngine() bool
GetFalcoSyscallFilter() []string
}
1 change: 0 additions & 1 deletion internal/config/config_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package config
import "io"

type ConfigClient interface {
// global configuration
GetConfigurationData() (io.Reader, error)
ParseConfiguration(data io.Reader) error
}
27 changes: 27 additions & 0 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package config

import (
"os"
"testing"
)

func TestConfig(t *testing.T) {
err := os.Setenv("SNIFFER_CONFIG", "../../configuration/ConfigurationFile.json")
if err != nil {
t.Fatalf("failed to set env SNIFFER_CONFIG with err %v", err)
}

cfg := Config{}
configData, err := cfg.GetConfigurationData()
if err != nil {
t.Fatalf("GetConfigurationData failed with err %v", err)
}
err = cfg.ParseConfiguration(configData)
if err != nil {
t.Fatalf("ParseConfiguration failed with err %v", err)
}

if cfg.data.IsFalcoEbpfEngine() == false {
t.Fatalf("IsFalcoEbpfEngine need to be falco")
}
}
101 changes: 101 additions & 0 deletions internal/config/v1/config_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package config

var falcoSyscallFilter []string

const (
FALCO_EBPF_ENGINE_TYPE = "falco"
KUBESCAPE_EBPF_ENGINE_TYPE = "kubescape"
)

const (
SNIFFER_SERVICE_RELEVANT_CVES = "relevantCVEs"
)

// all the struct and arguments names must be visible outside from the package since the json parser package need to parse them

type FalcoEbpfEngineData struct {
KernelObjPath string `json:"kernelObjPath"`
EbpfEngineLoaderPath string `json:"ebpfEngineLoaderPath"`
}

type EbpfEngine struct {
EbpfEngineType string `json:"type"`
Data interface{} `json:"data"`
}

type NodeData struct {
Name string `json:"name"`
}

type Features struct {
Name string `json:"name"`
}

type ContainerSniffing struct {
SniffingMaxTime string `json:"sniffingMaxTime"`
}

type DataStorage struct {
URL string `json:"URL"`
}

type OutputDataStorageData struct {
DataStorage `json:"dataStorage"`
}

type OutputDataStorage struct {
OutputDataStorageType string `json:"type"`
Data interface{} `json:"data"`
UpdateDataPeriod string `json:"updateDataPeriod"`
}

type SnifferData struct {
EbpfEngine `json:"ebpfEngine"`
NodeData `json:"node"`
FeatureList []Features `json:"features"`
ContainerSniffing `json:"containerSniffing"`
OutputDataStorage `json:"outputDataStorage"`
}

type Services struct {
ServiceType string `json:"type"`
Data interface{} `json:"data"`
}

type ConfigData struct {
ServicesList []Services `json:"services"`
}

func (c *ConfigData) IsFalcoEbpfEngine() bool {
for i := range c.ServicesList {
switch v := c.ServicesList[i].Data.(type) {
case map[string]interface{}:
return v["ebpfEngine"].(map[string]interface{})["type"] == FALCO_EBPF_ENGINE_TYPE
default:
return false
}
}
return false
}

func (c *ConfigData) setFalcoSyscallFilter() {
if c.IsFalcoEbpfEngine() {
for i := range c.ServicesList {
switch v := c.ServicesList[i].Data.(type) {
case SnifferData:
for j := range v.FeatureList {
if v.FeatureList[j].Name == SNIFFER_SERVICE_RELEVANT_CVES {
falcoSyscallFilter = append(falcoSyscallFilter, []string{"open", "openat", "execve", "execveat"}...)
}
}
}
}
}
}

func (c *ConfigData) GetFalcoSyscallFilter() []string {
if len(falcoSyscallFilter) == 0 {
c.setFalcoSyscallFilter()
}
return falcoSyscallFilter
}
18 changes: 18 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
package main

import (
"fmt"
"sniffer/internal/config"

"github.com/kubescape/go-logger"
"github.com/kubescape/go-logger/helpers"
)

func main() {
cfg := config.Config{}
configData, err := cfg.GetConfigurationData()
if err != nil {
logger.L().Fatal("", helpers.String("error during getting configuration data: ", fmt.Sprintf("%v", err)))
}
err = cfg.ParseConfiguration(configData)
if err != nil {
logger.L().Fatal("", helpers.String("error during parsing configuration: ", fmt.Sprintf("%v", err)))
}

}