Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Auditbeat] fim(ebpf): enrich file events with container id #38328

Merged
merged 2 commits into from
Apr 8, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,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)
nicholasberlin marked this conversation as resolved.
Show resolved Hide resolved
}

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 @@ -671,8 +671,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
Loading