Skip to content

Commit

Permalink
[Auditbeat] fim(ebpf): enrich file events with container id (#38328)
Browse files Browse the repository at this point in the history
* fim(ebpf): enrich file events with container id

* fix(fim/ebpf): make container id event field ecs-compliant

---------

Co-authored-by: Panos Koutsovasilis <panos.koutsovasilis@elastic.co>
  • Loading branch information
mmat11 and pkoutsovasilis committed Apr 8, 2024
1 parent 0ca93e1 commit 5b0b682
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 31 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff]
- Add linux capabilities to processes in the system/process. {pull}37453[37453]
- Add opt-in eBPF backend for file_integrity module. {pull}37223[37223]
- Add process data to file events (Linux only, eBPF backend). {pull}38199[38199]
- Add container id to file events (Linux only, eBPF backend). {pull}38328[38328]

*Filebeat*

Expand Down
4 changes: 2 additions & 2 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12287,11 +12287,11 @@ SOFTWARE.

--------------------------------------------------------------------------------
Dependency : github.com/elastic/ebpfevents
Version: v0.5.0
Version: v0.6.0
Licence type (autodetected): Apache-2.0
--------------------------------------------------------------------------------

Contents of probable licence file $GOMODCACHE/github.com/elastic/ebpfevents@v0.5.0/LICENSE.txt:
Contents of probable licence file $GOMODCACHE/github.com/elastic/ebpfevents@v0.6.0/LICENSE.txt:

The https://github.com/elastic/ebpfevents repository contains source code under
various licenses:
Expand Down
23 changes: 14 additions & 9 deletions auditbeat/module/file_integrity/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,16 @@ func (d Digest) MarshalText() ([]byte, error) { return []byte(d.String()), nil }

// Event describes the filesystem change and includes metadata about the file.
type Event struct {
Timestamp time.Time `json:"timestamp"` // Time of event.
Path string `json:"path"` // The path associated with the event.
TargetPath string `json:"target_path,omitempty"` // Target path for symlinks.
Info *Metadata `json:"info"` // File metadata (if the file exists).
Source Source `json:"source"` // Source of the event.
Action Action `json:"action"` // Action (like created, updated).
Hashes map[HashType]Digest `json:"hash,omitempty"` // File hashes.
ParserResults mapstr.M `json:"file,omitempty"` // Results from running file parsers.
Process *Process `json:"process,omitempty"` // Process data. Available only on Linux when using the eBPF backend.
Timestamp time.Time `json:"timestamp"` // Time of event.
Path string `json:"path"` // The path associated with the event.
TargetPath string `json:"target_path,omitempty"` // Target path for symlinks.
Info *Metadata `json:"info"` // File metadata (if the file exists).
Source Source `json:"source"` // Source of the event.
Action Action `json:"action"` // Action (like created, updated).
Hashes map[HashType]Digest `json:"hash,omitempty"` // File hashes.
ParserResults mapstr.M `json:"file,omitempty"` // Results from running file parsers.
Process *Process `json:"process,omitempty"` // Process data. Available only on Linux when using the eBPF backend.
ContainerID string `json:"container_id,omitempty"` // Unique container ID. Available only on Linux when using the eBPF backend.

// Metadata
rtt time.Duration // Time taken to collect the info.
Expand Down Expand Up @@ -400,6 +401,10 @@ func buildMetricbeatEvent(e *Event, existedBefore bool) mb.Event {
out.MetricSetFields.Put("process", process)
}

if e.ContainerID != "" {
out.MetricSetFields.Put("container.id", e.ContainerID)
}

if len(e.Hashes) > 0 {
hashes := make(mapstr.M, len(e.Hashes))
for hashType, digest := range e.Hashes {
Expand Down
49 changes: 35 additions & 14 deletions auditbeat/module/file_integrity/event_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ import (
"os"
"os/user"
"path/filepath"
"regexp"
"strconv"
"time"

"github.com/elastic/beats/v7/libbeat/ebpf/sys"
"github.com/elastic/ebpfevents"
)

// cgroupRegex captures 64-character lowercase hexadecimal container IDs found in cgroup paths.
var cgroupRegex = regexp.MustCompile(`[-/]([0-9a-f]{64})(\.scope)?$`)

// NewEventFromEbpfEvent creates a new Event from an ebpfevents.Event.
func NewEventFromEbpfEvent(
ee ebpfevents.Event,
Expand All @@ -39,12 +43,12 @@ func NewEventFromEbpfEvent(
isExcludedPath func(string) bool,
) (Event, bool) {
var (
path, target string
action Action
metadata Metadata
process Process
err error
errors []error
path, target, cgroupPath string
action Action
metadata Metadata
process Process
err error
errors []error
)
switch ee.Type {
case ebpfevents.EventTypeFileCreate:
Expand All @@ -67,6 +71,8 @@ func NewEventFromEbpfEvent(
if err != nil {
errors = append(errors, err)
}

cgroupPath = fileCreateEvent.CgroupPath
case ebpfevents.EventTypeFileRename:
action = Moved

Expand All @@ -87,6 +93,8 @@ func NewEventFromEbpfEvent(
if err != nil {
errors = append(errors, err)
}

cgroupPath = fileRenameEvent.CgroupPath
case ebpfevents.EventTypeFileDelete:
action = Deleted

Expand All @@ -102,6 +110,8 @@ func NewEventFromEbpfEvent(
if err != nil {
errors = append(errors, err)
}

cgroupPath = fileDeleteEvent.CgroupPath
case ebpfevents.EventTypeFileModify:
fileModifyEvent := ee.Body.(*ebpfevents.FileModify)

Expand All @@ -128,17 +138,20 @@ func NewEventFromEbpfEvent(
if err != nil {
errors = append(errors, err)
}

cgroupPath = fileModifyEvent.CgroupPath
}

event := Event{
Timestamp: time.Now().UTC(),
Path: path,
TargetPath: target,
Info: &metadata,
Source: SourceEBPF,
Action: action,
Process: &process,
errors: errors,
Timestamp: time.Now().UTC(),
Path: path,
TargetPath: target,
Info: &metadata,
Source: SourceEBPF,
Action: action,
Process: &process,
ContainerID: containerIDFromCgroupPath(cgroupPath),
errors: errors,
}

if event.Action == Deleted {
Expand All @@ -158,6 +171,14 @@ func NewEventFromEbpfEvent(
return event, true
}

func containerIDFromCgroupPath(path string) string {
matches := cgroupRegex.FindStringSubmatch(path)
if len(matches) > 1 {
return matches[1]
}
return ""
}

func metadataFromFileCreate(evt *ebpfevents.FileCreate) (Metadata, error) {
var md Metadata
fillExtendedAttributes(&md, evt.Path)
Expand Down
9 changes: 6 additions & 3 deletions auditbeat/module/file_integrity/event_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
)

func TestNewEventFromEbpfEvent(t *testing.T) {
containerID := "d12fe576354a1805165303a4e34a69e5fe8db791ceb7e545f17811d1fbfba68f"
ebpfEvent := ebpfevents.Event{
Header: ebpfevents.Header{
Type: ebpfevents.EventTypeFileCreate,
Expand All @@ -52,6 +53,7 @@ func TestNewEventFromEbpfEvent(t *testing.T) {
Suid: 5,
Sgid: 6,
},
CgroupPath: "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod123.slice/cri-containerd-" + containerID + ".scope",
},
}
event, ok := NewEventFromEbpfEvent(
Expand All @@ -72,9 +74,10 @@ func TestNewEventFromEbpfEvent(t *testing.T) {
Group: event.Info.Group,
Mode: os.FileMode(0o644),
},
Process: event.Process, // 1:1 copy this as it changes on every machine
Source: SourceEBPF,
errors: nil,
Process: event.Process, // 1:1 copy this as it changes on every machine
ContainerID: containerID,
Source: SourceEBPF,
errors: nil,
}
event.Timestamp = expectedEvent.Timestamp

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ require (
github.com/aws/smithy-go v1.13.5
github.com/awslabs/kinesis-aggregation/go/v2 v2.0.0-20220623125934-28468a6701b5
github.com/elastic/bayeux v1.0.5
github.com/elastic/ebpfevents v0.5.0
github.com/elastic/ebpfevents v0.6.0
github.com/elastic/elastic-agent-autodiscover v0.6.8
github.com/elastic/elastic-agent-libs v0.7.5
github.com/elastic/elastic-agent-shipper-client v0.5.1-0.20230228231646-f04347b666f3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -672,8 +672,8 @@ github.com/elastic/bayeux v1.0.5 h1:UceFq01ipmT3S8DzFK+uVAkbCdiPR0Bqei8qIGmUeY0=
github.com/elastic/bayeux v1.0.5/go.mod h1:CSI4iP7qeo5MMlkznGvYKftp8M7qqP/3nzmVZoXHY68=
github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3 h1:lnDkqiRFKm0rxdljqrj3lotWinO9+jFmeDXIC4gvIQs=
github.com/elastic/dhcp v0.0.0-20200227161230-57ec251c7eb3/go.mod h1:aPqzac6AYkipvp4hufTyMj5PDIphF3+At8zr7r51xjY=
github.com/elastic/ebpfevents v0.5.0 h1:QkyMAYWo3fXFbYtXAXU8sZu2SQ4LXVYC6gLXIWXy02E=
github.com/elastic/ebpfevents v0.5.0/go.mod h1:ESG9gw7N+n5yCCMgdg1IIJENKWSmX7+X0Fi9GUs9nvU=
github.com/elastic/ebpfevents v0.6.0 h1:BrL3m7JFK7U6h2jkbk3xAWWs//IZnugCHEDds5u2v68=
github.com/elastic/ebpfevents v0.6.0/go.mod h1:ESG9gw7N+n5yCCMgdg1IIJENKWSmX7+X0Fi9GUs9nvU=
github.com/elastic/elastic-agent-autodiscover v0.6.8 h1:BSXz+QwjZAEt08G+T3GDGl14Bh9a6zD8luNCvZut/b8=
github.com/elastic/elastic-agent-autodiscover v0.6.8/go.mod h1:hFeFqneS2r4jD0/QzGkrNk0YVdN0JGh7lCWdsH7zcI4=
github.com/elastic/elastic-agent-client/v7 v7.8.1 h1:J9wZc/0mUvSEok0X5iR5+n60Jgb+AWooKddb3XgPWqM=
Expand Down

0 comments on commit 5b0b682

Please sign in to comment.