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] Cherry-pick #10500 to 6.x: System module: Add entity_id fields #10570

Merged
merged 1 commit into from
Feb 5, 2019
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 @@ -152,6 +152,7 @@ https://github.com/elastic/beats/compare/v6.6.0...6.x[Check the HEAD diff]
- System module `process` dataset: Add user information to processes. {pull}9963[9963]
- Add system `package` dataset. {pull}10225[10225]
- Add system module `login` dataset. {pull}9327[9327]
- Add `entity_id` fields. {pull}10500[10500]

*Filebeat*

Expand Down
43 changes: 43 additions & 0 deletions auditbeat/docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -3749,6 +3749,16 @@ If the event describes an action, this fields contains the outcome of that actio
--


*`user.entity_id`*::
+
--
type: keyword

ID uniquely identifying the user on a host. It is computed as a SHA-256 hash of the host ID, user ID, and user name.


--

*`user.terminal`*::
+
--
Expand All @@ -3757,6 +3767,28 @@ type: keyword
Terminal of the user.


--


*`process.entity_id`*::
+
--
type: keyword

ID uniquely identifying the process. It is computed as a SHA-256 hash of the host ID, PID, and process start time.


--


*`socket.entity_id`*::
+
--
type: keyword

ID uniquely identifying the socket. It is computed as a SHA-256 hash of the host ID, socket inode, local IP, local port, remote IP, and remote port.


--

[float]
Expand Down Expand Up @@ -3936,6 +3968,17 @@ The operating system's kernel version.



*`system.audit.package.entity_id`*::
+
--
type: keyword

ID uniquely identifying the package. It is computed as a SHA-256 hash of the
host ID, package name, and package version.


--

*`system.audit.package.name`*::
+
--
Expand Down
23 changes: 23 additions & 0 deletions x-pack/auditbeat/module/system/_meta/fields.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,34 @@
- name: user
type: group
fields:
- name: entity_id
type: keyword
description: >
ID uniquely identifying the user on a host. It is computed as a SHA-256 hash
of the host ID, user ID, and user name.
- name: terminal
type: keyword
description: >
Terminal of the user.

- name: process
type: group
fields:
- name: entity_id
type: keyword
description: >
ID uniquely identifying the process. It is computed as a SHA-256 hash of the
host ID, PID, and process start time.

- name: socket
type: group
fields:
- name: entity_id
type: keyword
description: >
ID uniquely identifying the socket. It is computed as a SHA-256 hash of the
host ID, socket inode, local IP, local port, remote IP, and remote port.

- name: system.audit
type: group
description: >
Expand Down
26 changes: 26 additions & 0 deletions x-pack/auditbeat/module/system/entity_hash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.

package system

import (
"crypto/sha256"
"encoding/hex"
"hash"
)

// EntityHash calculates a standard entity hash.
type EntityHash struct {
hash.Hash
}

// NewEntityHash creates a new EntityHash.
func NewEntityHash() EntityHash {
return EntityHash{sha256.New()}
}

// Sum returns the hash as a string.
func (h *EntityHash) Sum() string {
return hex.EncodeToString(h.Hash.Sum(nil))
}
2 changes: 1 addition & 1 deletion x-pack/auditbeat/module/system/fields.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion x-pack/auditbeat/module/system/package/_meta/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"event": {
"action": "existing_package",
"dataset": "package",
"id": "9ac4ea4c-5a0c-475f-b4c9-ec9d981ff11b",
"id": "ed069c3f-1d30-4e17-845b-cc915cf108b4",
"kind": "state",
"module": "system"
},
Expand All @@ -18,6 +18,7 @@
"system": {
"audit": {
"package": {
"entity_id": "c2c455d9f99375d9fefc61da52fa93778976d54b1964164778058980531d77dc",
"installtime": "2018-08-30T18:41:23.85657356+01:00",
"name": "zstd",
"summary": "Zstandard is a real-time compression algorithm",
Expand Down
5 changes: 5 additions & 0 deletions x-pack/auditbeat/module/system/package/_meta/fields.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
`package` contains information about an installed or removed package.
release: experimental
fields:
- name: entity_id
type: keyword
description: >
ID uniquely identifying the package. It is computed as a SHA-256 hash of the
host ID, package name, and package version.
- name: name
type: keyword
description: >
Expand Down
34 changes: 23 additions & 11 deletions x-pack/auditbeat/module/system/package/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/elastic/beats/libbeat/logp"
"github.com/elastic/beats/metricbeat/mb"
"github.com/elastic/beats/x-pack/auditbeat/cache"
"github.com/elastic/beats/x-pack/auditbeat/module/system"
"github.com/elastic/go-sysinfo"
"github.com/elastic/go-sysinfo/types"
)
Expand Down Expand Up @@ -85,7 +86,7 @@ func init() {

// MetricSet collects data about the system's packages.
type MetricSet struct {
mb.BaseMetricSet
system.SystemMetricSet
config config
log *logp.Logger
cache *cache.Cache
Expand Down Expand Up @@ -155,6 +156,15 @@ func (pkg Package) toMapStr() common.MapStr {
return mapstr
}

// entityID creates an ID that uniquely identifies this package across machines.
func (pkg Package) entityID(hostID string) string {
h := system.NewEntityHash()
h.Write([]byte(hostID))
h.Write([]byte(pkg.Name))
h.Write([]byte(pkg.Version))
return h.Sum()
}

func getOS() (*types.OSInfo, error) {
host, err := sysinfo.Host()
if err != nil {
Expand Down Expand Up @@ -184,11 +194,11 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
}

ms := &MetricSet{
BaseMetricSet: base,
config: config,
log: logp.NewLogger(metricsetName),
cache: cache.New(),
bucket: bucket,
SystemMetricSet: system.NewSystemMetricSet(base),
config: config,
log: logp.NewLogger(metricsetName),
cache: cache.New(),
bucket: bucket,
}

osInfo, err := getOS()
Expand Down Expand Up @@ -282,7 +292,7 @@ func (ms *MetricSet) reportState(report mb.ReporterV2) error {
return errors.Wrap(err, "error generating state ID")
}
for _, pkg := range packages {
event := packageEvent(pkg, eventTypeState, eventActionExistingPackage)
event := ms.packageEvent(pkg, eventTypeState, eventActionExistingPackage)
event.RootFields.Put("event.id", stateID.String())
report.Event(event)
}
Expand Down Expand Up @@ -327,19 +337,19 @@ func (ms *MetricSet) reportChanges(report mb.ReporterV2) error {
if missingPkg.Name == newPkg.Name {
found = true
updated[newPkg.Name] = struct{}{}
report.Event(packageEvent(newPkg, eventTypeEvent, eventActionPackageUpdated))
report.Event(ms.packageEvent(newPkg, eventTypeEvent, eventActionPackageUpdated))
break
}
}

if !found {
report.Event(packageEvent(missingPkg, eventTypeEvent, eventActionPackageRemoved))
report.Event(ms.packageEvent(missingPkg, eventTypeEvent, eventActionPackageRemoved))
}
}

for _, newPkg := range newPackages {
if _, contains := updated[newPkg.Name]; !contains {
report.Event(packageEvent(newPkg, eventTypeEvent, eventActionPackageInstalled))
report.Event(ms.packageEvent(newPkg, eventTypeEvent, eventActionPackageInstalled))
}
}

Expand All @@ -360,7 +370,7 @@ func convertToPackage(cacheValues []interface{}) []*Package {
return packages
}

func packageEvent(pkg *Package, eventType string, action eventAction) mb.Event {
func (ms *MetricSet) packageEvent(pkg *Package, eventType string, action eventAction) mb.Event {
event := mb.Event{
RootFields: common.MapStr{
"event": common.MapStr{
Expand All @@ -372,6 +382,8 @@ func packageEvent(pkg *Package, eventType string, action eventAction) mb.Event {
MetricSetFields: pkg.toMapStr(),
}

event.MetricSetFields.Put("entity_id", pkg.entityID(ms.HostID()))

if pkg.Error != nil {
event.RootFields.Put("error.message", pkg.Error.Error())
}
Expand Down
1 change: 1 addition & 0 deletions x-pack/auditbeat/module/system/process/_meta/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"args": [
"zsh"
],
"entity_id": "e2e0c5f51b093b71afed6af23debc906090d2f2f2afa9b930bf7e0803a6b53d5",
"executable": "/bin/zsh",
"name": "zsh",
"pid": 12936,
Expand Down
37 changes: 25 additions & 12 deletions x-pack/auditbeat/module/system/process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package process

import (
"encoding/binary"
"fmt"
"os"
"os/user"
Expand All @@ -21,6 +22,7 @@ import (
"github.com/elastic/beats/libbeat/logp"
"github.com/elastic/beats/metricbeat/mb"
"github.com/elastic/beats/x-pack/auditbeat/cache"
"github.com/elastic/beats/x-pack/auditbeat/module/system"
"github.com/elastic/go-sysinfo"
"github.com/elastic/go-sysinfo/types"
)
Expand Down Expand Up @@ -71,7 +73,7 @@ func init() {

// MetricSet collects data about the host.
type MetricSet struct {
mb.BaseMetricSet
system.SystemMetricSet
config Config
cache *cache.Cache
log *logp.Logger
Expand Down Expand Up @@ -111,6 +113,15 @@ func (p Process) toMapStr() common.MapStr {
}
}

// entityID creates an ID that uniquely identifies this process across machines.
func (p Process) entityID(hostID string) string {
h := system.NewEntityHash()
h.Write([]byte(hostID))
binary.Write(h, binary.LittleEndian, int64(p.Info.PID))
binary.Write(h, binary.LittleEndian, int64(p.Info.StartTime.Nanosecond()))
return h.Sum()
}

// New constructs a new MetricSet.
func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
cfgwarn.Experimental("The %v/%v dataset is experimental", moduleName, metricsetName)
Expand All @@ -126,11 +137,11 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) {
}

ms := &MetricSet{
BaseMetricSet: base,
config: config,
log: logp.NewLogger(metricsetName),
cache: cache.New(),
bucket: bucket,
SystemMetricSet: system.NewSystemMetricSet(base),
config: config,
log: logp.NewLogger(metricsetName),
cache: cache.New(),
bucket: bucket,
}

// Load from disk: Time when state was last sent
Expand Down Expand Up @@ -204,12 +215,12 @@ func (ms *MetricSet) reportState(report mb.ReporterV2) error {
}
for _, p := range processes {
if p.Error == nil {
event := processEvent(p, eventTypeState, eventActionExistingProcess)
event := ms.processEvent(p, eventTypeState, eventActionExistingProcess)
event.RootFields.Put("event.id", stateID.String())
report.Event(event)
} else {
ms.log.Warn(p.Error)
report.Event(processEvent(p, eventTypeError, eventActionProcessError))
report.Event(ms.processEvent(p, eventTypeError, eventActionProcessError))
}
}

Expand Down Expand Up @@ -245,25 +256,25 @@ func (ms *MetricSet) reportChanges(report mb.ReporterV2) error {
p := cacheValue.(*Process)

if p.Error == nil {
report.Event(processEvent(p, eventTypeEvent, eventActionProcessStarted))
report.Event(ms.processEvent(p, eventTypeEvent, eventActionProcessStarted))
} else {
ms.log.Warn(p.Error)
report.Event(processEvent(p, eventTypeError, eventActionProcessError))
report.Event(ms.processEvent(p, eventTypeError, eventActionProcessError))
}
}

for _, cacheValue := range stopped {
p := cacheValue.(*Process)

if p.Error == nil {
report.Event(processEvent(p, eventTypeEvent, eventActionProcessStopped))
report.Event(ms.processEvent(p, eventTypeEvent, eventActionProcessStopped))
}
}

return nil
}

func processEvent(process *Process, eventType string, action eventAction) mb.Event {
func (ms *MetricSet) processEvent(process *Process, eventType string, action eventAction) mb.Event {
event := mb.Event{
RootFields: common.MapStr{
"event": common.MapStr{
Expand Down Expand Up @@ -302,6 +313,8 @@ func processEvent(process *Process, eventType string, action eventAction) mb.Eve
event.RootFields.Put("error.message", process.Error.Error())
}

event.RootFields.Put("process.entity_id", process.entityID(ms.HostID()))

return event
}

Expand Down
Loading