From cca3666060512a6c82722e4820d07ab49aa690a2 Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Tue, 5 May 2020 11:32:37 -0400 Subject: [PATCH] [Auditbeat] Add system module login dataset ECS categorization fields (#18034) * [Auditbeat] Add system module login dataset ECS categorization fields * add changelog entry * Add related.user and related.ip (cherry picked from commit 6797b64f1338ef536fe47a84c0872453e3e5d565) --- CHANGELOG.next.asciidoc | 4 ++++ x-pack/auditbeat/module/system/login/login.go | 20 ++++++++++++---- .../module/system/login/login_test.go | 24 +++++++++++-------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 4bf08898fc8..572aae04170 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -283,6 +283,10 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Fix syscall kprobe arguments for 32-bit systems in socket module. {pull}17500[17500] - Fix memory leak on when we miss socket close kprobe events. {pull}17500[17500] - Add system module process dataset ECS categorization fields. {pull}18032[18032] +- Add system module socket dataset ECS categorization fields. {pull}18036[18036] +- Add ECS categories for system module host dataset. {pull}18031[18031] +- Add system module package dataset ECS categorization fields. {pull}18033[18033] +- Add system module login dataset ECS categorization fields. {pull}18034[18034] *Filebeat* diff --git a/x-pack/auditbeat/module/system/login/login.go b/x-pack/auditbeat/module/system/login/login.go index 8dc01b95e68..01e96e4dbc1 100644 --- a/x-pack/auditbeat/module/system/login/login.go +++ b/x-pack/auditbeat/module/system/login/login.go @@ -178,7 +178,7 @@ func (ms *MetricSet) loginEvent(loginRecord *LoginRecord) mb.Event { if loginRecord.Username != "" { event.RootFields.Put("user.name", loginRecord.Username) - + event.RootFields.Put("related.user", []string{loginRecord.Username}) if loginRecord.UID != -1 { event.RootFields.Put("user.id", loginRecord.UID) } @@ -194,6 +194,7 @@ func (ms *MetricSet) loginEvent(loginRecord *LoginRecord) mb.Event { if loginRecord.IP != nil { event.RootFields.Put("source.ip", loginRecord.IP) + event.RootFields.Put("related.ip", []string{loginRecord.IP.String()}) } if loginRecord.Hostname != "" && loginRecord.Hostname != loginRecord.IP.String() { @@ -202,13 +203,22 @@ func (ms *MetricSet) loginEvent(loginRecord *LoginRecord) mb.Event { switch loginRecord.Type { case userLoginRecord: - event.RootFields.Put("event.category", "authentication") + event.RootFields.Put("event.category", []string{"authentication"}) event.RootFields.Put("event.outcome", "success") - event.RootFields.Put("event.type", "authentication_success") + event.RootFields.Put("event.type", []string{"start", "authentication_success"}) case userLoginFailedRecord: - event.RootFields.Put("event.category", "authentication") + event.RootFields.Put("event.category", []string{"authentication"}) event.RootFields.Put("event.outcome", "failure") - event.RootFields.Put("event.type", "authentication_failure") + event.RootFields.Put("event.type", []string{"start", "authentication_failure"}) + case userLogoutRecord: + event.RootFields.Put("event.category", []string{"authentication"}) + event.RootFields.Put("event.type", []string{"end"}) + case bootRecord: + event.RootFields.Put("event.category", []string{"host"}) + event.RootFields.Put("event.type", []string{"start"}) + case shutdownRecord: + event.RootFields.Put("event.category", []string{"host"}) + event.RootFields.Put("event.type", []string{"end"}) } return event diff --git a/x-pack/auditbeat/module/system/login/login_test.go b/x-pack/auditbeat/module/system/login/login_test.go index 8c1bccc7753..818ad18314e 100644 --- a/x-pack/auditbeat/module/system/login/login_test.go +++ b/x-pack/auditbeat/module/system/login/login_test.go @@ -84,10 +84,10 @@ func TestWtmp(t *testing.T) { // utmpdump: [7] [14962] [ts/2] [vagrant ] [pts/2 ] [10.0.2.2 ] [10.0.2.2 ] [2019-01-24T09:51:51,367964+00:00] checkFieldValue(t, events[0].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_success"}) checkFieldValue(t, events[0].RootFields, "event.action", "user_login") checkFieldValue(t, events[0].RootFields, "event.outcome", "success") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_success") checkFieldValue(t, events[0].RootFields, "process.pid", 14962) checkFieldValue(t, events[0].RootFields, "source.ip", "10.0.2.2") checkFieldValue(t, events[0].RootFields, "user.name", "vagrant") @@ -123,10 +123,14 @@ func TestWtmp(t *testing.T) { } checkFieldValue(t, events[0].RootFields, "event.kind", "event") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"end"}) checkFieldValue(t, events[0].RootFields, "event.action", "user_logout") checkFieldValue(t, events[0].RootFields, "process.pid", 14962) checkFieldValue(t, events[0].RootFields, "source.ip", "10.0.2.2") + checkFieldValue(t, events[0].RootFields, "related.ip", []string{"10.0.2.2"}) checkFieldValue(t, events[0].RootFields, "user.name", "vagrant") + checkFieldValue(t, events[0].RootFields, "related.user", []string{"vagrant"}) checkFieldValue(t, events[0].RootFields, "user.terminal", "pts/2") } @@ -156,10 +160,10 @@ func TestBtmp(t *testing.T) { // utmpdump: [6] [03307] [ ] [root ] [ssh:notty ] [10.0.2.2 ] [10.0.2.2 ] [2019-02-20T17:42:26,000000+0000] checkFieldValue(t, events[0].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_failure"}) checkFieldValue(t, events[0].RootFields, "event.action", "user_login") checkFieldValue(t, events[0].RootFields, "event.outcome", "failure") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_failure") checkFieldValue(t, events[0].RootFields, "process.pid", 3307) checkFieldValue(t, events[0].RootFields, "source.ip", "10.0.2.2") checkFieldValue(t, events[0].RootFields, "user.id", 0) @@ -171,10 +175,10 @@ func TestBtmp(t *testing.T) { // The second UTMP entry in the btmp test file is a duplicate of the first, this is what Ubuntu 18.04 generates. // utmpdump: [6] [03307] [ ] [root ] [ssh:notty ] [10.0.2.2 ] [10.0.2.2 ] [2019-02-20T17:42:26,000000+0000] checkFieldValue(t, events[1].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_failure"}) checkFieldValue(t, events[1].RootFields, "event.action", "user_login") checkFieldValue(t, events[1].RootFields, "event.outcome", "failure") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_failure") checkFieldValue(t, events[1].RootFields, "process.pid", 3307) checkFieldValue(t, events[1].RootFields, "source.ip", "10.0.2.2") checkFieldValue(t, events[1].RootFields, "user.id", 0) @@ -185,10 +189,10 @@ func TestBtmp(t *testing.T) { // utmpdump: [7] [03788] [/0 ] [elastic ] [pts/0 ] [ ] [0.0.0.0 ] [2019-02-20T17:45:08,447344+0000] checkFieldValue(t, events[2].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_failure"}) checkFieldValue(t, events[2].RootFields, "event.action", "user_login") checkFieldValue(t, events[2].RootFields, "event.outcome", "failure") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_failure") checkFieldValue(t, events[2].RootFields, "process.pid", 3788) checkFieldValue(t, events[2].RootFields, "source.ip", "0.0.0.0") checkFieldValue(t, events[2].RootFields, "user.name", "elastic") @@ -198,10 +202,10 @@ func TestBtmp(t *testing.T) { // utmpdump: [7] [03788] [/0 ] [UNKNOWN ] [pts/0 ] [ ] [0.0.0.0 ] [2019-02-20T17:45:15,765318+0000] checkFieldValue(t, events[3].RootFields, "event.kind", "event") - checkFieldValue(t, events[0].RootFields, "event.category", "authentication") + checkFieldValue(t, events[0].RootFields, "event.category", []string{"authentication"}) + checkFieldValue(t, events[0].RootFields, "event.type", []string{"start", "authentication_failure"}) checkFieldValue(t, events[3].RootFields, "event.action", "user_login") checkFieldValue(t, events[3].RootFields, "event.outcome", "failure") - checkFieldValue(t, events[0].RootFields, "event.type", "authentication_failure") checkFieldValue(t, events[3].RootFields, "process.pid", 3788) checkFieldValue(t, events[3].RootFields, "source.ip", "0.0.0.0") contains, err := events[3].RootFields.HasKey("user.id")