-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add k8saudiovh plugin in falcosecurity repo
Signed-off-by: scraly <[email protected]>
- Loading branch information
Showing
11 changed files
with
765 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
libk8saudit-ovh.so | ||
.vscode | ||
falco.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Changelog | ||
|
||
## v0.1.0 | ||
|
||
* First version of the `k8saudit-ovh` plugin 🎉 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
SHELL=/bin/bash -o pipefail | ||
GO ?= go | ||
|
||
NAME := k8saudit-ovh | ||
OUTPUT := lib$(NAME).so | ||
|
||
ifeq ($(DEBUG), 1) | ||
GODEBUGFLAGS= GODEBUG=cgocheck=1 | ||
else | ||
GODEBUGFLAGS= GODEBUG=cgocheck=0 | ||
endif | ||
|
||
all: build | ||
|
||
clean: | ||
@rm -f lib$(NAME).so | ||
|
||
build: clean | ||
@$(GODEBUGFLAGS) $(GO) build -buildmode=c-shared -buildvcs=false -o $(OUTPUT) ./plugin | ||
|
||
install: | ||
sudo cp $(OUTPUT) /usr/share/falco/plugins/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
approvers: | ||
- scraly | ||
- Issif |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module github.com/falcosecurity/plugins/plugins/k8saudit-ovh | ||
|
||
go 1.23.3 | ||
|
||
require ( | ||
github.com/falcosecurity/plugin-sdk-go v0.7.4 | ||
github.com/falcosecurity/plugins/plugins/k8saudit v0.11.0 | ||
github.com/gorilla/websocket v1.5.3 | ||
golang.org/x/net v0.32.0 | ||
) | ||
|
||
require ( | ||
github.com/alecthomas/jsonschema v0.0.0-20220216202328-9eeeec9d044b // indirect | ||
github.com/iancoleman/orderedmap v0.3.0 // indirect | ||
github.com/valyala/fastjson v1.6.4 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
github.com/alecthomas/jsonschema v0.0.0-20220216202328-9eeeec9d044b h1:doCpXjVwui6HUN+xgNsNS3SZ0/jUZ68Eb+mJRNOZfog= | ||
github.com/alecthomas/jsonschema v0.0.0-20220216202328-9eeeec9d044b/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60= | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/falcosecurity/plugin-sdk-go v0.7.4 h1:iNV0pgWgJwOHqSCjTw4Hsvtu5WuwoqckAWzpIEy9giQ= | ||
github.com/falcosecurity/plugin-sdk-go v0.7.4/go.mod h1:NP+y22DYOS+G3GDXIXNmzf0CBL3nfPPMoQuHvAzfitQ= | ||
github.com/falcosecurity/plugins/plugins/k8saudit v0.11.0 h1:ywwQ8kQmMS0HL3PuwBSKUmERqePrCSnajxnSCNC0HQY= | ||
github.com/falcosecurity/plugins/plugins/k8saudit v0.11.0/go.mod h1:RmSc1za6asI52w3uVhZGb/p6RoQr2OWmp/Zc8+kiMWw= | ||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= | ||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= | ||
github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc= | ||
github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= | ||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | ||
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= | ||
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= | ||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= | ||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= | ||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= | ||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= | ||
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= | ||
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
package k8sauditovh | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"net" | ||
"net/http" | ||
"net/url" | ||
"os" | ||
"text/template" | ||
"time" | ||
|
||
"github.com/falcosecurity/plugin-sdk-go/pkg/sdk" | ||
"github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins" | ||
"github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins/source" | ||
"github.com/falcosecurity/plugins/plugins/k8saudit/pkg/k8saudit" | ||
|
||
"github.com/gorilla/websocket" | ||
) | ||
|
||
var ( | ||
ID uint32 | ||
Name string | ||
Description string | ||
Contact string | ||
Version string | ||
EventSource string | ||
) | ||
|
||
const ( | ||
pluginName = "k8saudit-ovh" | ||
|
||
// Time allowed to read the next pong message from the client. | ||
pongWait = 60 * time.Second | ||
) | ||
|
||
type PluginConfig struct { | ||
MaxEventSize uint64 `json:"maxEventSize" jsonschema:"title=Maximum event size,description=Maximum size of single audit event (Default: 262144),default=262144"` | ||
} | ||
|
||
// Plugin represents our plugin | ||
type Plugin struct { | ||
k8saudit.Plugin | ||
Logger *log.Logger | ||
Config PluginConfig | ||
} | ||
|
||
// Resets sets the configuration to its default values | ||
func (k *PluginConfig) Reset() { | ||
k.MaxEventSize = uint64(sdk.DefaultEvtSize) | ||
} | ||
|
||
// SetInfo is used to set the Info of the plugin | ||
func (p *Plugin) SetInfo(id uint32, name, description, contact, version, eventSource string) { | ||
ID = id | ||
Name = name | ||
Contact = contact | ||
Version = version | ||
EventSource = eventSource | ||
} | ||
|
||
// Info displays information of the plugin to Falco plugin framework | ||
func (p *Plugin) Info() *plugins.Info { | ||
return &plugins.Info{ | ||
ID: ID, | ||
Name: Name, | ||
Description: Description, | ||
Contact: Contact, | ||
Version: Version, | ||
EventSource: EventSource, | ||
} | ||
} | ||
|
||
// Init is called by the Falco plugin framework as first entry, | ||
// we use it for setting default configuration values and mapping | ||
// values from `init_config` (json format for this plugin) | ||
func (p *Plugin) Init(config string) error { | ||
p.Plugin.Config.Reset() | ||
p.Config.Reset() | ||
p.Logger = log.New(os.Stderr, "["+pluginName+"] ", log.LstdFlags|log.LUTC|log.Lmsgprefix) | ||
return nil | ||
} | ||
|
||
func (p *Plugin) OpenParams() ([]sdk.OpenParam, error) { | ||
return []sdk.OpenParam{ | ||
{Value: "", Desc: "The LDP Websocket URL to use to get the OVHcloud MKS Audit Logs sent to a LDP data stream"}, | ||
}, nil | ||
} | ||
|
||
// Open is called by Falco plugin framework for opening a stream of events, we call that an instance | ||
func (p *Plugin) Open(ovhLDPURL string) (source.Instance, error) { | ||
t, err := template.New("template").Funcs(template.FuncMap{ | ||
"color": color, | ||
"bColor": bColor, | ||
"noColor": func() string { return color("reset") }, | ||
"date": date, | ||
"join": join, | ||
"concat": concat, | ||
"duration": duration, | ||
"int": toInt, | ||
"float": toFloat, | ||
"string": toString, | ||
"get": get, | ||
"column": column, | ||
"begin": begin, | ||
"contain": contain, | ||
"level": level, | ||
}).Parse("{{._appID}}> {{.short_message}}") | ||
if err != nil { | ||
p.Logger.Fatalf("Failed to parse pattern: %s", err.Error()) | ||
} | ||
|
||
if ovhLDPURL == "" { | ||
return nil, fmt.Errorf("OVHcloud LDP URL can't be empty") | ||
} | ||
|
||
eventC := make(chan source.PushEvent) | ||
|
||
go func() { | ||
defer close(eventC) | ||
|
||
u := url.URL{Scheme: "wss", Host: ovhLDPURL, Path: ""} | ||
v, _ := url.QueryUnescape(u.String()) | ||
|
||
headers := make(http.Header) | ||
// headers.Set("Origin", "http://mySelf") | ||
wsChan, _, err := websocket.DefaultDialer.Dial(v, headers) | ||
if err != nil { | ||
eventC <- source.PushEvent{Err: err} | ||
return | ||
} | ||
defer wsChan.Close() | ||
|
||
for { | ||
//wsChan.SetReadDeadline(time.Now().Add(5 * time.Second)) | ||
wsChan.SetReadDeadline(time.Now().Add(pongWait)) | ||
_, msg, err := wsChan.ReadMessage() | ||
|
||
// Keep the WebSocket connection alive | ||
if t, ok := err.(net.Error); ok && t.Timeout() { | ||
// Timeout, send a Ping && continue | ||
if err := wsChan.WriteMessage(websocket.PingMessage, nil); err != nil { | ||
p.Logger.Println("The end host probably closed the connection", err.Error()) | ||
} | ||
continue | ||
} | ||
|
||
if err != nil { | ||
p.Logger.Printf("Error while reading from %q: %q. Will try to reconnect after 1s...\n", u.Host, err.Error()) | ||
time.Sleep(1 * time.Second) | ||
break | ||
} | ||
|
||
// Extract Message | ||
var logMessage struct { | ||
Message string `json:"message"` | ||
} | ||
json.Unmarshal(msg, &logMessage) | ||
|
||
// Extract infos | ||
var message map[string]interface{} | ||
json.Unmarshal([]byte(logMessage.Message), &message) | ||
|
||
var m bytes.Buffer | ||
err = t.Execute(&m, message) | ||
if err != nil { | ||
p.Logger.Println(err) | ||
continue | ||
} | ||
|
||
// Parse audit events payload thanks to k8saudit extract parse and extract methods | ||
values, err := p.Plugin.ParseAuditEventsPayload([]byte(m.String())[12:]) | ||
if err != nil { | ||
p.Logger.Println(err) | ||
continue | ||
} | ||
for _, j := range values { | ||
if j.Err != nil { | ||
p.Logger.Println(j.Err) | ||
continue | ||
} | ||
|
||
eventC <- *j | ||
} | ||
} | ||
}() | ||
return source.NewPushInstance(eventC) | ||
} |
Oops, something went wrong.