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(kprobes): enrich file events by coupling add_process_metadata processor #38776

Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9ae8f53
feat(processors/process_metadata): support reporting group id and name
pkoutsovasilis Apr 3, 2024
d022a61
feat(processors/process_metadata): support reporting process entity_id
pkoutsovasilis Apr 3, 2024
79be3a6
feat(fim/kprobes): allow metricsSets to expose beat processors after …
pkoutsovasilis Apr 3, 2024
de77ec4
doc: update CHANGELOG.next.asciidoc
pkoutsovasilis Apr 3, 2024
4f3149d
fix(linter): SA1015 prevent leaking the ticker
pkoutsovasilis Apr 4, 2024
fe8973e
fix(linter): SA1019 mark metricbeat/mb deprecation warnings that are …
pkoutsovasilis Apr 4, 2024
8f99586
fix(linter): check for return err
pkoutsovasilis Apr 4, 2024
ae86af4
fix(linter): prealloc slices
pkoutsovasilis Apr 4, 2024
46457aa
fix(linter): remove unused field
pkoutsovasilis Apr 4, 2024
da3ca7c
fix(linter): G601 prevent implicit memory aliasing in for loop
pkoutsovasilis Apr 4, 2024
63fd97d
doc: update CHANGELOG.next.asciidoc
pkoutsovasilis Apr 8, 2024
b68c2df
Merge remote-tracking branch 'refs/remotes/beats/main' into pkoutsova…
pkoutsovasilis Apr 9, 2024
586d027
fix: update filebaet fields.asciidoc (unrelated to this work)
pkoutsovasilis Apr 9, 2024
740f35b
doc: remove irrelevant changes from CHANGELOG.next.asciidoc
pkoutsovasilis Apr 9, 2024
bbb9d4f
feat(processor/metadata): introduce new type based allocation func
pkoutsovasilis Apr 12, 2024
0caf10d
feat(fim/kprobe): instantiate new processor alongside a new kprobes e…
pkoutsovasilis Apr 12, 2024
ca94e5f
fix(fim): remove redundant whitespace
pkoutsovasilis Apr 12, 2024
e335b2f
doc(metricbeat): enrich documentation about Processors attached to a …
pkoutsovasilis Apr 12, 2024
89b5128
Merge remote-tracking branch 'refs/remotes/beats/main' into pkoutsova…
pkoutsovasilis Apr 12, 2024
32c5c7c
fix(fim): gofumpt eventreader_kprobes.go
pkoutsovasilis Apr 12, 2024
a121cd8
fix(add_process_metadata): gofmt add_process_metadata.go gosysinfo_pr…
pkoutsovasilis Apr 12, 2024
1fbddbf
fix(lint): goimports eventreader_kprobes.go
pkoutsovasilis Apr 12, 2024
7bfae26
fix(winlogbeat): generate include list [unrelated to this PR]
pkoutsovasilis Apr 12, 2024
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 @@ -151,6 +151,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff]
- 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]
- Add process.entity_id, process.group.name and process.group.id in add_process_metadata processor. Make fim module with kprobes backend to always add an appropriately configured add_process_metadata processor to enrich file events {pull}38776[38776]

*Filebeat*

Expand Down
47 changes: 47 additions & 0 deletions auditbeat/module/file_integrity/eventreader_kprobes.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@ import (
"errors"
"fmt"
"path/filepath"
"sync"
"time"

"github.com/elastic/beats/v7/auditbeat/module/file_integrity/kprobes"
"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/processors/add_process_metadata"

conf "github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent-libs/mapstr"

"golang.org/x/sys/unix"
)
Expand All @@ -39,6 +44,41 @@ type kProbesReader struct {
log *logp.Logger

parsers []FileParser

processor beat.Processor
}

var processMetadataProcessorOnce = sync.OnceValues(func() (beat.Processor, error) {
config, err := conf.NewConfigFrom(mapstr.M{
andrewkroh marked this conversation as resolved.
Show resolved Hide resolved
"match_pids": []string{"process.pid"},
"overwrite_keys": true,
})

if err != nil {
return nil, err
}

return add_process_metadata.NewWithCache(config)
})

func newKProbesReader(config Config, l *logp.Logger, parsers []FileParser) (*kProbesReader, error) {

pkoutsovasilis marked this conversation as resolved.
Show resolved Hide resolved
processor, err := processMetadataProcessorOnce()
if err != nil {
return nil, err
}

return &kProbesReader{
config: config,
eventC: make(chan Event),
log: l,
parsers: parsers,
processor: processor,
}, nil
}

func (r kProbesReader) Processor() beat.Processor {
return r.processor
}

func (r kProbesReader) Start(done <-chan struct{}) (<-chan Event, error) {
Expand Down Expand Up @@ -152,6 +192,13 @@ func (r kProbesReader) nextEvent(done <-chan struct{}) *Event {
start := time.Now()
e := NewEvent(event.Path, kProbeTypeToAction(event.Op), SourceKProbes,
r.config.MaxFileSizeBytes, r.config.HashTypes, r.parsers)

if e.Process == nil {
e.Process = &Process{}
}

e.Process.PID = event.PID

e.rtt = time.Since(start)

return &e
Expand Down
6 changes: 1 addition & 5 deletions auditbeat/module/file_integrity/eventreader_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,7 @@ func NewEventReader(c Config, logger *logp.Logger) (EventProducer, error) {
if c.Backend == BackendKprobes {
l := logger.Named("kprobes")
l.Info("selected backend: kprobes")
return &kProbesReader{
config: c,
log: l,
parsers: FileParsers(c),
}, nil
return newKProbesReader(c, l, FileParsers(c))
}

// unimplemented
Expand Down
20 changes: 20 additions & 0 deletions auditbeat/module/file_integrity/metricset.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
bolt "go.etcd.io/bbolt"

"github.com/elastic/beats/v7/auditbeat/datastore"
"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/metricbeat/mb"
"github.com/elastic/beats/v7/metricbeat/mb/parse"
"github.com/elastic/elastic-agent-libs/logp"
Expand Down Expand Up @@ -62,6 +63,11 @@ type EventProducer interface {
Start(done <-chan struct{}) (<-chan Event, error)
}

// eventProducerWithProcessor is an EventProducer that requires a Processor
type eventProducerWithProcessor interface {
Processor() beat.Processor
}

// MetricSet for monitoring file integrity.
type MetricSet struct {
mb.BaseMetricSet
Expand All @@ -78,6 +84,9 @@ type MetricSet struct {

// Used when a hash can't be calculated
nullHashes map[HashType]Digest

// Processors
processors []beat.Processor
}

// New returns a new file.MetricSet.
Expand Down Expand Up @@ -105,6 +114,13 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
log: logger,
}

// reader supports a processor
pkoutsovasilis marked this conversation as resolved.
Show resolved Hide resolved
if rWithProcessor, ok := r.(eventProducerWithProcessor); ok {
pkoutsovasilis marked this conversation as resolved.
Show resolved Hide resolved
if proc := rWithProcessor.Processor(); proc != nil {
ms.processors = append(ms.processors, proc)
}
}

ms.nullHashes = make(map[HashType]Digest, len(config.HashTypes))
for _, hashType := range ms.config.HashTypes {
// One byte is enough so that the hashes are persisted to the datastore.
Expand All @@ -117,6 +133,10 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
return ms, nil
}

func (ms *MetricSet) Processors() []beat.Processor {
return ms.processors
}

// Run runs the MetricSet. The method will not return control to the caller
// until it is finished (to stop it close the reporter.Done() channel).
func (ms *MetricSet) Run(reporter mb.PushReporterV2) {
Expand Down
70 changes: 70 additions & 0 deletions filebeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -111136,6 +111136,13 @@ type: keyword

--

*`o365.audit.Activity`*::
+
--
type: keyword

--

*`o365.audit.Actor`*::
+
--
Expand Down Expand Up @@ -111360,6 +111367,13 @@ type: object

--

*`o365.audit.Experience`*::
+
--
type: keyword

--

*`o365.audit.ExtendedProperties.*`*::
+
--
Expand Down Expand Up @@ -111605,13 +111619,41 @@ type: keyword

--

*`o365.audit.ObjectDisplayName`*::
+
--
type: keyword

--

*`o365.audit.ObjectType`*::
+
--
type: keyword

--

*`o365.audit.Operation`*::
+
--
type: keyword

--

*`o365.audit.OperationId`*::
+
--
type: keyword

--

*`o365.audit.OperationProperties`*::
+
--
type: object

--

*`o365.audit.OrganizationId`*::
+
--
Expand Down Expand Up @@ -111661,6 +111703,13 @@ type: keyword

--

*`o365.audit.RequestId`*::
+
--
type: keyword

--

*`o365.audit.ResultStatus`*::
+
--
Expand Down Expand Up @@ -111801,6 +111850,13 @@ type: keyword

--

*`o365.audit.Timestamp`*::
+
--
type: keyword

--

*`o365.audit.UniqueSharingId`*::
+
--
Expand Down Expand Up @@ -111857,6 +111913,20 @@ type: keyword

--

*`o365.audit.WorkspaceId`*::
+
--
type: keyword

--

*`o365.audit.WorkspaceName`*::
+
--
type: keyword

--

*`o365.audit.YammerNetworkId`*::
+
--
Expand Down
36 changes: 29 additions & 7 deletions libbeat/processors/add_process_metadata/add_process_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/elastic/elastic-agent-libs/mapstr"
"github.com/elastic/elastic-agent-system-metrics/metric/system/cgroup"
"github.com/elastic/elastic-agent-system-metrics/metric/system/resolve"
"github.com/elastic/go-sysinfo"
)

const (
Expand Down Expand Up @@ -65,16 +66,19 @@ type addProcessMetadata struct {
cidProvider cidProvider
log *logp.Logger
mappings mapstr.M
uniqueID []byte
}

type processMetadata struct {
name, title, exe, username, userid string
args []string
env map[string]string
startTime time.Time
pid, ppid int
//
fields mapstr.M
entityID string
name, title, exe string
username, userid string
groupname, groupid string
args []string
env map[string]string
startTime time.Time
pid, ppid int
fields mapstr.M
}

type processMetadataProvider interface {
Expand Down Expand Up @@ -134,6 +138,13 @@ func newProcessMetadataProcessorWithProvider(cfg *conf.C, provider processMetada
log: log,
mappings: mappings,
}

if host, _ := sysinfo.Host(); host != nil {
if uniqueID := host.Info().UniqueID; uniqueID != "" {
p.uniqueID = []byte(uniqueID)
}
}

// don't use cgroup.ProcessCgroupPaths to save it from doing the work when container id disabled
if ok := containsValue(mappings, "container.id"); ok {
if withCache && config.CgroupCacheExpireTime != 0 {
Expand Down Expand Up @@ -311,6 +322,7 @@ func (p *addProcessMetadata) String() string {

func (p *processMetadata) toMap() mapstr.M {
process := mapstr.M{
"entity_id": p.entityID,
"name": p.name,
"title": p.title,
"executable": p.exe,
Expand All @@ -332,6 +344,16 @@ func (p *processMetadata) toMap() mapstr.M {
}
process["owner"] = user
}
if p.groupname != "" || p.groupid != "" {
group := mapstr.M{}
if p.groupname != "" {
group["name"] = p.groupname
}
if p.groupid != "" {
group["id"] = p.groupid
}
process["group"] = group
}

return mapstr.M{
"process": process,
Expand Down
Loading
Loading